From fa4234d877ea3193bfd0e18ff68dcb8fb84b47b5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 6 Nov 2020 15:03:51 +0100 Subject: [PATCH] test: Mock IBD in net_processing fuzzers --- src/Makefile.test_util.include | 2 ++ src/test/fuzz/process_message.cpp | 7 ++++++- src/test/fuzz/process_messages.cpp | 6 ++++++ src/test/util/validation.cpp | 22 ++++++++++++++++++++++ src/test/util/validation.h | 17 +++++++++++++++++ src/validation.h | 6 +++--- 6 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 src/test/util/validation.cpp create mode 100644 src/test/util/validation.h diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include index d7bc73defb4..0621da8ddf6 100644 --- a/src/Makefile.test_util.include +++ b/src/Makefile.test_util.include @@ -15,6 +15,7 @@ TEST_UTIL_H = \ test/util/setup_common.h \ test/util/str.h \ test/util/transaction_utils.h \ + test/util/validation.h \ test/util/wallet.h libtest_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) @@ -27,6 +28,7 @@ libtest_util_a_SOURCES = \ test/util/setup_common.cpp \ test/util/str.cpp \ test/util/transaction_utils.cpp \ + test/util/validation.cpp \ test/util/wallet.cpp \ $(TEST_UTIL_H) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 3ef03137ecf..93903998783 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -63,10 +64,14 @@ void test_one_input(const std::vector& buffer) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); + TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + chainstate.ResetIbd(); const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) { return; } + const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()}; + if (jump_out_of_ibd) chainstate.JumpOutOfIbd(); CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes(), SER_NETWORK, PROTOCOL_VERSION}; CNode& p2p_node = *MakeUnique(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, ConnectionType::OUTBOUND_FULL_RELAY).release(); p2p_node.fSuccessfullyConnected = true; @@ -76,7 +81,7 @@ void test_one_input(const std::vector& buffer) g_setup->m_node.peerman->InitializeNode(&p2p_node); try { g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream, - GetTime(), std::atomic{false}); + GetTime(), std::atomic{false}); } catch (const std::ios_base::failure&) { } SyncWithValidationInterfaceQueue(); diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index f722eeac3a6..19ea92b750d 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,10 @@ void test_one_input(const std::vector& buffer) FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); + TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + chainstate.ResetIbd(); std::vector peers; + bool jump_out_of_ibd{false}; const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); for (int i = 0; i < num_peers_to_add; ++i) { @@ -58,6 +62,8 @@ void test_one_input(const std::vector& buffer) } while (fuzzed_data_provider.ConsumeBool()) { + if (!jump_out_of_ibd) jump_out_of_ibd = fuzzed_data_provider.ConsumeBool(); + if (jump_out_of_ibd && chainstate.IsInitialBlockDownload()) chainstate.JumpOutOfIbd(); const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; CSerializedNetMsg net_msg; diff --git a/src/test/util/validation.cpp b/src/test/util/validation.cpp new file mode 100644 index 00000000000..1aed492c3c0 --- /dev/null +++ b/src/test/util/validation.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include + +void TestChainState::ResetIbd() +{ + m_cached_finished_ibd = false; + assert(IsInitialBlockDownload()); +} + +void TestChainState::JumpOutOfIbd() +{ + Assert(IsInitialBlockDownload()); + m_cached_finished_ibd = true; + Assert(!IsInitialBlockDownload()); +} diff --git a/src/test/util/validation.h b/src/test/util/validation.h new file mode 100644 index 00000000000..b13aa0be60d --- /dev/null +++ b/src/test/util/validation.h @@ -0,0 +1,17 @@ +// Copyright (c) 2020 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_UTIL_VALIDATION_H +#define BITCOIN_TEST_UTIL_VALIDATION_H + +#include + +struct TestChainState : public CChainState { + /** Reset the ibd cache to its initial state */ + void ResetIbd(); + /** Toggle IsInitialBlockDownload from true to false */ + void JumpOutOfIbd(); +}; + +#endif // BITCOIN_TEST_UTIL_VALIDATION_H diff --git a/src/validation.h b/src/validation.h index 3d9fa92c155..ffb038ad75f 100644 --- a/src/validation.h +++ b/src/validation.h @@ -503,9 +503,9 @@ enum class CoinsCacheSizeState * whereas block information and metadata independent of the current tip is * kept in `BlockMetadataManager`. */ -class CChainState { -private: - +class CChainState +{ +protected: /** * Every received block is assigned a unique and increasing identifier, so we * know which one to give priority in case of a fork.