Skip to content

Commit 09b3bef

Browse files
authored
Merge pull request #4315 from joostjager/async-fuzz
fuzz: support initial async monitor persistence in chanmon_consistency
2 parents 4281e49 + 1f2e903 commit 09b3bef

File tree

2 files changed

+66
-16
lines changed

2 files changed

+66
-16
lines changed

fuzz/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ cargo +nightly fuzz run --features "libfuzzer_fuzz" msg_ping_target
6868
Note: If you encounter a `SIGKILL` during run/build check for OOM in kernel logs and consider
6969
increasing RAM size for VM.
7070

71+
##### Fast builds for development
72+
73+
The default build uses LTO and single codegen unit, which is slow. For faster iteration during
74+
development, use the `-D` (dev) flag:
75+
76+
```shell
77+
cargo +nightly fuzz run --features "libfuzzer_fuzz" -D msg_ping_target
78+
```
79+
80+
The `-D` flag builds in development mode with faster compilation (still has optimizations via
81+
`opt-level = 1`). The first build will be slow as it rebuilds the standard library with
82+
sanitizer instrumentation, but subsequent builds will be fast.
83+
7184
If you wish to just generate fuzzing binary executables for `libFuzzer` and not run them:
7285
```shell
7386
cargo +nightly fuzz build --features "libfuzzer_fuzz" msg_ping_target

fuzz/src/chanmon_consistency.rs

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,10 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
299299
persisted_monitor: ser.0,
300300
pending_monitors: Vec::new(),
301301
},
302-
Ok(chain::ChannelMonitorUpdateStatus::InProgress) => {
303-
panic!("The test currently doesn't test initial-persistence via the async pipeline")
302+
Ok(chain::ChannelMonitorUpdateStatus::InProgress) => LatestMonitorState {
303+
persisted_monitor_id: monitor_id,
304+
persisted_monitor: Vec::new(),
305+
pending_monitors: vec![(monitor_id, ser.0)],
304306
},
305307
Ok(chain::ChannelMonitorUpdateStatus::UnrecoverableError) => panic!(),
306308
Err(()) => panic!(),
@@ -706,6 +708,26 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
706708
let broadcast = Arc::new(TestBroadcaster {});
707709
let router = FuzzRouter {};
708710

711+
// Read initial monitor styles from fuzz input (1 byte: 2 bits per node)
712+
let initial_mon_styles = if !data.is_empty() { data[0] } else { 0 };
713+
let mon_style = [
714+
RefCell::new(if initial_mon_styles & 0b01 != 0 {
715+
ChannelMonitorUpdateStatus::InProgress
716+
} else {
717+
ChannelMonitorUpdateStatus::Completed
718+
}),
719+
RefCell::new(if initial_mon_styles & 0b10 != 0 {
720+
ChannelMonitorUpdateStatus::InProgress
721+
} else {
722+
ChannelMonitorUpdateStatus::Completed
723+
}),
724+
RefCell::new(if initial_mon_styles & 0b100 != 0 {
725+
ChannelMonitorUpdateStatus::InProgress
726+
} else {
727+
ChannelMonitorUpdateStatus::Completed
728+
}),
729+
];
730+
709731
macro_rules! make_node {
710732
($node_id: expr, $fee_estimator: expr) => {{
711733
let logger: Arc<dyn Logger> =
@@ -725,7 +747,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
725747
logger.clone(),
726748
$fee_estimator.clone(),
727749
Arc::new(TestPersister {
728-
update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed),
750+
update_ret: Mutex::new(mon_style[$node_id as usize].borrow().clone()),
729751
}),
730752
Arc::clone(&keys_manager),
731753
));
@@ -762,9 +784,6 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
762784
}};
763785
}
764786

765-
let default_mon_style = RefCell::new(ChannelMonitorUpdateStatus::Completed);
766-
let mon_style = [default_mon_style.clone(), default_mon_style.clone(), default_mon_style];
767-
768787
let reload_node = |ser: &Vec<u8>,
769788
node_id: u8,
770789
old_monitors: &TestChainMonitor,
@@ -860,8 +879,21 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
860879
};
861880

862881
let mut channel_txn = Vec::new();
882+
macro_rules! complete_all_pending_monitor_updates {
883+
($monitor: expr) => {{
884+
for (channel_id, state) in $monitor.latest_monitors.lock().unwrap().iter_mut() {
885+
for (id, data) in state.pending_monitors.drain(..) {
886+
$monitor.chain_monitor.channel_monitor_updated(*channel_id, id).unwrap();
887+
if id >= state.persisted_monitor_id {
888+
state.persisted_monitor_id = id;
889+
state.persisted_monitor = data;
890+
}
891+
}
892+
}
893+
}};
894+
}
863895
macro_rules! make_channel {
864-
($source: expr, $dest: expr, $dest_keys_manager: expr, $chan_id: expr) => {{
896+
($source: expr, $dest: expr, $source_monitor: expr, $dest_monitor: expr, $dest_keys_manager: expr, $chan_id: expr) => {{
865897
let init_dest = Init {
866898
features: $dest.init_features(),
867899
networks: None,
@@ -965,12 +997,14 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
965997
}
966998
};
967999
$dest.handle_funding_created($source.get_our_node_id(), &funding_created);
1000+
// Complete any pending monitor updates for dest after watch_channel
1001+
complete_all_pending_monitor_updates!($dest_monitor);
9681002

969-
let funding_signed = {
1003+
let (funding_signed, channel_id) = {
9701004
let events = $dest.get_and_clear_pending_msg_events();
9711005
assert_eq!(events.len(), 1);
9721006
if let MessageSendEvent::SendFundingSigned { ref msg, .. } = events[0] {
973-
msg.clone()
1007+
(msg.clone(), msg.channel_id.clone())
9741008
} else {
9751009
panic!("Wrong event type");
9761010
}
@@ -984,19 +1018,22 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
9841018
}
9851019

9861020
$source.handle_funding_signed($dest.get_our_node_id(), &funding_signed);
1021+
// Complete any pending monitor updates for source after watch_channel
1022+
complete_all_pending_monitor_updates!($source_monitor);
1023+
9871024
let events = $source.get_and_clear_pending_events();
9881025
assert_eq!(events.len(), 1);
989-
let channel_id = if let events::Event::ChannelPending {
1026+
if let events::Event::ChannelPending {
9901027
ref counterparty_node_id,
991-
ref channel_id,
1028+
channel_id: ref event_channel_id,
9921029
..
9931030
} = events[0]
9941031
{
9951032
assert_eq!(counterparty_node_id, &$dest.get_our_node_id());
996-
channel_id.clone()
1033+
assert_eq!(*event_channel_id, channel_id);
9971034
} else {
9981035
panic!("Wrong event type");
999-
};
1036+
}
10001037

10011038
channel_id
10021039
}};
@@ -1087,8 +1124,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
10871124

10881125
let mut nodes = [node_a, node_b, node_c];
10891126

1090-
let chan_1_id = make_channel!(nodes[0], nodes[1], keys_manager_b, 0);
1091-
let chan_2_id = make_channel!(nodes[1], nodes[2], keys_manager_c, 1);
1127+
let chan_1_id = make_channel!(nodes[0], nodes[1], monitor_a, monitor_b, keys_manager_b, 0);
1128+
let chan_2_id = make_channel!(nodes[1], nodes[2], monitor_b, monitor_c, keys_manager_c, 1);
10921129

10931130
for node in nodes.iter() {
10941131
confirm_txn!(node);
@@ -1124,7 +1161,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11241161
}};
11251162
}
11261163

1127-
let mut read_pos = 0;
1164+
let mut read_pos = 1; // First byte was consumed for initial mon_style
11281165
macro_rules! get_slice {
11291166
($len: expr) => {{
11301167
let slice_len = $len as usize;

0 commit comments

Comments
 (0)