Make the `P2PGossipSync` `UtxoLookup` exchangable without &mut self
[rust-lightning] / lightning / src / ln / functional_test_utils.rs
index 39730b4a9e3b02fad4f388e7d9e19c6a5d517a86..5ce40f0578a39d9028506877092802c649149515 100644 (file)
@@ -15,6 +15,7 @@ use crate::sign::EntropySource;
 use crate::chain::channelmonitor::ChannelMonitor;
 use crate::chain::transaction::OutPoint;
 use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, PaymentFailureReason};
+use crate::events::bump_transaction::{BumpTransactionEventHandler, Wallet, WalletSource};
 use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 use crate::ln::channelmanager::{AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA};
 use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
@@ -27,18 +28,16 @@ use crate::util::scid_utils;
 use crate::util::test_utils;
 use crate::util::test_utils::{panicking, TestChainMonitor, TestScorer, TestKeysInterface};
 use crate::util::errors::APIError;
-use crate::util::config::UserConfig;
+use crate::util::config::{UserConfig, MaxDustHTLCExposure};
 use crate::util::ser::{ReadableArgs, Writeable};
 
 use bitcoin::blockdata::block::{Block, BlockHeader};
 use bitcoin::blockdata::transaction::{Transaction, TxOut};
-use bitcoin::network::constants::Network;
-
 use bitcoin::hash_types::BlockHash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::Hash as _;
-
-use bitcoin::secp256k1::PublicKey;
+use bitcoin::network::constants::Network;
+use bitcoin::secp256k1::{PublicKey, SecretKey};
 
 use crate::io;
 use crate::prelude::*;
@@ -289,6 +288,19 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: Block, sk
        }
        call_claimable_balances(node);
        node.node.test_process_background_events();
+
+       for tx in &block.txdata {
+               for input in &tx.input {
+                       node.wallet_source.remove_utxo(input.previous_output);
+               }
+               let wallet_script = node.wallet_source.get_change_script().unwrap();
+               for (idx, output) in tx.output.iter().enumerate() {
+                       if output.script_pubkey == wallet_script {
+                               let outpoint = bitcoin::OutPoint { txid: tx.txid(), vout: idx as u32 };
+                               node.wallet_source.add_utxo(outpoint, output.value);
+                       }
+               }
+       }
 }
 
 pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
@@ -375,6 +387,13 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
        pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,
        pub connect_style: Rc<RefCell<ConnectStyle>>,
        pub override_init_features: Rc<RefCell<Option<InitFeatures>>>,
+       pub wallet_source: Arc<test_utils::TestWalletSource>,
+       pub bump_tx_handler: BumpTransactionEventHandler<
+               &'c test_utils::TestBroadcaster,
+               Arc<Wallet<Arc<test_utils::TestWalletSource>, &'c test_utils::TestLogger>>,
+               &'b test_utils::TestKeysInterface,
+               &'c test_utils::TestLogger,
+       >,
 }
 impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
        pub fn best_block_hash(&self) -> BlockHash {
@@ -542,11 +561,11 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
        }
 }
 
-pub fn create_chan_between_nodes<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+pub fn create_chan_between_nodes<'a, 'b, 'c: 'd, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
        create_chan_between_nodes_with_value(node_a, node_b, 100000, 10001)
 }
 
-pub fn create_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+pub fn create_chan_between_nodes_with_value<'a, 'b, 'c: 'd, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
        let (channel_ready, channel_id, tx) = create_chan_between_nodes_with_value_a(node_a, node_b, channel_value, push_msat);
        let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(node_a, node_b, &channel_ready);
        (announcement, as_update, bs_update, channel_id, tx)
@@ -1150,7 +1169,7 @@ pub fn create_chan_between_nodes_with_value_confirm_second<'a, 'b, 'c>(node_recv
        }), channel_id)
 }
 
-pub fn create_chan_between_nodes_with_value_confirm<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, tx: &Transaction) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), [u8; 32]) {
+pub fn create_chan_between_nodes_with_value_confirm<'a, 'b, 'c: 'd, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, tx: &Transaction) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), [u8; 32]) {
        let conf_height = core::cmp::max(node_a.best_block_info().1 + 1, node_b.best_block_info().1 + 1);
        create_chan_between_nodes_with_value_confirm_first(node_a, node_b, tx, conf_height);
        confirm_transaction_at(node_a, tx, conf_height);
@@ -1159,7 +1178,7 @@ pub fn create_chan_between_nodes_with_value_confirm<'a, 'b, 'c, 'd>(node_a: &'a
        create_chan_between_nodes_with_value_confirm_second(node_b, node_a)
 }
 
-pub fn create_chan_between_nodes_with_value_a<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), [u8; 32], Transaction) {
+pub fn create_chan_between_nodes_with_value_a<'a, 'b, 'c: 'd, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), [u8; 32], Transaction) {
        let tx = create_chan_between_nodes_with_value_init(node_a, node_b, channel_value, push_msat);
        let (msgs, chan_id) = create_chan_between_nodes_with_value_confirm(node_a, node_b, &tx);
        (msgs, chan_id, tx)
@@ -1199,11 +1218,11 @@ pub fn create_chan_between_nodes_with_value_b<'a, 'b, 'c>(node_a: &Node<'a, 'b,
        ((*announcement).clone(), as_update, bs_update)
 }
 
-pub fn create_announced_chan_between_nodes<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+pub fn create_announced_chan_between_nodes<'a, 'b, 'c: 'd, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
        create_announced_chan_between_nodes_with_value(nodes, a, b, 100000, 10001)
 }
 
-pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c: 'd, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
        let chan_announcement = create_chan_between_nodes_with_value(&nodes[a], &nodes[b], channel_value, push_msat);
        update_nodes_with_chan_announce(nodes, a, b, &chan_announcement.0, &chan_announcement.1, &chan_announcement.2);
        (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
@@ -1806,6 +1825,28 @@ macro_rules! get_route_and_payment_hash {
        }}
 }
 
+pub fn check_payment_claimable(
+       event: &Event, expected_payment_hash: PaymentHash, expected_payment_secret: PaymentSecret,
+       expected_recv_value: u64, expected_payment_preimage: Option<PaymentPreimage>,
+       expected_receiver_node_id: PublicKey,
+) {
+       match event {
+               Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, .. } => {
+                       assert_eq!(expected_payment_hash, *payment_hash);
+                       assert_eq!(expected_recv_value, *amount_msat);
+                       assert_eq!(expected_receiver_node_id, receiver_node_id.unwrap());
+                       match purpose {
+                               PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
+                                       assert_eq!(&expected_payment_preimage, payment_preimage);
+                                       assert_eq!(expected_payment_secret, *payment_secret);
+                               },
+                               _ => {},
+                       }
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
+
 #[macro_export]
 #[cfg(any(test, ldk_bench, feature = "_test_utils"))]
 macro_rules! expect_payment_claimable {
@@ -1815,22 +1856,8 @@ macro_rules! expect_payment_claimable {
        ($node: expr, $expected_payment_hash: expr, $expected_payment_secret: expr, $expected_recv_value: expr, $expected_payment_preimage: expr, $expected_receiver_node_id: expr) => {
                let events = $node.node.get_and_clear_pending_events();
                assert_eq!(events.len(), 1);
-               match events[0] {
-                       $crate::events::Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, .. } => {
-                               assert_eq!($expected_payment_hash, *payment_hash);
-                               assert_eq!($expected_recv_value, amount_msat);
-                               assert_eq!($expected_receiver_node_id, receiver_node_id.unwrap());
-                               match purpose {
-                                       $crate::events::PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
-                                               assert_eq!(&$expected_payment_preimage, payment_preimage);
-                                               assert_eq!($expected_payment_secret, *payment_secret);
-                                       },
-                                       _ => {},
-                               }
-                       },
-                       _ => panic!("Unexpected event"),
-               }
-       }
+               $crate::ln::functional_test_utils::check_payment_claimable(&events[0], $expected_payment_hash, $expected_payment_secret, $expected_recv_value, $expected_payment_preimage, $expected_receiver_node_id)
+       };
 }
 
 #[macro_export]
@@ -2582,8 +2609,10 @@ pub fn test_default_channel_config() -> UserConfig {
        // It now defaults to 1, so we simply set it to the expected value here.
        default_config.channel_handshake_config.our_htlc_minimum_msat = 1000;
        // When most of our tests were written, we didn't have the notion of a `max_dust_htlc_exposure_msat`,
-       // It now defaults to 5_000_000 msat; to avoid interfering with tests we bump it to 50_000_000 msat.
-       default_config.channel_config.max_dust_htlc_exposure_msat = 50_000_000;
+       // to avoid interfering with tests we bump it to 50_000_000 msat (assuming the default test
+       // feerate of 253).
+       default_config.channel_config.max_dust_htlc_exposure =
+               MaxDustHTLCExposure::FeeRateMultiplier(50_000_000 / 253);
        default_config
 }
 
@@ -2612,6 +2641,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
 
        for i in 0..node_count {
                let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
+               let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));
                nodes.push(Node{
                        chain_source: cfgs[i].chain_source, tx_broadcaster: cfgs[i].tx_broadcaster,
                        fee_estimator: cfgs[i].fee_estimator, router: &cfgs[i].router,
@@ -2622,6 +2652,11 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
                        blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
                        connect_style: Rc::clone(&connect_style),
                        override_init_features: Rc::clone(&cfgs[i].override_init_features),
+                       wallet_source: Arc::clone(&wallet_source),
+                       bump_tx_handler: BumpTransactionEventHandler::new(
+                               cfgs[i].tx_broadcaster, Arc::new(Wallet::new(Arc::clone(&wallet_source), cfgs[i].logger)),
+                               &cfgs[i].keys_manager, cfgs[i].logger,
+                       ),
                })
        }
 
@@ -2826,13 +2861,6 @@ macro_rules! get_chan_reestablish_msgs {
                                        panic!("Unexpected event")
                                }
                        }
-                       for chan in $src_node.node.list_channels() {
-                               if chan.is_public && chan.counterparty.node_id != $dst_node.node.get_our_node_id() {
-                                       if let Some(scid) = chan.short_channel_id {
-                                               assert!(announcements.remove(&scid));
-                                       }
-                               }
-                       }
                        assert!(announcements.is_empty());
                        res
                }