fuzz: Use time helpers in node_eviction
What changed, and why it matters
This commit only changes Bitcoin Core's internal fuzz testing code, which is used to automatically generate random inputs to find bugs during development. It does not change any production networking, consensus, or wallet code that runs on real Bitcoin nodes. There is no security issue here for end users.
No action required; this is a test-only refactoring change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors fuzz-test helpers to use a templated ConsumeDuration
Changed components
src/test/fuzz/addrman.cppsrc/test/fuzz/node_eviction.cppsrc/test/fuzz/util.cppsrc/test/fuzz/util.hInspect captured patch +18 / −13
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
index 6b4519c1..75048028 100644
--- a/src/test/fuzz/addrman.cpp
+++ b/src/test/fuzz/addrman.cpp
@@ -145,7 +145,7 @@ FUZZ_TARGET(addrman, .init = initialize_addrman)
addresses.push_back(ConsumeAddress(fuzzed_data_provider));
}
auto net_addr = ConsumeNetAddr(fuzzed_data_provider);
- auto time_penalty = ConsumeDuration(fuzzed_data_provider, /*min=*/0s, /*max=*/100000000s);
+ auto time_penalty = ConsumeDuration<std::chrono::seconds>(fuzzed_data_provider, /*min=*/0s, /*max=*/100000000s);
addr_man.Add(addresses, net_addr, time_penalty);
},
[&] {
diff --git a/src/test/fuzz/node_eviction.cpp b/src/test/fuzz/node_eviction.cpp
index 04eab335..2ecc91a0 100644
--- a/src/test/fuzz/node_eviction.cpp
+++ b/src/test/fuzz/node_eviction.cpp
@@ -19,13 +19,14 @@ FUZZ_TARGET(node_eviction)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
std::vector<NodeEvictionCandidate> eviction_candidates;
- LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
+ {
eviction_candidates.push_back({
/*id=*/fuzzed_data_provider.ConsumeIntegral<NodeId>(),
- /*m_connected=*/std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
- /*m_min_ping_time=*/std::chrono::microseconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
- /*m_last_block_time=*/std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
- /*m_last_tx_time=*/std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
+ /*m_connected=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
+ /*m_min_ping_time=*/ConsumeDuration<decltype(NodeEvictionCandidate::m_min_ping_time)>(fuzzed_data_provider, /*min=*/std::chrono::years{-1}, /*max=*/decltype(CNode::m_min_ping_time.load())::max()),
+ /*m_last_block_time=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
+ /*m_last_tx_time=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
/*fRelevantServices=*/fuzzed_data_provider.ConsumeBool(),
/*m_relay_txs=*/fuzzed_data_provider.ConsumeBool(),
/*fBloomFilter=*/fuzzed_data_provider.ConsumeBool(),
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index f505357d..da0e2dea 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -36,12 +36,7 @@ NodeSeconds ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::opt
// Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime.
static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z").value()};
static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z").value()};
- return NodeSeconds{ConsumeDuration(fuzzed_data_provider, min.value_or(time_min) * 1s, max.value_or(time_max) * 1s)};
-}
-
-std::chrono::seconds ConsumeDuration(FuzzedDataProvider& fuzzed_data_provider, std::chrono::seconds min, std::chrono::seconds max) noexcept
-{
- return 1s * fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(min.count(), max.count());
+ return NodeSeconds{ConsumeDuration<std::chrono::seconds>(fuzzed_data_provider, min.value_or(time_min) * 1s, max.value_or(time_max) * 1s)};
}
CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<Txid>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index aa1eed8b..fd53e39f 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -140,7 +140,16 @@ template <typename WeakEnumType, size_t size>
[[nodiscard]] CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max = std::nullopt) noexcept;
[[nodiscard]] NodeSeconds ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min = std::nullopt, const std::optional<int64_t>& max = std::nullopt) noexcept;
-[[nodiscard]] std::chrono::seconds ConsumeDuration(FuzzedDataProvider& fuzzed_data_provider, std::chrono::seconds min, std::chrono::seconds max) noexcept;
+
+template <class Dur>
+// Having the compiler infer the template argument from the function argument
+// is dangerous, because the desired return value generally has a different
+// type than the function argument. So std::common_type is used to force the
+// call site to specify the type of the return value.
+[[nodiscard]] Dur ConsumeDuration(FuzzedDataProvider& fuzzed_data_provider, std::common_type_t<Dur> min, std::common_type_t<Dur> max) noexcept
+{
+ return Dur{fuzzed_data_provider.ConsumeIntegralInRange(min.count(), max.count())};
+}
[[nodiscard]] CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<Txid>>& prevout_txids, int max_num_in = 10, int max_num_out = 10) noexcept;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.