Avoid grind signatures in fuzz builds
What changed, and why it matters
This commit fixes a fuzz-testing configuration issue. The project has a feature called 'grind_signatures' that makes cryptographic signatures slightly smaller on average, but it is meant only for real network use because it changes transaction weights. The fuzz tests were accidentally inheriting this feature, which could make fuzzing miss bugs that appear with the normal signature size. The patch disables the feature in fuzz builds and adds a compile-time guard to prevent accidentally enabling it in fuzzing mode. It also updates a hard-coded test seed to match the new (slightly larger) transaction weight.
No immediate production action required. This is a fuzzing-harness hardening change. Reviewers should verify that fuzz builds no longer inherit grind_signatures and that the updated splice seed still exercises the intended code paths.
Security signals we found
Compile-time guard prevents dangerous feature combination
Feature misconfiguration in fuzz builds could mask real-world transaction-weight bugs
grind_signatures changes signature size/weight behavior
Fuzz seeds updated to reflect changed weight model
Evidence from the diff
The commit prevents the ‘grind_signatures’ feature from being enabled in fuzz builds. It sets default-features=false for the lightning dependency in fuzz/Cargo.toml and lightning-persister/Cargo.toml, then explicitly enables only ‘std’, ‘regex’, and ‘_test_utils’. It adds a compile_error! guard in lightning/src/lib.rs that fails compilation if both cfg(fuzzing) and feature=’grind_signatures’ are active. The splice fuzz seed in fuzz/src/full_stack.rs is refreshed because disabling grind_signatures changes the no-low-R weight model, altering the signed funding transaction amount (115538 -> 115537 sats) and the fake txid (0x31 -> 0x32).
Changed components
fuzz/Cargo.tomllightning-persister/Cargo.tomllightning/src/lib.rsfuzz/src/full_stack.rsInspect captured patch +14 / −11
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
index 274b19d..76b4968 100644
--- a/fuzz/Cargo.toml
+++ b/fuzz/Cargo.toml
@@ -6,7 +6,7 @@ publish = false
edition = "2021"
[dependencies]
-lightning = { path = "../lightning", features = ["regex", "_test_utils"] }
+lightning = { path = "../lightning", default-features = false, features = ["std", "regex", "_test_utils"] }
lightning-invoice = { path = "../lightning-invoice" }
lightning-liquidity = { path = "../lightning-liquidity" }
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs
index 58509bb..13506ee 100644
--- a/fuzz/src/full_stack.rs
+++ b/fuzz/src/full_stack.rs
@@ -1885,8 +1885,8 @@ fn splice_seed() -> Vec<u8> {
// CommitmentSigned message with proper signature (r=f7, s=01...) and funding_txid TLV
// signature r encodes sighash first byte f7, s follows the pattern from funding_created
// TLV type 1 (odd/optional) for funding_txid as per impl_writeable_msg!(CommitmentSigned, ...)
- // Note: txid is encoded in reverse byte order (Bitcoin standard), so to get display 0000...0031, encode 3100...0000
- ext_from_hex("0084 c000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000f7 0100000000000000000000000000000000000000000000000000000000000000 0000 01 20 3100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
+ // Note: txid is encoded in reverse byte order (Bitcoin standard), so to get display 0000...0032, encode 3200...0000
+ ext_from_hex("0084 c000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000f7 0100000000000000000000000000000000000000000000000000000000000000 0000 01 20 3200000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
// After commitment_signed exchange, we need to exchange tx_signatures.
// Message type IDs: TxSignatures = 71 (0x0047)
@@ -1899,19 +1899,19 @@ fn splice_seed() -> Vec<u8> {
// inbound read from peer id 0 of len 150 (134 message + 16 MAC)
ext_from_hex("030096", &mut test);
// TxSignatures message with shared_input_signature TLV (type 0)
- // txid must match the splice funding txid (0x31 in reverse byte order)
+ // txid must match the splice funding txid (0x32 in reverse byte order)
// shared_input_signature: 64-byte fuzz signature for the shared input
- ext_from_hex("0047 c000000000000000000000000000000000000000000000000000000000000000 3100000000000000000000000000000000000000000000000000000000000000 0000 00 40 00000000000000000000000000000000000000000000000000000000000000dc 0100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
+ ext_from_hex("0047 c000000000000000000000000000000000000000000000000000000000000000 3200000000000000000000000000000000000000000000000000000000000000 0000 00 40 00000000000000000000000000000000000000000000000000000000000000dc 0100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
// Connect a block with the splice funding transaction to confirm it
// The splice funding tx: version(4) + input_count(1) + txid(32) + vout(4) + script_len(1) + sequence(4)
// + output_count(1) + value(8) + script_len(1) + script(34) + locktime(4) = 94 bytes = 0x5e
// Transaction structure from FundingTransactionReadyForSigning:
// - Input: spending c000...00:0 with sequence 0xfffffffd
- // - Output: 115538 sats to OP_0 PUSH32 6e00...00
+ // - Output: 115537 sats to OP_0 PUSH32 6e00...00
// - Locktime: 13
ext_from_hex("0c005e", &mut test);
- ext_from_hex("02000000 01 c000000000000000000000000000000000000000000000000000000000000000 00000000 00 fdffffff 01 52c3010000000000 22 00206e00000000000000000000000000000000000000000000000000000000000000 0d000000", &mut test);
+ ext_from_hex("02000000 01 c000000000000000000000000000000000000000000000000000000000000000 00000000 00 fdffffff 01 51c3010000000000 22 00206e00000000000000000000000000000000000000000000000000000000000000 0d000000", &mut test);
// Connect additional blocks to reach minimum_depth confirmations
for _ in 0..5 {
@@ -1928,8 +1928,8 @@ fn splice_seed() -> Vec<u8> {
// inbound read from peer id 0 of len 82 (66 message + 16 MAC)
ext_from_hex("030052", &mut test);
// SpliceLocked message (type 77 = 0x004d): channel_id + splice_txid + mac
- // splice_txid must match the splice funding txid (0x31 in reverse byte order)
- ext_from_hex("004d c000000000000000000000000000000000000000000000000000000000000000 3100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
+ // splice_txid must match the splice funding txid (0x32 in reverse byte order)
+ ext_from_hex("004d c000000000000000000000000000000000000000000000000000000000000000 3200000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
test
}
@@ -2059,6 +2059,6 @@ mod tests {
// Splice locked
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendSpliceLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 for channel c000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1));
- assert_eq!(log_entries.get(&("lightning::ln::channel".to_string(), "Promoting splice funding txid 0000000000000000000000000000000000000000000000000000000000000031".to_string())), Some(&1));
+ assert_eq!(log_entries.get(&("lightning::ln::channel".to_string(), "Promoting splice funding txid 0000000000000000000000000000000000000000000000000000000000000032".to_string())), Some(&1));
}
}
diff --git a/lightning-persister/Cargo.toml b/lightning-persister/Cargo.toml
index 19c5ac2..cb2aae5 100644
--- a/lightning-persister/Cargo.toml
+++ b/lightning-persister/Cargo.toml
@@ -20,7 +20,7 @@ tokio = ["dep:tokio"]
[dependencies]
bitcoin = "0.32.2"
-lightning = { version = "0.3.0", path = "../lightning" }
+lightning = { version = "0.3.0", path = "../lightning", default-features = false, features = ["std"] }
tokio = { version = "1.35", optional = true, default-features = false, features = ["rt-multi-thread"] }
[target.'cfg(windows)'.dependencies]
diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs
index ee3b0f4..496d1e5 100644
--- a/lightning/src/lib.rs
+++ b/lightning/src/lib.rs
@@ -43,6 +43,9 @@
#[cfg(all(fuzzing, test))]
compile_error!("Tests will always fail with cfg=fuzzing");
+#[cfg(all(fuzzing, feature = "grind_signatures"))]
+compile_error!("Fuzz builds must not enable grind_signatures");
+
#[macro_use]
extern crate alloc;
Why this scored 26/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.