test/fuzz: Invoke LoadMempool via CChainState

Not only does this increase coverage, it is also more correct in that
when ::LoadMempool is called with a mempool and chainstate, it calls
AcceptToMemoryPool with just the chainstate.

AcceptToMemoryPool will then act on the chainstate's mempool via
CChainState::GetMempool, which may be different from the mempool
originally passed to ::LoadMempool. (In this fuzz test's case, it
definitely is different)

Also, move DummyChainstate to its own file since it's now used by the
validation_load_mempool fuzz test to replace CChainState's m_mempool.
This commit is contained in:
Carl Dong 2022-05-17 14:45:18 -04:00
parent b3267258b0
commit b857ac60d9
6 changed files with 29 additions and 13 deletions

View File

@ -10,6 +10,7 @@ EXTRA_LIBRARIES += \
TEST_FUZZ_H = \ TEST_FUZZ_H = \
test/fuzz/fuzz.h \ test/fuzz/fuzz.h \
test/fuzz/FuzzedDataProvider.h \ test/fuzz/FuzzedDataProvider.h \
test/fuzz/mempool_utils.h \
test/fuzz/util.h test/fuzz/util.h
libtest_fuzz_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(NATPMP_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) libtest_fuzz_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(NATPMP_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)

View File

@ -0,0 +1,19 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_TEST_FUZZ_MEMPOOL_UTILS_H
#define BITCOIN_TEST_FUZZ_MEMPOOL_UTILS_H
#include <validation.h>
class DummyChainState final : public CChainState
{
public:
void SetMempool(CTxMemPool* mempool)
{
m_mempool = mempool;
}
};
#endif // BITCOIN_TEST_FUZZ_MEMPOOL_UTILS_H

View File

@ -8,6 +8,7 @@
#include <node/miner.h> #include <node/miner.h>
#include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
#include <test/fuzz/mempool_utils.h>
#include <test/fuzz/util.h> #include <test/fuzz/util.h>
#include <test/util/mining.h> #include <test/util/mining.h>
#include <test/util/script.h> #include <test/util/script.h>
@ -34,15 +35,6 @@ struct MockedTxPool : public CTxMemPool {
} }
}; };
class DummyChainState final : public CChainState
{
public:
void SetMempool(CTxMemPool* mempool)
{
m_mempool = mempool;
}
};
void initialize_tx_pool() void initialize_tx_pool()
{ {
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();

View File

@ -7,6 +7,7 @@
#include <node/mempool_persist_args.h> #include <node/mempool_persist_args.h>
#include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
#include <test/fuzz/mempool_utils.h>
#include <test/fuzz/util.h> #include <test/fuzz/util.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <txmempool.h> #include <txmempool.h>
@ -36,9 +37,12 @@ FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool)
CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)}; CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)};
auto& chainstate{static_cast<DummyChainState&>(g_setup->m_node.chainman->ActiveChainstate())};
chainstate.SetMempool(&pool);
auto fuzzed_fopen = [&](const fs::path&, const char*) { auto fuzzed_fopen = [&](const fs::path&, const char*) {
return fuzzed_file_provider.open(); return fuzzed_file_provider.open();
}; };
(void)LoadMempool(pool, g_setup->m_node.chainman->ActiveChainstate(), fuzzed_fopen); (void)chainstate.LoadMempool(g_setup->m_args, fuzzed_fopen);
(void)DumpMempool(pool, MempoolPath(g_setup->m_args), fuzzed_fopen, true); (void)DumpMempool(pool, MempoolPath(g_setup->m_args), fuzzed_fopen, true);
} }

View File

@ -3865,11 +3865,11 @@ void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeigh
} }
} }
void CChainState::LoadMempool(const ArgsManager& args) void CChainState::LoadMempool(const ArgsManager& args, FopenFn mockable_fopen_function)
{ {
if (!m_mempool) return; if (!m_mempool) return;
if (args.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { if (args.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
::LoadMempool(*m_mempool, *this); ::LoadMempool(*m_mempool, *this, mockable_fopen_function);
} }
m_mempool->SetLoadTried(!ShutdownRequested()); m_mempool->SetLoadTried(!ShutdownRequested());
} }

View File

@ -679,7 +679,7 @@ public:
void CheckBlockIndex(); void CheckBlockIndex();
/** Load the persisted mempool from disk */ /** Load the persisted mempool from disk */
void LoadMempool(const ArgsManager& args); void LoadMempool(const ArgsManager& args, fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen);
/** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */ /** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */
bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main);