Skip to content

Commit f1941e8

Browse files
committed
pool: Add and use MemPoolOptions, ApplyArgsManOptions
Reviewers: Note that CTxMemPool now requires a non-defaulted CTxMemPool::Options for its constructor. Meaning that there's no need to worry about a stray CTxMemPool constructor somewhere defaulting to something incorrect. All instances of CTxMemPool construction are addressed here in this commit. We set options for CTxMemPool and construct it in many different ways. A good example can be seen in how we determine CTxMemPool's check_ratio in AppInitMain(...). 1. We first set the default based on chainparams's DefaultConsistencyChecks() 2. Then, we apply the ArgsManager option on top of that default 3. Finally, we clamp the result of that between 0 and 1 Million With this patch, most CTxMemPool construction are along the lines of: MemPoolOptions mempool_opts{...default overrides...}; ApplyArgsManOptions(argsman, mempool_opts); ...hard overrides... CTxMemPool pool{mempool_opts}; This "compositional" style of building options means that we can omit unnecessary/irrelevant steps wherever we want but also maintain full customizability. For example: - For users of libbitcoinkernel, where we eventually want to remove ArgsManager, they simply won't call (or even know about) ApplyArgsManOptions. - See src/init.cpp to see how the check_ratio CTxMemPool option works after this change. A MemPoolOptionsForTest helper was also added and used by tests/fuzz tests where a local CTxMemPool needed to be created. The change in src/test/fuzz/tx_pool.cpp seemingly changes behaviour by applying ArgsManager options on top of the CTxMemPool::Options defaults. However, in future commits where we introduce flags like -maxmempool, the call to ApplyArgsManOptions is actually what preserves the existing behaviour. Previously, although it wasn't obvious, our CTxMemPool would consult gArgs for flags like -maxmempool when it needed it, so it already relied on ArgsManager information. This patchset just laid bare the obfuscatory perils of globals. [META] As this patchset progresses, we will move more and more CTxMemPool-relevant options into MemPoolOptions and add their ArgsMan-related logic to ApplyArgsManOptions.
1 parent 0199bd3 commit f1941e8

File tree

12 files changed

+127
-16
lines changed

12 files changed

+127
-16
lines changed

src/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,13 @@ BITCOIN_CORE_H = \
173173
kernel/checks.h \
174174
kernel/coinstats.h \
175175
kernel/context.h \
176+
kernel/mempool_options.h \
176177
key.h \
177178
key_io.h \
178179
logging.h \
179180
logging/timer.h \
180181
mapport.h \
182+
mempool_args.h \
181183
memusage.h \
182184
merkleblock.h \
183185
net.h \
@@ -361,6 +363,7 @@ libbitcoin_node_a_SOURCES = \
361363
kernel/coinstats.cpp \
362364
kernel/context.cpp \
363365
mapport.cpp \
366+
mempool_args.cpp \
364367
net.cpp \
365368
netgroup.cpp \
366369
net_processing.cpp \

src/init.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <interfaces/init.h>
3131
#include <interfaces/node.h>
3232
#include <mapport.h>
33+
#include <mempool_args.h>
3334
#include <net.h>
3435
#include <net_permissions.h>
3536
#include <net_processing.h>
@@ -62,6 +63,7 @@
6263
#include <txorphanage.h>
6364
#include <util/asmap.h>
6465
#include <util/check.h>
66+
#include <util/designator.h>
6567
#include <util/moneystr.h>
6668
#include <util/strencodings.h>
6769
#include <util/string.h>
@@ -1426,10 +1428,16 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14261428

14271429
assert(!node.mempool);
14281430
assert(!node.chainman);
1429-
const int mempool_check_ratio = std::clamp<int>(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0, 1000000);
1431+
1432+
CTxMemPool::Options mempool_opts{
1433+
Desig(estimator) node.fee_estimator.get(),
1434+
Desig(check_ratio) chainparams.DefaultConsistencyChecks() ? 1 : 0,
1435+
};
1436+
ApplyArgsManOptions(args, mempool_opts);
1437+
mempool_opts.check_ratio = std::clamp<int>(mempool_opts.check_ratio, 0, 1'000'000);
14301438

14311439
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
1432-
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), mempool_check_ratio);
1440+
node.mempool = std::make_unique<CTxMemPool>(mempool_opts);
14331441

14341442
const ChainstateManager::Options chainman_opts{
14351443
chainparams,

src/kernel/mempool_options.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
#ifndef BITCOIN_KERNEL_MEMPOOL_OPTIONS_H
5+
#define BITCOIN_KERNEL_MEMPOOL_OPTIONS_H
6+
7+
class CBlockPolicyEstimator;
8+
9+
namespace kernel {
10+
/**
11+
* Options struct containing options for constructing a CTxMemPool. Default
12+
* constructor populates the struct with sane default values which can be
13+
* modified.
14+
*
15+
* Most of the time, this struct should be referenced as CTxMemPool::Options.
16+
*/
17+
struct MemPoolOptions {
18+
/* Used to estimate appropriate transaction fees. */
19+
CBlockPolicyEstimator* estimator{nullptr};
20+
/* The ratio used to determine how often sanity checks will run. */
21+
int check_ratio{0};
22+
};
23+
} // namespace kernel
24+
25+
#endif // BITCOIN_KERNEL_MEMPOOL_OPTIONS_H

src/mempool_args.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <mempool_args.h>
6+
7+
#include <kernel/mempool_options.h>
8+
9+
#include <util/system.h>
10+
11+
using kernel::MemPoolOptions;
12+
13+
void ApplyArgsManOptions(const ArgsManager& argsman, MemPoolOptions& mempool_opts)
14+
{
15+
mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio);
16+
}

src/mempool_args.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_MEMPOOL_ARGS_H
6+
#define BITCOIN_MEMPOOL_ARGS_H
7+
8+
class ArgsManager;
9+
namespace kernel {
10+
struct MemPoolOptions;
11+
};
12+
13+
void ApplyArgsManOptions(const ArgsManager& argsman, kernel::MemPoolOptions& mempool_opts);
14+
15+
#endif // BITCOIN_MEMPOOL_ARGS_H

src/test/fuzz/rbf.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <mempool_args.h>
56
#include <policy/rbf.h>
67
#include <primitives/transaction.h>
78
#include <sync.h>
@@ -34,8 +35,11 @@ FUZZ_TARGET_INIT(rbf, initialize_rbf)
3435
if (!mtx) {
3536
return;
3637
}
37-
CTxMemPool pool;
38-
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
38+
39+
CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)};
40+
41+
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
42+
{
3943
const std::optional<CMutableTransaction> another_mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
4044
if (!another_mtx) {
4145
break;

src/test/fuzz/tx_pool.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <consensus/validation.h>
6+
#include <mempool_args.h>
7+
#include <node/context.h>
68
#include <node/miner.h>
79
#include <test/fuzz/FuzzedDataProvider.h>
810
#include <test/fuzz/fuzz.h>
@@ -15,6 +17,7 @@
1517
#include <validationinterface.h>
1618

1719
using node::BlockAssembler;
20+
using node::NodeContext;
1821

1922
namespace {
2023

@@ -121,6 +124,19 @@ void MockTime(FuzzedDataProvider& fuzzed_data_provider, const CChainState& chain
121124
SetMockTime(time);
122125
}
123126

127+
CTxMemPool MakeMempool(const NodeContext& node)
128+
{
129+
// Take the default options for tests...
130+
CTxMemPool::Options mempool_opts{MemPoolOptionsForTest(node)};
131+
132+
// ...override specific options for this specific fuzz suite
133+
mempool_opts.estimator = nullptr;
134+
mempool_opts.check_ratio = 1;
135+
136+
// ...and construct a CTxMemPool from it
137+
return CTxMemPool{mempool_opts};
138+
}
139+
124140
FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
125141
{
126142
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
@@ -142,7 +158,7 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
142158
// The sum of the values of all spendable outpoints
143159
constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN};
144160

145-
CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1};
161+
CTxMemPool tx_pool_{MakeMempool(node)};
146162
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_);
147163

148164
chainstate.SetMempool(&tx_pool);
@@ -320,7 +336,7 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
320336
txids.push_back(ConsumeUInt256(fuzzed_data_provider));
321337
}
322338

323-
CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1};
339+
CTxMemPool tx_pool_{MakeMempool(node)};
324340
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_);
325341

326342
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)

src/test/fuzz/validation_load_mempool.cpp

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

55
#include <chainparamsbase.h>
6+
#include <mempool_args.h>
67
#include <test/fuzz/FuzzedDataProvider.h>
78
#include <test/fuzz/fuzz.h>
89
#include <test/fuzz/util.h>
@@ -30,7 +31,8 @@ FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool)
3031
SetMockTime(ConsumeTime(fuzzed_data_provider));
3132
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
3233

33-
CTxMemPool pool{};
34+
CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)};
35+
3436
auto fuzzed_fopen = [&](const fs::path&, const char*) {
3537
return fuzzed_file_provider.open();
3638
};

src/test/util/setup_common.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
#include <init.h>
1515
#include <init/common.h>
1616
#include <interfaces/chain.h>
17+
#include <mempool_args.h>
1718
#include <net.h>
1819
#include <net_processing.h>
1920
#include <node/blockstorage.h>
2021
#include <node/chainstate.h>
22+
#include <node/context.h>
2123
#include <node/miner.h>
2224
#include <noui.h>
2325
#include <policy/fees.h>
@@ -32,6 +34,8 @@
3234
#include <test/util/net.h>
3335
#include <timedata.h>
3436
#include <txdb.h>
37+
#include <txmempool.h>
38+
#include <util/designator.h>
3539
#include <util/strencodings.h>
3640
#include <util/string.h>
3741
#include <util/thread.h>
@@ -50,11 +54,12 @@
5054

5155
using node::BlockAssembler;
5256
using node::CalculateCacheSizes;
57+
using node::fPruneMode;
58+
using node::fReindex;
5359
using node::LoadChainstate;
60+
using node::NodeContext;
5461
using node::RegenerateCommitments;
5562
using node::VerifyLoadedChainstate;
56-
using node::fPruneMode;
57-
using node::fReindex;
5863

5964
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
6065
UrlDecodeFn* const URL_DECODE = nullptr;
@@ -149,6 +154,18 @@ BasicTestingSetup::~BasicTestingSetup()
149154
gArgs.ClearArgs();
150155
}
151156

157+
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext& node)
158+
{
159+
CTxMemPool::Options mempool_opts{
160+
Desig(estimator) node.fee_estimator.get(),
161+
// Default to always checking mempool regardless of
162+
// chainparams.DefaultConsistencyChecks for tests
163+
Desig(check_ratio) 1,
164+
};
165+
ApplyArgsManOptions(*node.args, mempool_opts);
166+
return mempool_opts;
167+
}
168+
152169
ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
153170
: BasicTestingSetup(chainName, extra_args)
154171
{
@@ -161,7 +178,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
161178
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
162179

163180
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>();
164-
m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), m_node.args->GetIntArg("-checkmempool", 1));
181+
m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node));
165182

166183
m_cache_sizes = CalculateCacheSizes(m_args);
167184

src/test/util/setup_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ struct BasicTestingSetup {
9090
ArgsManager m_args;
9191
};
9292

93+
94+
CTxMemPool::Options MemPoolOptionsForTest(const node::NodeContext& node);
95+
9396
/** Testing setup that performs all steps up until right before
9497
* ChainstateManager gets initialized. Meant for testing ChainstateManager
9598
* initialization behaviour.

0 commit comments

Comments
 (0)