The Stratum v2 spec defines a Job Declarator Server (JDS), whose job it is to approve custom miner templates. Since #34020 it can use getTransactionsByWitnessID() to request transactions from the node, instead of maintaining its own mempool mirror (see https://github.com/stratum-mining/sv2-apps/pull/911), and then request any missing transactions from the miner.
The new TxCollection interface introduced by this PR optimizes this further. We build and validate the block template ourselves now, based on the requested transaction list and our own mempool, so known transactions don't need to cross the IPC boundary. This also fits the draft spec for JDS custom job validation through a Template Provider.
The following flow is demonstrated in https://github.com/stratum-mining/sv2-apps/pull/599:
- Miner generates a template, e.g. using our
createNewBlock()IPC method - They send the list of
Wtxids to the pool's JDS - JDS calls
Mining::collectTxs()(this PR) with thatWtxidlist - We check the list against our mempool and hold a
CTransactionReffor each match - The JDS queries
unknownTxPos()to learn what's missing from the collection - The JDS requests the fully serialized missing transactions from the miner (using native Stratum v2 messages)
- JDS calls
addMissingTxs()which completes the collection - JDS calls
makeTemplate()which reconstructs the block and validates it, optionally with the coinbase it intends to use (e.g. to check the reward amount); a node-generated dummy is used otherwise. The JDS needs the check to succeed, may relay the BIP-22 failure reason to the miner. - It returns a
BlockTemplatewhich works as if we generated the template ourselves, but with methods likewaitNext()disabled. The JDS can callsubmitSolution()(the sv2 spec allows for redundant block reconstruction by both the miner node and the JDS).
If this sounds very similar to compact block relay: it is! In fact, it would be easy to expand the above methods to take transaction short ids instead of Wtxid. That may be useful for the p2pool revival project, which needs a way to validate and relay weak blocks as compact blocks. The p2pool client software would need to (trivially) verify the PoW, but could use the TxCollection interface to reconstruct and verify the block content. That said, the SRI JDS implementation is much further along and likely to be the first consumer of this.
Commits:
- ipc: add TxCollection scaffold - step 3 and 4
- mining: add TxCollection unknownTxPos - step 5
- mining: add TxCollection addMissingTxs - step 7
- mining: add coinbase transaction helper - we need a dummy coinbase to verify the block, so extract a helper from
BlockAssembler::CreateNewBlock() - mining: assemble block templates from TxCollection - step 8, node implementation
- ipc: expose TxCollection template creation - step 8 and 9, including restrictions on externally generated templates
- mining: allow TxCollection templates to use a supplied coinbase - optional coinbase in step 8
Potential followups:
- https://github.com/Sjors/bitcoin/pull/122
- expose total fees for externally generated templates, building on #36525
- have
addMissingTxs()(optionally) insert favorable transactions into our mempool - add a data structure to store transactions that don't meet our mempool threshold (so
TxCollectioncan grab them, instead of needing another round trip)