|
10 | 10 | //! Functional tests which test for correct behavior across node restarts.
|
11 | 11 |
|
12 | 12 | use crate::chain::{ChannelMonitorUpdateStatus, Watch};
|
| 13 | +use crate::chain::chaininterface::LowerBoundedFeeEstimator; |
13 | 14 | use crate::chain::channelmonitor::ChannelMonitor;
|
| 15 | +use crate::chain::keysinterface::KeysInterface; |
14 | 16 | use crate::chain::transaction::OutPoint;
|
15 | 17 | use crate::ln::channelmanager::{self, ChannelManager, ChannelManagerReadArgs, PaymentId};
|
16 | 18 | use crate::ln::msgs;
|
17 | 19 | use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
|
18 | 20 | use crate::util::enforcing_trait_impls::EnforcingSigner;
|
19 | 21 | use crate::util::test_utils;
|
20 |
| -use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; |
| 22 | +use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; |
21 | 23 | use crate::util::ser::{Writeable, ReadableArgs};
|
22 | 24 | use crate::util::config::UserConfig;
|
23 | 25 |
|
@@ -811,3 +813,123 @@ fn test_partial_claim_before_restart() {
|
811 | 813 | do_test_partial_claim_before_restart(false);
|
812 | 814 | do_test_partial_claim_before_restart(true);
|
813 | 815 | }
|
| 816 | + |
| 817 | +fn do_forwarded_payment_no_manager_persistence(use_cs_commitment: bool, claim_htlc: bool) { |
| 818 | + if !use_cs_commitment { assert!(!claim_htlc); } |
| 819 | + // If we go to forward a payment, and the ChannelMonitor persistence completes, but the |
| 820 | + // ChannelManager does not, we shouldn't try to forward the payment again, nor should we fail |
| 821 | + // it back until the ChannelMonitor decides the fate of the HTLC. |
| 822 | + // This was never an issue, but it may be easy to regress here going forward. |
| 823 | + let chanmon_cfgs = create_chanmon_cfgs(3); |
| 824 | + let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); |
| 825 | + let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); |
| 826 | + |
| 827 | + let persister; |
| 828 | + let new_chain_monitor; |
| 829 | + let nodes_1_deserialized; |
| 830 | + |
| 831 | + let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs); |
| 832 | + |
| 833 | + let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2; |
| 834 | + let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2; |
| 835 | + |
| 836 | + let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000); |
| 837 | + let payment_id = PaymentId(nodes[0].keys_manager.backing.get_secure_random_bytes()); |
| 838 | + let htlc_expiry = nodes[0].best_block_info().1 + TEST_FINAL_CLTV; |
| 839 | + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), payment_id).unwrap(); |
| 840 | + check_added_monitors!(nodes[0], 1); |
| 841 | + |
| 842 | + let payment_event = SendEvent::from_node(&nodes[0]); |
| 843 | + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); |
| 844 | + commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false); |
| 845 | + |
| 846 | + let node_encoded = nodes[1].node.encode(); |
| 847 | + |
| 848 | + expect_pending_htlcs_forwardable!(nodes[1]); |
| 849 | + |
| 850 | + let payment_event = SendEvent::from_node(&nodes[1]); |
| 851 | + nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]); |
| 852 | + nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg); |
| 853 | + check_added_monitors!(nodes[2], 1); |
| 854 | + |
| 855 | + if claim_htlc { |
| 856 | + get_monitor!(nodes[2], chan_id_2).provide_payment_preimage(&payment_hash, &payment_preimage, |
| 857 | + &nodes[2].tx_broadcaster, &LowerBoundedFeeEstimator(nodes[2].fee_estimator), &nodes[2].logger); |
| 858 | + } |
| 859 | + assert!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty()); |
| 860 | + |
| 861 | + let _ = nodes[2].node.get_and_clear_pending_msg_events(); |
| 862 | + |
| 863 | + nodes[2].node.force_close_broadcasting_latest_txn(&chan_id_2, &nodes[1].node.get_our_node_id()).unwrap(); |
| 864 | + let cs_commitment_tx = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); |
| 865 | + assert_eq!(cs_commitment_tx.len(), if claim_htlc { 2 } else { 1 }); |
| 866 | + |
| 867 | + check_added_monitors!(nodes[2], 1); |
| 868 | + check_closed_event!(nodes[2], 1, ClosureReason::HolderForceClosed); |
| 869 | + check_closed_broadcast!(nodes[2], true); |
| 870 | + |
| 871 | + let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode(); |
| 872 | + let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode(); |
| 873 | + reload_node!(nodes[1], node_encoded, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized); |
| 874 | + |
| 875 | + check_closed_event!(nodes[1], 1, ClosureReason::OutdatedChannelManager); |
| 876 | + |
| 877 | + let bs_commitment_tx = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); |
| 878 | + assert_eq!(bs_commitment_tx.len(), 1); |
| 879 | + |
| 880 | + nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), true); |
| 881 | + reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); |
| 882 | + |
| 883 | + if use_cs_commitment { |
| 884 | + // If we confirm a commitment transaction that has the HTLC on-chain, nodes[1] should wait |
| 885 | + // for an HTLC-spending transaction before it does anything with the HTLC upstream. |
| 886 | + confirm_transaction(&nodes[1], &cs_commitment_tx[0]); |
| 887 | + assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); |
| 888 | + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); |
| 889 | + |
| 890 | + if claim_htlc { |
| 891 | + confirm_transaction(&nodes[1], &cs_commitment_tx[1]); |
| 892 | + } else { |
| 893 | + connect_blocks(&nodes[1], htlc_expiry - nodes[1].best_block_info().1); |
| 894 | + let bs_htlc_timeout_tx = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); |
| 895 | + assert_eq!(bs_htlc_timeout_tx.len(), 1); |
| 896 | + confirm_transaction(&nodes[1], &bs_htlc_timeout_tx[0]); |
| 897 | + } |
| 898 | + } else { |
| 899 | + confirm_transaction(&nodes[1], &bs_commitment_tx[0]); |
| 900 | + } |
| 901 | + |
| 902 | + if !claim_htlc { |
| 903 | + expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], [HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_id_2 }]); |
| 904 | + } else { |
| 905 | + expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(1000), false, true); |
| 906 | + } |
| 907 | + check_added_monitors!(nodes[1], 1); |
| 908 | + |
| 909 | + let events = nodes[1].node.get_and_clear_pending_msg_events(); |
| 910 | + assert_eq!(events.len(), 1); |
| 911 | + match &events[0] { |
| 912 | + MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { update_fulfill_htlcs, update_fail_htlcs, commitment_signed, .. }, .. } => { |
| 913 | + if claim_htlc { |
| 914 | + nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_htlcs[0]); |
| 915 | + } else { |
| 916 | + nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlcs[0]); |
| 917 | + } |
| 918 | + commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false); |
| 919 | + }, |
| 920 | + _ => panic!("Unexpected event"), |
| 921 | + } |
| 922 | + |
| 923 | + if claim_htlc { |
| 924 | + expect_payment_sent!(nodes[0], payment_preimage); |
| 925 | + } else { |
| 926 | + expect_payment_failed!(nodes[0], payment_hash, false); |
| 927 | + } |
| 928 | +} |
| 929 | + |
| 930 | +#[test] |
| 931 | +fn forwarded_payment_no_manager_persistence() { |
| 932 | + do_forwarded_payment_no_manager_persistence(true, true); |
| 933 | + do_forwarded_payment_no_manager_persistence(true, false); |
| 934 | + do_forwarded_payment_no_manager_persistence(false, false); |
| 935 | +} |
0 commit comments