X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=de6488d144e65f437e6e57c6d47c23182393e462;hb=1508253bf081db5e57d9ee3256553dd623f889da;hp=fde5cf8268bc8157fa78d713f6d89aba7b54af3e;hpb=8829d1b80f99aa9bb34a5132a380b1d5dc7e303a;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index fde5cf82..de6488d1 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -65,7 +65,7 @@ fn test_insane_channel_opens() { let push_msat = (channel_value_sat - channel_reserve_satoshis) * 1000; // Have node0 initiate a channel to node1 with aforementioned parameters - nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_sat, push_msat, 42).unwrap(); + nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_sat, push_msat, 42, None).unwrap(); // Extract the channel open message from node0 to node1 let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); @@ -436,7 +436,7 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { } if steps & 0x0f == 0 { return; } - nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42).unwrap(); + nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap(); let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); if steps & 0x0f == 1 { return; } @@ -580,16 +580,15 @@ fn test_update_fee_that_funder_cannot_afford() { //Confirm that the new fee based on the last local commitment txn is what we expected based on the feerate of 260 set above. //This value results in a fee that is exactly what the funder can afford (277 sat + 1000 sat channel reserve) { - let mut chan_lock = nodes[1].node.channel_state.lock().unwrap(); - let chan = chan_lock.by_id.get_mut(&channel_id).unwrap(); + let commitment_tx = get_local_commitment_txn!(nodes[1], channel_id)[0].clone(); //We made sure neither party's funds are below the dust limit so -2 non-HTLC txns from number of outputs - let num_htlcs = chan.channel_monitor().get_latest_local_commitment_txn()[0].output.len() - 2; + let num_htlcs = commitment_tx.output.len() - 2; let total_fee: u64 = feerate * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000; - let mut actual_fee = chan.channel_monitor().get_latest_local_commitment_txn()[0].output.iter().fold(0, |acc, output| acc + output.value); + let mut actual_fee = commitment_tx.output.iter().fold(0, |acc, output| acc + output.value); actual_fee = channel_value - actual_fee; assert_eq!(total_fee, actual_fee); - } //drop the mutex + } //Add 2 to the previous fee rate to the final fee increases by 1 (with no HTLCs the fee is essentially //fee_rate*(724/1000) so the increment of 1*0.724 is rounded back down) @@ -605,9 +604,8 @@ fn test_update_fee_that_funder_cannot_afford() { //Should produce and error. nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &update2_msg.commitment_signed); nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Funding remote cannot afford proposed new fee".to_string(), 1); - - //clear the message we could not handle - nodes[1].node.get_and_clear_pending_msg_events(); + check_added_monitors!(nodes[1], 1); + check_closed_broadcast!(nodes[1], true); } #[test] @@ -1141,6 +1139,7 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) { // checks it, but in this case nodes[0] didn't ever get a chance to receive a // closing_signed so we do it ourselves check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); } assert!(nodes[0].node.list_channels().is_empty()); @@ -1475,7 +1474,7 @@ fn test_duplicate_htlc_different_direction_onchain() { check_added_monitors!(nodes[0], 1); // Broadcast node 1 commitment txn - let remote_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let remote_txn = get_local_commitment_txn!(nodes[1], chan_1.2); assert_eq!(remote_txn[0].output.len(), 4); // 1 local, 1 remote, 1 htlc inbound, 1 htlc outbound let mut has_both_htlcs = 0; // check htlcs match ones committed @@ -1490,6 +1489,7 @@ fn test_duplicate_htlc_different_direction_onchain() { let header = BlockHeader { version: 0x2000_0000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![remote_txn[0].clone()] }, 1); + check_added_monitors!(nodes[0], 1); // Check we only broadcast 1 timeout tx let claim_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); @@ -1499,10 +1499,10 @@ fn test_duplicate_htlc_different_direction_onchain() { check_spends!(claim_txn[3], claim_txn[2]); assert_eq!(htlc_pair.0.input.len(), 1); assert_eq!(htlc_pair.0.input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC 1 <--> 0, preimage tx - check_spends!(htlc_pair.0, remote_txn[0].clone()); + check_spends!(htlc_pair.0, remote_txn[0]); assert_eq!(htlc_pair.1.input.len(), 1); assert_eq!(htlc_pair.1.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx - check_spends!(htlc_pair.1, remote_txn[0].clone()); + check_spends!(htlc_pair.1, remote_txn[0]); let events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 2); @@ -1670,6 +1670,7 @@ fn do_channel_reserve_test(test_recv: bool) { assert_eq!(nodes[1].node.list_channels().len(), 1); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data, "Remote HTLC add would put them over their reserve value"); + check_added_monitors!(nodes[1], 1); return; } } @@ -1959,10 +1960,12 @@ fn channel_monitor_network_test() { // Simple case with no pending HTLCs: nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true); + check_added_monitors!(nodes[1], 1); { let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1); + check_added_monitors!(nodes[0], 1); test_txn_broadcast(&nodes[0], &chan_1, None, HTLCType::NONE); } get_announce_close_broadcast_events(&nodes, 0, 1); @@ -1974,10 +1977,12 @@ fn channel_monitor_network_test() { // Simple case of one pending HTLC to HTLC-Timeout nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true); + check_added_monitors!(nodes[1], 1); { let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[2].block_notifier.block_connected(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1); + check_added_monitors!(nodes[2], 1); test_txn_broadcast(&nodes[2], &chan_2, None, HTLCType::NONE); } get_announce_close_broadcast_events(&nodes, 1, 2); @@ -2007,6 +2012,7 @@ fn channel_monitor_network_test() { // nodes[3] gets the preimage, but nodes[2] already disconnected, resulting in a nodes[2] // HTLC-Timeout and a nodes[3] claim against it (+ its own announces) nodes[2].node.peer_disconnected(&nodes[3].node.get_our_node_id(), true); + check_added_monitors!(nodes[2], 1); let node2_commitment_txid; { let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT); @@ -2017,6 +2023,7 @@ fn channel_monitor_network_test() { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[3].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 1); + check_added_monitors!(nodes[3], 1); check_preimage_claim(&nodes[3], &node_txn); } @@ -2043,6 +2050,7 @@ fn channel_monitor_network_test() { header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[3].block_notifier.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]); } + check_added_monitors!(nodes[3], 1); // Clear bumped claiming txn spending node 2 commitment tx. Bumped txn are generated after reaching some height timer. { @@ -2067,6 +2075,7 @@ fn channel_monitor_network_test() { nodes[4].block_notifier.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]); } + check_added_monitors!(nodes[4], 1); test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS); header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; @@ -2101,7 +2110,7 @@ fn test_justice_tx() { // A pending HTLC which will be revoked: let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; // Get the will-be-revoked local txn from nodes[0] - let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.iter_mut().next().unwrap().1.channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_5.2); assert_eq!(revoked_local_txn.len(), 2); // First commitment tx, then HTLC tx assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_5.3.txid()); @@ -2120,15 +2129,19 @@ fn test_justice_tx() { assert_eq!(node_txn.len(), 2); // ChannelMonitor: penalty tx, ChannelManager: local commitment tx assert_eq!(node_txn[0].input.len(), 2); // We should claim the revoked output and the HTLC output - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); node_txn.swap_remove(0); node_txn.truncate(1); } + check_added_monitors!(nodes[1], 1); test_txn_broadcast(&nodes[1], &chan_5, None, HTLCType::NONE); nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + // Verify broadcast of revoked HTLC-timeout let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT); header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + check_added_monitors!(nodes[0], 1); + // Broadcast revoked HTLC-timeout on node 1 nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[1].clone()] }, 1); test_revoked_htlc_claim_txn_broadcast(&nodes[1], node_txn[1].clone(), revoked_local_txn[0].clone()); } @@ -2148,7 +2161,7 @@ fn test_justice_tx() { // A pending HTLC which will be revoked: let payment_preimage_4 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; // Get the will-be-revoked local txn from B - let revoked_local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.iter_mut().next().unwrap().1.channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan_6.2); assert_eq!(revoked_local_txn.len(), 1); // Only commitment tx assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_6.3.txid()); @@ -2163,14 +2176,16 @@ fn test_justice_tx() { assert_eq!(node_txn.len(), 2); //ChannelMonitor: penalty tx, ChannelManager: local commitment tx assert_eq!(node_txn[0].input.len(), 1); // We claim the received HTLC output - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); node_txn.swap_remove(0); } + check_added_monitors!(nodes[0], 1); test_txn_broadcast(&nodes[0], &chan_6, None, HTLCType::NONE); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); let node_txn = test_txn_broadcast(&nodes[1], &chan_6, Some(revoked_local_txn[0].clone()), HTLCType::SUCCESS); header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + check_added_monitors!(nodes[1], 1); nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[1].clone()] }, 1); test_revoked_htlc_claim_txn_broadcast(&nodes[0], node_txn[1].clone(), revoked_local_txn[0].clone()); } @@ -2189,7 +2204,7 @@ fn revoked_output_claim() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); // node[0] is gonna to revoke an old state thus node[1] should be able to claim the revoked output - let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); assert_eq!(revoked_local_txn.len(), 1); // Only output is the full channel value back to nodes[0]: assert_eq!(revoked_local_txn[0].output.len(), 1); @@ -2199,15 +2214,17 @@ fn revoked_output_claim() { // Inform nodes[1] that nodes[0] broadcast a stale tx let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 2); // ChannelMonitor: justice tx against revoked to_local output, ChannelManager: local commitment tx - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - check_spends!(node_txn[1], chan_1.3.clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], chan_1.3); // Inform nodes[0] that a watchtower cheated on its behalf, so it will force-close the chan nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); get_announce_close_broadcast_events(&nodes, 0, 1); + check_added_monitors!(nodes[0], 1) } #[test] @@ -2228,14 +2245,14 @@ fn claim_htlc_outputs_shared_tx() { let (_payment_preimage_2, payment_hash_2) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000); // Get the will-be-revoked local txn from node[0] - let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); assert_eq!(revoked_local_txn.len(), 2); // commitment tx + 1 HTLC-Timeout tx assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid()); assert_eq!(revoked_local_txn[1].input.len(), 1); assert_eq!(revoked_local_txn[1].input[0].previous_output.txid, revoked_local_txn[0].txid()); assert_eq!(revoked_local_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC-Timeout - check_spends!(revoked_local_txn[1], revoked_local_txn[0].clone()); + check_spends!(revoked_local_txn[1], revoked_local_txn[0]); //Revoke the old state claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1, 3_000_000); @@ -2243,7 +2260,9 @@ fn claim_htlc_outputs_shared_tx() { { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + check_added_monitors!(nodes[0], 1); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + check_added_monitors!(nodes[1], 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(); @@ -2259,7 +2278,7 @@ fn claim_htlc_outputs_shared_tx() { assert_eq!(node_txn.len(), 3); // ChannelMonitor: penalty tx, ChannelManager: local commitment + HTLC-timeout assert_eq!(node_txn[0].input.len(), 3); // Claim the revoked output + both revoked HTLC outputs - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); let mut witness_lens = BTreeSet::new(); witness_lens.insert(node_txn[0].input[0].witness.last().unwrap().len()); @@ -2304,7 +2323,7 @@ fn claim_htlc_outputs_single_tx() { let (_payment_preimage_2, payment_hash_2) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000); // Get the will-be-revoked local txn from node[0] - let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); //Revoke the old state claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1, 3_000_000); @@ -2312,7 +2331,9 @@ fn claim_htlc_outputs_single_tx() { { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 200); + check_added_monitors!(nodes[0], 1); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 200); + check_added_monitors!(nodes[1], 1); connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash()); let events = nodes[1].node.get_and_clear_pending_events(); @@ -2325,62 +2346,53 @@ fn claim_htlc_outputs_single_tx() { } let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 26); + assert_eq!(node_txn.len(), 21); // ChannelMonitor: justice tx revoked offered htlc, justice tx revoked received htlc, justice tx revoked to_local (3) // ChannelManager: local commmitment + local HTLC-timeout (2) - // ChannelMonitor: bumped justice tx * 7 (7), after one increase, bumps on HTLC aren't generated not being substantial anymore - // ChannelMonitor: local commitment + local HTLC-timeout (14) - - - assert_eq!(node_txn[3], node_txn[5]); - assert_eq!(node_txn[3], node_txn[7]); - assert_eq!(node_txn[3], node_txn[9]); - assert_eq!(node_txn[3], node_txn[14]); - assert_eq!(node_txn[3], node_txn[17]); - assert_eq!(node_txn[3], node_txn[20]); - assert_eq!(node_txn[3], node_txn[23]); - - assert_eq!(node_txn[4], node_txn[6]); - assert_eq!(node_txn[4], node_txn[8]); - assert_eq!(node_txn[4], node_txn[10]); - assert_eq!(node_txn[4], node_txn[15]); - assert_eq!(node_txn[4], node_txn[18]); - assert_eq!(node_txn[4], node_txn[21]); - assert_eq!(node_txn[4], node_txn[24]); - + // ChannelMonitor: bumped justice tx (4), after one increase, bumps on HTLC aren't generated not being substantial anymore + // ChannelMonito r: local commitment + local HTLC-timeout (14) + + assert_eq!(node_txn[0], node_txn[5]); + assert_eq!(node_txn[0], node_txn[7]); + assert_eq!(node_txn[0], node_txn[9]); + assert_eq!(node_txn[0], node_txn[13]); + assert_eq!(node_txn[0], node_txn[15]); + assert_eq!(node_txn[0], node_txn[17]); + assert_eq!(node_txn[0], node_txn[19]); + + assert_eq!(node_txn[1], node_txn[6]); + assert_eq!(node_txn[1], node_txn[8]); + assert_eq!(node_txn[1], node_txn[10]); + assert_eq!(node_txn[1], node_txn[14]); + assert_eq!(node_txn[1], node_txn[16]); + assert_eq!(node_txn[1], node_txn[18]); + assert_eq!(node_txn[1], node_txn[20]); + + + // Check the pair local commitment and HTLC-timeout broadcast due to HTLC expiration and present 8 times (rebroadcast at every block from 200 to 206) assert_eq!(node_txn[0].input.len(), 1); + check_spends!(node_txn[0], chan_1.3); assert_eq!(node_txn[1].input.len(), 1); - assert_eq!(node_txn[2].input.len(), 1); + let witness_script = node_txn[1].input[0].witness.last().unwrap(); + assert_eq!(witness_script.len(), OFFERED_HTLC_SCRIPT_WEIGHT); //Spending an offered htlc output + check_spends!(node_txn[1], node_txn[0]); - fn get_txout(out_point: &BitcoinOutPoint, tx: &Transaction) -> Option { - if out_point.txid == tx.txid() { - tx.output.get(out_point.vout as usize).cloned() - } else { - None - } - } - node_txn[0].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap(); - node_txn[1].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap(); - node_txn[2].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap(); + // Justice transactions are indices 2-3-4 + assert_eq!(node_txn[2].input.len(), 1); + assert_eq!(node_txn[3].input.len(), 1); + assert_eq!(node_txn[4].input.len(), 1); + check_spends!(node_txn[2], revoked_local_txn[0]); + check_spends!(node_txn[3], revoked_local_txn[0]); + check_spends!(node_txn[4], revoked_local_txn[0]); let mut witness_lens = BTreeSet::new(); - witness_lens.insert(node_txn[0].input[0].witness.last().unwrap().len()); - witness_lens.insert(node_txn[1].input[0].witness.last().unwrap().len()); witness_lens.insert(node_txn[2].input[0].witness.last().unwrap().len()); + witness_lens.insert(node_txn[3].input[0].witness.last().unwrap().len()); + witness_lens.insert(node_txn[4].input[0].witness.last().unwrap().len()); assert_eq!(witness_lens.len(), 3); assert_eq!(*witness_lens.iter().skip(0).next().unwrap(), 77); // revoked to_local assert_eq!(*witness_lens.iter().skip(1).next().unwrap(), OFFERED_HTLC_SCRIPT_WEIGHT); // revoked offered HTLC assert_eq!(*witness_lens.iter().skip(2).next().unwrap(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // revoked received HTLC - - assert_eq!(node_txn[3].input.len(), 1); - check_spends!(node_txn[3], chan_1.3.clone()); - - assert_eq!(node_txn[4].input.len(), 1); - let witness_script = node_txn[4].input[0].witness.last().unwrap(); - assert_eq!(witness_script.len(), OFFERED_HTLC_SCRIPT_WEIGHT); //Spending an offered htlc output - assert_eq!(node_txn[4].input[0].previous_output.txid, node_txn[3].txid()); - assert_ne!(node_txn[4].input[0].previous_output.txid, node_txn[0].input[0].previous_output.txid); - assert_ne!(node_txn[4].input[0].previous_output.txid, node_txn[1].input[0].previous_output.txid); } get_announce_close_broadcast_events(&nodes, 0, 1); assert_eq!(nodes[0].node.list_channels().len(), 0); @@ -2422,9 +2434,9 @@ fn test_htlc_on_chain_success() { // Broadcast legit commitment tx from C on B's chain // Broadcast HTLC Success transaction 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_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let commitment_tx = get_local_commitment_txn!(nodes[2], chan_2.2); assert_eq!(commitment_tx.len(), 1); - check_spends!(commitment_tx[0], chan_2.3.clone()); + check_spends!(commitment_tx[0], chan_2.3); nodes[2].node.claim_funds(our_payment_preimage, 3_000_000); nodes[2].node.claim_funds(our_payment_preimage_2, 3_000_000); check_added_monitors!(nodes[2], 2); @@ -2436,6 +2448,7 @@ fn test_htlc_on_chain_success() { nodes[2].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); check_closed_broadcast!(nodes[2], false); + check_added_monitors!(nodes[2], 1); let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 3 (commitment tx, 2*htlc-success tx), ChannelMonitor : 4 (2*2 * HTLC-Success tx) assert_eq!(node_txn.len(), 7); assert_eq!(node_txn[0], node_txn[3]); @@ -2443,8 +2456,8 @@ fn test_htlc_on_chain_success() { assert_eq!(node_txn[0], node_txn[5]); assert_eq!(node_txn[1], node_txn[6]); assert_eq!(node_txn[2], commitment_tx[0]); - check_spends!(node_txn[0], commitment_tx[0].clone()); - check_spends!(node_txn[1], commitment_tx[0].clone()); + check_spends!(node_txn[0], commitment_tx[0]); + check_spends!(node_txn[1], commitment_tx[0]); assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output @@ -2454,6 +2467,12 @@ fn test_htlc_on_chain_success() { // Verify that B's ChannelManager is able to extract preimage from HTLC Success tx and pass it backward nodes[1].block_notifier.block_connected(&Block { header, txdata: node_txn}, 1); + { + 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_2.3.txid()); + added_monitors.clear(); + } let events = nodes[1].node.get_and_clear_pending_msg_events(); { let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap(); @@ -2483,8 +2502,8 @@ fn test_htlc_on_chain_success() { assert_eq!(node_txn.len(), if $htlc_offered { 7 } else { 5 }); // Node[1]: ChannelManager: 3 (commitment tx, 2*HTLC-Timeout tx), ChannelMonitor: 2 (timeout tx) // Node[0]: ChannelManager: 3 (commtiemtn tx, 2*HTLC-Timeout tx), ChannelMonitor: 2 HTLC-timeout * 2 (block-rescan) - check_spends!(node_txn[0], $commitment_tx.clone()); - check_spends!(node_txn[1], $commitment_tx.clone()); + check_spends!(node_txn[0], $commitment_tx); + check_spends!(node_txn[1], $commitment_tx); if $htlc_offered { assert_eq!(node_txn[0], node_txn[5]); assert_eq!(node_txn[1], node_txn[6]); @@ -2502,9 +2521,9 @@ fn test_htlc_on_chain_success() { assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment } - check_spends!(node_txn[2], $chan_tx.clone()); - check_spends!(node_txn[3], node_txn[2].clone()); - check_spends!(node_txn[4], node_txn[2].clone()); + check_spends!(node_txn[2], $chan_tx); + check_spends!(node_txn[3], node_txn[2]); + check_spends!(node_txn[4], node_txn[2]); assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), 71); assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); @@ -2522,19 +2541,20 @@ fn test_htlc_on_chain_success() { // 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_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_1.3.clone()); + let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); + check_spends!(commitment_tx[0], chan_1.3); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 3 (commitment tx + HTLC-Sucess * 2), ChannelMonitor : 1 (HTLC-Success) assert_eq!(node_txn.len(), 4); - check_spends!(node_txn[0], commitment_tx[0].clone()); + check_spends!(node_txn[0], commitment_tx[0]); assert_eq!(node_txn[0].input.len(), 2); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[0].input[1].witness.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()); + check_spends!(node_txn[1], chan_1.3); assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71); check_spends!(node_txn[2], node_txn[1]); check_spends!(node_txn[3], node_txn[1]); @@ -2544,6 +2564,7 @@ fn test_htlc_on_chain_success() { // Verify that A's ChannelManager is able to extract preimage from preimage tx and generate PaymentSent nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone(), node_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 2); let mut first_claimed = false; @@ -2590,8 +2611,8 @@ fn test_htlc_on_chain_timeout() { 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 - let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_2.3.clone()); + let commitment_tx = get_local_commitment_txn!(nodes[2], chan_2.2); + check_spends!(commitment_tx[0], chan_2.3); nodes[2].node.fail_htlc_backwards(&payment_hash); check_added_monitors!(nodes[2], 0); expect_pending_htlcs_forwardable!(nodes[2]); @@ -2611,9 +2632,10 @@ fn test_htlc_on_chain_timeout() { }; nodes[2].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); check_closed_broadcast!(nodes[2], false); + check_added_monitors!(nodes[2], 1); 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()); + check_spends!(node_txn[0], chan_2.3); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), 71); // Broadcast timeout transaction by B on received output from C's commitment tx on B's chain @@ -2623,27 +2645,26 @@ fn test_htlc_on_chain_timeout() { { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 7); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : (local commitment tx + HTLC-timeout) * 2 (block-rescan), timeout tx - assert_eq!(node_txn[1], node_txn[3]); - assert_eq!(node_txn[1], node_txn[5]); - assert_eq!(node_txn[2], node_txn[4]); - assert_eq!(node_txn[2], node_txn[6]); - 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(); + assert_eq!(node_txn[0], node_txn[3]); + assert_eq!(node_txn[0], node_txn[5]); + assert_eq!(node_txn[1], node_txn[4]); + assert_eq!(node_txn[1], node_txn[6]); + + check_spends!(node_txn[2], commitment_tx[0]); + assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + + check_spends!(node_txn[0], chan_2.3); + check_spends!(node_txn[1], node_txn[0]); + assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), 71); + assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + + timeout_tx = node_txn[2].clone(); node_txn.clear(); } nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![timeout_tx]}, 1); connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); - check_added_monitors!(nodes[1], 0); + check_added_monitors!(nodes[1], 1); check_closed_broadcast!(nodes[1], false); expect_pending_htlcs_forwardable!(nodes[1]); @@ -2664,17 +2685,18 @@ fn test_htlc_on_chain_timeout() { 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_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_1.3.clone()); + let commitment_tx = get_local_commitment_txn!(nodes[1], chan_1.2); + check_spends!(commitment_tx[0], chan_1.3); nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 200); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 timeout tx assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[0], commitment_tx[0].clone()); + check_spends!(node_txn[0], commitment_tx[0]); 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()); + check_spends!(node_txn[1], chan_1.3); + check_spends!(node_txn[2], node_txn[1]); 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); } @@ -2695,7 +2717,7 @@ fn test_simple_commitment_revoked_fail_backward() { 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_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[2], chan_2.2); // Revoke the old state claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage, 3_000_000); @@ -2704,7 +2726,7 @@ fn test_simple_commitment_revoked_fail_backward() { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); - check_added_monitors!(nodes[1], 0); + check_added_monitors!(nodes[1], 1); check_closed_broadcast!(nodes[1], false); expect_pending_htlcs_forwardable!(nodes[1]); @@ -2766,7 +2788,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], if no_to_remote { 10_000 } else { 3_000_000 }); // Get the will-be-revoked local txn from nodes[2] - let revoked_local_txn = nodes[2].node.channel_state.lock().unwrap().by_id.get_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[2], chan_2.2); assert_eq!(revoked_local_txn[0].output.len(), if no_to_remote { 1 } else { 2 }); // Revoke the old state claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage, if no_to_remote { 10_000 } else { 3_000_000}); @@ -2859,6 +2881,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + check_added_monitors!(nodes[1], 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(); @@ -2978,6 +3001,7 @@ fn test_htlc_ignore_latest_remote_commitment() { route_payment(&nodes[0], &[&nodes[1]], 10000000); nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 2); @@ -2985,6 +3009,7 @@ fn test_htlc_ignore_latest_remote_commitment() { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone(), node_txn[1].clone()]}, 1); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); // Duplicate the block_connected call since this may happen due to other listeners // registering new transactions @@ -3036,6 +3061,7 @@ fn test_force_close_fail_back() { nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id); check_closed_broadcast!(nodes[2], false); + check_added_monitors!(nodes[2], 1); let tx = { let mut node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap(); // Note that we don't bother broadcasting the HTLC-Success transaction here as we don't @@ -3050,6 +3076,7 @@ fn test_force_close_fail_back() { // Note no UpdateHTLCs event here from nodes[1] to nodes[0]! check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); // Now check that if we add the preimage to ChannelMonitor it broadcasts our HTLC-Success.. { @@ -3095,6 +3122,7 @@ fn test_unconf_chan() { height -= 1; } check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let channel_state = nodes[0].node.channel_state.lock().unwrap(); assert_eq!(channel_state.by_id.len(), 0); assert_eq!(channel_state.short_to_id.len(), 0); @@ -3811,6 +3839,13 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { create_announced_chan_between_nodes(&nodes, 2, 0, InitFeatures::supported(), InitFeatures::supported()); let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, InitFeatures::supported(), InitFeatures::supported()); + let mut node_0_stale_monitors_serialized = Vec::new(); + for monitor in nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter() { + let mut writer = test_utils::TestVecWriter(Vec::new()); + monitor.1.write_for_disk(&mut writer).unwrap(); + node_0_stale_monitors_serialized.push(writer.0); + } + let (our_payment_preimage, _) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000); // Serialize the ChannelManager here, but the monitor we keep up-to-date @@ -3833,6 +3868,15 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), &fee_estimator); nodes[0].chan_monitor = &new_chan_monitor; + + let mut node_0_stale_monitors = Vec::new(); + for serialized in node_0_stale_monitors_serialized.iter() { + let mut read = &serialized[..]; + let (_, monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut read, Arc::new(test_utils::TestLogger::new())).unwrap(); + assert!(read.is_empty()); + node_0_stale_monitors.push(monitor); + } + let mut node_0_monitors = Vec::new(); for serialized in node_0_monitors_serialized.iter() { let mut read = &serialized[..]; @@ -3841,9 +3885,25 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { node_0_monitors.push(monitor); } - let mut nodes_0_read = &nodes_0_serialized[..]; keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())); - let (_, nodes_0_deserialized_tmp) = <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + + let mut nodes_0_read = &nodes_0_serialized[..]; + if let Err(msgs::DecodeError::InvalidValue) = + <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + default_config: UserConfig::default(), + keys_manager: &keys_manager, + fee_estimator: &fee_estimator, + monitor: nodes[0].chan_monitor, + tx_broadcaster: nodes[0].tx_broadcaster.clone(), + logger: Arc::new(test_utils::TestLogger::new()), + channel_monitors: &mut node_0_stale_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().unwrap(), monitor) }).collect(), + }) { } else { + panic!("If the monitor(s) are stale, this indicates a bug and we should get an Err return"); + }; + + let mut nodes_0_read = &nodes_0_serialized[..]; + let (_, nodes_0_deserialized_tmp) = + <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: UserConfig::default(), keys_manager: &keys_manager, fee_estimator: &fee_estimator, @@ -3949,7 +4009,7 @@ macro_rules! check_spendable_outputs { let local_delaysig = secp_ctx.sign(&sighash, key); spend_tx.input[0].witness.push(local_delaysig.serialize_der().to_vec()); spend_tx.input[0].witness[0].push(SigHashType::All as u8); - spend_tx.input[0].witness.push(vec!(0)); + spend_tx.input[0].witness.push(vec!()); spend_tx.input[0].witness.push(witness_script.clone().into_bytes()); txn.push(spend_tx); }, @@ -4013,16 +4073,19 @@ fn test_claim_sizeable_push_msat() { let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000, InitFeatures::supported(), InitFeatures::supported()); nodes[1].node.force_close_channel(&chan.2); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan.3.clone()); + check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); // We can't force trimming of to_remote output as channel_reserve_satoshis block us to do so at channel opening let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 1); - check_spends!(spend_txn[0], node_txn[0].clone()); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4037,19 +4100,23 @@ fn test_claim_on_remote_sizeable_push_msat() { let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000, InitFeatures::supported(), InitFeatures::supported()); nodes[0].node.force_close_channel(&chan.2); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan.3.clone()); + check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); // We can't force trimming of to_remote output as channel_reserve_satoshis block us to do so at channel opening let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4064,22 +4131,26 @@ fn test_claim_on_remote_revoked_sizeable_push_msat() { let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000, InitFeatures::supported(), InitFeatures::supported()); 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_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan.2); assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid()); claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 3_000_000); - let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + 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 spend_txn = check_spendable_outputs!(nodes[1], 1); - assert_eq!(spend_txn.len(), 4); - assert_eq!(spend_txn[0], spend_txn[2]); // to_remote output on revoked remote commitment_tx - check_spends!(spend_txn[0], revoked_local_txn[0].clone()); - assert_eq!(spend_txn[1], spend_txn[3]); // to_local output on local commitment tx - check_spends!(spend_txn[1], node_txn[0].clone()); + assert_eq!(spend_txn.len(), 3); + assert_eq!(spend_txn[0], spend_txn[1]); // to_remote output on revoked remote commitment_tx + check_spends!(spend_txn[0], revoked_local_txn[0]); + check_spends!(spend_txn[2], node_txn[0]); } #[test] @@ -4094,7 +4165,7 @@ fn test_static_spendable_outputs_preimage_tx() { let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; - let commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + 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()); @@ -4103,6 +4174,7 @@ fn test_static_spendable_outputs_preimage_tx() { assert!(nodes[1].node.claim_funds(payment_preimage, 3_000_000)); check_added_monitors!(nodes[1], 1); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()] }, 1); + check_added_monitors!(nodes[1], 1); let events = nodes[1].node.get_and_clear_pending_msg_events(); match events[0] { MessageSendEvent::UpdateHTLCs { .. } => {}, @@ -4116,16 +4188,72 @@ fn test_static_spendable_outputs_preimage_tx() { // Check B's monitor was able to send back output descriptor event for preimage tx on A's commitment tx let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelManager : 2 (local commitment tx + HTLC-Success), ChannelMonitor: preimage tx assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[0], commitment_tx[0].clone()); + check_spends!(node_txn[0], commitment_tx[0]); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); -eprintln!("{:?}", node_txn[1]); + check_spends!(node_txn[1], chan_1.3); + 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 spend_txn = check_spendable_outputs!(nodes[1], 1); + assert_eq!(spend_txn.len(), 1); + 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 spend_txn = check_spendable_outputs!(nodes[1], 1); // , 0, 0, 1, 1); - assert_eq!(spend_txn.len(), 2); - assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); + 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] @@ -4139,25 +4267,29 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); 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.iter_mut().next().unwrap().1.channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); 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, 3_000_000); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 2); assert_eq!(node_txn[0].input.len(), 2); - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + + 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 spend_txn = check_spendable_outputs!(nodes[1], 1); - assert_eq!(spend_txn.len(), 2); - assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); + assert_eq!(spend_txn.len(), 1); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4171,7 +4303,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); 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_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid()); @@ -4181,30 +4313,40 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { // A will generate HTLC-Timeout from revoked commitment tx nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 3); assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]); assert_eq!(revoked_htlc_txn[0].input.len(), 1); assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); - check_spends!(revoked_htlc_txn[1], chan_1.3.clone()); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); + check_spends!(revoked_htlc_txn[1], chan_1.3); // B will generate justice tx from A's revoked commitment/HTLC tx - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 4 ); // ChannelMonitor: justice tx on revoked commitment, justice tx on revoked HTLC-timeout, adjusted justice tx, ChannelManager: local commitment tx + assert_eq!(node_txn.len(), 4); // ChannelMonitor: justice tx on revoked commitment, justice tx on revoked HTLC-timeout, adjusted justice tx, ChannelManager: local commitment tx + assert_eq!(node_txn[0].input.len(), 2); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], chan_1.3); assert_eq!(node_txn[2].input.len(), 1); - check_spends!(node_txn[2], revoked_htlc_txn[0].clone()); + check_spends!(node_txn[2], revoked_htlc_txn[0]); + assert_eq!(node_txn[3].input.len(), 1); + check_spends!(node_txn[3], revoked_local_txn[0]); + + 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(), node_txn[2].clone()] }, 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); // Check B's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[1], 1); - assert_eq!(spend_txn.len(), 3); - assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); - check_spends!(spend_txn[2], node_txn[2].clone()); + assert_eq!(spend_txn.len(), 2); + check_spends!(spend_txn[0], node_txn[0]); + check_spends!(spend_txn[1], node_txn[2]); } #[test] @@ -4218,7 +4360,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); 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_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan_1.2); assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid()); @@ -4228,31 +4370,37 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { // B will generate HTLC-Success from revoked commitment tx nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 3); assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]); assert_eq!(revoked_htlc_txn[0].input.len(), 1); assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); // A will generate justice tx from B's revoked commitment/HTLC tx nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 3); // ChannelMonitor: justice tx on revoked commitment, justice tx on revoked HTLC-success, ChannelManager: local commitment tx assert_eq!(node_txn[2].input.len(), 1); - check_spends!(node_txn[2], revoked_htlc_txn[0].clone()); + check_spends!(node_txn[2], revoked_htlc_txn[0]); + + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[0].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone(), node_txn[2].clone()] }, 1); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); // Check A's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[0], 1); - assert_eq!(spend_txn.len(), 5); + assert_eq!(spend_txn.len(), 5); // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking + assert_eq!(spend_txn[0], spend_txn[1]); assert_eq!(spend_txn[0], spend_txn[2]); - assert_eq!(spend_txn[1], spend_txn[3]); - check_spends!(spend_txn[0], revoked_local_txn[0].clone()); // spending to_remote output from revoked local tx - check_spends!(spend_txn[1], node_txn[0].clone()); // spending justice tx output from revoked local tx htlc received output - check_spends!(spend_txn[4], node_txn[2].clone()); // spending justice tx output on htlc success tx + check_spends!(spend_txn[0], revoked_local_txn[0]); // spending to_remote output from revoked local tx + check_spends!(spend_txn[3], node_txn[0]); // spending justice tx output from revoked local tx htlc received output + check_spends!(spend_txn[4], node_txn[2]); // spending justice tx output on htlc success tx } #[test] @@ -4280,8 +4428,8 @@ fn test_onchain_to_onchain_claim() { 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_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_2.3.clone()); + let commitment_tx = get_local_commitment_txn!(nodes[2], chan_2.2); + check_spends!(commitment_tx[0], chan_2.3); nodes[2].node.claim_funds(payment_preimage, 3_000_000); check_added_monitors!(nodes[2], 1); let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id()); @@ -4292,14 +4440,15 @@ fn test_onchain_to_onchain_claim() { nodes[2].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); check_closed_broadcast!(nodes[2], false); + check_added_monitors!(nodes[2], 1); 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(), 4); assert_eq!(c_txn[0], c_txn[2]); assert_eq!(c_txn[0], c_txn[3]); 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()); + check_spends!(c_txn[1], chan_2.3); + check_spends!(c_txn[2], c_txn[1]); 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 @@ -4312,16 +4461,17 @@ fn test_onchain_to_onchain_claim() { // ChannelMonitor: claim tx, ChannelManager: local commitment tx + HTLC-timeout tx assert_eq!(b_txn.len(), 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 + check_spends!(b_txn[2], b_txn[1]); // 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 + check_spends!(b_txn[0], c_txn[1]); // 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(); } + check_added_monitors!(nodes[1], 1); let msg_events = nodes[1].node.get_and_clear_pending_msg_events(); check_added_monitors!(nodes[1], 1); match msg_events[0] { @@ -4339,19 +4489,20 @@ fn test_onchain_to_onchain_claim() { _ => 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_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); let b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelMonitor: HTLC-Success tx, ChannelManager: local commitment tx + HTLC-Success tx assert_eq!(b_txn.len(), 3); check_spends!(b_txn[1], chan_1.3); - check_spends!(b_txn[2], b_txn[1].clone()); - check_spends!(b_txn[0], commitment_tx[0].clone()); + check_spends!(b_txn[2], b_txn[1]); + check_spends!(b_txn[0], commitment_tx[0]); 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[0].lock_time, 0); // Success tx check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); } #[test] @@ -4370,35 +4521,36 @@ fn test_duplicate_payment_hash_one_failure_one_success() { *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_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let commitment_txn = get_local_commitment_txn!(nodes[2], chan_2.2); assert_eq!(commitment_txn[0].input.len(), 1); - check_spends!(commitment_txn[0], chan_2.3.clone()); + check_spends!(commitment_txn[0], chan_2.3); let header = BlockHeader { version: 0x20000000, 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_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); let htlc_timeout_tx; { // Extract one of the two HTLC-Timeout transaction let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelMonitor: timeout tx * 2, ChannelManager: local commitment tx + HTLC-timeout * 2 assert_eq!(node_txn.len(), 5); - check_spends!(node_txn[0], commitment_txn[0].clone()); + check_spends!(node_txn[0], commitment_txn[0]); assert_eq!(node_txn[0].input.len(), 1); - check_spends!(node_txn[1], commitment_txn[0].clone()); + check_spends!(node_txn[1], commitment_txn[0]); assert_eq!(node_txn[1].input.len(), 1); assert_ne!(node_txn[0].input[0], node_txn[1].input[0]); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - 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()); + check_spends!(node_txn[2], chan_2.3); + check_spends!(node_txn[3], node_txn[2]); + check_spends!(node_txn[4], node_txn[2]); htlc_timeout_tx = node_txn[1].clone(); } nodes[2].node.claim_funds(our_payment_preimage, 900_000); nodes[2].block_notifier.block_connected(&Block { header, txdata: vec![commitment_txn[0].clone()] }, 1); - check_added_monitors!(nodes[2], 2); + check_added_monitors!(nodes[2], 3); let events = nodes[2].node.get_and_clear_pending_msg_events(); match events[0] { MessageSendEvent::UpdateHTLCs { .. } => {}, @@ -4410,7 +4562,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() { } let htlc_success_txn: Vec<_> = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); assert_eq!(htlc_success_txn.len(), 7); - check_spends!(htlc_success_txn[2], chan_2.3.clone()); + check_spends!(htlc_success_txn[2], chan_2.3); check_spends!(htlc_success_txn[3], htlc_success_txn[2]); check_spends!(htlc_success_txn[4], htlc_success_txn[2]); assert_eq!(htlc_success_txn[0], htlc_success_txn[5]); @@ -4420,8 +4572,8 @@ fn test_duplicate_payment_hash_one_failure_one_success() { 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()); + check_spends!(htlc_success_txn[0], commitment_txn[0]); + check_spends!(htlc_success_txn[1], commitment_txn[0]); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![htlc_timeout_tx] }, 200); connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash()); @@ -4487,15 +4639,16 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0; - let local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let local_txn = get_local_commitment_txn!(nodes[1], chan_1.2); assert_eq!(local_txn[0].input.len(), 1); - check_spends!(local_txn[0], chan_1.3.clone()); + check_spends!(local_txn[0], chan_1.3); // Give B knowledge of preimage to be able to generate a local HTLC-Success Tx nodes[1].node.claim_funds(payment_preimage, 9_000_000); check_added_monitors!(nodes[1], 1); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![local_txn[0].clone()] }, 1); + check_added_monitors!(nodes[1], 1); let events = nodes[1].node.get_and_clear_pending_msg_events(); match events[0] { MessageSendEvent::UpdateHTLCs { .. } => {}, @@ -4505,16 +4658,23 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() { MessageSendEvent::BroadcastChannelUpdate { .. } => {}, _ => panic!("Unexepected event"), } - let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0].clone()); + let node_txn = { + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn[0].input.len(), 1); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[0], local_txn[0]); + vec![node_txn[0].clone(), node_txn[2].clone()] + }; + + let header_201 = 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_201, txdata: node_txn.clone() }, 201); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash()); // Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); - check_spends!(spend_txn[0], node_txn[0].clone()); - check_spends!(spend_txn[1], node_txn[2].clone()); + check_spends!(spend_txn[0], node_txn[0]); + check_spends!(spend_txn[1], node_txn[1]); } fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, announce_latest: bool) { @@ -4544,7 +4704,7 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno // Rebalance and check output sanity... send_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 500000, 500_000); send_payment(&nodes[1], &[&nodes[2], &nodes[3], &nodes[5]], 500000, 500_000); - assert_eq!(nodes[3].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn()[0].output.len(), 2); + assert_eq!(get_local_commitment_txn!(nodes[3], chan.2)[0].output.len(), 2); let ds_dust_limit = nodes[3].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().our_dust_limit_satoshis; // 0th HTLC: @@ -4581,8 +4741,8 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno // Double-check that six of the new HTLC were added // We now have six HTLCs pending over the dust limit and six HTLCs under the dust limit (ie, // with to_local and to_remote outputs, 8 outputs and 6 HTLCs not included). - assert_eq!(nodes[3].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn().len(), 1); - assert_eq!(nodes[3].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn()[0].output.len(), 8); + assert_eq!(get_local_commitment_txn!(nodes[3], chan.2).len(), 1); + assert_eq!(get_local_commitment_txn!(nodes[3], chan.2)[0].output.len(), 8); // Now fail back three of the over-dust-limit and three of the under-dust-limit payments in one go. // Fail 0th below-dust, 4th above-dust, 8th above-dust, 10th below-dust HTLCs @@ -4613,7 +4773,7 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno nodes[3].node.handle_update_fail_htlc(&nodes[5].node.get_our_node_id(), &two_removes.update_fail_htlcs[1]); commitment_signed_dance!(nodes[3], nodes[5], two_removes.commitment_signed, false); - let ds_prev_commitment_tx = nodes[3].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let ds_prev_commitment_tx = get_local_commitment_txn!(nodes[3], chan.2); expect_pending_htlcs_forwardable!(nodes[3]); check_added_monitors!(nodes[3], 1); @@ -4641,7 +4801,7 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno // // Alternatively, we may broadcast the previous commitment transaction, which should only // result in failures for the below-dust HTLCs, ie the 0th, 1st, 2nd, 3rd, 9th, and 10th HTLCs. - let ds_last_commitment_tx = nodes[3].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let ds_last_commitment_tx = get_local_commitment_txn!(nodes[3], chan.2); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; if announce_latest { @@ -4652,7 +4812,7 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno connect_blocks(&nodes[2].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); check_closed_broadcast!(nodes[2], false); expect_pending_htlcs_forwardable!(nodes[2]); - check_added_monitors!(nodes[2], 2); + check_added_monitors!(nodes[2], 3); let cs_msgs = nodes[2].node.get_and_clear_pending_msg_events(); assert_eq!(cs_msgs.len(), 2); @@ -4780,32 +4940,43 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { // Create some initial channels let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); - route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0; - let local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let (_, our_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000); + let local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); assert_eq!(local_txn[0].input.len(), 1); - check_spends!(local_txn[0], chan_1.3.clone()); + check_spends!(local_txn[0], chan_1.3); // Timeout HTLC on A's chain and so it can generate a HTLC-Timeout tx let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![local_txn[0].clone()] }, 200); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); - let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0].clone()); + let htlc_timeout = { + let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn[0].input.len(), 1); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[0], local_txn[0]); + node_txn[0].clone() + }; + + let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[0].block_notifier.block_connected(&Block { header: header_201, txdata: vec![htlc_timeout.clone()] }, 201); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash()); + let events = nodes[0].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"), + } // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor let spend_txn = check_spendable_outputs!(nodes[0], 1); - assert_eq!(spend_txn.len(), 8); - assert_eq!(spend_txn[0], spend_txn[2]); - assert_eq!(spend_txn[0], spend_txn[4]); - assert_eq!(spend_txn[0], spend_txn[6]); - assert_eq!(spend_txn[1], spend_txn[3]); - assert_eq!(spend_txn[1], spend_txn[5]); - assert_eq!(spend_txn[1], spend_txn[7]); - check_spends!(spend_txn[0], local_txn[0].clone()); - check_spends!(spend_txn[1], node_txn[0].clone()); + assert_eq!(spend_txn.len(), 3); + assert_eq!(spend_txn[0], spend_txn[1]); + check_spends!(spend_txn[0], local_txn[0]); + check_spends!(spend_txn[2], htlc_timeout); } #[test] @@ -4821,12 +4992,16 @@ fn test_static_output_closing_tx() { let closing_tx = close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true).2; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1); + nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[0], 2); assert_eq!(spend_txn.len(), 1); - check_spends!(spend_txn[0], closing_tx.clone()); + check_spends!(spend_txn[0], closing_tx); + + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash()); - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1); let spend_txn = check_spendable_outputs!(nodes[1], 2); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], closing_tx); @@ -4870,6 +5045,7 @@ fn do_htlc_claim_local_commitment_only(use_dust: bool) { } test_txn_broadcast(&nodes[1], &chan, None, if use_dust { HTLCType::NONE } else { HTLCType::SUCCESS }); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); } fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) { @@ -4898,6 +5074,7 @@ fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) { } test_txn_broadcast(&nodes[0], &chan, None, HTLCType::NONE); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); } fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no_close: bool) { @@ -4941,6 +5118,7 @@ fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no if !check_revoke_no_close { test_txn_broadcast(&nodes[0], &chan, None, HTLCType::NONE); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); } else { let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); @@ -5442,12 +5620,12 @@ fn bolt2_open_channel_sending_node_checks_part1() { //This test needs to be on i // BOLT #2 spec: Sending node must ensure temporary_channel_id is unique from any other channel ID with the same peer. let channel_value_satoshis=10000; let push_msat=10001; - nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).unwrap(); + nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None).unwrap(); let node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::supported(), &node0_to_1_send_open_channel); //Create a second channel with a channel_id collision - assert!(nodes[0].node.create_channel(nodes[0].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).is_err()); + assert!(nodes[0].node.create_channel(nodes[0].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None).is_err()); } #[test] @@ -5460,18 +5638,18 @@ fn bolt2_open_channel_sending_node_checks_part2() { // BOLT #2 spec: Sending node must set funding_satoshis to less than 2^24 satoshis let channel_value_satoshis=2^24; let push_msat=10001; - assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).is_err()); + assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None).is_err()); // BOLT #2 spec: Sending node must set push_msat to equal or less than 1000 * funding_satoshis let channel_value_satoshis=10000; // Test when push_msat is equal to 1000 * funding_satoshis. let push_msat=1000*channel_value_satoshis+1; - assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).is_err()); + assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None).is_err()); // BOLT #2 spec: Sending node must set set channel_reserve_satoshis greater than or equal to dust_limit_satoshis let channel_value_satoshis=10000; let push_msat=10001; - assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).is_ok()); //Create a valid channel + assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None).is_ok()); //Create a valid channel let node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); assert!(node0_to_1_send_open_channel.channel_reserve_satoshis>=node0_to_1_send_open_channel.dust_limit_satoshis); @@ -5501,7 +5679,6 @@ fn bolt2_open_channel_sending_node_checks_part2() { #[test] fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { - //BOLT2 Requirement: MUST offer amount_msat greater than 0. //BOLT2 Requirement: MUST NOT offer amount_msat below the receiving node's htlc_minimum_msat (same validation check catches both of these) let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -5511,7 +5688,7 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { let mut route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); - route.hops[0].fee_msat = 0; + route.hops[0].fee_msat = 100; let err = nodes[0].node.send_payment(route, our_payment_hash); @@ -5524,6 +5701,52 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send less than their minimum HTLC value".to_string(), 1); } +#[test] +fn test_update_add_htlc_bolt2_sender_zero_value_msat() { + //BOLT2 Requirement: MUST offer amount_msat greater than 0. + 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, 100000, 95000000, InitFeatures::supported(), InitFeatures::supported()); + let mut route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + + route.hops[0].fee_msat = 0; + + let err = nodes[0].node.send_payment(route, our_payment_hash); + + if let Err(APIError::ChannelUnavailable{err}) = err { + assert_eq!(err, "Cannot send 0-msat HTLC"); + } else { + assert!(false); + } + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); + nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send 0-msat HTLC".to_string(), 1); +} + +#[test] +fn test_update_add_htlc_bolt2_receiver_zero_value_msat() { + //BOLT2 Requirement: MUST offer amount_msat greater than 0. + 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, 100000, 95000000, InitFeatures::supported(), InitFeatures::supported()); + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + updates.update_add_htlcs[0].amount_msat = 0; + + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); + nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Remote side tried to send a 0-msat HTLC".to_string(), 1); + check_closed_broadcast!(nodes[1], true).unwrap(); + check_added_monitors!(nodes[1], 1); +} + #[test] fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { //BOLT 2 Requirement: MUST set cltv_expiry less than 500000000. @@ -5646,6 +5869,7 @@ fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { assert!(nodes[1].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data, "Remote side tried to send less than our minimum HTLC value"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -5671,6 +5895,7 @@ fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { assert!(nodes[1].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data, "Remote HTLC add would put them over their reserve value"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -5716,6 +5941,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { assert!(nodes[1].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data, "Remote tried to push more than our max accepted HTLCs"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -5737,6 +5963,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { assert!(nodes[1].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data,"Remote HTLC add would put them over our max HTLC value"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -5758,6 +5985,7 @@ fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { assert!(nodes[1].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data,"Remote provided CLTV expiry in seconds instead of block height"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -5803,6 +6031,7 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { assert!(nodes[1].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[1], true).unwrap(); assert_eq!(err_msg.data, "Remote skipped HTLC ID"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -5833,6 +6062,7 @@ fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() { assert!(nodes[0].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[0], true).unwrap(); assert_eq!(err_msg.data, "Remote tried to fulfill/fail HTLC before it had been committed"); + check_added_monitors!(nodes[0], 1); } #[test] @@ -5863,6 +6093,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() { assert!(nodes[0].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[0], true).unwrap(); assert_eq!(err_msg.data, "Remote tried to fulfill/fail HTLC before it had been committed"); + check_added_monitors!(nodes[0], 1); } #[test] @@ -5894,6 +6125,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() assert!(nodes[0].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[0], true).unwrap(); assert_eq!(err_msg.data, "Remote tried to fulfill/fail HTLC before it had been committed"); + check_added_monitors!(nodes[0], 1); } #[test] @@ -5934,6 +6166,7 @@ fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() { assert!(nodes[0].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[0], true).unwrap(); assert_eq!(err_msg.data, "Remote tried to fulfill/fail an HTLC we couldn't find"); + check_added_monitors!(nodes[0], 1); } #[test] @@ -5974,9 +6207,9 @@ fn test_update_fulfill_htlc_bolt2_wrong_preimage() { assert!(nodes[0].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[0], true).unwrap(); assert_eq!(err_msg.data, "Remote tried to fulfill HTLC with an incorrect preimage"); + check_added_monitors!(nodes[0], 1); } - #[test] fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_message() { //BOLT 2 Requirement: A receiving node: if the BADONION bit in failure_code is not set for update_fail_malformed_htlc MUST fail the channel. @@ -6019,6 +6252,7 @@ fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_messag assert!(nodes[0].node.list_channels().is_empty()); let err_msg = check_closed_broadcast!(nodes[0], true).unwrap(); assert_eq!(err_msg.data, "Got update_fail_malformed_htlc with BADONION not set"); + check_added_monitors!(nodes[0], 1); } #[test] @@ -6118,7 +6352,7 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) { route_payment(&nodes[0], &[&nodes[1]], 1000000); // Cache one local commitment tx as previous - let as_prev_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let as_prev_commitment_tx = get_local_commitment_txn!(nodes[0], chan.2); // Fail one HTLC to prune it in the will-be-latest-local commitment tx assert!(nodes[1].node.fail_htlc_backwards(&payment_hash_2)); @@ -6132,7 +6366,7 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) { check_added_monitors!(nodes[0], 1); // Cache one local commitment tx as lastest - let as_last_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let as_last_commitment_tx = get_local_commitment_txn!(nodes[0], chan.2); let events = nodes[0].node.get_and_clear_pending_msg_events(); match events[0] { @@ -6158,12 +6392,8 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) { nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![as_prev_commitment_tx[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"), - } + check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); @@ -6265,8 +6495,8 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { let (_payment_preimage_1, dust_hash) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000); let (_payment_preimage_2, non_dust_hash) = route_payment(&nodes[0], &[&nodes[1]], 1000000); - let as_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - let bs_commitment_tx = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let as_commitment_tx = get_local_commitment_txn!(nodes[0], chan.2); + let bs_commitment_tx = get_local_commitment_txn!(nodes[1], chan.2); // We revoked bs_commitment_tx if revoked { @@ -6279,12 +6509,8 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { if local { // We fail dust-HTLC 1 by broadcast of local commitment tx nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![as_commitment_tx[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"), - } + check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone()); let parent_hash = connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 2, true, header.bitcoin_hash()); @@ -6314,13 +6540,9 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { } else { // We fail dust-HTLC 1 by broadcast of remote commitment tx. If revoked, fail also non-dust HTLC nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![bs_commitment_tx[0].clone()]}, 1); + check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - let events = nodes[0].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 1); - match events[0] { - MessageSendEvent::BroadcastChannelUpdate { .. } => {}, - _ => panic!("Unexpected event"), - } timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone()); let parent_hash = connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 2, true, header.bitcoin_hash()); let header_2 = BlockHeader { version: 0x20000000, prev_blockhash: parent_hash, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; @@ -6401,20 +6623,8 @@ fn test_upfront_shutdown_script() { node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh(); // Test we enforce upfront_scriptpbukey if by providing a diffrent one at closing that we disconnect peer nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown); - let events = nodes[2].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 2); - match events[0] { - MessageSendEvent::BroadcastChannelUpdate { .. } => {}, - _ => panic!("Unexpected event"), - } - if let MessageSendEvent::HandleError { ref action, .. } = events[1] { - match action { - &ErrorAction::SendErrorMessage { ref msg } => { - assert_eq!(msg.data,"Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey"); - }, - _ => { assert!(false); } - } - } else { assert!(false); } + assert_eq!(check_closed_broadcast!(nodes[2], true).unwrap().data, "Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey"); + check_added_monitors!(nodes[2], 1); // We test that in case of peer committing upfront to a script, if it doesn't change at closing, we sign let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone()); @@ -6501,7 +6711,7 @@ fn test_user_configurable_csv_delay() { } else { assert!(false) } // We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in Channel::new_from_req() - nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42).unwrap(); + nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42, None).unwrap(); let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id()); open_channel.to_self_delay = 200; if let Err(error) = Channel::new_from_req(&&test_utils::TestFeeEstimator { sat_per_kw: 253 }, &keys_manager, nodes[1].node.get_our_node_id(), InitFeatures::supported(), &open_channel, 0, Arc::new(test_utils::TestLogger::new()), &low_our_to_self_config) { @@ -6512,7 +6722,7 @@ fn test_user_configurable_csv_delay() { } else { assert!(false); } // We test msg.to_self_delay <= config.their_to_self_delay is enforced in Chanel::accept_channel() - nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1000000, 1000000, 42).unwrap(); + nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1000000, 1000000, 42, None).unwrap(); nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::supported(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id())); let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()); accept_channel.to_self_delay = 200; @@ -6527,7 +6737,7 @@ fn test_user_configurable_csv_delay() { } else { assert!(false); } // We test msg.to_self_delay <= config.their_to_self_delay is enforced in Channel::new_from_req() - nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42).unwrap(); + nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42, None).unwrap(); let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id()); open_channel.to_self_delay = 200; if let Err(error) = Channel::new_from_req(&&test_utils::TestFeeEstimator { sat_per_kw: 253 }, &keys_manager, nodes[1].node.get_our_node_id(), InitFeatures::supported(), &open_channel, 0, Arc::new(test_utils::TestLogger::new()), &high_their_to_self_config) { @@ -6571,7 +6781,7 @@ fn test_data_loss_protect() { let logger: Arc = Arc::new(test_utils::TestLogger::with_id(format!("node {}", 0))); let mut chan_monitor = <(Sha256dHash, ChannelMonitor)>::read(&mut ::std::io::Cursor::new(previous_chan_monitor_state.0), Arc::clone(&logger)).unwrap().1; let chain_monitor = Arc::new(ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&logger))); - tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), broadcasted_txn: Mutex::new(HashSet::new())}; + tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::clone(&logger)); monitor = test_utils::TestChannelMonitor::new(chain_monitor.clone(), &tx_broadcaster, logger.clone(), &fee_estimator); @@ -6606,7 +6816,7 @@ fn test_data_loss_protect() { // Check we update monitor following learning of per_commitment_point from B nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_0[0]); - check_added_monitors!(nodes[0], 1); + check_added_monitors!(nodes[0], 2); { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); @@ -6633,33 +6843,21 @@ fn test_data_loss_protect() { // Check we close channel detecting A is fallen-behind nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]); - let events = nodes[1].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 2); - match events[0] { - MessageSendEvent::BroadcastChannelUpdate { .. } => {}, - _ => panic!("Unexpected event"), - } - match events [1] { - MessageSendEvent::HandleError { ref action, .. } => { - match action { - &ErrorAction::SendErrorMessage { ref msg } => { - assert_eq!(msg.data, "Peer attempted to reestablish channel with a very old local commitment transaction"); }, - _ => panic!("Unexpected event!"), - } - }, - _ => panic!("Unexpected event"), - } + assert_eq!(check_closed_broadcast!(nodes[1], true).unwrap().data, "Peer attempted to reestablish channel with a very old local commitment transaction"); + check_added_monitors!(nodes[1], 1); + // Check A is able to claim to_remote output let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan.3.clone()); + check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; - nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 1); + nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 0); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash()); let spend_txn = check_spendable_outputs!(nodes[0], 1); assert_eq!(spend_txn.len(), 1); - check_spends!(spend_txn[0], node_txn[0].clone()); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -6789,7 +6987,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 3000000, 30).unwrap(); send_along_route(&nodes[1], route, &vec!(&nodes[0])[..], 3000000); - let revoked_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_txn = get_local_commitment_txn!(nodes[0], chan.2); // Revoked commitment txn with 4 outputs : to_local, to_remote, 1 outgoing HTLC, 1 incoming HTLC assert_eq!(revoked_txn[0].output.len(), 4); assert_eq!(revoked_txn[0].input.len(), 1); @@ -6810,6 +7008,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 3_000_000); let header = BlockHeader { version: 0x20000000, prev_blockhash: header_114, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_txn[0].clone()] }, 115); + check_added_monitors!(nodes[1], 1); // One or more justice tx should have been broadcast, check it let penalty_1; @@ -6819,7 +7018,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { assert_eq!(node_txn.len(), 3); // justice tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout (broadcasted from ChannelManager) assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); - check_spends!(node_txn[0], revoked_txn[0].clone()); + check_spends!(node_txn[0], revoked_txn[0]); let fee_1 = penalty_sum - node_txn[0].output[0].value; feerate_1 = fee_1 * 1000 / node_txn[0].get_weight() as u64; penalty_1 = node_txn[0].txid(); @@ -6836,7 +7035,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { if node_txn[0].input[0].previous_output.txid == revoked_txid { assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); - check_spends!(node_txn[0], revoked_txn[0].clone()); + check_spends!(node_txn[0], revoked_txn[0]); penalty_2 = node_txn[0].txid(); // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast assert_ne!(penalty_2, penalty_1); @@ -6859,7 +7058,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { if node_txn[0].input[0].previous_output.txid == revoked_txid { assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); - check_spends!(node_txn[0], revoked_txn[0].clone()); + check_spends!(node_txn[0], revoked_txn[0]); penalty_3 = node_txn[0].txid(); // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast assert_ne!(penalty_3, penalty_2); @@ -6891,7 +7090,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3_000_000).0; route_payment(&nodes[1], &vec!(&nodes[0])[..], 3_000_000).0; - let revoked_local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan.2); assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid()); @@ -6902,117 +7101,75 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { // B will generate both revoked HTLC-timeout/HTLC-preimage txn from revoked commitment tx nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); - let mut received = ::std::usize::MAX; - let mut offered = ::std::usize::MAX; let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 6); if revoked_htlc_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { assert_eq!(revoked_htlc_txn[0].input.len(), 1); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); assert_eq!(revoked_htlc_txn[1].input.len(), 1); assert_eq!(revoked_htlc_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0].clone()); - received = 0; - offered = 1; + check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); } else if revoked_htlc_txn[1].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { assert_eq!(revoked_htlc_txn[1].input.len(), 1); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0].clone()); + check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); assert_eq!(revoked_htlc_txn[0].input.len(), 1); assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); - received = 1; - offered = 0; + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); } // Broadcast set of revoked txn on A - let header_128 = connect_blocks(&nodes[0].block_notifier, 128, 0, true, header.bitcoin_hash()); + let header_128 = connect_blocks(&nodes[0].block_notifier, 128, 0, true, header.bitcoin_hash()); let header_129 = BlockHeader { version: 0x20000000, prev_blockhash: header_128, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header: header_129, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone(), revoked_htlc_txn[1].clone()] }, 129); let first; - let second; let feerate_1; - let feerate_2; + let penalty_txn; { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 6); // 3 penalty txn on revoked commitment tx + A commitment tx + 2 penalty tnx on revoked HTLC txn + assert_eq!(node_txn.len(), 5); // 3 penalty txn on revoked commitment tx + A commitment tx + 1 penalty tnx on revoked HTLC txn // Verify claim tx are spending revoked HTLC txn - assert_eq!(node_txn[4].input.len(), 1); + assert_eq!(node_txn[4].input.len(), 2); assert_eq!(node_txn[4].output.len(), 1); - check_spends!(node_txn[4], revoked_htlc_txn[0].clone()); + check_spends!(node_txn[4], revoked_htlc_txn[0], revoked_htlc_txn[1]); first = node_txn[4].txid(); - assert_eq!(node_txn[5].input.len(), 1); - assert_eq!(node_txn[5].output.len(), 1); - check_spends!(node_txn[5], revoked_htlc_txn[1].clone()); - second = node_txn[5].txid(); // Store both feerates for later comparison - let fee_1 = revoked_htlc_txn[0].output[0].value - node_txn[4].output[0].value; + let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[1].output[0].value - node_txn[4].output[0].value; feerate_1 = fee_1 * 1000 / node_txn[4].get_weight() as u64; - let fee_2 = revoked_htlc_txn[1].output[0].value - node_txn[5].output[0].value; - feerate_2 = fee_2 * 1000 / node_txn[5].get_weight() as u64; + penalty_txn = vec![node_txn[0].clone(), node_txn[1].clone(), node_txn[2].clone()]; node_txn.clear(); } // Connect three more block to see if bumped penalty are issued for HTLC txn - let header_132 = connect_blocks(&nodes[0].block_notifier, 3, 129, true, header_129.bitcoin_hash()); - let penalty_local_tx; + let header_130 = BlockHeader { version: 0x20000000, prev_blockhash: header_129.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[0].block_notifier.block_connected(&Block { header: header_130, txdata: penalty_txn }, 130); { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 3); // 2 bumped penalty txn on offered/received HTLC outputs of revoked commitment tx + 1 penalty tx on to_local of revoked commitment tx + 2 bumped penalty tx on revoked HTLC txn + assert_eq!(node_txn.len(), 2); // 2 bumped penalty txn on revoked commitment tx - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - check_spends!(node_txn[1], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], revoked_local_txn[0]); - check_spends!(node_txn[2], revoked_local_txn[0].clone()); - - penalty_local_tx = node_txn[2].clone(); node_txn.clear(); }; - // Few more blocks to broadcast and confirm penalty_local_tx - let header_133 = BlockHeader { version: 0x20000000, prev_blockhash: header_132, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[0].block_notifier.block_connected(&Block { header: header_133, txdata: vec![penalty_local_tx] }, 133); - let header_135 = connect_blocks(&nodes[0].block_notifier, 2, 133, true, header_133.bitcoin_hash()); - { - let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - node_txn.clear(); - } + + // Few more blocks to confirm penalty txn + let header_135 = connect_blocks(&nodes[0].block_notifier, 5, 130, true, header_130.bitcoin_hash()); + assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty()); let header_144 = connect_blocks(&nodes[0].block_notifier, 9, 135, true, header_135); let node_txn = { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); - - let mut penalty_offered = ::std::usize::MAX; - let mut penalty_received = ::std::usize::MAX; - - { - for (i, tx) in node_txn.iter().enumerate() { - if tx.input[0].previous_output.txid == revoked_htlc_txn[offered].txid() { - penalty_offered = i; - } else if tx.input[0].previous_output.txid == revoked_htlc_txn[received].txid() { - penalty_received = i; - } - } - } + assert_eq!(node_txn.len(), 1); - assert_eq!(node_txn[penalty_received].input.len(), 1); - assert_eq!(node_txn[penalty_received].output.len(), 1); - assert_eq!(node_txn[penalty_offered].input.len(), 1); - assert_eq!(node_txn[penalty_offered].output.len(), 1); + assert_eq!(node_txn[0].input.len(), 2); + check_spends!(node_txn[0], revoked_htlc_txn[0], revoked_htlc_txn[1]); // Verify bumped tx is different and 25% bump heuristic - check_spends!(node_txn[penalty_offered], revoked_htlc_txn[offered].clone()); - assert_ne!(first, node_txn[penalty_offered].txid()); - let fee = revoked_htlc_txn[offered].output[0].value - node_txn[penalty_offered].output[0].value; - let new_feerate = fee * 1000 / node_txn[penalty_offered].get_weight() as u64; - assert!(new_feerate * 100 > feerate_1 * 125); - - check_spends!(node_txn[penalty_received], revoked_htlc_txn[received].clone()); - assert_ne!(second, node_txn[penalty_received].txid()); - let fee = revoked_htlc_txn[received].output[0].value - node_txn[penalty_received].output[0].value; - let new_feerate = fee * 1000 / node_txn[penalty_received].get_weight() as u64; - assert!(new_feerate * 100 > feerate_2 * 125); - let txn = vec![node_txn[0].clone(), node_txn[1].clone()]; + assert_ne!(first, node_txn[0].txid()); + let fee_2 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[1].output[0].value - node_txn[0].output[0].value; + let feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64; + assert!(feerate_2 * 100 > feerate_1 * 125); + let txn = vec![node_txn[0].clone()]; node_txn.clear(); txn }; @@ -7022,10 +7179,17 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { connect_blocks(&nodes[0].block_notifier, 20, 145, true, header_145.bitcoin_hash()); { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); //TODO: fix check_spend_remote_htlc lack of watch output + // We verify than no new transaction has been broadcast because previously + // we were buggy on this exact behavior by not tracking for monitoring remote HTLC outputs (see #411) + // which means we wouldn't see a spend of them by a justice tx and bumped justice tx + // were generated forever instead of safe cleaning after confirmation and ANTI_REORG_SAFE_DELAY blocks. + // Enforce spending of revoked htlc output by claiming transaction remove request as expected and dry + // up bumped justice generation. + assert_eq!(node_txn.len(), 0); node_txn.clear(); } check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); } #[test] @@ -7047,7 +7211,7 @@ fn test_bump_penalty_txn_on_remote_commitment() { route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000).0; // Remote commitment txn with 4 outputs : to_local, to_remote, 1 outgoing HTLC, 1 incoming HTLC - let remote_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let remote_txn = get_local_commitment_txn!(nodes[0], chan.2); assert_eq!(remote_txn[0].output.len(), 4); assert_eq!(remote_txn[0].input.len(), 1); assert_eq!(remote_txn[0].input[0].previous_output.txid, chan.3.txid()); @@ -7056,7 +7220,7 @@ fn test_bump_penalty_txn_on_remote_commitment() { nodes[1].node.claim_funds(payment_preimage, 3_000_000); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![remote_txn[0].clone()] }, 1); - check_added_monitors!(nodes[1], 1); + check_added_monitors!(nodes[1], 2); // One or more claim tx should have been broadcast, check it let timeout; @@ -7068,8 +7232,8 @@ fn test_bump_penalty_txn_on_remote_commitment() { assert_eq!(node_txn.len(), 5); // 2 * claim tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout + local HTLC-success (broadcasted from ChannelManager) assert_eq!(node_txn[0].input.len(), 1); assert_eq!(node_txn[1].input.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); - check_spends!(node_txn[1], remote_txn[0].clone()); + check_spends!(node_txn[0], remote_txn[0]); + check_spends!(node_txn[1], remote_txn[0]); check_spends!(node_txn[2], chan.3); check_spends!(node_txn[3], node_txn[2]); check_spends!(node_txn[4], node_txn[2]); @@ -7106,8 +7270,8 @@ fn test_bump_penalty_txn_on_remote_commitment() { assert_eq!(node_txn.len(), 2); assert_eq!(node_txn[0].input.len(), 1); assert_eq!(node_txn[1].input.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); - check_spends!(node_txn[1], remote_txn[0].clone()); + check_spends!(node_txn[0], remote_txn[0]); + check_spends!(node_txn[1], remote_txn[0]); if node_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { let index = node_txn[0].input[0].previous_output.vout; let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; @@ -7155,13 +7319,13 @@ fn test_set_outpoints_partial_claiming() { let payment_preimage_2 = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3_000_000).0; // Remote commitment txn with 4 outputs: to_local, to_remote, 2 outgoing HTLC - let remote_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let remote_txn = get_local_commitment_txn!(nodes[1], chan.2); assert_eq!(remote_txn.len(), 3); assert_eq!(remote_txn[0].output.len(), 4); assert_eq!(remote_txn[0].input.len(), 1); assert_eq!(remote_txn[0].input[0].previous_output.txid, chan.3.txid()); - check_spends!(remote_txn[1], remote_txn[0].clone()); - check_spends!(remote_txn[2], remote_txn[0].clone()); + check_spends!(remote_txn[1], remote_txn[0]); + check_spends!(remote_txn[2], remote_txn[0]); // Connect blocks on node A to advance height towards TEST_FINAL_CLTV let prev_header_100 = connect_blocks(&nodes[1].block_notifier, 100, 0, false, Default::default()); @@ -7175,33 +7339,35 @@ fn test_set_outpoints_partial_claiming() { // Connect blocks on node A commitment transaction let header = BlockHeader { version: 0x20000000, prev_blockhash: prev_header_100, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![remote_txn[0].clone()] }, 101); + check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); // Verify node A broadcast tx claiming both HTLCs { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelMonitor: claim tx, ChannelManager: local commitment tx + HTLC-Success*2 assert_eq!(node_txn.len(), 4); - check_spends!(node_txn[0], remote_txn[0].clone()); - check_spends!(node_txn[1], chan.3.clone()); + check_spends!(node_txn[0], remote_txn[0]); + check_spends!(node_txn[1], chan.3); check_spends!(node_txn[2], node_txn[1]); check_spends!(node_txn[3], node_txn[1]); assert_eq!(node_txn[0].input.len(), 2); node_txn.clear(); } - nodes[0].node.get_and_clear_pending_msg_events(); // Connect blocks on node B connect_blocks(&nodes[1].block_notifier, 135, 0, false, Default::default()); + check_closed_broadcast!(nodes[1], false); + check_added_monitors!(nodes[1], 1); // Verify node B broadcast 2 HTLC-timeout txn let partial_claim_tx = { let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[1], node_txn[0].clone()); - check_spends!(node_txn[2], node_txn[0].clone()); + check_spends!(node_txn[1], node_txn[0]); + check_spends!(node_txn[2], node_txn[0]); assert_eq!(node_txn[1].input.len(), 1); assert_eq!(node_txn[2].input.len(), 1); node_txn[1].clone() }; - nodes[1].node.get_and_clear_pending_msg_events(); // Broadcast partial claim on node A, should regenerate a claiming tx with HTLC dropped let header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; @@ -7209,7 +7375,7 @@ fn test_set_outpoints_partial_claiming() { { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); + check_spends!(node_txn[0], remote_txn[0]); assert_eq!(node_txn[0].input.len(), 1); //dropped HTLC node_txn.clear(); } @@ -7220,7 +7386,7 @@ fn test_set_outpoints_partial_claiming() { { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); + check_spends!(node_txn[0], remote_txn[0]); assert_eq!(node_txn[0].input.len(), 2); //resurrected HTLC node_txn.clear(); } @@ -7260,6 +7426,7 @@ fn test_counterparty_raa_skip_no_crash() { nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &msgs::RevokeAndACK { channel_id, per_commitment_secret, next_per_commitment_point }); assert_eq!(check_closed_broadcast!(nodes[1], true).unwrap().data, "Received an unexpected revoke_and_ack"); + check_added_monitors!(nodes[1], 1); } #[test] @@ -7277,7 +7444,7 @@ fn test_bump_txn_sanitize_tracking_maps() { let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9_000_000).0; route_payment(&nodes[1], &vec!(&nodes[0])[..], 9_000_000).0; - let revoked_local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); + let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan.2); assert_eq!(revoked_local_txn[0].input.len(), 1); assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid()); @@ -7289,12 +7456,13 @@ fn test_bump_txn_sanitize_tracking_maps() { let header_129 = BlockHeader { version: 0x20000000, prev_blockhash: header_128, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header: header_129, txdata: vec![revoked_local_txn[0].clone()] }, 129); check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); let penalty_txn = { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 4); //ChannelMonitor: justice txn * 3, ChannelManager: local commitment tx - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - check_spends!(node_txn[1], revoked_local_txn[0].clone()); - check_spends!(node_txn[2], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], revoked_local_txn[0]); + check_spends!(node_txn[2], revoked_local_txn[0]); let penalty_txn = vec![node_txn[0].clone(), node_txn[1].clone(), node_txn[2].clone()]; node_txn.clear(); penalty_txn @@ -7305,8 +7473,45 @@ fn test_bump_txn_sanitize_tracking_maps() { { let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap(); if let Some(monitor) = monitors.get(&OutPoint::new(chan.3.txid(), 0)) { - assert!(monitor.pending_claim_requests.is_empty()); - assert!(monitor.claimable_outpoints.is_empty()); + assert!(monitor.onchain_tx_handler.pending_claim_requests.is_empty()); + assert!(monitor.onchain_tx_handler.claimable_outpoints.is_empty()); } } } + +#[test] +fn test_override_channel_config() { + 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); + + // Node0 initiates a channel to node1 using the override config. + let mut override_config = UserConfig::default(); + override_config.own_channel_config.our_to_self_delay = 200; + + nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 16_000_000, 12_000_000, 42, Some(override_config)).unwrap(); + + // Assert the channel created by node0 is using the override config. + let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); + assert_eq!(res.channel_flags, 0); + assert_eq!(res.to_self_delay, 200); +} + +#[test] +fn test_override_0msat_htlc_minimum() { + let mut zero_config = UserConfig::default(); + zero_config.own_channel_config.our_htlc_minimum_msat = 0; + 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, Some(zero_config.clone())]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 16_000_000, 12_000_000, 42, Some(zero_config)).unwrap(); + let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); + assert_eq!(res.htlc_minimum_msat, 1); + + nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::supported(), &res); + let res = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()); + assert_eq!(res.htlc_minimum_msat, 1); +}