diff --git a/src/node/miner.cpp b/src/node/miner.cpp index ce5452d1f9dba3..314a7304c1812b 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -59,8 +59,10 @@ 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(options.nBlockMaxWeight, 4000, DEFAULT_BLOCK_MAX_WEIGHT); + if (options.sanity_check_block_weight) { + // Limit weight to between 4K and DEFAULT_BLOCK_MAX_WEIGHT for sanity: + options.nBlockMaxWeight = std::clamp(options.nBlockMaxWeight, 4000, DEFAULT_BLOCK_MAX_WEIGHT); + } return options; } @@ -423,9 +425,23 @@ void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSele } ++nPackagesSelected; + size_per_feerate[CFeeRate{packageFees, packageSize}] += packageSize; // Update transactions that depend on each of these nDescendantsUpdated += UpdatePackagesForAdded(mempool, ancestors, mapModifiedTx); } } + +std::map BlockAssembler::GetFeeRateStats() +{ + return std::move(size_per_feerate); +} + +std::map GetCustomBlockFeeRateHistogram(Chainstate& chainstate, const CTxMemPool* mempool, size_t block_weight) +{ + BlockAssembler::Options options = {.nBlockMaxWeight = block_weight, .sanity_check_block_weight = false}; + BlockAssembler assembler(chainstate, mempool, options); + assembler.CreateNewBlock(CScript{}); + return assembler.GetFeeRateStats(); +} } // namespace node diff --git a/src/node/miner.h b/src/node/miner.h index 06a917228dccc2..8af8afba28f1f1 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -143,6 +143,7 @@ class BlockAssembler uint64_t nBlockSigOpsCost; CAmount nFees; std::unordered_set inBlock; + std::map size_per_feerate; // Chain context for the block int nHeight; @@ -159,6 +160,8 @@ class BlockAssembler CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE}; // Whether to call TestBlockValidity() at the end of CreateNewBlock(). bool test_block_validity{true}; + // Whether we limit nBlockMaxWeight between 4k and DEFAULT_BLOCK_MAX_WEIGHT. + bool sanity_check_block_weight{true}; }; explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool); @@ -170,6 +173,10 @@ class BlockAssembler inline static std::optional m_last_block_num_txs{}; inline static std::optional m_last_block_weight{}; + /** Return a map from feerates to vbyte, indicating how many vbytes were + * included in the block at which feerate. This can only be called once. */ + std::map GetFeeRateStats(); + private: const Options m_options; @@ -204,6 +211,9 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman); +/** Get feerate statistics of a block weight from the mempool. */ +std::map GetCustomBlockFeeRateHistogram(Chainstate& chainstate, const CTxMemPool* mempool, size_t block_weight); + /** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */ void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options); } // namespace node