Skip to content

node: online mining can accept a foreign coinbase (--mine_online_foreign, --mine_online_reserve) - #2160

Draft
profinch wants to merge 2 commits into
BeamMW:masterfrom
profinch:feat/foreign-coinbase
Draft

profinch wants to merge 2 commits into
BeamMW:masterfrom
profinch:feat/foreign-coinbase

Conversation

@profinch

@profinch profinch commented Oct 8, 2026

Copy link
Copy Markdown

What

Lets a mining pool pay its miners in the block itself, with coinbase outputs the miners created and signed with their own keys, so the pool never holds their coins. It is the coinbase half of a P2Pool for Beam.

Beam is Mimblewimble: whoever creates an output can spend it, so the block builder cannot make outputs for the miners. The miners make them in advance, as pairs: a coinbase output with a public value plus a kernel whose excess is minus the output's blinding factor. Each pair balances by itself, needs no offset and no co-signer, and is made with the miner key and tagged with the owner key exactly like the coinbase of a node mining for that wallet, so the wallet finds it through its ordinary UTXO events. The pool puts the pairs for what each miner is owed into the coinbase, plus one output of its own for the rest (fee, transaction fees, rounding). Consensus already allows any number of coinbase outputs and kernels as long as they add up to the emission plus the fees (since HF6).

The node side

Online mining already lets the owner wallet finalize the block. The only thing in the way is the check at finalization that every coinbase output is recognized by the node's owner key, and the block space reserved for a single coinbase output. Two options, both off by default, so nothing changes unless they are set:

Option Effect
--mine_online_foreign=1 Skip the "outputs correspond to our viewer's Kdf" check at finalization. If the finalization then fails in the chain context (a kernel already visible, a block too large), drop the finalizer and keep mining on the node's own miner key, instead of stalling.
--mine_online_reserve=<bytes> Block space kept free for the coinbase when a block is assembled for finalization, on top of the single output and kernel reserved today.

41 lines over 7 files. Consensus is untouched: a node without the options accepts the blocks.

The second commit is independent and only for test chains: with --consensus=FakePoW the node left mining off whatever the options said; now --mining_threads and --pow_solve_time apply when the solve time is set explicitly, so a FakePoW node can serve its stratum server like a PoW node. Happy to drop it from this PR if you prefer.

Tested

  • Two nodes in one process on a FakePoW chain with every fork active: the mining one with the options and a finalizer paying three miners, the other a stock node validating every block and serving the first miner's wallet. Both end on the same tip; every coinbase output belongs to exactly one key; the wallet finds every coin and spends one; a pair whose kernel is already in the chain makes the node drop the finalizer once and lose no block; without --mine_online_foreign the node refuses the foreign outputs.
  • A private chain end to end with the stock binaries: patched beam-node, the finalizer, the pool server, the miner's tool, a CPU miner, a second stock node holding the miner wallet's owner key, and beam-wallet itself. 50 blocks; the wallet showed what the blocks paid to the groth and spent it; the fee landed in the next coinbase.
  • nodetest passes.

The pool side (finalizer daemon, miner's tool, pool server) is at https://github.com/profinch/bumblebeam/tree/main/tools/coinbase, with the same patch as a file and the test harness.

…ign, --mine_online_reserve)

Lets a pool pay its miners in the block itself, with coinbase outputs the
miners created and signed with their own keys (a "pair": an output with a
public value and a kernel whose excess is minus the output's blinding
factor, so each pair balances by itself). The pool's owner wallet finalizes
the block as today, but the coinbase it returns carries outputs the node's
owner key does not recognize.

Two options, both off by default, so nothing changes unless they are set:

  --mine_online_foreign=1   skip the "outputs correspond to our viewer's
                            Kdf" check at finalization; if the finalization
                            then fails in the chain context (a kernel
                            already visible, a block too large), drop the
                            finalizer and keep mining on the node's own
                            miner key, instead of stalling
  --mine_online_reserve=N   block space in bytes kept free for the coinbase
                            when a block is assembled for finalization,
                            on top of the single output and kernel it
                            reserves today

Consensus is untouched: a node without these options accepts the blocks.
Tested with two nodes on a FakePoW chain (the mining one with the options,
a stock one validating every block and serving the miner's wallet), and on
a private chain with the stock beam-node and beam-wallet.
…me is given

For test chains: with --consensus=FakePoW the node left mining off whatever the
options said. Now --mining_threads and --pow_solve_time apply when the solve time
is set explicitly, so a FakePoW node can serve its stratum server (or mine with
the fake solver) exactly like a PoW node.
@profinch
profinch marked this pull request as draft October 8, 2026 10:53
profinch added a commit to profinch/bumblebeam that referenced this pull request Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant