X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=49d0c0a9fe5ad26d97a1aba43d116f415c4131e2;hb=eff8af21103e43f763cb10ae6a75c1543a2d4068;hp=485091fe29b9425695790d9101c18b400d95bf08;hpb=c0199224ab24cb37934bc14b5a52ab6415429308;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 485091fe..49d0c0a9 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -25,7 +25,7 @@ use util::config::UserConfig; use util::logger::Logger; use bitcoin::util::hash::BitcoinHash; -use bitcoin_hashes::sha256d::Hash as Sha256dHash; +use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::util::bip143; use bitcoin::util::address::Address; use bitcoin::util::bip32::{ChildNumber, ExtendedPubKey, ExtendedPrivKey}; @@ -36,11 +36,11 @@ use bitcoin::blockdata::opcodes; use bitcoin::blockdata::constants::genesis_block; use bitcoin::network::constants::Network; -use bitcoin_hashes::sha256::Hash as Sha256; -use bitcoin_hashes::Hash; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::Hash; -use secp256k1::{Secp256k1, Message}; -use secp256k1::key::{PublicKey,SecretKey}; +use bitcoin::secp256k1::{Secp256k1, Message}; +use bitcoin::secp256k1::key::{PublicKey,SecretKey}; use std::collections::{BTreeSet, HashMap, HashSet}; use std::default::Default; @@ -3618,8 +3618,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() { claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000); } -#[test] -fn test_htlc_timeout() { +fn do_test_htlc_timeout(send_partial_mpp: bool) { // If the user fails to claim/fail an HTLC within the HTLC CLTV timeout we fail it for them // to avoid our counterparty failing the channel. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -3628,7 +3627,24 @@ fn test_htlc_timeout() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); - let (_, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1]], 100000); + + let our_payment_hash = if send_partial_mpp { + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(&nodes[0]); + let payment_secret = PaymentSecret([0xdb; 32]); + // Use the utility function send_payment_along_path to send the payment with MPP data which + // indicates there are more HTLCs coming. + nodes[0].node.send_payment_along_path(&route.paths[0], &our_payment_hash, &Some(payment_secret), 200000, CHAN_CONFIRM_DEPTH).unwrap(); + check_added_monitors!(nodes[0], 1); + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + // Now do the relevant commitment_signed/RAA dances along the path, noting that the final + // hop should *not* yet generate any PaymentReceived event(s). + pass_along_path(&nodes[0], &[&nodes[1]], 100000, our_payment_hash, Some(payment_secret), events.drain(..).next().unwrap(), false); + our_payment_hash + } else { + route_payment(&nodes[0], &[&nodes[1]], 100000).1 + }; let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected_checked(&header, 101, &[], &[]); @@ -3656,6 +3672,89 @@ fn test_htlc_timeout() { expect_payment_failed!(nodes[0], our_payment_hash, true, 0x4000 | 15, &expected_failure_data[..]); } +#[test] +fn test_htlc_timeout() { + do_test_htlc_timeout(true); + do_test_htlc_timeout(false); +} + +fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { + // Tests that HTLCs in the holding cell are timed out after the requisite number of blocks. + let chanmon_cfgs = create_chanmon_cfgs(3); + let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); + let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs); + create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); + create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::supported(), InitFeatures::supported()); + + // Route a first payment to get the 1 -> 2 channel in awaiting_raa... + let route = nodes[1].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap(); + let (_, first_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[1].node.send_payment(&route, first_payment_hash, &None).unwrap(); + assert_eq!(nodes[1].node.get_and_clear_pending_msg_events().len(), 1); + check_added_monitors!(nodes[1], 1); + + // Now attempt to route a second payment, which should be placed in the holding cell + let (_, second_payment_hash) = get_payment_preimage_hash!(nodes[0]); + if forwarded_htlc { + let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap(); + nodes[0].node.send_payment(&route, second_payment_hash, &None).unwrap(); + check_added_monitors!(nodes[0], 1); + let payment_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); + commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false); + expect_pending_htlcs_forwardable!(nodes[1]); + check_added_monitors!(nodes[1], 0); + } else { + nodes[1].node.send_payment(&route, second_payment_hash, &None).unwrap(); + check_added_monitors!(nodes[1], 0); + } + + let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected_checked(&header, 101, &[], &[]); + for i in 102..TEST_FINAL_CLTV + 100 - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS { + header.prev_blockhash = header.bitcoin_hash(); + nodes[1].block_notifier.block_connected_checked(&header, i, &[], &[]); + } + + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); + assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); + + header.prev_blockhash = header.bitcoin_hash(); + nodes[1].block_notifier.block_connected_checked(&header, TEST_FINAL_CLTV + 100 - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS, &[], &[]); + + if forwarded_htlc { + expect_pending_htlcs_forwardable!(nodes[1]); + check_added_monitors!(nodes[1], 1); + let fail_commit = nodes[1].node.get_and_clear_pending_msg_events(); + assert_eq!(fail_commit.len(), 1); + match fail_commit[0] { + MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fail_htlcs, ref commitment_signed, .. }, .. } => { + nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlcs[0]); + commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, true, true); + }, + _ => unreachable!(), + } + expect_payment_failed!(nodes[0], second_payment_hash, false); + if let &MessageSendEvent::PaymentFailureNetworkUpdate { ref update } = &nodes[0].node.get_and_clear_pending_msg_events()[0] { + match update { + &HTLCFailChannelUpdate::ChannelUpdateMessage { .. } => {}, + _ => panic!("Unexpected event"), + } + } else { + panic!("Unexpected event"); + } + } else { + expect_payment_failed!(nodes[1], second_payment_hash, true); + } +} + +#[test] +fn test_holding_cell_htlc_add_timeouts() { + do_test_holding_cell_htlc_add_timeouts(false); + do_test_holding_cell_htlc_add_timeouts(true); +} + #[test] fn test_invalid_channel_announcement() { //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs @@ -5341,8 +5440,8 @@ fn run_onion_failure_test_with_fail_intercept(_name: &str, test_case: impl msgs::ChannelUpdate { fn dummy() -> msgs::ChannelUpdate { - use secp256k1::ffi::Signature as FFISignature; - use secp256k1::Signature; + use bitcoin::secp256k1::ffi::Signature as FFISignature; + use bitcoin::secp256k1::Signature; msgs::ChannelUpdate { signature: Signature::from(FFISignature::new()), contents: msgs::UnsignedChannelUpdate { @@ -5378,7 +5477,7 @@ impl Writeable for BogusOnionHopData { fn test_onion_failure() { use ln::msgs::ChannelUpdate; use ln::channelmanager::CLTV_FAR_FAR_AWAY; - use secp256k1; + use bitcoin::secp256k1; const BADONION: u16 = 0x8000; const PERM: u16 = 0x4000;