Skip to content

Commit 4f8bd39

Browse files
committed
Merge bitcoin/bitcoin#34913: fuzz: Use time helpers in node_eviction
fa1ebde fuzz: Use time helpers in node_eviction (MarcoFalke) Pull request description: The `node_eviction` fuzz test has many issues: * It uses the full `int64_t` range (in seconds) as input, which is absurdly large (millions of years) and also violates https://en.cppreference.com/w/cpp/chrono/duration.html: > Each of the predefined duration types up to hours covers a range of at least ±292 years. * It does not use the existing `ConsumeDuration` and `ConsumeTime` helpers, which makes specifying a proper range difficult. So fix all issues by using `ConsumeTime` for time points with default arguments, and `ConsumeDuration` with the same precision, as well as possibly negative values. ACKs for top commit: marcofleon: crACK fa1ebde brunoerg: reACK fa1ebde w0xlt: ACK fa1ebde Tree-SHA512: 22045e6c563a9169327737895ea2f3a7b1dcb4fd24fce56d91caa1e132d03a85cbaaa5f78218d23cfa203fe2ee4b147894c02870eb20ae1c232ad55ccdb6f7f7
2 parents 21da421 + fa1ebde commit 4f8bd39

4 files changed

Lines changed: 18 additions & 13 deletions

File tree

src/test/fuzz/addrman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ FUZZ_TARGET(addrman, .init = initialize_addrman)
145145
addresses.push_back(ConsumeAddress(fuzzed_data_provider));
146146
}
147147
auto net_addr = ConsumeNetAddr(fuzzed_data_provider);
148-
auto time_penalty = ConsumeDuration(fuzzed_data_provider, /*min=*/0s, /*max=*/100000000s);
148+
auto time_penalty = ConsumeDuration<std::chrono::seconds>(fuzzed_data_provider, /*min=*/0s, /*max=*/100000000s);
149149
addr_man.Add(addresses, net_addr, time_penalty);
150150
},
151151
[&] {

src/test/fuzz/node_eviction.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ FUZZ_TARGET(node_eviction)
1919
{
2020
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
2121
std::vector<NodeEvictionCandidate> eviction_candidates;
22-
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
22+
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
23+
{
2324
eviction_candidates.push_back({
2425
/*id=*/fuzzed_data_provider.ConsumeIntegral<NodeId>(),
25-
/*m_connected=*/std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
26-
/*m_min_ping_time=*/std::chrono::microseconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
27-
/*m_last_block_time=*/std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
28-
/*m_last_tx_time=*/std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int64_t>()},
26+
/*m_connected=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
27+
/*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()),
28+
/*m_last_block_time=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
29+
/*m_last_tx_time=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
2930
/*fRelevantServices=*/fuzzed_data_provider.ConsumeBool(),
3031
/*m_relay_txs=*/fuzzed_data_provider.ConsumeBool(),
3132
/*fBloomFilter=*/fuzzed_data_provider.ConsumeBool(),

src/test/fuzz/util.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ NodeSeconds ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::opt
3636
// Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime.
3737
static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z").value()};
3838
static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z").value()};
39-
return NodeSeconds{ConsumeDuration(fuzzed_data_provider, min.value_or(time_min) * 1s, max.value_or(time_max) * 1s)};
40-
}
41-
42-
std::chrono::seconds ConsumeDuration(FuzzedDataProvider& fuzzed_data_provider, std::chrono::seconds min, std::chrono::seconds max) noexcept
43-
{
44-
return 1s * fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(min.count(), max.count());
39+
return NodeSeconds{ConsumeDuration<std::chrono::seconds>(fuzzed_data_provider, min.value_or(time_min) * 1s, max.value_or(time_max) * 1s)};
4540
}
4641

4742
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

src/test/fuzz/util.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,16 @@ template <typename WeakEnumType, size_t size>
140140
[[nodiscard]] CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max = std::nullopt) noexcept;
141141

142142
[[nodiscard]] NodeSeconds ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min = std::nullopt, const std::optional<int64_t>& max = std::nullopt) noexcept;
143-
[[nodiscard]] std::chrono::seconds ConsumeDuration(FuzzedDataProvider& fuzzed_data_provider, std::chrono::seconds min, std::chrono::seconds max) noexcept;
143+
144+
template <class Dur>
145+
// Having the compiler infer the template argument from the function argument
146+
// is dangerous, because the desired return value generally has a different
147+
// type than the function argument. So std::common_type is used to force the
148+
// call site to specify the type of the return value.
149+
[[nodiscard]] Dur ConsumeDuration(FuzzedDataProvider& fuzzed_data_provider, std::common_type_t<Dur> min, std::common_type_t<Dur> max) noexcept
150+
{
151+
return Dur{fuzzed_data_provider.ConsumeIntegralInRange(min.count(), max.count())};
152+
}
144153

145154
[[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;
146155

0 commit comments

Comments
 (0)