Skip to content

Commit bb4d148

Browse files
committed
Make fuzz targets deterministic
Use deterministic time and hash table ordering when building with cfg(fuzzing) to ensure fuzz test cases reproduce consistently. In channelmanager, use highest_seen_timestamp instead of SystemTime::now() under cfg(fuzzing) for duration_since_epoch and stale payment removal. In hash_tables, extend the existing test deterministic hasher to also apply under cfg(fuzzing), always using zeroed SipHash keys. AI tools were used in preparing this commit.
1 parent 450c03a commit bb4d148

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8936,11 +8936,11 @@ impl<
89368936
let _ = self.handle_error(err, counterparty_node_id);
89378937
}
89388938

8939-
#[cfg(feature = "std")]
8939+
#[cfg(all(feature = "std", not(fuzzing)))]
89408940
let duration_since_epoch = std::time::SystemTime::now()
89418941
.duration_since(std::time::SystemTime::UNIX_EPOCH)
89428942
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
8943-
#[cfg(not(feature = "std"))]
8943+
#[cfg(any(not(feature = "std"), fuzzing))]
89448944
let duration_since_epoch = Duration::from_secs(
89458945
self.highest_seen_timestamp.load(Ordering::Acquire).saturating_sub(7200) as u64,
89468946
);
@@ -14129,7 +14129,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1412914129
let currency =
1413014130
Network::from_chain_hash(self.chain_hash).map(Into::into).unwrap_or(Currency::Bitcoin);
1413114131

14132-
#[cfg(feature = "std")]
14132+
#[cfg(all(feature = "std", not(fuzzing)))]
1413314133
let duration_since_epoch = {
1413414134
use std::time::SystemTime;
1413514135
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)
@@ -14139,7 +14139,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1413914139
// This may be up to 2 hours in the future because of bitcoin's block time rule or about
1414014140
// 10-30 minutes in the past if a block hasn't been found recently. This should be fine as
1414114141
// the default invoice expiration is 2 hours, though shorter expirations may be problematic.
14142-
#[cfg(not(feature = "std"))]
14142+
#[cfg(any(not(feature = "std"), fuzzing))]
1414314143
let duration_since_epoch =
1414414144
Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
1414514145

@@ -14998,10 +14998,12 @@ impl<
1499814998
pub(super) fn duration_since_epoch(&self) -> Duration {
1499914999
#[cfg(not(feature = "std"))]
1500015000
let now = Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
15001-
#[cfg(feature = "std")]
15001+
#[cfg(all(feature = "std", not(fuzzing)))]
1500215002
let now = std::time::SystemTime::now()
1500315003
.duration_since(std::time::SystemTime::UNIX_EPOCH)
1500415004
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
15005+
#[cfg(all(feature = "std", fuzzing))]
15006+
let now = Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
1500515007

1500615008
now
1500715009
}

lightning/src/util/hash_tables.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
pub use hashbrown::hash_map;
77

88
mod hashbrown_tables {
9-
#[cfg(all(feature = "std", not(test)))]
9+
#[cfg(all(feature = "std", not(test), not(fuzzing)))]
1010
mod hasher {
1111
pub use std::collections::hash_map::RandomState;
1212
}
13-
#[cfg(all(feature = "std", test))]
13+
#[cfg(all(feature = "std", any(test, fuzzing)))]
1414
mod hasher {
1515
#![allow(deprecated)] // hash::SipHasher was deprecated in favor of something only in std.
1616
use core::hash::{BuildHasher, Hasher};
@@ -27,7 +27,10 @@ mod hashbrown_tables {
2727

2828
impl RandomState {
2929
pub fn new() -> RandomState {
30-
if std::env::var("LDK_TEST_DETERMINISTIC_HASHES").map(|v| v == "1").unwrap_or(false)
30+
if cfg!(fuzzing)
31+
|| std::env::var("LDK_TEST_DETERMINISTIC_HASHES")
32+
.map(|v| v == "1")
33+
.unwrap_or(false)
3134
{
3235
RandomState::Deterministic
3336
} else {

0 commit comments

Comments
 (0)