X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_test_utils.rs;h=39396685f005abf2e9bf795ad7428724c02186dc;hb=b7d0357a8ad42415eb38e83aa4595b51e86d1a98;hp=27002679ed78e914b533efe2147efbff123fb1f9;hpb=397386539d19ea368d1f37566b6b0640b90c9668;p=rust-lightning diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 27002679..39396685 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -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>>, pub connect_style: Rc>, pub override_init_features: Rc>>, + pub wallet_source: Arc, + pub bump_tx_handler: BumpTransactionEventHandler< + &'c test_utils::TestBroadcaster, + Arc, &'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 { @@ -1100,6 +1119,15 @@ pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, ' assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id); assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42); node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &open_channel_msg); + if node_b.node.get_current_default_configuration().manually_accept_inbound_channels { + let events = node_b.node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match &events[0] { + Event::OpenChannelRequest { temporary_channel_id, counterparty_node_id, .. } => + node_b.node.accept_inbound_channel(temporary_channel_id, counterparty_node_id, 42).unwrap(), + _ => panic!("Unexpected event"), + }; + } let accept_channel_msg = get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id()); assert_eq!(accept_channel_msg.temporary_channel_id, create_chan_id); node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_channel_msg); @@ -1797,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, + 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 { @@ -1806,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] @@ -1942,6 +1978,16 @@ macro_rules! expect_payment_forwarded { } } +#[cfg(test)] +#[macro_export] +macro_rules! expect_channel_shutdown_state { + ($node: expr, $chan_id: expr, $state: path) => { + let chan_details = $node.node.list_channels().into_iter().filter(|cd| cd.channel_id == $chan_id).collect::>(); + assert_eq!(chan_details.len(), 1); + assert_eq!(chan_details[0].channel_shutdown_state, Some($state)); + } +} + #[cfg(any(test, ldk_bench, feature = "_test_utils"))] pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) { let events = node.node.get_and_clear_pending_events(); @@ -2563,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 } @@ -2572,12 +2620,13 @@ pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec let mut chanmgrs = Vec::new(); for i in 0..node_count { let network = Network::Testnet; + let genesis_block = bitcoin::blockdata::constants::genesis_block(network); let params = ChainParameters { network, best_block: BestBlock::from_network(network), }; let node = ChannelManager::new(cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, &cfgs[i].router, cfgs[i].logger, cfgs[i].keys_manager, - cfgs[i].keys_manager, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { test_default_channel_config() }, params); + cfgs[i].keys_manager, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { test_default_channel_config() }, params, genesis_block.header.time); chanmgrs.push(node); } @@ -2592,6 +2641,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec(node_count: usize, cfgs: &'b Vec { + pub node_a: &'a Node<'b, 'c, 'd>, + pub node_b: &'a Node<'b, 'c, 'd>, + pub send_channel_ready: (bool, bool), + pub pending_htlc_adds: (i64, i64), + pub pending_htlc_claims: (usize, usize), + pub pending_htlc_fails: (usize, usize), + pub pending_cell_htlc_claims: (usize, usize), + pub pending_cell_htlc_fails: (usize, usize), + pub pending_raa: (bool, bool), +} + +impl<'a, 'b, 'c, 'd> ReconnectArgs<'a, 'b, 'c, 'd> { + pub fn new(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>) -> Self { + Self { + node_a, + node_b, + send_channel_ready: (false, false), + pending_htlc_adds: (0, 0), + pending_htlc_claims: (0, 0), + pending_htlc_fails: (0, 0), + pending_cell_htlc_claims: (0, 0), + pending_cell_htlc_fails: (0, 0), + pending_raa: (false, false), + } + } +} + /// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas /// for claims/fails they are separated out. -pub fn reconnect_nodes<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, send_channel_ready: (bool, bool), pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) { +pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) { + let ReconnectArgs { + node_a, node_b, send_channel_ready, pending_htlc_adds, pending_htlc_claims, pending_htlc_fails, + pending_cell_htlc_claims, pending_cell_htlc_fails, pending_raa + } = args; node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: node_b.node.init_features(), networks: None, remote_network_address: None }, true).unwrap();