Merge pull request #949 from TheBlueMatt/2021-06-send-priv-update
[rust-lightning] / lightning / src / ln / functional_test_utils.rs
index 2b276c92898b85b21cf13941a2ae33e40861644d..2e9439916df7b8c64760813d94685621183dba01 100644 (file)
 //! A bunch of useful utilities for building networks of nodes and exchanging messages between
 //! nodes for functional tests.
 
-use chain::{Confirm, Listen, Watch};
+use chain::{BestBlock, Confirm, Listen, Watch};
 use chain::channelmonitor::ChannelMonitor;
 use chain::transaction::OutPoint;
 use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure};
+use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure};
 use routing::router::{Route, get_route};
 use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
 use ln::features::{InitFeatures, InvoiceFeatures};
@@ -42,9 +42,8 @@ use bitcoin::secp256k1::key::PublicKey;
 use prelude::*;
 use core::cell::RefCell;
 use std::rc::Rc;
-use std::sync::Mutex;
+use std::sync::{Arc, Mutex};
 use core::mem;
-use std::collections::HashMap;
 
 pub const CHAN_CONFIRM_DEPTH: u32 = 10;
 
@@ -149,14 +148,14 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, s
                }
        }
        node.node.test_process_background_events();
-       node.blocks.borrow_mut().push((block.header, height));
+       node.blocks.lock().unwrap().push((block.header, height));
 }
 
 pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
        for i in 0..count {
-               let orig_header = node.blocks.borrow_mut().pop().unwrap();
+               let orig_header = node.blocks.lock().unwrap().pop().unwrap();
                assert!(orig_header.1 > 0); // Cannot disconnect genesis
-               let prev_header = node.blocks.borrow().last().unwrap().clone();
+               let prev_header = node.blocks.lock().unwrap().last().unwrap().clone();
 
                match *node.connect_style.borrow() {
                        ConnectStyle::FullBlockViaListen => {
@@ -178,7 +177,7 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32)
 }
 
 pub fn disconnect_all_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>) {
-       let count = node.blocks.borrow_mut().len() as u32 - 1;
+       let count = node.blocks.lock().unwrap().len() as u32 - 1;
        disconnect_blocks(node, count);
 }
 
@@ -212,15 +211,18 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
        pub network_payment_count: Rc<RefCell<u8>>,
        pub network_chan_count: Rc<RefCell<u32>>,
        pub logger: &'c test_utils::TestLogger,
-       pub blocks: RefCell<Vec<(BlockHeader, u32)>>,
+       pub blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>,
        pub connect_style: Rc<RefCell<ConnectStyle>>,
 }
 impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
        pub fn best_block_hash(&self) -> BlockHash {
-               self.blocks.borrow_mut().last().unwrap().0.block_hash()
+               self.blocks.lock().unwrap().last().unwrap().0.block_hash()
        }
        pub fn best_block_info(&self) -> (BlockHash, u32) {
-               self.blocks.borrow_mut().last().map(|(a, b)| (a.block_hash(), *b)).unwrap()
+               self.blocks.lock().unwrap().last().map(|(a, b)| (a.block_hash(), *b)).unwrap()
+       }
+       pub fn get_block_header(&self, height: u32) -> BlockHeader {
+               self.blocks.lock().unwrap()[height as usize].0
        }
 }
 
@@ -296,7 +298,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                                        fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: 253 },
                                        chain_monitor: self.chain_monitor,
                                        tx_broadcaster: &test_utils::TestBroadcaster {
-                                               txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone())
+                                               txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()),
+                                               blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())),
                                        },
                                        logger: &test_utils::TestLogger::new(),
                                        channel_monitors,
@@ -305,7 +308,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
 
                        let persister = test_utils::TestPersister::new();
                        let broadcaster = test_utils::TestBroadcaster {
-                               txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone())
+                               txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()),
+                               blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())),
                        };
                        let chain_source = test_utils::TestChainSource::new(Network::Testnet);
                        let chain_monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &broadcaster, &self.logger, &feeest, &persister, &self.keys_manager);
@@ -996,6 +1000,30 @@ macro_rules! expect_payment_sent {
        }
 }
 
+#[cfg(test)]
+macro_rules! expect_payment_failure_chan_update {
+       ($node: expr, $scid: expr, $chan_closed: expr) => {
+               let events = $node.node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => {
+                               match update {
+                                       &HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } if !$chan_closed => {
+                                               assert_eq!(msg.contents.short_channel_id, $scid);
+                                               assert_eq!(msg.contents.flags & 2, 0);
+                                       },
+                                       &HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } if $chan_closed => {
+                                               assert_eq!(short_channel_id, $scid);
+                                               assert!(is_permanent);
+                                       },
+                                       _ => panic!("Unexpected update type"),
+                               }
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+}
+
 #[cfg(test)]
 macro_rules! expect_payment_failed {
        ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr $(, $expected_error_code: expr, $expected_error_data: expr)*) => {
@@ -1284,7 +1312,10 @@ pub fn fail_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
 pub fn create_chanmon_cfgs(node_count: usize) -> Vec<TestChanMonCfg> {
        let mut chan_mon_cfgs = Vec::new();
        for i in 0..node_count {
-               let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())};
+               let tx_broadcaster = test_utils::TestBroadcaster {
+                       txn_broadcasted: Mutex::new(Vec::new()),
+                       blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet).header, 0)])),
+               };
                let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
                let chain_source = test_utils::TestChainSource::new(Network::Testnet);
                let logger = test_utils::TestLogger::with_id(format!("node {}", i));
@@ -1345,7 +1376,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
                                 keys_manager: &cfgs[i].keys_manager, node: &chan_mgrs[i], net_graph_msg_handler,
                                 node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
                                 network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
-                                blocks: RefCell::new(vec![(genesis_block(Network::Testnet).header, 0)]),
+                                blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
                                 connect_style: Rc::clone(&connect_style),
                })
        }
@@ -1552,18 +1583,20 @@ macro_rules! handle_chan_reestablish_msgs {
                        let mut revoke_and_ack = None;
                        let mut commitment_update = None;
                        let order = if let Some(ev) = msg_events.get(idx) {
-                               idx += 1;
                                match ev {
                                        &MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
                                                assert_eq!(*node_id, $dst_node.node.get_our_node_id());
                                                revoke_and_ack = Some(msg.clone());
+                                               idx += 1;
                                                RAACommitmentOrder::RevokeAndACKFirst
                                        },
                                        &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
                                                assert_eq!(*node_id, $dst_node.node.get_our_node_id());
                                                commitment_update = Some(updates.clone());
+                                               idx += 1;
                                                RAACommitmentOrder::CommitmentFirst
                                        },
+                                       &MessageSendEvent::SendChannelUpdate { .. } => RAACommitmentOrder::CommitmentFirst,
                                        _ => panic!("Unexpected event"),
                                }
                        } else {
@@ -1576,16 +1609,24 @@ macro_rules! handle_chan_reestablish_msgs {
                                                assert_eq!(*node_id, $dst_node.node.get_our_node_id());
                                                assert!(revoke_and_ack.is_none());
                                                revoke_and_ack = Some(msg.clone());
+                                               idx += 1;
                                        },
                                        &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
                                                assert_eq!(*node_id, $dst_node.node.get_our_node_id());
                                                assert!(commitment_update.is_none());
                                                commitment_update = Some(updates.clone());
+                                               idx += 1;
                                        },
+                                       &MessageSendEvent::SendChannelUpdate { .. } => {},
                                        _ => panic!("Unexpected event"),
                                }
                        }
 
+                       if let Some(&MessageSendEvent::SendChannelUpdate { ref node_id, ref msg }) = msg_events.get(idx) {
+                               assert_eq!(*node_id, $dst_node.node.get_our_node_id());
+                               assert_eq!(msg.contents.flags & 2, 0); // "disabled" flag must not be set as we just reconnected.
+                       }
+
                        (funding_locked, revoke_and_ack, commitment_update, order)
                }
        }