Merge bitcoin/bitcoin#34479: fuzz: Add and use NodeClockContext

faea12ecd9 test: Fixup docs for NodeClockContext and SteadyClockContext (MarcoFalke)
eeeeb2a0b9 fuzz: Use NodeClockContext (MarcoFalke)
fa4fae6227 test: Add NodeClockContext (MarcoFalke)

Pull request description:

  Iterating over fuzz inputs will usually be done in the same process. As the mocktime is global, it can theoretically leak from one fuzz input run into the next run, making it less deterministic.

  Fix this issue, by adding and using a context manager to handle the mocktime and reset it before the end.

  This refactor should not change any behavior.

ACKs for top commit:
  seduless:
    re-ACK faea12ecd9
  dergoegge:
    utACK faea12ecd9
  brunoerg:
    code review ACK faea12ecd9

Tree-SHA512: e222c4e4217a504d058b30f1e975dfdfff019363c82385bd62f368b16fb029c46a5d1b43cd773dbdd9efcd7f968d46dbe2c75812971696b1b879b8f081fc6b1b
This commit is contained in:
merge-script
2026-03-18 16:09:31 +01:00
28 changed files with 101 additions and 48 deletions

View File

@@ -14,6 +14,7 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/asmap.h>
#include <util/chaintype.h>
@@ -116,7 +117,7 @@ FUZZ_TARGET(addrman, .init = initialize_addrman)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
auto addr_man_ptr = std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio());
if (fuzzed_data_provider.ConsumeBool()) {
@@ -201,7 +202,7 @@ FUZZ_TARGET(addrman_serdeser, .init = initialize_addrman)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
AddrManDeterministic addr_man1{netgroupman, fuzzed_data_provider, GetCheckRatio()};

View File

@@ -10,6 +10,7 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/fs.h>
#include <util/readwritefile.h>
@@ -44,7 +45,7 @@ FUZZ_TARGET(banman, .init = initialize_banman)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};
@@ -124,7 +125,7 @@ FUZZ_TARGET(banman, .init = initialize_banman)
}
if (!force_read_and_write_to_err) {
ban_man.DumpBanlist();
SetMockTime(ConsumeTime(fuzzed_data_provider));
clock_ctx.set(ConsumeTime(fuzzed_data_provider));
banmap_t banmap;
ban_man.GetBanned(banmap);
BanMan ban_man_read{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/0};

View File

@@ -12,6 +12,7 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/validation.h>
#include <validation.h>
@@ -41,7 +42,7 @@ void initialize_block_index_tree()
FUZZ_TARGET(block_index_tree, .init = initialize_block_index_tree)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
auto& chainman = static_cast<TestChainstateManager&>(*g_setup->m_node.chainman);
auto& blockman = static_cast<TestBlockManager&>(chainman.m_blockman);
CBlockIndex* genesis = chainman.ActiveChainstate().m_chain[0];

View File

@@ -15,6 +15,7 @@
#include <test/fuzz/util/net.h>
#include <test/fuzz/util/threadinterrupt.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/translation.h>
#include <cstdint>
@@ -40,7 +41,7 @@ FUZZ_TARGET(connman, .init = initialize_connman)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
auto addr_man_ptr{std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio())};
if (fuzzed_data_provider.ConsumeBool()) {

View File

@@ -9,6 +9,7 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <uint256.h>
#include <util/chaintype.h>
#include <util/time.h>
@@ -59,7 +60,7 @@ FUZZ_TARGET(headers_sync_state, .init = initialize_headers_sync_state_fuzz)
CBlockHeader genesis_header{Params().GenesisBlock()};
CBlockIndex start_index(genesis_header);
SetMockTime(ConsumeTime(fuzzed_data_provider, /*min=*/start_index.GetMedianTimePast()));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider, /*min=*/start_index.GetMedianTimePast())};
const uint256 genesis_hash = genesis_header.GetHash();
start_index.phashBlock = &genesis_hash;

View File

@@ -13,6 +13,7 @@
#include <test/fuzz/util/net.h>
#include <test/fuzz/util/threadinterrupt.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/fs_helpers.h>
#include <util/threadinterrupt.h>
@@ -26,7 +27,7 @@ FUZZ_TARGET(i2p, .init = initialize_i2p)
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
// Mock CreateSock() to create FuzzedSock.
auto CreateSockOrig = CreateSock;

View File

@@ -9,6 +9,7 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/time.h>
#include <validation.h>
@@ -28,7 +29,7 @@ void initialize_load_external_block_file()
FUZZ_TARGET(load_external_block_file, .init = initialize_load_external_block_file)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider};
AutoFile fuzzed_block_file{fuzzed_file_provider.open()};
if (fuzzed_block_file.IsNull()) {

View File

@@ -6,10 +6,11 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/mempool.h>
#include <test/util/mining.h>
#include <test/util/script.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/txmempool.h>
#include <test/util/mining.h>
#include <node/miner.h>
#include <node/mini_miner.h>
@@ -42,7 +43,7 @@ FUZZ_TARGET(mini_miner, .init = initialize_miner)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
bilingual_str error;
CTxMemPool pool{CTxMemPool::Options{}, error};
Assert(error.empty());

View File

@@ -14,6 +14,7 @@
#include <test/fuzz/util/net.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/asmap.h>
#include <util/chaintype.h>
#include <util/time.h>
@@ -31,7 +32,7 @@ void initialize_net()
FUZZ_TARGET(net, .init = initialize_net)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
CNode node{ConsumeNode(fuzzed_data_provider)};
node.SetCommonVersion(fuzzed_data_provider.ConsumeIntegral<int>());
if (const auto service_opt =
@@ -80,7 +81,7 @@ FUZZ_TARGET(net, .init = initialize_net)
FUZZ_TARGET(local_address, .init = initialize_net)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
CService service{ConsumeService(fuzzed_data_provider)};
CNode node{ConsumeNode(fuzzed_data_provider)};
{

View File

@@ -17,6 +17,7 @@
#include <test/util/mining.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/validation.h>
#include <util/time.h>
#include <validationinterface.h>
@@ -44,7 +45,7 @@ FUZZ_TARGET(p2p_handshake, .init = ::initialize)
auto& connman = static_cast<ConnmanTestMsg&>(*g_setup->m_node.connman);
auto& chainman = static_cast<TestChainstateManager&>(*g_setup->m_node.chainman);
SetMockTime(1610000000); // any time to successfully reset ibd
NodeClockContext clock_ctx{1610000000s}; // any time to successfully reset ibd
chainman.ResetIbd();
node::Warnings warnings{};
@@ -80,10 +81,11 @@ FUZZ_TARGET(p2p_handshake, .init = ::initialize)
continue;
}
SetMockTime(GetTime() +
clock_ctx += std::chrono::seconds{
fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(
-std::chrono::seconds{10min}.count(), // Allow mocktime to go backwards slightly
std::chrono::seconds{TIMEOUT_INTERVAL}.count()));
std::chrono::seconds{TIMEOUT_INTERVAL}.count()),
};
CSerializedNetMsg net_msg;
net_msg.m_type = PickValue(fuzzed_data_provider, ALL_NET_MESSAGE_TYPES);

View File

@@ -176,7 +176,7 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
ChainstateManager& chainman = *g_testing_setup->m_node.chainman;
CBlockHeader base{chainman.GetParams().GenesisBlock()};
SetMockTime(base.nTime);
const NodeClockContext clock_ctx{base.Time()};
LOCK(NetEventsInterface::g_msgproc_mutex);

View File

@@ -12,6 +12,7 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/mempool.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
#include <util/check.h>
@@ -47,7 +48,7 @@ FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
auto block{ConsumeDeserializable<CBlock>(fuzzed_data_provider, TX_WITH_WITNESS)};
if (!block || block->vtx.size() == 0 ||

View File

@@ -18,6 +18,7 @@
#include <test/util/mining.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/validation.h>
#include <util/check.h>
#include <util/time.h>
@@ -74,7 +75,7 @@ FUZZ_TARGET(process_message, .init = initialize_process_message)
connman.Reset();
auto& chainman{static_cast<TestChainstateManager&>(*node.chainman)};
const auto block_index_size{WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size())};
SetMockTime(1610000000); // any time to successfully reset ibd
NodeClockContext clock_ctx{1610000000s}; // any time to successfully reset ibd
chainman.ResetIbd();
chainman.DisableNextWrite();
@@ -107,8 +108,7 @@ FUZZ_TARGET(process_message, .init = initialize_process_message)
connman.AddTestNode(p2p_node);
FillNode(fuzzed_data_provider, connman, p2p_node);
const auto mock_time = ConsumeTime(fuzzed_data_provider);
SetMockTime(mock_time);
clock_ctx.set(ConsumeTime(fuzzed_data_provider));
CSerializedNetMsg net_msg;
net_msg.m_type = random_message_type;

View File

@@ -17,6 +17,7 @@
#include <test/util/mining.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/validation.h>
#include <util/time.h>
#include <validationinterface.h>
@@ -64,7 +65,7 @@ FUZZ_TARGET(process_messages, .init = initialize_process_messages)
connman.Reset();
auto& chainman{static_cast<TestChainstateManager&>(*node.chainman)};
const auto block_index_size{WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size())};
SetMockTime(1610000000); // any time to successfully reset ibd
NodeClockContext clock_ctx{1610000000s}; // any time to successfully reset ibd
chainman.ResetIbd();
chainman.DisableNextWrite();
@@ -102,8 +103,7 @@ FUZZ_TARGET(process_messages, .init = initialize_process_messages)
{
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::MESSAGE_TYPE_SIZE).c_str()};
const auto mock_time = ConsumeTime(fuzzed_data_provider);
SetMockTime(mock_time);
clock_ctx.set(ConsumeTime(fuzzed_data_provider));
CSerializedNetMsg net_msg;
net_msg.m_type = random_message_type;

View File

@@ -11,6 +11,7 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/mempool.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
#include <util/check.h>
@@ -53,7 +54,7 @@ FUZZ_TARGET(rbf, .init = initialize_rbf)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
if (!mtx) {
return;
@@ -95,7 +96,7 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
// "Real" virtual size is not important for this test since ConsumeTxMemPoolEntry generates its own virtual size values
// so we construct small transactions for performance reasons. Child simply needs an input for later to perhaps connect to parent.

View File

@@ -17,6 +17,7 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <tinyformat.h>
#include <uint256.h>
#include <univalue.h>
@@ -370,7 +371,7 @@ FUZZ_TARGET(rpc, .init = initialize_rpc)
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
bool good_data{true};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
const std::string rpc_command = fuzzed_data_provider.ConsumeRandomLengthString(64);
if (!g_limit_to_rpc_command.empty() && rpc_command != g_limit_to_rpc_command) {
return;

View File

@@ -9,6 +9,7 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/time.h>
#include <cstdint>
@@ -30,7 +31,7 @@ void initialize_socks5()
FUZZ_TARGET(socks5, .init = initialize_socks5)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
ProxyCredentials proxy_credentials;
proxy_credentials.username = fuzzed_data_provider.ConsumeRandomLengthString(512);
proxy_credentials.password = fuzzed_data_provider.ConsumeRandomLengthString(512);

View File

@@ -15,11 +15,12 @@
#include <test/util/mining.h>
#include <test/util/script.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
#include <util/hasher.h>
#include <util/rbf.h>
#include <util/time.h>
#include <txmempool.h>
#include <validation.h>
#include <validationinterface.h>
@@ -168,7 +169,7 @@ FUZZ_TARGET(txdownloadman, .init = initialize)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
// Initialize txdownloadman
bilingual_str error;
@@ -293,7 +294,7 @@ FUZZ_TARGET(txdownloadman_impl, .init = initialize)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
// Initialize a TxDownloadManagerImpl
bilingual_str error;

View File

@@ -15,6 +15,7 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <uint256.h>
#include <util/check.h>
#include <util/feefrac.h>
@@ -40,7 +41,7 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
FastRandomContext orphanage_rng{ConsumeUInt256(fuzzed_data_provider)};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
auto orphanage = node::MakeTxOrphanage();
std::vector<COutPoint> outpoints; // Duplicates are tolerated
@@ -227,7 +228,7 @@ FUZZ_TARGET(txorphan_protected, .init = initialize_orphanage)
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
FastRandomContext orphanage_rng{ConsumeUInt256(fuzzed_data_provider)};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
// We have num_peers peers. Some subset of them will never exceed their reserved weight or announcement count, and
// should therefore never have any orphans evicted.

View File

@@ -42,8 +42,10 @@ struct CheckGlobalsImpl {
std::cerr << "\n\n"
"The current fuzz target accessed system time.\n\n"
"This is acceptable, but requires the fuzz target to call \n"
"SetMockTime() at the beginning of processing the fuzz input.\n\n"
"This is acceptable, but requires the fuzz target to use \n"
"a NodeClockContext, SteadyClockContext or call \n"
"SetMockTime() at the \n" "beginning of processing the \n"
"fuzz input.\n\n"
"Without setting mock time, time-dependent behavior can lead \n"
"to non-reproducible bugs or inefficient fuzzing.\n\n"

View File

@@ -21,6 +21,7 @@
#include <test/fuzz/util.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <uint256.h>
#include <util/check.h>
#include <util/fs.h>
@@ -103,7 +104,7 @@ void utxo_snapshot_fuzz(FuzzBufferType buffer)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider, /*min=*/1296688602)); // regtest genesis block timestamp
NodeClockContext clock_ctx{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};

View File

@@ -14,6 +14,7 @@
#include <test/fuzz/util.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/chaintype.h>
#include <util/time.h>
#include <validation.h>
@@ -24,7 +25,7 @@ FUZZ_TARGET(utxo_total_supply)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider, /*min=*/1296688602)); // regtest genesis block timestamp
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider, /*min=*/1296688602)}; // regtest genesis block timestamp
/** The testing setup that creates a chainman only (no chainstate) */
ChainTestingSetup test_setup{
ChainType::REGTEST,

View File

@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <node/mempool_persist.h>
#include <test/util/time.h>
#include <node/mempool_args.h>
#include <node/mempool_persist_args.h>
@@ -40,7 +41,7 @@ FUZZ_TARGET(validation_load_mempool, .init = initialize_validation_load_mempool)
{
SeedRandomStateForTest(SeedRand::ZEROS);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
NodeClockContext clock_ctx{ConsumeTime(fuzzed_data_provider)};
FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider};
bilingual_str error;