diff options
author | MarcoFalke <falke.marco@gmail.com> | 2020-11-10 19:50:52 +0100 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2020-11-10 19:51:11 +0100 |
commit | fa8dd34e918cd80db215df8937aaf6bb1552fcd9 (patch) | |
tree | fc87a7dae12887880b668d3a7c14ceaae5ca2a90 | |
parent | 42f950cb27b732782d55282cdcd934396fcd7071 (diff) | |
parent | fa4234d877ea3193bfd0e18ff68dcb8fb84b47b5 (diff) |
Merge #20332: test: Mock IBD in net_processing fuzzers
fa4234d877ea3193bfd0e18ff68dcb8fb84b47b5 test: Mock IBD in net_processing fuzzers (MarcoFalke)
Pull request description:
Without this the fuzzers fail to detect trivial crasher bugs, such as https://github.com/bitcoin/bitcoin/pull/20317#issuecomment-723047111
ACKs for top commit:
practicalswift:
Tested ACK fa4234d877ea3193bfd0e18ff68dcb8fb84b47b5
Tree-SHA512: ce5da5c0a604b7559805a98ffdde882b44ca4f91b003b493d6e1be230714ce4cccb11dbfc1fc175f9d8fc779551c0a4103ceb4b473552928207d7d78ae329e10
-rw-r--r-- | src/Makefile.test_util.include | 2 | ||||
-rw-r--r-- | src/test/fuzz/process_message.cpp | 7 | ||||
-rw-r--r-- | src/test/fuzz/process_messages.cpp | 6 | ||||
-rw-r--r-- | src/test/util/validation.cpp | 22 | ||||
-rw-r--r-- | src/test/util/validation.h | 17 | ||||
-rw-r--r-- | src/validation.h | 6 |
6 files changed, 56 insertions, 4 deletions
diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include index d7bc73defb..0621da8ddf 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 3ef03137ec..9390399878 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -16,6 +16,7 @@ #include <test/util/mining.h> #include <test/util/net.h> #include <test/util/setup_common.h> +#include <test/util/validation.h> #include <util/memory.h> #include <validationinterface.h> #include <version.h> @@ -63,10 +64,14 @@ void test_one_input(const std::vector<uint8_t>& 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<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION}; CNode& p2p_node = *MakeUnique<CNode>(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<uint8_t>& 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::chrono::microseconds>(), std::atomic<bool>{false}); + GetTime<std::chrono::microseconds>(), std::atomic<bool>{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 f722eeac3a..19ea92b750 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -12,6 +12,7 @@ #include <test/util/mining.h> #include <test/util/net.h> #include <test/util/setup_common.h> +#include <test/util/validation.h> #include <util/memory.h> #include <validation.h> #include <validationinterface.h> @@ -39,7 +40,10 @@ void test_one_input(const std::vector<uint8_t>& 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<CNode*> 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<uint8_t>& 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 0000000000..1aed492c3c --- /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 <test/util/validation.h> + +#include <util/check.h> +#include <util/time.h> +#include <validation.h> + +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 0000000000..b13aa0be60 --- /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 <validation.h> + +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 3d9fa92c15..ffb038ad75 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. |