Skip to content

Commit f01120d

Browse files
committed
fuzz: Add upgrade/downgrade simulation to chanmon_consistency and fix chacha20 build
1 parent cb951b4 commit f01120d

2 files changed

Lines changed: 149 additions & 34 deletions

File tree

fuzz/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ lightning-invoice = { path = "../lightning-invoice" }
2323
lightning-liquidity = { path = "../lightning-liquidity" }
2424
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
2525
lightning-persister = { path = "../lightning-persister", features = ["tokio"]}
26+
lightning_0_2 = { package = "lightning", version = "0.2.0", features = ["_test_utils"] }
2627
bech32 = "0.11.0"
2728
bitcoin = { version = "0.32.4", features = ["secp-lowmemory"] }
2829
tokio = { version = "~1.35", default-features = false, features = ["rt-multi-thread"] }

fuzz/src/chanmon_consistency.rs

Lines changed: 148 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,28 @@ impl FeeEstimator for FuzzEstimator {
130130
}
131131
}
132132

133+
impl lightning_0_2::chain::chaininterface::FeeEstimator for FuzzEstimator {
134+
fn get_est_sat_per_1000_weight(
135+
&self, conf_target: lightning_0_2::chain::chaininterface::ConfirmationTarget,
136+
) -> u32 {
137+
match conf_target {
138+
lightning_0_2::chain::chaininterface::ConfirmationTarget::MaximumFeeEstimate
139+
| lightning_0_2::chain::chaininterface::ConfirmationTarget::UrgentOnChainSweep => {
140+
MAX_FEE
141+
},
142+
lightning_0_2::chain::chaininterface::ConfirmationTarget::ChannelCloseMinimum
143+
| lightning_0_2::chain::chaininterface::ConfirmationTarget::AnchorChannelFee
144+
| lightning_0_2::chain::chaininterface::ConfirmationTarget::MinAllowedAnchorChannelRemoteFee
145+
| lightning_0_2::chain::chaininterface::ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee
146+
| lightning_0_2::chain::chaininterface::ConfirmationTarget::OutputSpendingFee => 253,
147+
lightning_0_2::chain::chaininterface::ConfirmationTarget::NonAnchorChannelFee => {
148+
let val = self.ret_val.load(atomic::Ordering::Relaxed);
149+
cmp::min(val, MAX_FEE)
150+
},
151+
}
152+
}
153+
}
154+
133155
impl FuzzEstimator {
134156
fn feerate_sat_per_kw(&self) -> FeeRate {
135157
let feerate = self.ret_val.load(atomic::Ordering::Acquire);
@@ -182,6 +204,14 @@ impl BroadcasterInterface for TestBroadcaster {
182204
}
183205
}
184206

207+
impl lightning_0_2::chain::chaininterface::BroadcasterInterface for TestBroadcaster {
208+
fn broadcast_transactions(&self, txs: &[&bitcoin::Transaction]) {
209+
for tx in txs {
210+
self.txn_broadcasted.borrow_mut().push((*tx).clone());
211+
}
212+
}
213+
}
214+
185215
struct ChainState {
186216
blocks: Vec<(Header, Vec<Transaction>)>,
187217
confirmed_txids: HashSet<Txid>,
@@ -290,31 +320,30 @@ impl TestChainMonitor {
290320
latest_monitors: Mutex::new(new_hash_map()),
291321
}
292322
}
323+
fn do_watch_channel_bytes(
324+
&self, channel_id_bytes: [u8; 32], monitor_id: u64, serialized_monitor: Vec<u8>,
325+
) {
326+
let channel_id = ChannelId(channel_id_bytes);
327+
let state = LatestMonitorState {
328+
persisted_monitor_id: monitor_id,
329+
persisted_monitor: serialized_monitor,
330+
pending_monitors: Vec::new(),
331+
};
332+
let mut latest_monitors = self.latest_monitors.lock().unwrap();
333+
latest_monitors.insert(channel_id, state);
334+
}
293335
}
294-
impl chain::Watch<TestChannelSigner> for TestChainMonitor {
336+
impl lightning::chain::Watch<TestChannelSigner> for TestChainMonitor {
295337
fn watch_channel(
296-
&self, channel_id: ChannelId, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
338+
&self, channel_id: lightning::ln::types::ChannelId,
339+
monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
297340
) -> Result<chain::ChannelMonitorUpdateStatus, ()> {
298341
let mut ser = VecWriter(Vec::new());
299-
monitor.write(&mut ser).unwrap();
342+
lightning::util::ser::Writeable::write(&(BlockHash::all_zeros(), monitor.clone()), &mut ser).unwrap();
300343
let monitor_id = monitor.get_latest_update_id();
301344
let res = self.chain_monitor.watch_channel(channel_id, monitor);
302-
let state = match res {
303-
Ok(chain::ChannelMonitorUpdateStatus::Completed) => LatestMonitorState {
304-
persisted_monitor_id: monitor_id,
305-
persisted_monitor: ser.0,
306-
pending_monitors: Vec::new(),
307-
},
308-
Ok(chain::ChannelMonitorUpdateStatus::InProgress) => LatestMonitorState {
309-
persisted_monitor_id: monitor_id,
310-
persisted_monitor: Vec::new(),
311-
pending_monitors: vec![(monitor_id, ser.0)],
312-
},
313-
Ok(chain::ChannelMonitorUpdateStatus::UnrecoverableError) => panic!(),
314-
Err(()) => panic!(),
315-
};
316-
if self.latest_monitors.lock().unwrap().insert(channel_id, state).is_some() {
317-
panic!("Already had monitor pre-watch_channel");
345+
if res == Ok(chain::ChannelMonitorUpdateStatus::Completed) {
346+
self.do_watch_channel_bytes(channel_id.0, monitor_id, ser.0);
318347
}
319348
res
320349
}
@@ -330,13 +359,11 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
330359
.as_ref()
331360
.map(|(_, data)| data)
332361
.unwrap_or(&map_entry.persisted_monitor);
333-
let deserialized_monitor =
334-
<(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
335-
&mut &latest_monitor_data[..],
336-
(&*self.keys, &*self.keys),
337-
)
338-
.unwrap()
339-
.1;
362+
let deserialized_monitor: (BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>) =
363+
ReadableArgs::read(&mut &latest_monitor_data[..], (&*self.keys, &*self.keys))
364+
.unwrap();
365+
366+
let deserialized_monitor = deserialized_monitor.1;
340367
deserialized_monitor
341368
.update_monitor(
342369
update,
@@ -368,6 +395,41 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
368395
}
369396
}
370397

398+
impl lightning_0_2::chain::Watch<lightning_0_2::util::test_channel_signer::TestChannelSigner> for TestChainMonitor {
399+
fn watch_channel(
400+
&self,
401+
channel_id: lightning_0_2::ln::types::ChannelId,
402+
monitor: lightning_0_2::chain::channelmonitor::ChannelMonitor<lightning_0_2::util::test_channel_signer::TestChannelSigner>
403+
) -> Result<lightning_0_2::chain::ChannelMonitorUpdateStatus, ()> {
404+
let monitor_id = monitor.get_latest_update_id();
405+
let mut ser = Vec::new();
406+
407+
lightning_0_2::util::ser::Writeable::write(
408+
&(BlockHash::all_zeros(), monitor.clone()),
409+
&mut ser
410+
).unwrap();
411+
self.do_watch_channel_bytes(channel_id.0, monitor_id, ser);
412+
Ok(lightning_0_2::chain::ChannelMonitorUpdateStatus::Completed)
413+
}
414+
fn update_channel(
415+
&self, _channel_id: lightning_0_2::ln::types::ChannelId,
416+
_update: &lightning_0_2::chain::channelmonitor::ChannelMonitorUpdate,
417+
) -> lightning_0_2::chain::ChannelMonitorUpdateStatus {
418+
lightning_0_2::chain::ChannelMonitorUpdateStatus::Completed
419+
}
420+
421+
fn release_pending_monitor_events(
422+
&self,
423+
) -> Vec<(
424+
lightning_0_2::chain::transaction::OutPoint,
425+
lightning_0_2::ln::types::ChannelId,
426+
Vec<lightning_0_2::chain::channelmonitor::MonitorEvent>,
427+
PublicKey,
428+
)> {
429+
Vec::new()
430+
}
431+
}
432+
371433
struct KeyProvider {
372434
node_secret: SecretKey,
373435
rand_bytes_id: atomic::AtomicU32,
@@ -385,6 +447,33 @@ impl EntropySource for KeyProvider {
385447
}
386448
}
387449

450+
impl lightning_0_2::sign::EntropySource for KeyProvider {
451+
fn get_secure_random_bytes(&self) -> [u8; 32] {
452+
lightning::sign::EntropySource::get_secure_random_bytes(self)
453+
}
454+
}
455+
456+
impl lightning_0_2::sign::SignerProvider for KeyProvider {
457+
type EcdsaSigner = lightning_0_2::util::test_channel_signer::TestChannelSigner;
458+
459+
fn generate_channel_keys_id(&self, _inbound: bool, _user_channel_id: u128) -> [u8; 32] {
460+
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed) as u8;
461+
[id; 32]
462+
}
463+
464+
fn derive_channel_signer(&self, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner {
465+
unreachable!()
466+
}
467+
468+
fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result<bitcoin::ScriptBuf, ()> {
469+
unreachable!()
470+
}
471+
472+
fn get_shutdown_scriptpubkey(&self) -> Result<lightning_0_2::ln::script::ShutdownScript, ()> {
473+
unreachable!()
474+
}
475+
}
476+
388477
impl NodeSigner for KeyProvider {
389478
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
390479
let node_secret = match recipient {
@@ -436,7 +525,9 @@ impl NodeSigner for KeyProvider {
436525
fn sign_gossip_message(
437526
&self, msg: lightning::ln::msgs::UnsignedGossipMessage,
438527
) -> Result<Signature, ()> {
439-
let msg_hash = Message::from_digest(Sha256dHash::hash(&msg.encode()[..]).to_byte_array());
528+
let mut ser = Vec::new();
529+
lightning::util::ser::Writeable::write(&msg, &mut ser).unwrap();
530+
let msg_hash = Message::from_digest(Sha256dHash::hash(&ser[..]).to_byte_array());
440531
let secp_ctx = Secp256k1::signing_only();
441532
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
442533
}
@@ -1000,11 +1091,34 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
10001091
// Use a different value of `use_old_mons` if we have another monitor (only for node B)
10011092
// by shifting `use_old_mons` one in base-3.
10021093
use_old_mons /= 3;
1003-
let mon = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
1004-
&mut &serialized_mon[..],
1005-
(&**keys, &**keys),
1006-
)
1007-
.expect("Failed to read monitor");
1094+
let mut serialized_mon = serialized_mon;
1095+
1096+
if use_old_mons % 9 == 2 {
1097+
let old_mon_res: Result<(BlockHash, lightning_0_2::chain::channelmonitor::ChannelMonitor<lightning_0_2::util::test_channel_signer::TestChannelSigner>), _> =
1098+
lightning_0_2::util::ser::ReadableArgs::read(
1099+
&mut &serialized_mon[..],
1100+
(&**keys, &**keys),
1101+
);
1102+
1103+
if let Ok(old_mon) = old_mon_res {
1104+
let mut out = Vec::new();
1105+
let (block_hash, old_monitor) = old_mon;
1106+
1107+
if lightning_0_2::util::ser::Writeable::write(&(block_hash, old_monitor), &mut out).is_ok() {
1108+
let check_res: Result<(BlockHash, ChannelMonitor<TestChannelSigner>), _> =
1109+
lightning::util::ser::ReadableArgs::read(&mut &out[..], (&**keys, &**keys));
1110+
if check_res.is_ok() {
1111+
serialized_mon = out;
1112+
}
1113+
}
1114+
}
1115+
}
1116+
1117+
let mon: (BlockHash, ChannelMonitor<TestChannelSigner>) =
1118+
lightning::util::ser::ReadableArgs::read(
1119+
&mut &serialized_mon[..],
1120+
(&**keys, &**keys),
1121+
).expect("Failed to read monitor");
10081122
monitors.insert(channel_id, mon.1);
10091123
// Update the latest `ChannelMonitor` state to match what we just told LDK.
10101124
prev_state.persisted_monitor = serialized_mon;
@@ -1034,8 +1148,8 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
10341148
channel_monitors: monitor_refs,
10351149
};
10361150

1037-
let manager =
1038-
<(BlockHash, ChanMan)>::read(&mut &ser[..], read_args).expect("Failed to read manager");
1151+
let manager: (BlockHash, ChanMan) =
1152+
lightning::util::ser::ReadableArgs::read(&mut &ser[..], read_args).expect("Failed to read manager");
10391153
let res = (manager.1, chain_monitor.clone());
10401154
for (channel_id, mon) in monitors.drain() {
10411155
assert_eq!(

0 commit comments

Comments
 (0)