Skip to content

Commit 489b587

Browse files
committed
Merge bitcoin/bitcoin#25215: [kernel 2d/n] Reduce CTxMemPool constructor call sites
d273e53 bench/rpc_mempool: Create ChainTestingSetup, use its CTxMemPool (Carl Dong) 020caba bench: Use existing CTxMemPool in TestingSetup (Carl Dong) 86e732d scripted-diff: test: Use CTxMemPool in TestingSetup (Carl Dong) 213457e test/policyestimator: Use ChainTestingSetup's CTxMemPool (Carl Dong) 319f0ce rest/getutxos: Don't construct empty mempool (Carl Dong) 03574b9 tree-wide: clang-format CTxMemPool references (Carl Dong) Pull request description: This is part of the `libbitcoinkernel` project: #24303, https://github.com/bitcoin/bitcoin/projects/18 This PR reduces the number of call sites where we explicitly construct CTxMemPool. This is done in preparation for later PRs which decouple the mempool module from `ArgsManager`, eventually all of libbitcoinkernel will be decoupled from `ArgsManager`. The changes in this PR: - Allows us to have less code churn as we modify `CTxMemPool`'s constructor in later PRs - In many cases, we can make use of existing `CTxMemPool` instances, getting rid of extraneous constructions - In other cases, we construct a `ChainTestingSetup` and use the `CTxMemPool` there, so that we can rely on the logic in `setup_common` to set things up correctly ## Notes for Reviewers ### A note on using existing mempools When evaluating whether or not it's appropriate to use an existing mempool in a `*TestingSetup` struct, the key is to make sure that the mempool has the same lifetime as the `*TestingSetup` struct. Example 1: In [`src/fuzz/tx_pool.cpp`](https://github.com/bitcoin/bitcoin/blob/b4f686952a60bbadc7ed2250651d0d6af0959f4d/src/test/fuzz/tx_pool.cpp), the `TestingSetup` is initialized in `initialize_tx_pool` and lives as a static global, while the `CTxMemPool` is in the `tx_pool_standard` fuzz target, meaning that each time the `tx_pool_standard` fuzz target gets run, a new `CTxMemPool` is created. If we were to use the static global `TestingSetup`'s CTxMemPool we might run into problems since its `CTxMemPool` will carry state between subsequent runs. This is why we don't modify `src/fuzz/tx_pool.cpp` in this PR. Example 2: In [`src/bench/mempool_eviction.cpp`](https://github.com/bitcoin/bitcoin/blob/b4f686952a60bbadc7ed2250651d0d6af0959f4d/src/bench/mempool_eviction.cpp), we see that the `TestingSetup` is in the same scope as the constructed `CTxMemPool`, so it is safe to use its `CTxMemPool`. ### A note on checking `CTxMemPool` ctor call sites After the "tree-wide: clang-format CTxMemPool references" commit, you can find all `CTxMemPool` ctor call sites with the following command: ```sh git grep -E -e 'make_unique<CTxMemPool>' \ -e '\bCTxMemPool\s+[^({;]+[({]' \ -e '\bCTxMemPool\s+[^;]+;' \ -e '\bnew\s+CTxMemPool\b' ``` At the end of the PR, you will find that there are still quite a few call sites that we can seemingly get rid of: ```sh $ git grep -E -e 'make_unique<CTxMemPool>' -e '\bCTxMemPool\s+[^({;]+[({]' -e '\bCTxMemPool\s+[^;]+;' -e '\bnew\s+CTxMemPool\b' # rearranged for easier explication src/init.cpp: node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), mempool_check_ratio); src/test/util/setup_common.cpp: m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1); src/rpc/mining.cpp: CTxMemPool empty_mempool; src/test/util/setup_common.cpp: CTxMemPool empty_pool; src/bench/mempool_stress.cpp: CTxMemPool pool; src/bench/mempool_stress.cpp: CTxMemPool pool; src/test/fuzz/rbf.cpp: CTxMemPool pool; src/test/fuzz/tx_pool.cpp: CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1}; src/test/fuzz/tx_pool.cpp: CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1}; src/test/fuzz/validation_load_mempool.cpp: CTxMemPool pool{}; src/txmempool.h: /** Create a new CTxMemPool. ``` Let's break them down one by one: ``` src/init.cpp: node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), mempool_check_ratio); src/test/util/setup_common.cpp: m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1); ``` Necessary ----- ``` src/rpc/mining.cpp: CTxMemPool empty_mempool; src/test/util/setup_common.cpp: CTxMemPool empty_pool; ``` These are fixed in #25223 where we stop requiring the `BlockAssembler` to have a `CTxMemPool` if it's not going to consult it anyway (as is the case in these two call sites) ----- ``` src/bench/mempool_stress.cpp: CTxMemPool pool; src/bench/mempool_stress.cpp: CTxMemPool pool; ``` Fixed in #24927. ----- ``` src/test/fuzz/rbf.cpp: CTxMemPool pool; src/test/fuzz/tx_pool.cpp: CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1}; src/test/fuzz/tx_pool.cpp: CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1}; src/test/fuzz/validation_load_mempool.cpp: CTxMemPool pool{}; ``` These are all cases where we don't want the `CTxMemPool` state to persist between runs, see the previous section "A note on using existing mempools" ----- ``` src/txmempool.h: /** Create a new CTxMemPool. ``` It's a comment (someone link me to a grep that understands syntax plz thx) ACKs for top commit: laanwj: Code review ACK d273e53 Tree-SHA512: c4ff3d23217a7cc4a7145defc7b901725073ef73bcac3a252ed75f672c87e98ca0368d1d8c3f606b5b49f641e7d8387d26ef802141b650b215876f191fb6d5f9
2 parents faf25b0 + d273e53 commit 489b587

9 files changed

+29
-26
lines changed

src/bench/mempool_eviction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static void MempoolEviction(benchmark::Bench& bench)
108108
tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
109109
tx7.vout[1].nValue = 10 * COIN;
110110

111-
CTxMemPool pool;
111+
CTxMemPool& pool = *Assert(testing_setup->m_node.mempool);
112112
LOCK2(cs_main, pool.cs);
113113
// Create transaction references outside the "hot loop"
114114
const CTransactionRef tx1_r{MakeTransactionRef(tx1)};

src/bench/rpc_mempool.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <bench/bench.h>
6+
#include <chainparamsbase.h>
67
#include <rpc/mempool.h>
8+
#include <test/util/setup_common.h>
79
#include <txmempool.h>
810

911
#include <univalue.h>
@@ -17,7 +19,8 @@ static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& poo
1719

1820
static void RpcMempool(benchmark::Bench& bench)
1921
{
20-
CTxMemPool pool;
22+
const auto testing_setup = MakeNoLogFileContext<const ChainTestingSetup>(CBaseChainParams::MAIN);
23+
CTxMemPool& pool = *Assert(testing_setup->m_node.mempool);
2124
LOCK2(cs_main, pool.cs);
2225

2326
for (int i = 0; i < 1000; ++i) {

src/net_processing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4635,7 +4635,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
46354635
namespace {
46364636
class CompareInvMempoolOrder
46374637
{
4638-
CTxMemPool *mp;
4638+
CTxMemPool* mp;
46394639
bool m_wtxid_relay;
46404640
public:
46414641
explicit CompareInvMempoolOrder(CTxMemPool *_mempool, bool use_wtxid)

src/rest.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,10 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
799799
if (!maybe_chainman) return false;
800800
ChainstateManager& chainman = *maybe_chainman;
801801
{
802-
auto process_utxos = [&vOutPoints, &outs, &hits](const CCoinsView& view, const CTxMemPool& mempool) {
802+
auto process_utxos = [&vOutPoints, &outs, &hits](const CCoinsView& view, const CTxMemPool* mempool) {
803803
for (const COutPoint& vOutPoint : vOutPoints) {
804804
Coin coin;
805-
bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin);
805+
bool hit = (!mempool || !mempool->isSpent(vOutPoint)) && view.GetCoin(vOutPoint, coin);
806806
hits.push_back(hit);
807807
if (hit) outs.emplace_back(std::move(coin));
808808
}
@@ -815,10 +815,10 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
815815
LOCK2(cs_main, mempool->cs);
816816
CCoinsViewCache& viewChain = chainman.ActiveChainstate().CoinsTip();
817817
CCoinsViewMemPool viewMempool(&viewChain, *mempool);
818-
process_utxos(viewMempool, *mempool);
818+
process_utxos(viewMempool, mempool);
819819
} else {
820-
LOCK(cs_main); // no need to lock mempool!
821-
process_utxos(chainman.ActiveChainstate().CoinsTip(), CTxMemPool());
820+
LOCK(cs_main);
821+
process_utxos(chainman.ActiveChainstate().CoinsTip(), nullptr);
822822
}
823823

824824
for (size_t i = 0; i < hits.size(); ++i) {

src/test/blockencodings_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ constexpr long SHARED_TX_OFFSET{3};
5454

5555
BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
5656
{
57-
CTxMemPool pool;
57+
CTxMemPool& pool = *Assert(m_node.mempool);
5858
TestMemPoolEntryHelper entry;
5959
CBlock block(BuildBlockTestCase());
6060

@@ -137,7 +137,7 @@ class TestHeaderAndShortIDs {
137137

138138
BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
139139
{
140-
CTxMemPool pool;
140+
CTxMemPool& pool = *Assert(m_node.mempool);
141141
TestMemPoolEntryHelper entry;
142142
CBlock block(BuildBlockTestCase());
143143

@@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
207207

208208
BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
209209
{
210-
CTxMemPool pool;
210+
CTxMemPool& pool = *Assert(m_node.mempool);
211211
TestMemPoolEntryHelper entry;
212212
CBlock block(BuildBlockTestCase());
213213

@@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
258258

259259
BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
260260
{
261-
CTxMemPool pool;
261+
CTxMemPool& pool = *Assert(m_node.mempool);
262262
CMutableTransaction coinbase;
263263
coinbase.vin.resize(1);
264264
coinbase.vin[0].scriptSig.resize(10);

src/test/mempool_tests.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
5656
}
5757

5858

59-
CTxMemPool testPool;
59+
CTxMemPool& testPool = *Assert(m_node.mempool);
6060
LOCK2(cs_main, testPool.cs);
6161

6262
// Nothing in pool, remove should do nothing:
@@ -108,20 +108,20 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
108108
BOOST_CHECK_EQUAL(testPool.size(), 0U);
109109
}
110110

111-
template<typename name>
112-
static void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
111+
template <typename name>
112+
static void CheckSort(CTxMemPool& pool, std::vector<std::string>& sortedOrder) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
113113
{
114114
BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
115115
typename CTxMemPool::indexed_transaction_set::index<name>::type::iterator it = pool.mapTx.get<name>().begin();
116-
int count=0;
116+
int count = 0;
117117
for (; it != pool.mapTx.get<name>().end(); ++it, ++count) {
118118
BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]);
119119
}
120120
}
121121

122122
BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
123123
{
124-
CTxMemPool pool;
124+
CTxMemPool& pool = *Assert(m_node.mempool);
125125
LOCK2(cs_main, pool.cs);
126126
TestMemPoolEntryHelper entry;
127127

@@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
294294

295295
BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
296296
{
297-
CTxMemPool pool;
297+
CTxMemPool& pool = *Assert(m_node.mempool);
298298
LOCK2(cs_main, pool.cs);
299299
TestMemPoolEntryHelper entry;
300300

@@ -423,7 +423,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
423423

424424
BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
425425
{
426-
CTxMemPool pool;
426+
CTxMemPool& pool = *Assert(m_node.mempool);
427427
LOCK2(cs_main, pool.cs);
428428
TestMemPoolEntryHelper entry;
429429

@@ -594,7 +594,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests)
594594
{
595595
size_t ancestors, descendants;
596596

597-
CTxMemPool pool;
597+
CTxMemPool& pool = *Assert(m_node.mempool);
598598
LOCK2(cs_main, pool.cs);
599599
TestMemPoolEntryHelper entry;
600600

@@ -753,7 +753,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTestsDiamond)
753753
{
754754
size_t ancestors, descendants;
755755

756-
CTxMemPool pool;
756+
CTxMemPool& pool = *Assert(m_node.mempool);
757757
LOCK2(::cs_main, pool.cs);
758758
TestMemPoolEntryHelper entry;
759759

src/test/policyestimator_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212

1313
#include <boost/test/unit_test.hpp>
1414

15-
BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup)
15+
BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, ChainTestingSetup)
1616

1717
BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
1818
{
19-
CBlockPolicyEstimator feeEst;
20-
CTxMemPool mpool(&feeEst);
19+
CBlockPolicyEstimator& feeEst = *Assert(m_node.fee_estimator);
20+
CTxMemPool& mpool = *Assert(m_node.mempool);
2121
LOCK2(cs_main, mpool.cs);
2222
TestMemPoolEntryHelper entry;
2323
CAmount basefee(2000);

src/test/validation_chainstate_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
3030
ChainstateManager manager{chainman_opts};
3131

3232
WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
33-
CTxMemPool mempool;
33+
CTxMemPool& mempool = *Assert(m_node.mempool);
3434

3535
//! Create and add a Coin with DynamicMemoryUsage of 80 bytes to the given view.
3636
auto add_coin = [](CCoinsViewCache& coins_view) -> COutPoint {

src/test/validation_flush_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, ChainTestingSetup)
2020
//!
2121
BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
2222
{
23-
CTxMemPool mempool;
23+
CTxMemPool& mempool = *Assert(m_node.mempool);
2424
BlockManager blockman{};
2525
CChainState chainstate{&mempool, blockman, *Assert(m_node.chainman)};
2626
chainstate.InitCoinsDB(/*cache_size_bytes=*/1 << 10, /*in_memory=*/true, /*should_wipe=*/false);

0 commit comments

Comments
 (0)