Skip to content

Commit 8230ff7

Browse files
committed
Stop reading fee estimates directly in full_stack_target
The `full_stack` fuzzer tries to just expose much of the entire library to the fuzzer, and as such when a request comes in from LDK to estimate the current fee it tries to read two bytes of fuzzing input and returns that as the fee to LDK. However, because LDK regularly changes when it requests a fee estimate from the user this causes the fuzz input required to reach a codepath to change regularly, making any existing fuzz corpus stale. Instead, here, we allow the fuzz input to load a fee estimate result into a buffer, and if its empty simply return 253. This allows the fuzzer to still reach fee-estimate-triggered overflows, but only invalidates fuzzing seeds that relied on fee estimate inputs rather than all seeds whenever LDK changes fee estimate calls.
1 parent df9232b commit 8230ff7

File tree

1 file changed

+12
-77
lines changed

1 file changed

+12
-77
lines changed

fuzz/src/full_stack.rs

Lines changed: 12 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ use bitcoin::secp256k1::schnorr;
7979
use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey};
8080

8181
use lightning::util::dyn_signer::DynSigner;
82+
83+
use std::collections::VecDeque;
8284
use std::cell::RefCell;
8385
use std::cmp;
84-
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
86+
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
8587
use std::sync::{Arc, Mutex};
8688

8789
#[inline]
@@ -110,7 +112,7 @@ pub fn slice_to_be24(v: &[u8]) -> u32 {
110112
struct InputData {
111113
data: Vec<u8>,
112114
read_pos: AtomicUsize,
113-
halt_fee_est_reads: AtomicBool,
115+
fee_estimates: Mutex<VecDeque<u32>>,
114116
}
115117
impl InputData {
116118
fn get_slice(&self, len: usize) -> Option<&[u8]> {
@@ -137,14 +139,10 @@ struct FuzzEstimator {
137139
}
138140
impl FeeEstimator for FuzzEstimator {
139141
fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u32 {
140-
if self.input.halt_fee_est_reads.load(Ordering::Acquire) {
141-
return 253;
142-
}
143-
//TODO: We should actually be testing at least much more than 64k...
144-
match self.input.get_slice(2) {
145-
Some(slice) => cmp::max(slice_to_be16(slice) as u32, 253),
146-
None => 253,
142+
if let Some(val) = self.input.fee_estimates.lock().unwrap().pop_front() {
143+
return val;
147144
}
145+
return 253;
148146
}
149147
}
150148

@@ -539,7 +537,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
539537
let input = Arc::new(InputData {
540538
data: data.to_vec(),
541539
read_pos: AtomicUsize::new(0),
542-
halt_fee_est_reads: AtomicBool::new(false),
540+
fee_estimates: Mutex::new(VecDeque::new()),
543541
});
544542
let fee_est = Arc::new(FuzzEstimator { input: input.clone() });
545543
let router = FuzzRouter {};
@@ -882,12 +880,10 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
882880
11 => {
883881
let mut txn = broadcast.txn_broadcasted.lock().unwrap().split_off(0);
884882
if !txn.is_empty() {
885-
input.halt_fee_est_reads.store(true, Ordering::Release);
886883
loss_detector.connect_block(&txn[..]);
887884
for _ in 2..100 {
888885
loss_detector.connect_block(&[]);
889886
}
890-
input.halt_fee_est_reads.store(false, Ordering::Release);
891887
}
892888
for tx in txn.drain(..) {
893889
loss_detector.funding_txn.push(tx);
@@ -986,6 +982,10 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
986982
);
987983
}
988984
},
985+
48 => {
986+
let fee = u32::from_le_bytes(get_slice!(4).try_into().unwrap());
987+
input.fee_estimates.lock().unwrap().push_back(fee);
988+
},
989989
_ => return,
990990
}
991991
loss_detector.handler.process_events();
@@ -1084,8 +1084,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
10841084
// rest of open_channel and mac
10851085
ext_from_hex("030000000000000000000000000000000000000000000000000000000000000005 020900000000000000000000000000000000000000000000000000000000000000 01 0000 01021000 03000000000000000000000000000000", &mut test);
10861086

1087-
// One feerate request returning min feerate, which our open_channel also uses (ingested by FuzzEstimator)
1088-
ext_from_hex("00fd", &mut test);
10891087
// client should now respond with accept_channel (CHECK 1: type 33 to peer 03000000)
10901088

10911089
// inbound read from peer id 0 of len 18
@@ -1102,45 +1100,19 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
11021100
ext_from_hex("0c005e", &mut test);
11031101
// the funding transaction
11041102
ext_from_hex("020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae0000000000000000000000000000000000000000000000000000000000000000000000", &mut test);
1105-
// Two feerate requests during block connection
1106-
ext_from_hex("00fd00fd", &mut test);
11071103
// connect a block with no transactions, one per line
11081104
ext_from_hex("0c0000", &mut test);
1109-
// Two feerate requests during block connection
1110-
ext_from_hex("00fd00fd", &mut test);
11111105
ext_from_hex("0c0000", &mut test);
1112-
// Two feerate requests during block connection
1113-
ext_from_hex("00fd00fd", &mut test);
11141106
ext_from_hex("0c0000", &mut test);
1115-
// Two feerate requests during block connection
1116-
ext_from_hex("00fd00fd", &mut test);
11171107
ext_from_hex("0c0000", &mut test);
1118-
// Two feerate requests during block connection
1119-
ext_from_hex("00fd00fd", &mut test);
11201108
ext_from_hex("0c0000", &mut test);
1121-
// Two feerate requests during block connection
1122-
ext_from_hex("00fd00fd", &mut test);
11231109
ext_from_hex("0c0000", &mut test);
1124-
// Two feerate requests during block connection
1125-
ext_from_hex("00fd00fd", &mut test);
11261110
ext_from_hex("0c0000", &mut test);
1127-
// Two feerate requests during block connection
1128-
ext_from_hex("00fd00fd", &mut test);
11291111
ext_from_hex("0c0000", &mut test);
1130-
// Two feerate requests during block connection
1131-
ext_from_hex("00fd00fd", &mut test);
11321112
ext_from_hex("0c0000", &mut test);
1133-
// Two feerate requests during block connection
1134-
ext_from_hex("00fd00fd", &mut test);
11351113
ext_from_hex("0c0000", &mut test);
1136-
// Two feerate requests during block connection
1137-
ext_from_hex("00fd00fd", &mut test);
11381114
ext_from_hex("0c0000", &mut test);
1139-
// Two feerate requests during block connection
1140-
ext_from_hex("00fd00fd", &mut test);
11411115
ext_from_hex("0c0000", &mut test);
1142-
// Two feerate requests during block connection
1143-
ext_from_hex("00fd00fd", &mut test);
11441116
// by now client should have sent a channel_ready (CHECK 3: SendChannelReady to 03000000 for chan 3d000000)
11451117

11461118
// inbound read from peer id 0 of len 18
@@ -1171,17 +1143,12 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
11711143
ext_from_hex("030120", &mut test);
11721144
// init message (type 16) with static_remotekey required, no anchors/taproot, and other bits optional and mac
11731145
ext_from_hex("0010 00021aaa 0008aaa210aa2a0a9aaa 01000000000000000000000000000000", &mut test);
1174-
// One feerate request on peer connection due to a list_channels call when seeing if the async
1175-
// receive offer cache needs updating
1176-
ext_from_hex("00fd", &mut test);
11771146

11781147
// create outbound channel to peer 1 for 50k sat
11791148
ext_from_hex(
11801149
"05 01 030200000000000000000000000000000000000000000000000000000000000000 00c350 0003e8",
11811150
&mut test,
11821151
);
1183-
// One feerate requests (all returning min feerate) (gonna be ingested by FuzzEstimator)
1184-
ext_from_hex("00fd", &mut test);
11851152

11861153
// inbound read from peer id 1 of len 18
11871154
ext_from_hex("030112", &mut test);
@@ -1201,8 +1168,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
12011168

12021169
// create the funding transaction (client should send funding_created now)
12031170
ext_from_hex("0a", &mut test);
1204-
// Two feerate requests to check the dust exposure on the initial commitment tx
1205-
ext_from_hex("00fd00fd", &mut test);
12061171

12071172
// inbound read from peer id 1 of len 18
12081173
ext_from_hex("030112", &mut test);
@@ -1251,9 +1216,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
12511216
// end of update_add_htlc from 0 to 1 via client and mac
12521217
ext_from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ab00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
12531218

1254-
// One feerate request to check dust exposure
1255-
ext_from_hex("00fd", &mut test);
1256-
12571219
// inbound read from peer id 0 of len 18
12581220
ext_from_hex("030012", &mut test);
12591221
// message header indicating message length 100
@@ -1275,8 +1237,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
12751237

12761238
// process the now-pending HTLC forward
12771239
ext_from_hex("07", &mut test);
1278-
// Four feerate requests to check dust exposure while forwarding the HTLC
1279-
ext_from_hex("00fd00fd00fd00fd", &mut test);
12801240
// client now sends id 1 update_add_htlc and commitment_signed (CHECK 7: UpdateHTLCs event for node 03020000 with 1 HTLCs for channel 2f000000)
12811241

12821242
// we respond with commitment_signed then revoke_and_ack (a weird, but valid, order)
@@ -1352,9 +1312,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
13521312
// end of update_add_htlc from 0 to 1 via client and mac
13531313
ext_from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ab00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
13541314

1355-
// One feerate request to check dust exposure
1356-
ext_from_hex("00fd", &mut test);
1357-
13581315
// now respond to the update_fulfill_htlc+commitment_signed messages the client sent to peer 0
13591316
// inbound read from peer id 0 of len 18
13601317
ext_from_hex("030012", &mut test);
@@ -1387,9 +1344,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
13871344
// process the now-pending HTLC forward
13881345
ext_from_hex("07", &mut test);
13891346

1390-
// Four feerate requests to check dust exposure while forwarding the HTLC
1391-
ext_from_hex("00fd00fd00fd00fd", &mut test);
1392-
13931347
// client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
13941348
// we respond with revoke_and_ack, then commitment_signed, then update_fail_htlc
13951349

@@ -1487,9 +1441,6 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
14871441
// end of update_add_htlc from 0 to 1 via client and mac
14881442
ext_from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 5200000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
14891443

1490-
// One feerate request to check dust exposure
1491-
ext_from_hex("00fd", &mut test);
1492-
14931444
// inbound read from peer id 0 of len 18
14941445
ext_from_hex("030012", &mut test);
14951446
// message header indicating message length 164
@@ -1511,43 +1462,27 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
15111462

15121463
// process the now-pending HTLC forward
15131464
ext_from_hex("07", &mut test);
1514-
// Four feerate requests to check dust exposure while forwarding the HTLC
1515-
ext_from_hex("00fd00fd00fd00fd", &mut test);
15161465
// client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
15171466

15181467
// connect a block with one transaction of len 125
15191468
ext_from_hex("0c007d", &mut test);
15201469
// the commitment transaction for channel 2900000000000000000000000000000000000000000000000000000000000000
15211470
ext_from_hex("020000000129000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200201f0000000000000000000000000000000000000000000000000000000000000013c00000000000001600143b0000000000000000000000000000000000000005000020", &mut test);
1522-
// Two feerate requests during block connection
1523-
ext_from_hex("00fd00fd", &mut test);
15241471
//
15251472
// connect a block with one transaction of len 94
15261473
ext_from_hex("0c005e", &mut test);
15271474
// the HTLC timeout transaction
15281475
ext_from_hex("0200000001200000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020e60000000000000000000000000000000000000000000000000000000000000000000000", &mut test);
1529-
// Two feerate requests during block connection
1530-
ext_from_hex("00fd00fd", &mut test);
15311476
// connect a block with no transactions
15321477
ext_from_hex("0c0000", &mut test);
1533-
// Two feerate requests during block connection
1534-
ext_from_hex("00fd00fd", &mut test);
15351478
// connect a block with no transactions
15361479
ext_from_hex("0c0000", &mut test);
1537-
// Two feerate requests during block connection
1538-
ext_from_hex("00fd00fd", &mut test);
15391480
// connect a block with no transactions
15401481
ext_from_hex("0c0000", &mut test);
1541-
// Two feerate requests during block connection
1542-
ext_from_hex("00fd00fd", &mut test);
15431482
// connect a block with no transactions
15441483
ext_from_hex("0c0000", &mut test);
1545-
// Two feerate requests during block connection
1546-
ext_from_hex("00fd00fd", &mut test);
15471484
// connect a block with no transactions
15481485
ext_from_hex("0c0000", &mut test);
1549-
// Two feerate requests during block connection
1550-
ext_from_hex("00fd00fd", &mut test);
15511486

15521487
// process the now-pending HTLC forward
15531488
ext_from_hex("07", &mut test);

0 commit comments

Comments
 (0)