Provide peer local_features to handle_open_channel/accept_channel
[rust-lightning] / fuzz / fuzz_targets / chanmon_fail_consistency.rs
index f457a30913b870e4005628697f2f665519108670..c26ff88a7ef404b8fd0bf8635f389ec1f64a12fc 100644 (file)
@@ -36,7 +36,7 @@ use lightning::ln::channelmonitor;
 use lightning::ln::channelmonitor::{ChannelMonitorUpdateErr, HTLCUpdate};
 use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage};
 use lightning::ln::router::{Route, RouteHop};
-use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, HandleError, UpdateAddHTLC};
+use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, HandleError, UpdateAddHTLC, LocalFeatures};
 use lightning::util::{reset_rng_state, fill_bytes, events};
 use lightning::util::logger::Logger;
 use lightning::util::config::UserConfig;
@@ -49,6 +49,8 @@ use utils::test_logger;
 use secp256k1::key::{PublicKey,SecretKey};
 use secp256k1::Secp256k1;
 
+use std::cmp::Ordering;
+use std::collections::HashSet;
 use std::sync::{Arc,Mutex};
 use std::io::Cursor;
 
@@ -69,9 +71,9 @@ pub struct TestChannelMonitor {
        pub update_ret: Mutex<Result<(), channelmonitor::ChannelMonitorUpdateErr>>,
 }
 impl TestChannelMonitor {
-       pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>) -> Self {
+       pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>, feeest: Arc<chaininterface::FeeEstimator>) -> Self {
                Self {
-                       simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger),
+                       simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger, feeest),
                        update_ret: Mutex::new(Ok(())),
                }
        }
@@ -142,13 +144,13 @@ pub fn do_test(data: &[u8]) {
                ($node_id: expr) => { {
                        let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
                        let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
-                       let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone()));
+                       let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
 
                        let keys_manager = Arc::new(KeyProvider { node_id: $node_id });
                        let mut config = UserConfig::new();
                        config.channel_options.fee_proportional_millionths = 0;
                        config.channel_options.announced_channel = true;
-                       config.channel_limits.min_dust_limit_satoshis = 0;
+                       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
                        (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap(),
                        monitor)
                } }
@@ -166,7 +168,7 @@ pub fn do_test(data: &[u8]) {
                                } else { panic!("Wrong event type"); }
                        };
 
-                       $dest.handle_open_channel(&$source.get_our_node_id(), &open_channel).unwrap();
+                       $dest.handle_open_channel(&$source.get_our_node_id(), LocalFeatures::new(), &open_channel).unwrap();
                        let accept_channel = {
                                let events = $dest.get_and_clear_pending_msg_events();
                                assert_eq!(events.len(), 1);
@@ -175,7 +177,7 @@ pub fn do_test(data: &[u8]) {
                                } else { panic!("Wrong event type"); }
                        };
 
-                       $source.handle_accept_channel(&$dest.get_our_node_id(), &accept_channel).unwrap();
+                       $source.handle_accept_channel(&$dest.get_our_node_id(), LocalFeatures::new(), &accept_channel).unwrap();
                        {
                                let events = $source.get_and_clear_pending_events();
                                assert_eq!(events.len(), 1);
@@ -435,13 +437,36 @@ pub fn do_test(data: &[u8]) {
 
                macro_rules! process_events {
                        ($node: expr, $fail: expr) => { {
-                               for event in nodes[$node].get_and_clear_pending_events() {
+                               // In case we get 256 payments we may have a hash collision, resulting in the
+                               // second claim/fail call not finding the duplicate-hash HTLC, so we have to
+                               // deduplicate the calls here.
+                               let mut claim_set = HashSet::new();
+                               let mut events = nodes[$node].get_and_clear_pending_events();
+                               // Sort events so that PendingHTLCsForwardable get processed last. This avoids a
+                               // case where we first process a PendingHTLCsForwardable, then claim/fail on a
+                               // PaymentReceived, claiming/failing two HTLCs, but leaving a just-generated
+                               // PaymentReceived event for the second HTLC in our pending_events (and breaking
+                               // our claim_set deduplication).
+                               events.sort_by(|a, b| {
+                                       if let events::Event::PaymentReceived { .. } = a {
+                                               if let events::Event::PendingHTLCsForwardable { .. } = b {
+                                                       Ordering::Less
+                                               } else { Ordering::Equal }
+                                       } else if let events::Event::PendingHTLCsForwardable { .. } = a {
+                                               if let events::Event::PaymentReceived { .. } = b {
+                                                       Ordering::Greater
+                                               } else { Ordering::Equal }
+                                       } else { Ordering::Equal }
+                               });
+                               for event in events.drain(..) {
                                        match event {
                                                events::Event::PaymentReceived { payment_hash, .. } => {
-                                                       if $fail {
-                                                               assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
-                                                       } else {
-                                                               assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0)));
+                                                       if claim_set.insert(payment_hash.0) {
+                                                               if $fail {
+                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
+                                                               } else {
+                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0)));
+                                                               }
                                                        }
                                                },
                                                events::Event::PaymentSent { .. } => {},