]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Add test for failing/fulfilling HTLCs from on-chain actions
authorAntoine Riard <ariard@student.42.fr>
Mon, 10 Dec 2018 19:25:31 +0000 (14:25 -0500)
committerMatt Corallo <git@bluematt.me>
Fri, 14 Dec 2018 22:00:22 +0000 (17:00 -0500)
Including detection of timeout claims, fulfill claims, and
failing all current HTLCs in case of revoked-commitment broadcast.

src/ln/channelmanager.rs

index 70db9092392ee6b9d78ad6fb6c3e0aa1efa54df3..db1e57b2803d286f1b777ccb3e3bf89e2f8f09fc 100644 (file)
@@ -6139,6 +6139,340 @@ mod tests {
                assert_eq!(nodes[1].node.list_channels().len(), 0);
        }
 
+       #[test]
+       fn test_htlc_on_chain_success() {
+               // Test that in case of an unilateral close onchain, we detect the state of output thanks to
+               // ChainWatchInterface and pass the preimage backward accordingly. So here we test that ChannelManager is
+               // broadcasting the right event to other nodes in payment path.
+               // A --------------------> B ----------------------> C (preimage)
+               // First, C should claim the HTLC output via HTLC-Success when its own latest local
+               // commitment transaction was broadcast.
+               // Then, B should learn the preimage from said transactions, attempting to claim backwards
+               // towards B.
+               // B should be able to claim via preimage if A then broadcasts its local tx.
+               // Finally, when A sees B's latest local commitment transaction it should be able to claim
+               // the HTLC output via the preimage it learned (which, once confirmed should generate a
+               // PaymentSent event).
+
+               let nodes = create_network(3);
+
+               // Create some initial channels
+               let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+               let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               // Rebalance the network a bit by relaying one payment through all the channels...
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+
+               let (our_payment_preimage, _payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3000000);
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+
+               // Broadcast legit commitment tx from C on B's chain
+               // Broadcast HTLC Success transation by C on received output from C's commitment tx on B's chain
+               let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
+               assert_eq!(commitment_tx.len(), 1);
+               check_spends!(commitment_tx[0], chan_2.3.clone());
+               nodes[2].node.claim_funds(our_payment_preimage);
+               check_added_monitors!(nodes[2], 1);
+               let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
+               assert!(updates.update_add_htlcs.is_empty());
+               assert!(updates.update_fail_htlcs.is_empty());
+               assert!(updates.update_fail_malformed_htlcs.is_empty());
+               assert_eq!(updates.update_fulfill_htlcs.len(), 1);
+
+               nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1);
+               let events = nodes[2].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx), ChannelMonitor : 2 (2 * HTLC-Success tx)
+               assert_eq!(node_txn.len(), 3);
+               assert_eq!(node_txn[1], commitment_tx[0]);
+               assert_eq!(node_txn[0], node_txn[2]);
+               check_spends!(node_txn[0], commitment_tx[0].clone());
+               assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+               assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output
+               assert_eq!(node_txn[0].lock_time, 0);
+
+               // Verify that B's ChannelManager is able to extract preimage from HTLC Success tx and pass it backward
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: node_txn}, 1);
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               {
+                       let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap();
+                       assert_eq!(added_monitors.len(), 1);
+                       assert_eq!(added_monitors[0].0.txid, chan_1.3.txid());
+                       added_monitors.clear();
+               }
+               assert_eq!(events.len(), 2);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               match events[1] {
+                       MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. } } => {
+                               assert!(update_add_htlcs.is_empty());
+                               assert!(update_fail_htlcs.is_empty());
+                               assert_eq!(update_fulfill_htlcs.len(), 1);
+                               assert!(update_fail_malformed_htlcs.is_empty());
+                               assert_eq!(nodes[0].node.get_our_node_id(), *node_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+               {
+                       // nodes[1] now broadcasts its own local state as a fallback, suggesting an alternate
+                       // commitment transaction with a corresponding HTLC-Timeout transaction, as well as a
+                       // timeout-claim of the output that nodes[2] just claimed via success.
+                       let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 (timeout tx) * 2 (block-rescan)
+                       assert_eq!(node_txn.len(), 4);
+                       assert_eq!(node_txn[0], node_txn[3]);
+                       check_spends!(node_txn[0], commitment_tx[0].clone());
+                       assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+                       assert_ne!(node_txn[0].lock_time, 0);
+                       assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment
+                       check_spends!(node_txn[1], chan_2.3.clone());
+                       check_spends!(node_txn[2], node_txn[1].clone());
+                       assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71);
+                       assert_eq!(node_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+                       assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output
+                       assert_ne!(node_txn[2].lock_time, 0);
+                       node_txn.clear();
+               }
+
+               // Broadcast legit commitment tx from A on B's chain
+               // Broadcast preimage tx by B on offered output from A commitment tx  on A's chain
+               let commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
+               check_spends!(commitment_tx[0], chan_1.3.clone());
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1);
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx), ChannelMonitor : 1 (HTLC-Success) * 2 (block-rescan)
+               assert_eq!(node_txn.len(), 3);
+               assert_eq!(node_txn[0], node_txn[2]);
+               check_spends!(node_txn[0], commitment_tx[0].clone());
+               assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+               assert_eq!(node_txn[0].lock_time, 0);
+               assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment
+               check_spends!(node_txn[1], chan_1.3.clone());
+               assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71);
+               // We don't bother to check that B can claim the HTLC output on its commitment tx here as
+               // we already checked the same situation with A.
+
+               // Verify that A's ChannelManager is able to extract preimage from preimage tx and generate PaymentSent
+               nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone(), node_txn[0].clone()] }, 1);
+               let events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               let events = nodes[0].node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::PaymentSent { payment_preimage } => {
+                               assert_eq!(payment_preimage, our_payment_preimage);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+               let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 (HTLC-Timeout tx) * 2 (block-rescan)
+               assert_eq!(node_txn.len(), 4);
+               assert_eq!(node_txn[0], node_txn[3]);
+               check_spends!(node_txn[0], commitment_tx[0].clone());
+               assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+               assert_ne!(node_txn[0].lock_time, 0);
+               assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output
+               check_spends!(node_txn[1], chan_1.3.clone());
+               check_spends!(node_txn[2], node_txn[1].clone());
+               assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71);
+               assert_eq!(node_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+               assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output
+               assert_ne!(node_txn[2].lock_time, 0);
+       }
+
+       #[test]
+       fn test_htlc_on_chain_timeout() {
+               // Test that in case of an unilateral close onchain, we detect the state of output thanks to
+               // ChainWatchInterface and timeout the HTLC  bacward accordingly. So here we test that ChannelManager is
+               // broadcasting the right event to other nodes in payment path.
+               // A ------------------> B ----------------------> C (timeout)
+               //    B's commitment tx                 C's commitment tx
+               //            \                                  \
+               //         B's HTLC timeout tx               B's timeout tx
+
+               let nodes = create_network(3);
+
+               // Create some intial channels
+               let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+               let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               // Rebalance the network a bit by relaying one payment thorugh all the channels...
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+
+               let (_payment_preimage, payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3000000);
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+
+               // Brodacast legit commitment tx from C on B's chain
+               let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
+               check_spends!(commitment_tx[0], chan_2.3.clone());
+               nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
+               {
+                       let mut added_monitors = nodes[2].chan_monitor.added_monitors.lock().unwrap();
+                       assert_eq!(added_monitors.len(), 1);
+                       added_monitors.clear();
+               }
+               let events = nodes[2].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
+                               assert!(update_add_htlcs.is_empty());
+                               assert!(!update_fail_htlcs.is_empty());
+                               assert!(update_fulfill_htlcs.is_empty());
+                               assert!(update_fail_malformed_htlcs.is_empty());
+                               assert_eq!(nodes[1].node.get_our_node_id(), *node_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+               nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1);
+               let events = nodes[2].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { .. } } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx)
+               assert_eq!(node_txn.len(), 1);
+               check_spends!(node_txn[0], chan_2.3.clone());
+               assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), 71);
+
+               // Broadcast timeout transaction by B on received output fron C's commitment tx on B's chain
+               // Verify that B's ChannelManager is able to detect that HTLC is timeout by its own tx and react backward in consequence
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 200);
+               let timeout_tx;
+               {
+                       let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+                       assert_eq!(node_txn.len(), 8); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 6 (HTLC-Timeout tx, commitment tx, timeout tx) * 2 (block-rescan)
+                       assert_eq!(node_txn[0], node_txn[5]);
+                       assert_eq!(node_txn[1], node_txn[6]);
+                       assert_eq!(node_txn[2], node_txn[7]);
+                       check_spends!(node_txn[0], commitment_tx[0].clone());
+                       assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+                       check_spends!(node_txn[1], chan_2.3.clone());
+                       check_spends!(node_txn[2], node_txn[1].clone());
+                       assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), 71);
+                       assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+                       check_spends!(node_txn[3], chan_2.3.clone());
+                       check_spends!(node_txn[4], node_txn[3].clone());
+                       assert_eq!(node_txn[3].input[0].witness.clone().last().unwrap().len(), 71);
+                       assert_eq!(node_txn[4].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+                       timeout_tx = node_txn[0].clone();
+                       node_txn.clear();
+               }
+
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![timeout_tx]}, 1);
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               check_added_monitors!(nodes[1], 1);
+               assert_eq!(events.len(), 2);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { .. } } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               match events[1] {
+                       MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. } } => {
+                               assert!(update_add_htlcs.is_empty());
+                               assert!(!update_fail_htlcs.is_empty());
+                               assert!(update_fulfill_htlcs.is_empty());
+                               assert!(update_fail_malformed_htlcs.is_empty());
+                               assert_eq!(nodes[0].node.get_our_node_id(), *node_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+               let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // Well... here we detect our own htlc_timeout_tx so no tx to be generated
+               assert_eq!(node_txn.len(), 0);
+
+               // Broadcast legit commitment tx from B on A's chain
+               let commitment_tx = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
+               check_spends!(commitment_tx[0], chan_1.3.clone());
+
+               nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 200);
+               let events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { .. } } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 2 (timeout tx) * 2 block-rescan
+               assert_eq!(node_txn.len(), 4);
+               assert_eq!(node_txn[0], node_txn[3]);
+               check_spends!(node_txn[0], commitment_tx[0].clone());
+               assert_eq!(node_txn[0].clone().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].clone());
+               assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), 71);
+               assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+       }
+
+       #[test]
+       fn test_simple_commitment_revoked_fail_backward() {
+               // Test that in case of a revoked commitment tx, we detect the resolution of output by justice tx
+               // and fail backward accordingly.
+
+               let nodes = create_network(3);
+
+               // Create some initial channels
+               create_announced_chan_between_nodes(&nodes, 0, 1);
+               let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
+               // Get the will-be-revoked local txn from nodes[2]
+               let revoked_local_txn = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
+               // Revoke the old state
+               claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
+
+               route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
+
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               check_added_monitors!(nodes[1], 1);
+               assert_eq!(events.len(), 2);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { .. } } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               match events[1] {
+                       MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, ref commitment_signed, .. } } => {
+                               assert!(update_add_htlcs.is_empty());
+                               assert_eq!(update_fail_htlcs.len(), 1);
+                               assert!(update_fulfill_htlcs.is_empty());
+                               assert!(update_fail_malformed_htlcs.is_empty());
+                               assert_eq!(nodes[0].node.get_our_node_id(), *node_id);
+
+                               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlcs[0]).unwrap();
+                               commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
+
+                               let events = nodes[0].node.get_and_clear_pending_msg_events();
+                               assert_eq!(events.len(), 1);
+                               match events[0] {
+                                       MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
+                                       _ => panic!("Unexpected event"),
+                               }
+                               let events = nodes[0].node.get_and_clear_pending_events();
+                               assert_eq!(events.len(), 1);
+                               match events[0] {
+                                       Event::PaymentFailed { .. } => {},
+                                       _ => panic!("Unexpected event"),
+                               }
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
        #[test]
        fn test_htlc_ignore_latest_remote_commitment() {
                // Test that HTLC transactions spending the latest remote commitment transaction are simply
@@ -8555,6 +8889,226 @@ mod tests {
                check_spends!(spend_txn[4], node_txn[3].clone()); // spending justice tx output on htlc success tx
        }
 
+       #[test]
+       fn test_onchain_to_onchain_claim() {
+               // Test that in case of channel closure, we detect the state of output thanks to
+               // ChainWatchInterface and claim HTLC on downstream peer's remote commitment tx.
+               // First, have C claim an HTLC against its own latest commitment transaction.
+               // Then, broadcast these to B, which should update the monitor downstream on the A<->B
+               // channel.
+               // Finally, check that B will claim the HTLC output if A's latest commitment transaction
+               // gets broadcast.
+
+               let nodes = create_network(3);
+
+               // Create some initial channels
+               let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+               let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               // Rebalance the network a bit by relaying one payment through all the channels ...
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+
+               let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3000000);
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+               let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
+               check_spends!(commitment_tx[0], chan_2.3.clone());
+               nodes[2].node.claim_funds(payment_preimage);
+               check_added_monitors!(nodes[2], 1);
+               let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
+               assert!(updates.update_add_htlcs.is_empty());
+               assert!(updates.update_fail_htlcs.is_empty());
+               assert_eq!(updates.update_fulfill_htlcs.len(), 1);
+               assert!(updates.update_fail_malformed_htlcs.is_empty());
+
+               nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1);
+               let events = nodes[2].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+
+               let c_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Success tx), ChannelMonitor : 1 (HTLC-Success tx)
+               assert_eq!(c_txn.len(), 3);
+               assert_eq!(c_txn[0], c_txn[2]);
+               assert_eq!(commitment_tx[0], c_txn[1]);
+               check_spends!(c_txn[1], chan_2.3.clone());
+               check_spends!(c_txn[2], c_txn[1].clone());
+               assert_eq!(c_txn[1].input[0].witness.clone().last().unwrap().len(), 71);
+               assert_eq!(c_txn[2].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+               assert!(c_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output
+               assert_eq!(c_txn[0].lock_time, 0); // Success tx
+
+               // So we broadcast C's commitment tx and HTLC-Success on B's chain, we should successfully be able to extract preimage and update downstream monitor
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![c_txn[1].clone(), c_txn[2].clone()]}, 1);
+               {
+                       let mut b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+                       assert_eq!(b_txn.len(), 4);
+                       assert_eq!(b_txn[0], b_txn[3]);
+                       check_spends!(b_txn[1], chan_2.3); // B local commitment tx, issued by ChannelManager
+                       check_spends!(b_txn[2], b_txn[1].clone()); // HTLC-Timeout on B local commitment tx, issued by ChannelManager
+                       assert_eq!(b_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+                       assert!(b_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output
+                       assert_ne!(b_txn[2].lock_time, 0); // Timeout tx
+                       check_spends!(b_txn[0], c_txn[1].clone()); // timeout tx on C remote commitment tx, issued by ChannelMonitor, * 2 due to block rescan
+                       assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+                       assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment
+                       assert_ne!(b_txn[2].lock_time, 0); // Timeout tx
+                       b_txn.clear();
+               }
+               let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+               check_added_monitors!(nodes[1], 1);
+               match msg_events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate {  .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               match msg_events[1] {
+                       MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
+                               assert!(update_add_htlcs.is_empty());
+                               assert!(update_fail_htlcs.is_empty());
+                               assert_eq!(update_fulfill_htlcs.len(), 1);
+                               assert!(update_fail_malformed_htlcs.is_empty());
+                               assert_eq!(nodes[0].node.get_our_node_id(), *node_id);
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+               // Broadcast A's commitment tx on B's chain to see if we are able to claim inbound HTLC with our HTLC-Success tx
+               let commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1);
+               let b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+               assert_eq!(b_txn.len(), 3);
+               check_spends!(b_txn[1], chan_1.3); // Local commitment tx, issued by ChannelManager
+               assert_eq!(b_txn[0], b_txn[2]); // HTLC-Success tx, issued by ChannelMonitor, * 2 due to block rescan
+               check_spends!(b_txn[0], commitment_tx[0].clone());
+               assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+               assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment
+               assert_eq!(b_txn[2].lock_time, 0); // Success tx
+               let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+               match msg_events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate {  .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       #[test]
+       fn test_duplicate_payment_hash_one_failure_one_success() {
+               // Topology : A --> B --> C
+               // We route 2 payments with same hash between B and C, one will be timeout, the other successfully claim
+               let mut nodes = create_network(3);
+
+               create_announced_chan_between_nodes(&nodes, 0, 1);
+               let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+
+               let (our_payment_preimage, duplicate_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 900000);
+               *nodes[0].network_payment_count.borrow_mut() -= 1;
+               assert_eq!(route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 900000).1, duplicate_payment_hash);
+
+               let commitment_txn = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
+               assert_eq!(commitment_txn[0].input.len(), 1);
+               check_spends!(commitment_txn[0], chan_2.3.clone());
+
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_txn[0].clone()] }, 1);
+               let htlc_timeout_tx;
+               { // Extract one of the two HTLC-Timeout transaction
+                       let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+                       assert_eq!(node_txn.len(), 7);
+                       assert_eq!(node_txn[0], node_txn[5]);
+                       assert_eq!(node_txn[1], node_txn[6]);
+                       check_spends!(node_txn[0], commitment_txn[0].clone());
+                       assert_eq!(node_txn[0].input.len(), 1);
+                       check_spends!(node_txn[1], commitment_txn[0].clone());
+                       assert_eq!(node_txn[1].input.len(), 1);
+                       assert_ne!(node_txn[0].input[0], node_txn[1].input[0]);
+                       check_spends!(node_txn[2], chan_2.3.clone());
+                       check_spends!(node_txn[3], node_txn[2].clone());
+                       check_spends!(node_txn[4], node_txn[2].clone());
+                       htlc_timeout_tx = node_txn[1].clone();
+               }
+
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexepected event"),
+               }
+
+               nodes[2].node.claim_funds(our_payment_preimage);
+               nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_txn[0].clone()] }, 1);
+               check_added_monitors!(nodes[2], 2);
+               let events = nodes[2].node.get_and_clear_pending_msg_events();
+               match events[0] {
+                       MessageSendEvent::UpdateHTLCs { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               match events[1] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexepected event"),
+               }
+               let htlc_success_txn: Vec<_> = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
+               assert_eq!(htlc_success_txn.len(), 5);
+               check_spends!(htlc_success_txn[2], chan_2.3.clone());
+               assert_eq!(htlc_success_txn[0], htlc_success_txn[3]);
+               assert_eq!(htlc_success_txn[0].input.len(), 1);
+               assert_eq!(htlc_success_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+               assert_eq!(htlc_success_txn[1], htlc_success_txn[4]);
+               assert_eq!(htlc_success_txn[1].input.len(), 1);
+               assert_eq!(htlc_success_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+               assert_ne!(htlc_success_txn[0].input[0], htlc_success_txn[1].input[0]);
+               check_spends!(htlc_success_txn[0], commitment_txn[0].clone());
+               check_spends!(htlc_success_txn[1], commitment_txn[0].clone());
+
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![htlc_timeout_tx] }, 200);
+               let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+               assert!(htlc_updates.update_add_htlcs.is_empty());
+               assert_eq!(htlc_updates.update_fail_htlcs.len(), 1);
+               assert_eq!(htlc_updates.update_fail_htlcs[0].htlc_id, 1);
+               assert!(htlc_updates.update_fulfill_htlcs.is_empty());
+               assert!(htlc_updates.update_fail_malformed_htlcs.is_empty());
+               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]).unwrap();
+               assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
+               {
+                       commitment_signed_dance!(nodes[0], nodes[1], &htlc_updates.commitment_signed, false, true);
+                       let events = nodes[0].node.get_and_clear_pending_msg_events();
+                       assert_eq!(events.len(), 1);
+                       match events[0] {
+                               MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelClosed { .. }  } => {
+                               },
+                               _ => { panic!("Unexpected event"); }
+                       }
+               }
+               let events = nodes[0].node.get_and_clear_pending_events();
+               match events[0] {
+                       Event::PaymentFailed { ref payment_hash, .. } => {
+                               assert_eq!(*payment_hash, duplicate_payment_hash);
+                       }
+                       _ => panic!("Unexpected event"),
+               }
+
+               // Solve 2nd HTLC by broadcasting on B's chain HTLC-Success Tx from C
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![htlc_success_txn[0].clone()] }, 200);
+               let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+               assert!(updates.update_add_htlcs.is_empty());
+               assert!(updates.update_fail_htlcs.is_empty());
+               assert_eq!(updates.update_fulfill_htlcs.len(), 1);
+               assert_eq!(updates.update_fulfill_htlcs[0].htlc_id, 0);
+               assert!(updates.update_fail_malformed_htlcs.is_empty());
+               check_added_monitors!(nodes[1], 1);
+
+               nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]).unwrap();
+               commitment_signed_dance!(nodes[0], nodes[1], &updates.commitment_signed, false);
+
+               let events = nodes[0].node.get_and_clear_pending_events();
+               match events[0] {
+                       Event::PaymentSent { ref payment_preimage } => {
+                               assert_eq!(*payment_preimage, our_payment_preimage);
+                       }
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
        #[test]
        fn test_dynamic_spendable_outputs_local_htlc_success_tx() {
                let nodes = create_network(2);