From 7c123c08ddce87ae55abfa83bea4a691bc0bd5e7 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Tue, 7 Jan 2025 14:57:39 -0500 Subject: [PATCH] miner: add package feerate vector to CBlockTemplate - The package feerates are ordered by the sequence in which packages are selected for inclusion in the block template. - The commit also tests this new behaviour. Co-authored-by: willcl-ark --- src/node/miner.cpp | 1 + src/node/miner.h | 4 ++++ src/test/miner_tests.cpp | 26 +++++++++++++++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 5d7304b597..0ff5a1eade 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -421,6 +421,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda } ++nPackagesSelected; + pblocktemplate->m_package_feerates.emplace_back(packageFees, static_cast(packageSize)); // Update transactions that depend on each of these nDescendantsUpdated += UpdatePackagesForAdded(mempool, ancestors, mapModifiedTx); diff --git a/src/node/miner.h b/src/node/miner.h index f6461a8d55..3c4c66b0ba 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,9 @@ struct CBlockTemplate std::vector vTxFees; std::vector vTxSigOpsCost; std::vector vchCoinbaseCommitment; + /* A vector of package fee rates, ordered by the sequence in which + * packages are selected for inclusion in the block template.*/ + std::vector m_package_feerates; }; // Container for tracking updates to ancestor feerate as we include (parent) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index d48f9cca3f..d7bc790d0e 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include +#include #include @@ -123,19 +125,22 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const tx.vout[0].nValue = 5000000000LL - 1000; // This tx has a low fee: 1000 satoshis Txid hashParentTx = tx.GetHash(); // save this txid for later use - AddToMempool(tx_mempool, entry.Fee(1000).Time(Now()).SpendsCoinbase(true).FromTx(tx)); + const auto parent_tx{entry.Fee(1000).Time(Now()).SpendsCoinbase(true).FromTx(tx)}; + AddToMempool(tx_mempool, parent_tx); // This tx has a medium fee: 10000 satoshis tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 5000000000LL - 10000; Txid hashMediumFeeTx = tx.GetHash(); - AddToMempool(tx_mempool, entry.Fee(10000).Time(Now()).SpendsCoinbase(true).FromTx(tx)); + const auto medium_fee_tx{entry.Fee(10000).Time(Now()).SpendsCoinbase(true).FromTx(tx)}; + AddToMempool(tx_mempool, medium_fee_tx); // This tx has a high fee, but depends on the first transaction tx.vin[0].prevout.hash = hashParentTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee Txid hashHighFeeTx = tx.GetHash(); - AddToMempool(tx_mempool, entry.Fee(50000).Time(Now()).SpendsCoinbase(false).FromTx(tx)); + const auto high_fee_tx{entry.Fee(50000).Time(Now()).SpendsCoinbase(false).FromTx(tx)}; + AddToMempool(tx_mempool, high_fee_tx); std::unique_ptr block_template = mining->createNewBlock(options); BOOST_REQUIRE(block_template); @@ -145,6 +150,21 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const BOOST_CHECK(block.vtx[2]->GetHash() == hashHighFeeTx); BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx); + // Test the inclusion of package feerates in the block template and ensure they are sequential. + const auto block_package_feerates = BlockAssembler{m_node.chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates; + BOOST_CHECK(block_package_feerates.size() == 2); + + // parent_tx and high_fee_tx are added to the block as a package. + const auto combined_txs_fee = parent_tx.GetFee() + high_fee_tx.GetFee(); + const auto combined_txs_size = parent_tx.GetTxSize() + high_fee_tx.GetTxSize(); + FeeFrac package_feefrac{combined_txs_fee, combined_txs_size}; + // The package should be added first. + BOOST_CHECK(block_package_feerates[0] == package_feefrac); + + // The medium_fee_tx should be added next. + FeeFrac medium_tx_feefrac{medium_fee_tx.GetFee(), medium_fee_tx.GetTxSize()}; + BOOST_CHECK(block_package_feerates[1] == medium_tx_feefrac); + // Test that a package below the block min tx fee doesn't get included tx.vin[0].prevout.hash = hashHighFeeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee