From f9269d1ae251d0d3709e3dbcc85258a4c3c20765 Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Tue, 19 May 2026 16:35:58 +0200 Subject: [PATCH 1/2] Avoid grind signatures in fuzz builds Disable default lightning features in the fuzz crate and persister so fuzz builds do not inherit grind_signatures. Add a compile-time guard for fuzzing plus grind_signatures. Refresh the splice fuzz seed because the no-low-R weight model changes the signed funding transaction amount and fake-hash txid. --- fuzz/Cargo.toml | 2 +- fuzz/src/full_stack.rs | 18 +++++++++--------- lightning-persister/Cargo.toml | 2 +- lightning/src/lib.rs | 3 +++ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 274b19d8ee4..76b4968f043 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 58509bb9b08..13506ee3107 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -1885,8 +1885,8 @@ fn splice_seed() -> Vec { // 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 { // 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 { // 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 19c5ac2545e..cb2aae556b6 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 ee3b0f47a4d..496d1e5bb45 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; From 241ac47be6985373128e1ce1ff8151009d1c135a Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Tue, 19 May 2026 16:36:15 +0200 Subject: [PATCH 2/2] Account for fuzz signature weight When secp256k1_fuzz is active, dummy ECDSA signatures may serialize one byte larger per signature. Use fuzz-aware witness estimates for keyed-anchor bumping and HTLC resolution so debug weight assertions and aggregation limits use the fuzz signer bound. --- lightning/src/events/bump_transaction/mod.rs | 29 ++++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lightning/src/events/bump_transaction/mod.rs b/lightning/src/events/bump_transaction/mod.rs index 6a5e9948653..79f5aced1b6 100644 --- a/lightning/src/events/bump_transaction/mod.rs +++ b/lightning/src/events/bump_transaction/mod.rs @@ -331,7 +331,13 @@ impl= max_tx_weight - USER_COINS_WEIGHT_BUDGET { @@ -649,9 +667,8 @@ impl selection, Err(()) => { - let htlcs_to_remove = USER_COINS_WEIGHT_BUDGET.div_ceil( - chan_utils::aggregated_htlc_timeout_input_output_pair_weight(channel_type), - ); + let htlcs_to_remove = + USER_COINS_WEIGHT_BUDGET.div_ceil(htlc_timeout_input_output_pair_weight); batch_size = batch_size.checked_sub(htlcs_to_remove as usize).ok_or(())?; if batch_size == 0 { return Err(());