Skip to content

Commit d468abd

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

2 files changed

Lines changed: 155 additions & 33 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: 154 additions & 33 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,31 @@ 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+
if latest_monitors.insert(channel_id, state).is_some() {
334+
panic!("Already had monitor pre-watch_channel");
335+
}
336+
}
293337
}
294-
impl chain::Watch<TestChannelSigner> for TestChainMonitor {
338+
impl lightning::chain::Watch<TestChannelSigner> for TestChainMonitor {
295339
fn watch_channel(
296340
&self, channel_id: ChannelId, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
297341
) -> Result<chain::ChannelMonitorUpdateStatus, ()> {
298342
let mut ser = VecWriter(Vec::new());
299343
monitor.write(&mut ser).unwrap();
300344
let monitor_id = monitor.get_latest_update_id();
301345
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");
346+
if res == Ok(chain::ChannelMonitorUpdateStatus::Completed) {
347+
self.do_watch_channel_bytes(channel_id.0, monitor_id, ser.0);
318348
}
319349
res
320350
}
@@ -330,13 +360,11 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
330360
.as_ref()
331361
.map(|(_, data)| data)
332362
.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;
363+
let deserialized_monitor: (BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>) =
364+
ReadableArgs::read(&mut &latest_monitor_data[..], (&*self.keys, &*self.keys))
365+
.unwrap();
366+
367+
let deserialized_monitor = deserialized_monitor.1;
340368
deserialized_monitor
341369
.update_monitor(
342370
update,
@@ -368,6 +396,42 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
368396
}
369397
}
370398

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

452+
impl lightning_0_2::sign::EntropySource for KeyProvider {
453+
fn get_secure_random_bytes(&self) -> [u8; 32] {
454+
lightning::sign::EntropySource::get_secure_random_bytes(self)
455+
}
456+
}
457+
458+
impl lightning_0_2::sign::SignerProvider for KeyProvider {
459+
type EcdsaSigner = lightning_0_2::util::test_channel_signer::TestChannelSigner;
460+
461+
fn generate_channel_keys_id(&self, _inbound: bool, _user_channel_id: u128) -> [u8; 32] {
462+
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed) as u8;
463+
[id; 32]
464+
}
465+
466+
fn derive_channel_signer(&self, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner {
467+
unreachable!()
468+
}
469+
470+
fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result<bitcoin::ScriptBuf, ()> {
471+
unreachable!()
472+
}
473+
474+
fn get_shutdown_scriptpubkey(&self) -> Result<lightning_0_2::ln::script::ShutdownScript, ()> {
475+
unreachable!()
476+
}
477+
}
478+
388479
impl NodeSigner for KeyProvider {
389480
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
390481
let node_secret = match recipient {
@@ -436,7 +527,9 @@ impl NodeSigner for KeyProvider {
436527
fn sign_gossip_message(
437528
&self, msg: lightning::ln::msgs::UnsignedGossipMessage,
438529
) -> Result<Signature, ()> {
439-
let msg_hash = Message::from_digest(Sha256dHash::hash(&msg.encode()[..]).to_byte_array());
530+
let mut ser = Vec::new();
531+
lightning::util::ser::Writeable::write(&msg, &mut ser).unwrap();
532+
let msg_hash = Message::from_digest(Sha256dHash::hash(&ser[..]).to_byte_array());
440533
let secp_ctx = Secp256k1::signing_only();
441534
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
442535
}
@@ -999,12 +1092,40 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
9991092
};
10001093
// Use a different value of `use_old_mons` if we have another monitor (only for node B)
10011094
// by shifting `use_old_mons` one in base-3.
1002-
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");
1095+
let mut serialized_mon = serialized_mon;
1096+
if use_old_mons % 9 == 2 {
1097+
let old_mon_res: Result<
1098+
(BlockHash, lightning_0_2::chain::channelmonitor::ChannelMonitor<
1099+
lightning_0_2::util::test_channel_signer::TestChannelSigner
1100+
>),
1101+
_
1102+
> = lightning_0_2::util::ser::ReadableArgs::read(
1103+
&mut &serialized_mon[..],
1104+
(&**keys, &**keys),
1105+
);
1106+
1107+
if let Ok(old_mon) = old_mon_res {
1108+
let mut out = Vec::new();
1109+
let (block_hash, old_monitor) = old_mon;
1110+
1111+
if lightning_0_2::util::ser::Writeable::write(&(block_hash, old_monitor), &mut out).is_ok() {
1112+
serialized_mon = out;
1113+
} else {
1114+
return;
1115+
}
1116+
} else {
1117+
return;
1118+
}
1119+
}
1120+
1121+
let mon: (BlockHash, ChannelMonitor<TestChannelSigner>) =
1122+
match lightning::util::ser::ReadableArgs::read(
1123+
&mut &serialized_mon[..],
1124+
(&**keys, &**keys),
1125+
) {
1126+
Ok(m) => m,
1127+
Err(_) => return,
1128+
};
10081129
monitors.insert(channel_id, mon.1);
10091130
// Update the latest `ChannelMonitor` state to match what we just told LDK.
10101131
prev_state.persisted_monitor = serialized_mon;
@@ -1034,8 +1155,8 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
10341155
channel_monitors: monitor_refs,
10351156
};
10361157

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

0 commit comments

Comments
 (0)