mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
Merge bitcoin/bitcoin#35956: fuzz: scope fake clocks to target phases
4e5327bc98fuzz: refactor: scope fake clocks to target phases (Hao Xu)e33410d888fuzz: document arbitrary mocktimes (Hao Xu) Pull request description: Follow-up to #35482 (https://github.com/bitcoin/bitcoin/pull/35482#discussion_r3612852792), addressing a remaining issue with the lifetime of the mock node clock. This replaces the process-wide `FakeNodeClock` accessor with scoped clocks in the affected fuzz target initialization and input-processing phases, following the existing `FakeSteadyClock` pattern. The active clock is passed to `ResetChainmanAndMempool()` by reference. Tested the affected fuzz targets with `-runs=1`: - `cmpctblock` - `process_message` - `process_messages` - `utxo_snapshot` - `utxo_snapshot_invalid` ACKs for top commit: maflcko: review ACK4e5327bc98🚉 nervana21: re-ACK4e5327bc98Tree-SHA512: 7763bb2a06e3f33bcae3ad7b43f6d30a231e39197e8d274eadd496da1194fc0178b27cf016b451f36309d9277ce414c85daf734604c85a9deb3803b26b968e6a
This commit is contained in:
@@ -119,12 +119,13 @@ extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;
|
||||
|
||||
void initialize_cmpctblock()
|
||||
{
|
||||
FakeNodeClock init_clock{}; // Uses the existing mock time
|
||||
static const auto testing_setup = MakeNoLogFileContext<TestingSetup>();
|
||||
g_setup = testing_setup.get();
|
||||
g_nBits = Params().GenesisBlock().nBits;
|
||||
// Replace validation_signals before creating chainman and mempool so they use it.
|
||||
testing_setup->m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<ImmediateBackgroundTaskRunner>());
|
||||
g_mature_coinbase = ResetChainmanAndMempool(*g_setup);
|
||||
g_mature_coinbase = ResetChainmanAndMempool(*g_setup, init_clock);
|
||||
}
|
||||
|
||||
FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock)
|
||||
@@ -132,7 +133,7 @@ FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock)
|
||||
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||
|
||||
GetFakeNodeClock().set(1610000000s);
|
||||
FakeNodeClock node_clock{1610000000s}; // 2021-01-07, arbitrary
|
||||
FakeSteadyClock steady_clock;
|
||||
|
||||
auto setup = g_setup;
|
||||
@@ -422,10 +423,10 @@ FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock)
|
||||
[&]() {
|
||||
// Set mock time randomly or to tip's time.
|
||||
if (fuzzed_data_provider.ConsumeBool()) {
|
||||
GetFakeNodeClock().set(ConsumeTime(fuzzed_data_provider));
|
||||
node_clock.set(ConsumeTime(fuzzed_data_provider));
|
||||
} else {
|
||||
const NodeSeconds tip_time = WITH_LOCK(::cs_main, return chainman.ActiveChain().Tip()->Time());
|
||||
GetFakeNodeClock().set(tip_time);
|
||||
node_clock.set(tip_time);
|
||||
}
|
||||
|
||||
sent_net_msg = false;
|
||||
@@ -478,6 +479,6 @@ FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock)
|
||||
|
||||
if (initial_index_size != end_index_size || initial_sequence != end_sequence) {
|
||||
MakeRandDeterministicDANGEROUS(uint256::ZERO);
|
||||
g_mature_coinbase = ResetChainmanAndMempool(*g_setup);
|
||||
g_mature_coinbase = ResetChainmanAndMempool(*g_setup, node_clock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ FUZZ_TARGET(p2p_private_broadcast, .init = ::initialize)
|
||||
connman.Reset();
|
||||
auto& chainman{static_cast<TestChainstateManager&>(*node.chainman)};
|
||||
|
||||
FakeNodeClock clock_ctx{1610000000s};
|
||||
FakeNodeClock clock_ctx{1610000000s}; // 2021-01-07, arbitrary
|
||||
FakeSteadyClock steady_clock;
|
||||
chainman.ResetIbd();
|
||||
// Sometimes leave IBD: incoming TX processing (the broadcast-abort path)
|
||||
|
||||
@@ -48,6 +48,7 @@ extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;
|
||||
|
||||
void initialize_process_message()
|
||||
{
|
||||
FakeNodeClock init_clock{}; // Uses the existing mock time
|
||||
if (const auto val{std::getenv("LIMIT_TO_MESSAGE_TYPE")}) {
|
||||
LIMIT_TO_MESSAGE_TYPE = val;
|
||||
Assert(std::count(ALL_NET_MESSAGE_TYPES.begin(), ALL_NET_MESSAGE_TYPES.end(), LIMIT_TO_MESSAGE_TYPE)); // Unknown message type passed
|
||||
@@ -59,7 +60,7 @@ void initialize_process_message()
|
||||
{}),
|
||||
};
|
||||
g_setup = testing_setup.get();
|
||||
ResetChainmanAndMempool(*g_setup);
|
||||
ResetChainmanAndMempool(*g_setup, init_clock);
|
||||
}
|
||||
|
||||
FUZZ_TARGET(process_message, .init = initialize_process_message)
|
||||
@@ -73,7 +74,7 @@ FUZZ_TARGET(process_message, .init = initialize_process_message)
|
||||
auto& chainman{static_cast<TestChainstateManager&>(*node.chainman)};
|
||||
const auto block_index_size{WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size())};
|
||||
const auto initial_sequence{WITH_LOCK(node.mempool->cs, return node.mempool->GetSequence())};
|
||||
GetFakeNodeClock().set(1610000000s); // 2021-01-07, arbitrary
|
||||
FakeNodeClock node_clock{1610000000s}; // 2021-01-07, arbitrary
|
||||
FakeSteadyClock steady_clock;
|
||||
chainman.ResetIbd();
|
||||
chainman.DisableNextWrite();
|
||||
@@ -107,7 +108,7 @@ FUZZ_TARGET(process_message, .init = initialize_process_message)
|
||||
connman.AddTestNode(p2p_node);
|
||||
FillNode(fuzzed_data_provider, connman, p2p_node);
|
||||
|
||||
GetFakeNodeClock().set(ConsumeTime(fuzzed_data_provider));
|
||||
node_clock.set(ConsumeTime(fuzzed_data_provider));
|
||||
|
||||
CSerializedNetMsg net_msg;
|
||||
net_msg.m_type = random_message_type;
|
||||
@@ -136,6 +137,6 @@ FUZZ_TARGET(process_message, .init = initialize_process_message)
|
||||
if (block_index_size != WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size()) || initial_sequence != end_sequence) {
|
||||
// Reuse the global chainman and mempool, but reset them when dirty.
|
||||
MakeRandDeterministicDANGEROUS(uint256::ZERO);
|
||||
ResetChainmanAndMempool(*g_setup);
|
||||
ResetChainmanAndMempool(*g_setup, node_clock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +43,14 @@ extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;
|
||||
|
||||
void initialize_process_messages()
|
||||
{
|
||||
FakeNodeClock init_clock{}; // Uses the existing mock time
|
||||
static const auto testing_setup{
|
||||
MakeNoLogFileContext<TestingSetup>(
|
||||
/*chain_type=*/ChainType::REGTEST,
|
||||
{}),
|
||||
};
|
||||
g_setup = testing_setup.get();
|
||||
ResetChainmanAndMempool(*g_setup);
|
||||
ResetChainmanAndMempool(*g_setup, init_clock);
|
||||
}
|
||||
|
||||
FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
||||
@@ -63,7 +64,7 @@ FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
||||
auto& chainman{static_cast<TestChainstateManager&>(*node.chainman)};
|
||||
const auto block_index_size{WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size())};
|
||||
const auto initial_sequence{WITH_LOCK(node.mempool->cs, return node.mempool->GetSequence())};
|
||||
GetFakeNodeClock().set(1610000000s); // 2021-01-07, arbitrary
|
||||
FakeNodeClock node_clock{1610000000s}; // 2021-01-07, arbitrary
|
||||
FakeSteadyClock steady_clock;
|
||||
chainman.ResetIbd();
|
||||
chainman.DisableNextWrite();
|
||||
@@ -107,7 +108,7 @@ FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
||||
if (jump_out_of_ibd && chainman.IsInitialBlockDownload()) chainman.JumpOutOfIbd();
|
||||
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::MESSAGE_TYPE_SIZE).c_str()};
|
||||
|
||||
GetFakeNodeClock().set(ConsumeTime(fuzzed_data_provider));
|
||||
node_clock.set(ConsumeTime(fuzzed_data_provider));
|
||||
|
||||
CSerializedNetMsg net_msg;
|
||||
net_msg.m_type = random_message_type;
|
||||
@@ -136,6 +137,6 @@ FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
||||
if (block_index_size != WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size()) || initial_sequence != end_sequence) {
|
||||
// Reuse the global chainman and mempool, but reset them when dirty.
|
||||
MakeRandDeterministicDANGEROUS(uint256::ZERO);
|
||||
ResetChainmanAndMempool(*g_setup);
|
||||
ResetChainmanAndMempool(*g_setup, node_clock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ void initialize_chain()
|
||||
const auto params{CreateChainParams(ArgsManager{}, ChainType::REGTEST)};
|
||||
static const auto chain{CreateBlockChain(2 * COINBASE_MATURITY, *params)};
|
||||
g_chain = &chain;
|
||||
GetFakeNodeClock().set(chain.back()->Time());
|
||||
FakeNodeClock node_clock{chain.back()->Time()};
|
||||
|
||||
// Make sure we can generate a valid snapshot.
|
||||
sanity_check_snapshot();
|
||||
@@ -104,7 +104,7 @@ void utxo_snapshot_fuzz(FuzzBufferType buffer)
|
||||
{
|
||||
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||
GetFakeNodeClock().set(ConsumeTime(fuzzed_data_provider, /*min=*/1296688602)); // regtest genesis block timestamp
|
||||
FakeNodeClock node_clock{ConsumeTime(fuzzed_data_provider, /*min=*/1296688602)}; // regtest genesis block timestamp
|
||||
auto& setup{*g_setup};
|
||||
bool dirty_chainman{false}; // Reuse the global chainman, but reset it when it is dirty
|
||||
auto& chainman{*setup.m_node.chainman};
|
||||
|
||||
Reference in New Issue
Block a user