Test failing backward any pending HTLCs
[rust-lightning] / lightning / src / ln / functional_tests.rs
index 5cd98d2f76028b74e03624f60b5f95e2e99e4662..76749c3b37ad44c18df96c4ff476450247b37ddc 100644 (file)
@@ -2988,6 +2988,76 @@ fn test_commitment_revoked_fail_backward_exhaustive_b() {
        do_test_commitment_revoked_fail_backward_exhaustive(true, false, true);
 }
 
+#[test]
+fn fail_backward_pending_htlc_upon_channel_failure() {
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+       let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, InitFeatures::supported(), InitFeatures::supported());
+
+       // Alice -> Bob: Route a payment but without Bob sending revoke_and_ack.
+       {
+               let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
+               let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
+               nodes[0].node.send_payment(route, payment_hash).unwrap();
+               check_added_monitors!(nodes[0], 1);
+
+               let payment_event = {
+                       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+                       assert_eq!(events.len(), 1);
+                       SendEvent::from_event(events.remove(0))
+               };
+               assert_eq!(payment_event.node_id, nodes[1].node.get_our_node_id());
+               assert_eq!(payment_event.msgs.len(), 1);
+       }
+
+       // Alice -> Bob: Route another payment but now Alice waits for Bob's earlier revoke_and_ack.
+       let (_, failed_payment_hash) = get_payment_preimage_hash!(nodes[0]);
+       {
+               let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
+               nodes[0].node.send_payment(route, failed_payment_hash).unwrap();
+               check_added_monitors!(nodes[0], 0);
+
+               assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
+       }
+
+       // Alice <- Bob: Send a malformed update_add_htlc so Alice fails the channel.
+       {
+               let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
+               let (_, payment_hash) = get_payment_preimage_hash!(nodes[1]);
+
+               let secp_ctx = Secp256k1::new();
+               let session_priv = {
+                       let mut session_key = [0; 32];
+                       let mut rng = thread_rng();
+                       rng.fill_bytes(&mut session_key);
+                       SecretKey::from_slice(&session_key).expect("RNG is bad!")
+               };
+
+               let current_height = nodes[1].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
+               let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route, current_height).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route, &session_priv).unwrap();
+               let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash);
+
+               // Send a 0-msat update_add_htlc to fail the channel.
+               let update_add_htlc = msgs::UpdateAddHTLC {
+                       channel_id: chan.2,
+                       htlc_id: 0,
+                       amount_msat: 0,
+                       payment_hash,
+                       cltv_expiry,
+                       onion_routing_packet,
+               };
+               nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &update_add_htlc);
+       }
+
+       // Check that Alice fails backward the pending HTLC from the second payment.
+       expect_payment_failed!(nodes[0], failed_payment_hash, true);
+       check_closed_broadcast!(nodes[0], true);
+       check_added_monitors!(nodes[0], 1);
+}
+
 #[test]
 fn test_htlc_ignore_latest_remote_commitment() {
        // Test that HTLC transactions spending the latest remote commitment transaction are simply
@@ -4170,6 +4240,60 @@ fn test_static_spendable_outputs_preimage_tx() {
        check_spends!(spend_txn[0], node_txn[0]);
 }
 
+#[test]
+fn test_static_spendable_outputs_timeout_tx() {
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       // Create some initial channels
+       let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported());
+
+       // Rebalance the network a bit by relaying one payment through all the channels ...
+       send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
+
+       let (_, our_payment_hash) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3_000_000);
+
+       let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2);
+       assert_eq!(commitment_tx[0].input.len(), 1);
+       assert_eq!(commitment_tx[0].input[0].previous_output.txid, chan_1.3.txid());
+
+       // Settle A's commitment tx on B' chain
+       let header = BlockHeader { version: 0x2000_0000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+       nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()] }, 0);
+       check_added_monitors!(nodes[1], 1);
+       let events = nodes[1].node.get_and_clear_pending_msg_events();
+       match events[0] {
+               MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+
+       // Check B's monitor was able to send back output descriptor event for timeout tx on A's commitment tx
+       let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+       assert_eq!(node_txn.len(), 3); // ChannelManager : 2 (local commitent tx + HTLC-timeout), ChannelMonitor: timeout tx
+       check_spends!(node_txn[0],  commitment_tx[0].clone());
+       assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+       check_spends!(node_txn[1], chan_1.3.clone());
+       check_spends!(node_txn[2], node_txn[1]);
+
+       let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+       nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
+       connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
+       let events = nodes[1].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               Event::PaymentFailed { payment_hash, .. } => {
+                       assert_eq!(payment_hash, our_payment_hash);
+               },
+               _ => panic!("Unexpected event"),
+       }
+
+       let spend_txn = check_spendable_outputs!(nodes[1], 1);
+       assert_eq!(spend_txn.len(), 3); // SpendableOutput: remote_commitment_tx.to_remote (*2), timeout_tx.output (*1)
+       check_spends!(spend_txn[2], node_txn[0].clone());
+}
+
 #[test]
 fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
        let chanmon_cfgs = create_chanmon_cfgs(2);