mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-21 19:34:20 +02:00
net, fuzz: move CMPCTBLOCK_VERSION to header, use in cmpctblock harness
The cmpctblock harness now adds peers and processes the sendcmpct message.
This commit is contained in:
@@ -195,8 +195,6 @@ static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1};
|
||||
* based increments won't go above this, but the MAX_ADDR_TO_SEND increment following GETADDR
|
||||
* is exempt from this limit). */
|
||||
static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND};
|
||||
/** The compactblocks version we support. See BIP 152. */
|
||||
static constexpr uint64_t CMPCTBLOCKS_VERSION{2};
|
||||
/** For private broadcast, send a transaction to this many peers. */
|
||||
static constexpr size_t NUM_PRIVATE_BROADCAST_PER_TX{3};
|
||||
/** Private broadcast connections must complete within this time. Disconnect the peer if it takes longer. */
|
||||
|
||||
@@ -48,6 +48,8 @@ static const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK = 3;
|
||||
/** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends
|
||||
* less than this number, we reached its tip. Changing this value is a protocol upgrade. */
|
||||
static const unsigned int MAX_HEADERS_RESULTS = 2000;
|
||||
/** The compactblocks version we support. See BIP 152. */
|
||||
static constexpr uint64_t CMPCTBLOCKS_VERSION{2};
|
||||
|
||||
struct CNodeStateStats {
|
||||
int nSyncHeight = -1;
|
||||
|
||||
@@ -2,18 +2,25 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <addrman.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <netmessagemaker.h>
|
||||
#include <node/miner.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <protocol.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
#include <test/fuzz/util/net.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/net.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/script.h>
|
||||
#include <test/util/setup_common.h>
|
||||
@@ -30,6 +37,11 @@
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -74,14 +86,53 @@ FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock)
|
||||
NodeClockContext clock_ctx{1610000000s};
|
||||
|
||||
auto setup = g_setup;
|
||||
auto& mempool = *setup->m_node.mempool;
|
||||
auto& chainman = static_cast<TestChainstateManager&>(*setup->m_node.chainman);
|
||||
chainman.ResetIbd();
|
||||
chainman.DisableNextWrite();
|
||||
|
||||
AddrMan addrman{*setup->m_node.netgroupman, /*deterministic=*/true, /*consistency_check_ratio=*/0};
|
||||
auto& connman = *static_cast<ConnmanTestMsg*>(setup->m_node.connman.get());
|
||||
auto peerman = PeerManager::make(connman, addrman,
|
||||
/*banman=*/nullptr, chainman,
|
||||
mempool, *setup->m_node.warnings,
|
||||
PeerManager::Options{
|
||||
.deterministic_rng = true,
|
||||
});
|
||||
connman.SetMsgProc(peerman.get());
|
||||
|
||||
setup->m_node.validation_signals->RegisterValidationInterface(peerman.get());
|
||||
setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||
|
||||
LOCK(NetEventsInterface::g_msgproc_mutex);
|
||||
|
||||
std::vector<CNode*> peers;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release());
|
||||
CNode& p2p_node = *peers.back();
|
||||
FillNode(fuzzed_data_provider, connman, p2p_node);
|
||||
connman.AddTestNode(p2p_node);
|
||||
}
|
||||
|
||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 1000)
|
||||
{
|
||||
CSerializedNetMsg net_msg;
|
||||
bool sent_net_msg = true;
|
||||
bool requested_hb = false;
|
||||
bool sent_sendcmpct = false;
|
||||
bool valid_sendcmpct = false;
|
||||
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
[&]() {
|
||||
// Send a sendcmpct message, optionally setting hb mode.
|
||||
bool hb = fuzzed_data_provider.ConsumeBool();
|
||||
uint64_t version{fuzzed_data_provider.ConsumeBool() ? CMPCTBLOCKS_VERSION : fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
|
||||
net_msg = NetMsg::Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/hb, /*version=*/version);
|
||||
requested_hb = hb;
|
||||
sent_sendcmpct = true;
|
||||
valid_sendcmpct = version == CMPCTBLOCKS_VERSION;
|
||||
},
|
||||
[&]() {
|
||||
// Set mock time randomly or to tip's time.
|
||||
if (fuzzed_data_provider.ConsumeBool()) {
|
||||
@@ -90,6 +141,37 @@ FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock)
|
||||
const NodeSeconds tip_time = WITH_LOCK(::cs_main, return chainman.ActiveChain().Tip()->Time());
|
||||
clock_ctx.set(tip_time);
|
||||
}
|
||||
|
||||
sent_net_msg = false;
|
||||
});
|
||||
|
||||
if (!sent_net_msg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CNode& random_node = *PickValue(fuzzed_data_provider, peers);
|
||||
connman.FlushSendBuffer(random_node);
|
||||
(void)connman.ReceiveMsgFrom(random_node, std::move(net_msg));
|
||||
|
||||
bool more_work{true};
|
||||
while (more_work) {
|
||||
random_node.fPauseSend = false;
|
||||
|
||||
more_work = connman.ProcessMessagesOnce(random_node);
|
||||
peerman->SendMessages(random_node);
|
||||
}
|
||||
|
||||
std::vector<CNodeStats> stats;
|
||||
connman.GetNodeStats(stats);
|
||||
|
||||
if (sent_sendcmpct && !random_node.fDisconnect) {
|
||||
// If the fuzzer sent SENDCMPCT with proper version, check the node's state matches what it sent.
|
||||
const CNodeStats& random_node_stats = stats[random_node.GetId()];
|
||||
if (valid_sendcmpct) assert(random_node_stats.m_bip152_highbandwidth_from == requested_hb);
|
||||
}
|
||||
}
|
||||
|
||||
setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||
setup->m_node.validation_signals->UnregisterAllValidationInterfaces();
|
||||
connman.StopNodes();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user