X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fpayment_tests.rs;h=37ca25babe9eb48e48a443a143633d5996c467a1;hb=90541c2690c25d9d2d967f64615ddb0b0c84d286;hp=4fe3cef0d570c6013ba9d7f0851b88c8f5f8df3c;hpb=0a2a40c4fd05f39b9485cc0f000f7066636783cb;p=rust-lightning diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 4fe3cef0..37ca25ba 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -15,6 +15,7 @@ use chain::{ChannelMonitorUpdateErr, Confirm, Listen, Watch}; use chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor, LATENCY_GRACE_PERIOD_BLOCKS}; use chain::transaction::OutPoint; use chain::keysinterface::KeysInterface; +use ln::channel::EXPIRE_PREV_CONFIG_TICKS; use ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, ChannelManagerReadArgs, MPP_TIMEOUT_TICKS, PaymentId, PaymentSendFailure}; use ln::features::{InitFeatures, InvoiceFeatures}; use ln::msgs; @@ -70,7 +71,7 @@ fn retry_single_path_payment() { check_added_monitors!(nodes[1], 1); nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], htlc_updates.commitment_signed, false); - expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); + expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); // Rebalance the channel so the retry succeeds. send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000); @@ -173,7 +174,7 @@ fn mpp_retry() { check_added_monitors!(nodes[2], 1); nodes[0].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[2], htlc_updates.commitment_signed, false); - expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); + expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); // Rebalance the channel so the second half of the payment can succeed. send_payment(&nodes[3], &vec!(&nodes[2])[..], 1_500_000); @@ -251,7 +252,7 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) { check_added_monitors!(nodes[1], 1); commitment_signed_dance!(nodes[0], nodes[1], htlc_fail_updates_1_0.commitment_signed, false); - expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..])); + expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..])); } else { // Pass half of the payment along the second path. pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash, Some(payment_secret), events.remove(0), true, None); @@ -367,7 +368,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { let nodes_0_deserialized: ChannelManager; let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs); - let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); + let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; let (_, _, chan_id_2, _) = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); // Serialize the ChannelManager prior to sending payments @@ -484,7 +485,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { if confirm_before_reload { let best_block = nodes[0].blocks.lock().unwrap().last().unwrap().clone(); - nodes[0].node.best_block_updated(&best_block.0, best_block.1); + nodes[0].node.best_block_updated(&best_block.0.header, best_block.1); } // Create a new channel on which to retry the payment before we fail the payment via the @@ -506,17 +507,22 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { expect_payment_sent!(nodes[0], payment_preimage_1); connect_blocks(&nodes[0], TEST_FINAL_CLTV*4 + 20); let as_htlc_timeout_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); - check_spends!(as_htlc_timeout_txn[2], funding_tx); - check_spends!(as_htlc_timeout_txn[0], as_commitment_tx); - check_spends!(as_htlc_timeout_txn[1], as_commitment_tx); assert_eq!(as_htlc_timeout_txn.len(), 3); - if as_htlc_timeout_txn[0].input[0].previous_output == bs_htlc_claim_txn[0].input[0].previous_output { - confirm_transaction(&nodes[0], &as_htlc_timeout_txn[1]); + let (first_htlc_timeout_tx, second_htlc_timeout_tx) = if as_htlc_timeout_txn[0] == as_commitment_tx { + (&as_htlc_timeout_txn[1], &as_htlc_timeout_txn[2]) + } else { + assert_eq!(as_htlc_timeout_txn[2], as_commitment_tx); + (&as_htlc_timeout_txn[0], &as_htlc_timeout_txn[1]) + }; + check_spends!(first_htlc_timeout_tx, as_commitment_tx); + check_spends!(second_htlc_timeout_tx, as_commitment_tx); + if first_htlc_timeout_tx.input[0].previous_output == bs_htlc_claim_txn[0].input[0].previous_output { + confirm_transaction(&nodes[0], &second_htlc_timeout_tx); } else { - confirm_transaction(&nodes[0], &as_htlc_timeout_txn[0]); + confirm_transaction(&nodes[0], &first_htlc_timeout_tx); } nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear(); - expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); + expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); // Finally, retry the payment (which was reloaded from the ChannelMonitor when nodes[0] was // reloaded) via a route over the new channel, which work without issue and eventually be @@ -526,8 +532,19 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { // Update the fee on the middle hop to ensure PaymentSent events have the correct (retried) fee // and not the original fee. We also update node[1]'s relevant config as // do_claim_payment_along_route expects us to never overpay. - nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_id_2).unwrap().config.forwarding_fee_base_msat += 100_000; - new_route.paths[0][0].fee_msat += 100_000; + { + let mut channel_state = nodes[1].node.channel_state.lock().unwrap(); + let mut channel = channel_state.by_id.get_mut(&chan_id_2).unwrap(); + let mut new_config = channel.config(); + new_config.forwarding_fee_base_msat += 100_000; + channel.update_config(&new_config); + new_route.paths[0][0].fee_msat += 100_000; + } + + // Force expiration of the channel's previous config. + for _ in 0..EXPIRE_PREV_CONFIG_TICKS { + nodes[1].node.timer_tick_occurred(); + } assert!(nodes[0].node.retry_payment(&new_route, payment_id_1).is_err()); // Shouldn't be allowed to retry a fulfilled payment nodes[0].node.retry_payment(&new_route, payment_id).unwrap(); @@ -630,7 +647,8 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co let funding_txo = OutPoint { txid: funding_tx.txid(), index: 0 }; let mon_updates: Vec<_> = chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap() .get_mut(&funding_txo).unwrap().drain().collect(); - assert_eq!(mon_updates.len(), 1); + // If we are using chain::Confirm instead of chain::Listen, we will get the same update twice + assert!(mon_updates.len() == 1 || mon_updates.len() == 2); assert!(nodes[0].chain_monitor.release_pending_monitor_events().is_empty()); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); @@ -646,7 +664,9 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co chanmon_cfgs[0].persister.set_update_ret(Ok(())); let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new()); get_monitor!(nodes[0], chan_id).write(&mut chan_0_monitor_serialized).unwrap(); - nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_txo, mon_updates[0]).unwrap(); + for update in mon_updates { + nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_txo, update).unwrap(); + } if payment_timeout { expect_payment_failed!(nodes[0], payment_hash, true); } else {