TESTING
[rust-lightning] / fuzz / src / chanmon_consistency.rs
index adc00ed8d8eef01439ce7db27980e537621f12d1..c0b897e21a3ab65d97e0df0d01a3587f8fcb3f67 100644 (file)
@@ -85,7 +85,7 @@ pub struct TestChannelMonitor {
 impl TestChannelMonitor {
        pub fn new(chain_monitor: Arc<dyn chaininterface::ChainWatchInterface>, broadcaster: Arc<dyn chaininterface::BroadcasterInterface>, logger: Arc<dyn Logger>, feeest: Arc<dyn chaininterface::FeeEstimator>) -> Self {
                Self {
-                       simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger, feeest),
+                       simple_monitor: Arc::new(channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger, feeest)),
                        update_ret: Mutex::new(Ok(())),
                        latest_good_update: Mutex::new(HashMap::new()),
                        latest_update_good: Mutex::new(HashMap::new()),
@@ -150,7 +150,7 @@ impl KeysInterface for KeyProvider {
                PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, self.node_id]).unwrap())
        }
 
-       fn get_channel_keys(&self, _inbound: bool) -> EnforcingChannelKeys {
+       fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> EnforcingChannelKeys {
                EnforcingChannelKeys::new(InMemoryChannelKeys {
                        funding_key:               SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, self.node_id]).unwrap(),
                        revocation_base_key:       SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_id]).unwrap(),
@@ -159,6 +159,7 @@ impl KeysInterface for KeyProvider {
                        htlc_base_key:             SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
                        commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
                        remote_channel_pubkeys: None,
+                       channel_value_satoshis,
                })
        }
 
@@ -190,7 +191,7 @@ pub fn do_test(data: &[u8]) {
                        config.channel_options.fee_proportional_millionths = 0;
                        config.channel_options.announced_channel = true;
                        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-                       (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap(),
+                       (Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap()),
                        monitor)
                } }
        }
@@ -228,7 +229,7 @@ pub fn do_test(data: &[u8]) {
                                channel_monitors: &mut monitor_refs,
                        };
 
-                       let res = (<(Sha256d, ChannelManager<EnforcingChannelKeys>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor);
+                       let res = (<(Sha256d, ChannelManager<EnforcingChannelKeys, Arc<TestChannelMonitor>>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor);
                        for (_, was_good) in $old_monitors.latest_updates_good_at_last_ser.lock().unwrap().iter() {
                                if !was_good {
                                        // If the last time we updated a monitor we didn't successfully update (and we
@@ -412,24 +413,24 @@ pub fn do_test(data: &[u8]) {
                                let payment_hash = Sha256::hash(&[payment_id; 1]);
                                payment_id = payment_id.wrapping_add(1);
                                if let Err(_) = $source.send_payment(Route {
-                                       hops: vec![RouteHop {
+                                       paths: vec![vec![RouteHop {
                                                pubkey: $dest.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $dest.1,
                                                channel_features: ChannelFeatures::empty(),
                                                fee_msat: 5000000,
                                                cltv_expiry_delta: 200,
-                                       }],
-                               }, PaymentHash(payment_hash.into_inner())) {
+                                       }]],
+                               }, PaymentHash(payment_hash.into_inner()), None) {
                                        // Probably ran out of funds
                                        test_return!();
                                }
                        } };
-                       ($source: expr, $middle: expr, $dest: expr) => { {
+                       ($source: expr, $middle: expr, $dest: expr, false) => { {
                                let payment_hash = Sha256::hash(&[payment_id; 1]);
                                payment_id = payment_id.wrapping_add(1);
                                if let Err(_) = $source.send_payment(Route {
-                                       hops: vec![RouteHop {
+                                       paths: vec![vec![RouteHop {
                                                pubkey: $middle.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $middle.1,
@@ -443,8 +444,48 @@ pub fn do_test(data: &[u8]) {
                                                channel_features: ChannelFeatures::empty(),
                                                fee_msat: 5000000,
                                                cltv_expiry_delta: 200,
-                                       }],
-                               }, PaymentHash(payment_hash.into_inner())) {
+                                       }]],
+                               }, PaymentHash(payment_hash.into_inner()), None) {
+                                       // Probably ran out of funds
+                                       test_return!();
+                               }
+                       } };
+                       ($source: expr, $middle: expr, $dest: expr, true) => { {
+                               let payment_hash = Sha256::hash(&[payment_id; 1]);
+                               payment_id = payment_id.wrapping_add(1);
+                               let payment_secret = Sha256::hash(&[payment_id; 1]);
+                               payment_id = payment_id.wrapping_add(1);
+                               if let Err(_) = $source.send_payment(Route {
+                                       paths: vec![vec![RouteHop {
+                                               pubkey: $middle.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $middle.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 50000,
+                                               cltv_expiry_delta: 100,
+                                       },RouteHop {
+                                               pubkey: $dest.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $dest.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 5000000,
+                                               cltv_expiry_delta: 200,
+                                       }],vec![RouteHop {
+                                               pubkey: $middle.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $middle.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 50000,
+                                               cltv_expiry_delta: 100,
+                                       },RouteHop {
+                                               pubkey: $dest.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $dest.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 5000000,
+                                               cltv_expiry_delta: 200,
+                                       }]],
+                               }, PaymentHash(payment_hash.into_inner()), Some(&payment_secret.into_inner())) {
                                        // Probably ran out of funds
                                        test_return!();
                                }
@@ -460,7 +501,28 @@ pub fn do_test(data: &[u8]) {
                                        bc_events.clear();
                                        new_events
                                } else { Vec::new() };
-                               for event in events.iter().chain(nodes[$node].get_and_clear_pending_msg_events().iter()) {
+                               let ev = nodes[$node].get_and_clear_pending_msg_events();
+                               for event in events.iter().chain(ev.iter()) {
+                                       match event {
+                                               events::MessageSendEvent::UpdateHTLCs { updates: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. }, .. } => {
+                                                       println!("UPDATEHTLCs {} {} {} {}", update_add_htlcs.len(), update_fail_htlcs.len(), update_fulfill_htlcs.len(), update_fail_malformed_htlcs.len());
+                                               },
+                                               events::MessageSendEvent::SendRevokeAndACK { .. } => {
+                                                       println!("RAA");
+                                               },
+                                               events::MessageSendEvent::SendChannelReestablish { .. } => {
+                                                       println!("Chan REE");
+                                               },
+                                               events::MessageSendEvent::SendFundingLocked { .. } => {
+                                                       println!("FL");
+                                               },
+                                               events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {
+                                                       println!("Fail net update");
+                                               },
+                                               _ => panic!("Unhandled message event"),
+                                       }
+                               }
+                               for event in events.iter().chain(ev.iter()) {
                                        match event {
                                                events::MessageSendEvent::UpdateHTLCs { ref node_id, updates: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
                                                        for dest in nodes.iter() {
@@ -602,12 +664,12 @@ pub fn do_test(data: &[u8]) {
                                });
                                for event in events.drain(..) {
                                        match event {
-                                               events::Event::PaymentReceived { payment_hash, .. } => {
+                                               events::Event::PaymentReceived { payment_hash, payment_secret, .. } => {
                                                        if claim_set.insert(payment_hash.0) {
                                                                if $fail {
-                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
+                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash, &payment_secret));
                                                                } else {
-                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), 5_000_000));
+                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), &payment_secret, 5_000_000));
                                                                }
                                                        }
                                                },
@@ -622,7 +684,9 @@ pub fn do_test(data: &[u8]) {
                        } }
                }
 
-               match get_slice!(1)[0] {
+        let a = get_slice!(1)[0];
+        println!("PROCESSING {:x}", a);
+               match a {
                        0x00 => *monitor_a.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
                        0x01 => *monitor_b.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
                        0x02 => *monitor_c.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
@@ -636,8 +700,8 @@ pub fn do_test(data: &[u8]) {
                        0x0a => send_payment!(nodes[1], (&nodes[0], chan_a)),
                        0x0b => send_payment!(nodes[1], (&nodes[2], chan_b)),
                        0x0c => send_payment!(nodes[2], (&nodes[1], chan_b)),
-                       0x0d => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)),
-                       0x0e => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)),
+                       0x0d => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b), false),
+                       0x0e => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a), false),
                        0x0f => {
                                if !chan_a_disconnected {
                                        nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
@@ -720,6 +784,8 @@ pub fn do_test(data: &[u8]) {
                                nodes[2] = node_c.clone();
                                monitor_c = new_monitor_c;
                        },
+                       0x22 => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b), true),
+                       0x23 => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a), true),
                        _ => test_return!(),
                }
 
@@ -748,11 +814,3 @@ pub fn do_test(data: &[u8]) {
 pub extern "C" fn chanmon_consistency_run(data: *const u8, datalen: usize) {
        do_test(unsafe { std::slice::from_raw_parts(data, datalen) });
 }
-
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}