Merge pull request #1685 from wpaulino/anchors-prep
[rust-lightning] / lightning / src / ln / payment_tests.rs
index c6c4338cf49afa644dbe8a4c3c3a88b3657a34ed..88db36bd3cc334933ba13c4d9e4ba2d8b24d9a4b 100644 (file)
@@ -451,12 +451,12 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        assert_eq!(as_broadcasted_txn[0], as_commitment_tx);
 
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None }).unwrap();
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
        // error, as the channel has hit the chain.
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None }).unwrap();
        let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
        let as_err = nodes[0].node.get_and_clear_pending_msg_events();
@@ -508,13 +508,8 @@ 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);
-       assert_eq!(as_htlc_timeout_txn.len(), 3);
-       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])
-       };
+       assert_eq!(as_htlc_timeout_txn.len(), 2);
+       let (first_htlc_timeout_tx, second_htlc_timeout_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 {
@@ -670,13 +665,13 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
        assert!(nodes[0].node.has_pending_payments());
        assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None }).unwrap();
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
        // error, as the channel has hit the chain.
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
-       let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None }).unwrap();
+       let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
        let as_err = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(as_err.len(), 1);
@@ -894,7 +889,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
                nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_txo, update).unwrap();
        }
        if payment_timeout {
-               expect_payment_failed!(nodes[0], payment_hash, true);
+               expect_payment_failed!(nodes[0], payment_hash, false);
        } else {
                expect_payment_sent!(nodes[0], payment_preimage);
        }
@@ -938,7 +933,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
        if persist_manager_post_event {
                assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
        } else if payment_timeout {
-               expect_payment_failed!(nodes[0], payment_hash, true);
+               expect_payment_failed!(nodes[0], payment_hash, false);
        } else {
                expect_payment_sent!(nodes[0], payment_preimage);
        }
@@ -1200,3 +1195,57 @@ fn failed_probe_yields_event() {
                _ => panic!(),
        };
 }
+
+#[test]
+fn onchain_failed_probe_yields_event() {
+       // Tests that an attempt to probe over a channel that is eventaully closed results in a failure
+       // event.
+       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 nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
+       create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
+
+       let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id());
+
+       // Send a dust HTLC, which will be treated as if it timed out once the channel hits the chain.
+       let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], &payment_params, 1_000, 42);
+       let (payment_hash, payment_id) = nodes[0].node.send_probe(route.paths[0].clone()).unwrap();
+
+       // node[0] -- update_add_htlcs -> node[1]
+       check_added_monitors!(nodes[0], 1);
+       let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+       let probe_event = SendEvent::from_commitment_update(nodes[1].node.get_our_node_id(), updates);
+       nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &probe_event.msgs[0]);
+       check_added_monitors!(nodes[1], 0);
+       commitment_signed_dance!(nodes[1], nodes[0], probe_event.commitment_msg, false);
+       expect_pending_htlcs_forwardable!(nodes[1]);
+
+       check_added_monitors!(nodes[1], 1);
+       let _ = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
+
+       // Don't bother forwarding the HTLC onwards and just confirm the force-close transaction on
+       // Node A, which after 6 confirmations should result in a probe failure event.
+       let bs_txn = get_local_commitment_txn!(nodes[1], chan_id);
+       confirm_transaction(&nodes[0], &bs_txn[0]);
+       check_closed_broadcast!(&nodes[0], true);
+       check_added_monitors!(nodes[0], 1);
+
+       let mut events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 2);
+       let mut found_probe_failed = false;
+       for event in events.drain(..) {
+               match event {
+                       Event::ProbeFailed { payment_id: ev_pid, payment_hash: ev_ph, .. } => {
+                               assert_eq!(payment_id, ev_pid);
+                               assert_eq!(payment_hash, ev_ph);
+                               found_probe_failed = true;
+                       },
+                       Event::ChannelClosed { .. } => {},
+                       _ => panic!(),
+               }
+       }
+       assert!(found_probe_failed);
+}