From 53c79711b4c6ecc9715463398ec8c5e1c4806ffc Mon Sep 17 00:00:00 2001 From: Alec Chen Date: Sat, 22 Apr 2023 23:04:26 -0500 Subject: [PATCH 1/5] Add `PartialOrd`, `Ord` to `PaymentHash`, `PaymentPreimage` for tests --- lightning/src/ln/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 340213c5150..3a0efd38690 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -73,11 +73,13 @@ pub use self::peer_channel_encryptor::LN_MAX_MSG_LEN; /// /// This is not exported to bindings users as we just use [u8; 32] directly #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] +#[cfg_attr(test, derive(PartialOrd, Ord))] pub struct PaymentHash(pub [u8; 32]); /// payment_preimage type, use to route payment between hop /// /// This is not exported to bindings users as we just use [u8; 32] directly #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] +#[cfg_attr(test, derive(PartialOrd, Ord))] pub struct PaymentPreimage(pub [u8; 32]); /// payment_secret type, use to authenticate sender to the receiver and tie MPP HTLCs together /// From 84da915a12912d031a7fef4cb232627fae0b74fc Mon Sep 17 00:00:00 2001 From: Alec Chen Date: Sun, 23 Apr 2023 00:37:13 -0500 Subject: [PATCH 2/5] DRY up repeated HTLC `Balance`s in tests This makes it easier to add a new field on the `Balance` variants. --- lightning/src/ln/monitor_tests.rs | 225 +++++++++++------------------- 1 file changed, 78 insertions(+), 147 deletions(-) diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index d09f4229c8c..f8508a829bc 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -298,28 +298,41 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id); let remote_txn = get_local_commitment_txn!(nodes[1], chan_id); + let sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { + claimable_amount_satoshis: 3_000, + claimable_height: htlc_cltv_timeout, + }; + let sent_htlc_timeout_balance = Balance::MaybeTimeoutClaimableHTLC { + claimable_amount_satoshis: 4_000, + claimable_height: htlc_cltv_timeout, + }; + let received_htlc_balance = Balance::MaybePreimageClaimableHTLC { + claimable_amount_satoshis: 3_000, + expiry_height: htlc_cltv_timeout, + }; + let received_htlc_timeout_balance = Balance::MaybePreimageClaimableHTLC { + claimable_amount_satoshis: 4_000, + expiry_height: htlc_cltv_timeout, + }; + let received_htlc_claiming_balance = Balance::ContentiousClaimable { + claimable_amount_satoshis: 3_000, + timeout_height: htlc_cltv_timeout, + }; + let received_htlc_timeout_claiming_balance = Balance::ContentiousClaimable { + claimable_amount_satoshis: 4_000, + timeout_height: htlc_cltv_timeout, + }; + // Before B receives the payment preimage, it only suggests the push_msat value of 1_000 sats // as claimable. A lists both its to-self balance and the (possibly-claimable) HTLCs. assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose { claimable_amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 3_000, - claimable_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 4_000, - claimable_height: htlc_cltv_timeout, - }]), + }, sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose { claimable_amount_satoshis: 1_000, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 3_000, - expiry_height: htlc_cltv_timeout, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 4_000, - expiry_height: htlc_cltv_timeout, - }]), + }, received_htlc_balance.clone(), received_htlc_timeout_balance.clone()]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); nodes[1].node.claim_funds(payment_preimage); @@ -364,15 +377,9 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + if prev_commitment_tx { 1 } else { 2 } * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 4_000, - claimable_height: htlc_cltv_timeout, - }]; + }, sent_htlc_timeout_balance.clone()]; if !prev_commitment_tx { - a_expected_balances.push(Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 3_000, - claimable_height: htlc_cltv_timeout, - }); + a_expected_balances.push(sent_htlc_balance.clone()); } assert_eq!(sorted_vec(a_expected_balances), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); @@ -419,13 +426,7 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { claimable_amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 3_000, - claimable_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 4_000, - claimable_height: htlc_cltv_timeout, - }]), + }, sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // The main non-HTLC balance is just awaiting confirmations, but the claimable height is the // CSV delay, not ANTI_REORG_DELAY. @@ -435,13 +436,7 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { }, // Both HTLC balances are "contentious" as our counterparty could claim them if we wait too // long. - Balance::ContentiousClaimable { - claimable_amount_satoshis: 3_000, - timeout_height: htlc_cltv_timeout, - }, Balance::ContentiousClaimable { - claimable_amount_satoshis: 4_000, - timeout_height: htlc_cltv_timeout, - }]), + received_htlc_claiming_balance.clone(), received_htlc_timeout_claiming_balance.clone()]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); @@ -450,24 +445,12 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { // After ANTI_REORG_DELAY, A will consider its balance fully spendable and generate a // `SpendableOutputs` event. However, B still has to wait for the CSV delay. - assert_eq!(sorted_vec(vec![Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 3_000, - claimable_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 4_000, - claimable_height: htlc_cltv_timeout, - }]), + assert_eq!(sorted_vec(vec![sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 1_000, confirmation_height: node_b_commitment_claimable, - }, Balance::ContentiousClaimable { - claimable_amount_satoshis: 3_000, - timeout_height: htlc_cltv_timeout, - }, Balance::ContentiousClaimable { - claimable_amount_satoshis: 4_000, - timeout_height: htlc_cltv_timeout, - }]), + }, received_htlc_claiming_balance.clone(), received_htlc_timeout_claiming_balance.clone()]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); test_spendable_output(&nodes[0], &remote_txn[0]); @@ -481,19 +464,10 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { } else { expect_payment_sent!(nodes[0], payment_preimage); } - assert_eq!(sorted_vec(vec![Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 3_000, - claimable_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 4_000, - claimable_height: htlc_cltv_timeout, - }]), + assert_eq!(sorted_vec(vec![sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); - assert_eq!(vec![Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 4_000, - claimable_height: htlc_cltv_timeout, - }], + assert_eq!(vec![sent_htlc_timeout_balance.clone()], nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()); // When the HTLC timeout output is spendable in the next block, A should broadcast it @@ -540,10 +514,7 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { }, Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 3_000, confirmation_height: node_b_htlc_claimable, - }, Balance::ContentiousClaimable { - claimable_amount_satoshis: 4_000, - timeout_height: htlc_cltv_timeout, - }]), + }, received_htlc_timeout_claiming_balance.clone()]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // After reaching the commitment output CSV, we'll get a SpendableOutputs event for it and have @@ -554,10 +525,7 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 3_000, confirmation_height: node_b_htlc_claimable, - }, Balance::ContentiousClaimable { - claimable_amount_satoshis: 4_000, - timeout_height: htlc_cltv_timeout, - }]), + }, received_htlc_timeout_claiming_balance.clone()]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // After reaching the claimed HTLC output CSV, we'll get a SpendableOutptus event for it and @@ -565,20 +533,14 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { connect_blocks(&nodes[1], node_b_htlc_claimable - nodes[1].best_block_info().1); test_spendable_output(&nodes[1], &b_broadcast_txn[0]); - assert_eq!(vec![Balance::ContentiousClaimable { - claimable_amount_satoshis: 4_000, - timeout_height: htlc_cltv_timeout, - }], + assert_eq!(vec![received_htlc_timeout_claiming_balance.clone()], nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()); // Finally, mine the HTLC timeout transaction that A broadcasted (even though B should be able // to claim this HTLC with the preimage it knows!). It will remain listed as a claimable HTLC // until ANTI_REORG_DELAY confirmations on the spend. mine_transaction(&nodes[1], &a_broadcast_txn[1]); - assert_eq!(vec![Balance::ContentiousClaimable { - claimable_amount_satoshis: 4_000, - timeout_height: htlc_cltv_timeout, - }], + assert_eq!(vec![received_htlc_timeout_claiming_balance.clone()], nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()); connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1); assert_eq!(Vec::::new(), @@ -669,17 +631,20 @@ fn test_balances_on_local_commitment_htlcs() { check_closed_broadcast!(nodes[0], true); check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed); + let htlc_balance_known_preimage = Balance::MaybeTimeoutClaimableHTLC { + claimable_amount_satoshis: 10_000, + claimable_height: htlc_cltv_timeout, + }; + let htlc_balance_unknown_preimage = Balance::MaybeTimeoutClaimableHTLC { + claimable_amount_satoshis: 20_000, + claimable_height: htlc_cltv_timeout, + }; + assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, confirmation_height: node_a_commitment_claimable, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 10_000, - claimable_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 20_000, - claimable_height: htlc_cltv_timeout, - }]), + }, htlc_balance_known_preimage.clone(), htlc_balance_unknown_preimage.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // Get nodes[1]'s HTLC claim tx for the second HTLC @@ -698,13 +663,7 @@ fn test_balances_on_local_commitment_htlcs() { claimable_amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, confirmation_height: node_a_commitment_claimable, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 10_000, - claimable_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 20_000, - claimable_height: htlc_cltv_timeout, - }]), + }, htlc_balance_known_preimage.clone(), htlc_balance_unknown_preimage.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); assert_eq!(as_txn[1].lock_time.0, nodes[0].best_block_info().1 + 1); // as_txn[1] can be included in the next block @@ -722,10 +681,7 @@ fn test_balances_on_local_commitment_htlcs() { }, Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 10_000, confirmation_height: node_a_htlc_claimable, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 20_000, - claimable_height: htlc_cltv_timeout, - }]), + }, htlc_balance_unknown_preimage.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // Now confirm nodes[1]'s HTLC claim, giving nodes[0] the preimage. Note that the "maybe @@ -739,10 +695,7 @@ fn test_balances_on_local_commitment_htlcs() { }, Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 10_000, confirmation_height: node_a_htlc_claimable, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 20_000, - claimable_height: htlc_cltv_timeout, - }]), + }, htlc_balance_unknown_preimage.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // Finally make the HTLC transactions have ANTI_REORG_DELAY blocks. This call previously @@ -806,6 +759,23 @@ fn test_no_preimage_inbound_htlc_balances() { let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64; let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id); + let a_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { + claimable_amount_satoshis: 10_000, + claimable_height: htlc_cltv_timeout, + }; + let a_received_htlc_balance = Balance::MaybePreimageClaimableHTLC { + claimable_amount_satoshis: 20_000, + expiry_height: htlc_cltv_timeout, + }; + let b_received_htlc_balance = Balance::MaybePreimageClaimableHTLC { + claimable_amount_satoshis: 10_000, + expiry_height: htlc_cltv_timeout, + }; + let b_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { + claimable_amount_satoshis: 20_000, + claimable_height: htlc_cltv_timeout, + }; + // Both A and B will have an HTLC that's claimable on timeout and one that's claimable if they // receive the preimage. These will remain the same through the channel closure and until the // HTLC output is spent. @@ -813,24 +783,12 @@ fn test_no_preimage_inbound_htlc_balances() { assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose { claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 20_000, - expiry_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 10_000, - claimable_height: htlc_cltv_timeout, - }]), + }, a_received_htlc_balance.clone(), a_sent_htlc_balance.clone()]), sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose { claimable_amount_satoshis: 500_000 - 20_000, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 10_000, - expiry_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 20_000, - claimable_height: htlc_cltv_timeout, - }]), + }, b_received_htlc_balance.clone(), b_sent_htlc_balance.clone()]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); // Get nodes[0]'s commitment transaction and HTLC-Timeout transaction @@ -846,13 +804,7 @@ fn test_no_preimage_inbound_htlc_balances() { claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, confirmation_height: node_a_commitment_claimable, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 20_000, - expiry_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 10_000, - claimable_height: htlc_cltv_timeout, - }]); + }, a_received_htlc_balance.clone(), a_sent_htlc_balance.clone()]); mine_transaction(&nodes[0], &as_txn[0]); nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear(); @@ -872,13 +824,7 @@ fn test_no_preimage_inbound_htlc_balances() { let mut bs_pre_spend_claims = sorted_vec(vec![Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 500_000 - 20_000, confirmation_height: node_b_commitment_claimable, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 10_000, - expiry_height: htlc_cltv_timeout, - }, Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis: 20_000, - claimable_height: htlc_cltv_timeout, - }]); + }, b_received_htlc_balance.clone(), b_sent_htlc_balance.clone()]); assert_eq!(bs_pre_spend_claims, sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); @@ -930,10 +876,7 @@ fn test_no_preimage_inbound_htlc_balances() { claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, confirmation_height: node_a_commitment_claimable, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 20_000, - expiry_height: htlc_cltv_timeout, - }, Balance::ClaimableAwaitingConfirmations { + }, a_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 10_000, confirmation_height: as_timeout_claimable_height, }]), @@ -944,10 +887,7 @@ fn test_no_preimage_inbound_htlc_balances() { claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000, confirmation_height: node_a_commitment_claimable, - }, Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 20_000, - expiry_height: htlc_cltv_timeout, - }, Balance::ClaimableAwaitingConfirmations { + }, a_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 10_000, confirmation_height: as_timeout_claimable_height, }]), @@ -985,20 +925,14 @@ fn test_no_preimage_inbound_htlc_balances() { // was already claimed. mine_transaction(&nodes[1], &bs_htlc_timeout_claim[0]); let bs_timeout_claimable_height = nodes[1].best_block_info().1 + ANTI_REORG_DELAY - 1; - assert_eq!(sorted_vec(vec![Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 10_000, - expiry_height: htlc_cltv_timeout, - }, Balance::ClaimableAwaitingConfirmations { + assert_eq!(sorted_vec(vec![b_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 20_000, confirmation_height: bs_timeout_claimable_height, }]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); mine_transaction(&nodes[1], &as_htlc_timeout_claim[0]); - assert_eq!(sorted_vec(vec![Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 10_000, - expiry_height: htlc_cltv_timeout, - }, Balance::ClaimableAwaitingConfirmations { + assert_eq!(sorted_vec(vec![b_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations { claimable_amount_satoshis: 20_000, confirmation_height: bs_timeout_claimable_height, }]), @@ -1007,10 +941,7 @@ fn test_no_preimage_inbound_htlc_balances() { connect_blocks(&nodes[1], ANTI_REORG_DELAY - 2); expect_payment_failed!(nodes[1], to_a_failed_payment_hash, false); - assert_eq!(vec![Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis: 10_000, - expiry_height: htlc_cltv_timeout, - }], + assert_eq!(vec![b_received_htlc_balance.clone()], nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()); test_spendable_output(&nodes[1], &bs_htlc_timeout_claim[0]); From 0f933efc58e3bd9e0dce15146671a171433199f1 Mon Sep 17 00:00:00 2001 From: Alec Chen Date: Sun, 23 Apr 2023 01:03:15 -0500 Subject: [PATCH 3/5] Add payment preimage and hash to `ContentiousClaimable` --- lightning/src/chain/channelmonitor.rs | 8 +++++++- lightning/src/ln/monitor_tests.rs | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 5ff297b1af7..00fd1405a9b 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -606,6 +606,10 @@ pub enum Balance { /// The height at which the counterparty may be able to claim the balance if we have not /// done so. timeout_height: u32, + /// The payment hash that locks this HTLC. + payment_hash: PaymentHash, + /// The preimage that can be used to claim this HTLC. + payment_preimage: PaymentPreimage, }, /// HTLCs which we sent to our counterparty which are claimable after a timeout (less on-chain /// fees) if the counterparty does not know the preimage for the HTLCs. These are somewhat @@ -1604,7 +1608,7 @@ impl ChannelMonitorImpl { claimable_height: htlc.cltv_expiry, }); } - } else if self.payment_preimages.get(&htlc.payment_hash).is_some() { + } else if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) { // Otherwise (the payment was inbound), only expose it as claimable if // we know the preimage. // Note that if there is a pending claim, but it did not use the @@ -1620,6 +1624,8 @@ impl ChannelMonitorImpl { return Some(Balance::ContentiousClaimable { claimable_amount_satoshis: htlc.amount_msat / 1000, timeout_height: htlc.cltv_expiry, + payment_hash: htlc.payment_hash, + payment_preimage: *payment_preimage, }); } } else if htlc_resolved.is_none() { diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index f8508a829bc..a5f88dfbb7d 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -317,10 +317,14 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { let received_htlc_claiming_balance = Balance::ContentiousClaimable { claimable_amount_satoshis: 3_000, timeout_height: htlc_cltv_timeout, + payment_hash, + payment_preimage, }; let received_htlc_timeout_claiming_balance = Balance::ContentiousClaimable { claimable_amount_satoshis: 4_000, timeout_height: htlc_cltv_timeout, + payment_hash: timeout_payment_hash, + payment_preimage: timeout_payment_preimage, }; // Before B receives the payment preimage, it only suggests the push_msat value of 1_000 sats From ba9e51764d1049ffbc10c9f75fb9ba1b07e810f9 Mon Sep 17 00:00:00 2001 From: Alec Chen Date: Sun, 23 Apr 2023 01:03:51 -0500 Subject: [PATCH 4/5] Add payment hash to `MaybeTimeoutClaimableHTLC` --- lightning/src/chain/channelmonitor.rs | 4 ++++ lightning/src/ln/monitor_tests.rs | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 00fd1405a9b..865b2c55cb1 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -621,6 +621,8 @@ pub enum Balance { /// The height at which we will be able to claim the balance if our counterparty has not /// done so. claimable_height: u32, + /// The payment hash whose preimage our counterparty needs to claim this HTLC. + payment_hash: PaymentHash, }, /// HTLCs which we received from our counterparty which are claimable with a preimage which we /// do not currently have. This will only be claimable if we receive the preimage from the node @@ -1606,6 +1608,7 @@ impl ChannelMonitorImpl { return Some(Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: htlc.amount_msat / 1000, claimable_height: htlc.cltv_expiry, + payment_hash: htlc.payment_hash, }); } } else if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) { @@ -1793,6 +1796,7 @@ impl ChannelMonitor { res.push(Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: htlc.amount_msat / 1000, claimable_height: htlc.cltv_expiry, + payment_hash: htlc.payment_hash, }); } else if us.payment_preimages.get(&htlc.payment_hash).is_some() { claimable_inbound_htlc_value_sat += htlc.amount_msat / 1000; diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index a5f88dfbb7d..9b5dc10da68 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -301,10 +301,12 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { let sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 3_000, claimable_height: htlc_cltv_timeout, + payment_hash, }; let sent_htlc_timeout_balance = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 4_000, claimable_height: htlc_cltv_timeout, + payment_hash: timeout_payment_hash, }; let received_htlc_balance = Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: 3_000, @@ -638,10 +640,12 @@ fn test_balances_on_local_commitment_htlcs() { let htlc_balance_known_preimage = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 10_000, claimable_height: htlc_cltv_timeout, + payment_hash, }; let htlc_balance_unknown_preimage = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 20_000, claimable_height: htlc_cltv_timeout, + payment_hash: payment_hash_2, }; assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations { @@ -766,6 +770,7 @@ fn test_no_preimage_inbound_htlc_balances() { let a_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 10_000, claimable_height: htlc_cltv_timeout, + payment_hash: to_b_failed_payment_hash, }; let a_received_htlc_balance = Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: 20_000, @@ -778,6 +783,7 @@ fn test_no_preimage_inbound_htlc_balances() { let b_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 20_000, claimable_height: htlc_cltv_timeout, + payment_hash: to_a_failed_payment_hash, }; // Both A and B will have an HTLC that's claimable on timeout and one that's claimable if they @@ -1068,12 +1074,15 @@ fn do_test_revoked_counterparty_commitment_balances(confirm_htlc_spend_first: bo }, Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 2_000, claimable_height: missing_htlc_cltv_timeout, + payment_hash: missing_htlc_payment_hash, }, Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 4_000, claimable_height: htlc_cltv_timeout, + payment_hash: timeout_payment_hash, }, Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 5_000, claimable_height: live_htlc_cltv_timeout, + payment_hash: live_payment_hash, }]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); @@ -1502,9 +1511,11 @@ fn test_revoked_counterparty_aggregated_claims() { }, Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 4_000, claimable_height: htlc_cltv_timeout, + payment_hash: revoked_payment_hash, }, Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 3_000, claimable_height: htlc_cltv_timeout, + payment_hash: claimed_payment_hash, }]), sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances())); From 29b9eb3936fa9de3cafffe05506e537d44d2a862 Mon Sep 17 00:00:00 2001 From: Alec Chen Date: Sat, 22 Apr 2023 23:21:40 -0500 Subject: [PATCH 5/5] Add payment hash to `MaybePreimageClaimableHTLC` --- lightning/src/chain/channelmonitor.rs | 4 ++++ lightning/src/ln/monitor_tests.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 865b2c55cb1..9b2b1a766bc 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -634,6 +634,8 @@ pub enum Balance { /// The height at which our counterparty will be able to claim the balance if we have not /// yet received the preimage and claimed it ourselves. expiry_height: u32, + /// The payment hash whose preimage we need to claim this HTLC. + payment_hash: PaymentHash, }, /// The channel has been closed, and our counterparty broadcasted a revoked commitment /// transaction. @@ -1635,6 +1637,7 @@ impl ChannelMonitorImpl { return Some(Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: htlc.amount_msat / 1000, expiry_height: htlc.cltv_expiry, + payment_hash: htlc.payment_hash, }); } None @@ -1806,6 +1809,7 @@ impl ChannelMonitor { res.push(Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: htlc.amount_msat / 1000, expiry_height: htlc.cltv_expiry, + payment_hash: htlc.payment_hash, }); } } diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 9b5dc10da68..9c80d566e00 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -311,10 +311,12 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) { let received_htlc_balance = Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: 3_000, expiry_height: htlc_cltv_timeout, + payment_hash, }; let received_htlc_timeout_balance = Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: 4_000, expiry_height: htlc_cltv_timeout, + payment_hash: timeout_payment_hash, }; let received_htlc_claiming_balance = Balance::ContentiousClaimable { claimable_amount_satoshis: 3_000, @@ -775,10 +777,12 @@ fn test_no_preimage_inbound_htlc_balances() { let a_received_htlc_balance = Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: 20_000, expiry_height: htlc_cltv_timeout, + payment_hash: to_a_failed_payment_hash, }; let b_received_htlc_balance = Balance::MaybePreimageClaimableHTLC { claimable_amount_satoshis: 10_000, expiry_height: htlc_cltv_timeout, + payment_hash: to_b_failed_payment_hash, }; let b_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC { claimable_amount_satoshis: 20_000,