bugfix: compare real chunk weight against block weight limit

TestChunkBlockLimits() compared the chunk's sigops-adjusted weight against
block_max_weight, while nBlockWeight tracks real transaction weight. This
over-counted sigop-dense chunks and could skip ones that actually fit,
losing fees; the block sigop limit is enforced separately on the next line.

Pass the chunk's real weight (sum of GetTxWeight()) instead, and update the
test to show the chunk is now included.
This commit is contained in:
ismaelsadeeq
2026-06-22 10:53:54 +01:00
parent fc98790869
commit 5be248341a
3 changed files with 8 additions and 5 deletions

View File

@@ -243,11 +243,11 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
return std::move(pblocktemplate);
}
bool BlockAssembler::TestChunkBlockLimits(FeePerWeight chunk_feerate, int64_t chunk_sigops_cost) const
bool BlockAssembler::TestChunkBlockLimits(int64_t chunk_weight, int64_t chunk_sigops_cost) const
{
// block_max_weight has been flattened before block assembly limit checks.
Assert(m_options.block_max_weight);
if (nBlockWeight + chunk_feerate.size >= *m_options.block_max_weight) {
if (nBlockWeight + chunk_weight >= m_options.block_max_weight) {
return false;
}
if (nBlockSigOpsCost + chunk_sigops_cost >= MAX_BLOCK_SIGOPS_COST) {
@@ -310,12 +310,14 @@ void BlockAssembler::addChunks()
}
int64_t chunk_sig_ops = 0;
int64_t chunk_weight = 0;
for (const auto& tx : selected_transactions) {
chunk_sig_ops += tx.get().GetSigOpCost();
chunk_weight += tx.get().GetTxWeight();
}
// Check to see if this chunk will fit.
if (!TestChunkBlockLimits(chunk_feerate, chunk_sig_ops) || !TestChunkTransactions(selected_transactions)) {
if (!TestChunkBlockLimits(chunk_weight, chunk_sig_ops) || !TestChunkTransactions(selected_transactions)) {
// This chunk won't fit, so we skip it and will try the next best one.
m_mempool->SkipBuilderChunk();
++nConsecutiveFailed;

View File

@@ -108,7 +108,7 @@ private:
// helper functions for addChunks()
/** Test if a new chunk would "fit" in the block */
bool TestChunkBlockLimits(FeePerWeight chunk_feerate, int64_t chunk_sigops_cost) const;
bool TestChunkBlockLimits(int64_t chunk_weight, int64_t chunk_sigops_cost) const;
/** Perform locktime checks on each transaction in a chunk:
* This check should always succeed, and is here
* only as an extra check in case of a bug */

View File

@@ -368,7 +368,8 @@ void MinerTestingSetup::TestSigOpsAdjustedWeightChunkLimit(const CScript& script
.coinbase_output_script = scriptPubKey,
};
const CBlock block{mining->createNewBlock(options, /*cooldown=*/false)->getBlock()};
BOOST_CHECK_EQUAL(block.vtx.size(), 1U);
BOOST_CHECK_EQUAL(block.vtx.size(), 2U);
BOOST_CHECK(block.vtx[1]->GetHash() == tx.GetHash());
}
void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst, int baseheight)