From b6b5decfa9169f634b18a77b10f7ae6a20a6f240 Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Tue, 6 Nov 2018 00:43:06 +0000 Subject: [PATCH] Add test_static_spendable_outputs_justice_tx_revoked_htlc* Cover both HTLC-Timeout/Success cases --- src/ln/channelmanager.rs | 95 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 2fe0ec38..efa60181 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -7813,4 +7813,99 @@ mod tests { let spend_tx = check_static_output!(events, nodes, 0, 0, 1, 1); check_spends!(spend_tx, node_txn[0].clone()); } + + #[test] + fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { + let nodes = create_network(2); + + // Create some initial channels + let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1); + + let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; + let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone(); + assert_eq!(revoked_local_txn[0].input.len(), 1); + assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid()); + + claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage); + + let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + // A will generate HTLC-Timeout from revoked commitment tx + nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + let events = nodes[0].node.get_and_clear_pending_msg_events(); + match events[0] { + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + _ => panic!("Unexpected event"), + } + let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(revoked_htlc_txn.len(), 2); + assert_eq!(revoked_htlc_txn[0].input.len(), 1); + assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 133); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); + + // B will generate justice tx from A's revoked commitment/HTLC tx + nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); + let events = nodes[1].node.get_and_clear_pending_msg_events(); + match events[0] { + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + _ => panic!("Unexpected event"), + } + + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn.len(), 4); + assert_eq!(node_txn[3].input.len(), 1); + check_spends!(node_txn[3], revoked_htlc_txn[0].clone()); + + let events = nodes[1].chan_monitor.simple_monitor.get_and_clear_pending_events(); + // Check B's ChannelMonitor was able to generate the right spendable output descriptor + let spend_tx = check_static_output!(events, nodes, 1, 1, 1, 1); + check_spends!(spend_tx, node_txn[3].clone()); + } + + #[test] + fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { + let nodes = create_network(2); + + // Create some initial channels + let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1); + + let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; + let revoked_local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone(); + assert_eq!(revoked_local_txn[0].input.len(), 1); + assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid()); + + claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage); + + let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + // B will generate HTLC-Success from revoked commitment tx + 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(); + match events[0] { + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + _ => panic!("Unexpected event"), + } + let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + + assert_eq!(revoked_htlc_txn.len(), 2); + assert_eq!(revoked_htlc_txn[0].input.len(), 1); + assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 138); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); + + // A will generate justice tx from B's revoked commitment/HTLC tx + nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); + let events = nodes[0].node.get_and_clear_pending_msg_events(); + match events[0] { + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + _ => panic!("Unexpected event"), + } + + let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn.len(), 4); + assert_eq!(node_txn[3].input.len(), 1); + check_spends!(node_txn[3], revoked_htlc_txn[0].clone()); + + let events = nodes[0].chan_monitor.simple_monitor.get_and_clear_pending_events(); + // Check A's ChannelMonitor was able to generate the right spendable output descriptor + let spend_tx = check_static_output!(events, nodes, 1, 2, 1, 0); + check_spends!(spend_tx, node_txn[3].clone()); + } } -- 2.30.2