mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
refactor: add coinbase constraints to BlockCreateOptions
When generating a block template through e.g. getblocktemplate RPC, we reserve 4000 weight units and 400 sigops. Pools use this space for their coinbase outputs. At least one pool patched their Bitcoin Core node to adjust these hardcoded values. They eventually produced an invalid block which exceeded the sigops limit. https://bitcoin.stackexchange.com/questions/117837/how-many-sigops-are-in-the-invalid-block-783426 The existince of such patches suggests it may be useful to make this value configurable. This commit would make such a change easier. The main motivation however is that the Stratum v2 spec requires the pool to communicate the maximum bytes they intend to add to the coinbase outputs. A proposed change to the spec would also require them to communicate the maximum number of sigops. This commit also documents what happens when -blockmaxweight is lower than the coinbase reserved value. Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
parent
6b4c817d4b
commit
c504b6997b
@ -59,8 +59,11 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
|
||||
|
||||
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
|
||||
{
|
||||
// Limit weight to between 4K and DEFAULT_BLOCK_MAX_WEIGHT for sanity:
|
||||
options.nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, 4000, DEFAULT_BLOCK_MAX_WEIGHT);
|
||||
Assert(options.coinbase_max_additional_weight <= DEFAULT_BLOCK_MAX_WEIGHT);
|
||||
Assert(options.coinbase_output_max_additional_sigops <= MAX_BLOCK_SIGOPS_COST);
|
||||
// Limit weight to between coinbase_max_additional_weight and DEFAULT_BLOCK_MAX_WEIGHT for sanity:
|
||||
// Coinbase (reserved) outputs can safely exceed -blockmaxweight, but the rest of the block template will be empty.
|
||||
options.nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, options.coinbase_max_additional_weight, DEFAULT_BLOCK_MAX_WEIGHT);
|
||||
return options;
|
||||
}
|
||||
|
||||
@ -87,8 +90,8 @@ void BlockAssembler::resetBlock()
|
||||
inBlock.clear();
|
||||
|
||||
// Reserve space for coinbase tx
|
||||
nBlockWeight = 4000;
|
||||
nBlockSigOpsCost = 400;
|
||||
nBlockWeight = m_options.coinbase_max_additional_weight;
|
||||
nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
|
||||
|
||||
// These counters do not include coinbase tx
|
||||
nBlockTx = 0;
|
||||
@ -379,7 +382,7 @@ void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSele
|
||||
++nConsecutiveFailed;
|
||||
|
||||
if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight >
|
||||
m_options.nBlockMaxWeight - 4000) {
|
||||
m_options.nBlockMaxWeight - m_options.coinbase_max_additional_weight) {
|
||||
// Give up if we're close to full and haven't succeeded in a while
|
||||
break;
|
||||
}
|
||||
|
@ -32,6 +32,17 @@ struct BlockCreateOptions {
|
||||
* Set false to omit mempool transactions
|
||||
*/
|
||||
bool use_mempool{true};
|
||||
/**
|
||||
* The maximum additional weight which the pool will add to the coinbase
|
||||
* scriptSig, witness and outputs. This must include any additional
|
||||
* weight needed for larger CompactSize encoded lengths.
|
||||
*/
|
||||
size_t coinbase_max_additional_weight{4000};
|
||||
/**
|
||||
* The maximum additional sigops which the pool will add in coinbase
|
||||
* transaction outputs.
|
||||
*/
|
||||
size_t coinbase_output_max_additional_sigops{400};
|
||||
};
|
||||
} // namespace node
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user