]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Scan `onchain_events_awaiting_threshold_conf` once in balance calc
authorMatt Corallo <git@bluematt.me>
Tue, 17 May 2022 20:45:17 +0000 (20:45 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 15 Aug 2022 23:18:12 +0000 (23:18 +0000)
Instead of a series of different
`onchain_events_awaiting_threshold_conf.iter()...` calls to scan
for HTLC status in balance calculation, pull them all out into one
`for ... { match ... }` to do it once and simplify the code
somewhat.

lightning/src/chain/channelmonitor.rs

index 377657d6bca0ad974c87ee7d939710ea94a00a1d..f08895718f18f9ca8b4774d353e8b3e47156e172 100644 (file)
@@ -1449,67 +1449,82 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                        ($holder_commitment: expr, $htlc_iter: expr) => {
                                for htlc in $htlc_iter {
                                        if let Some(htlc_commitment_tx_output_idx) = htlc.transaction_output_index {
-                                               if let Some(conf_thresh) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
-                                                       if let OnchainEvent::MaturingOutput { descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) } = &event.event {
-                                                               if descriptor.outpoint.index as u32 == htlc_commitment_tx_output_idx { Some(event.confirmation_threshold()) } else { None }
-                                                       } else { None }
-                                               }) {
+                                               let mut htlc_update_pending = None;
+                                               let mut htlc_spend_pending = None;
+                                               let mut delayed_output_pending = None;
+                                               for event in us.onchain_events_awaiting_threshold_conf.iter() {
+                                                       match event.event {
+                                                               OnchainEvent::HTLCUpdate { commitment_tx_output_idx, htlc_value_satoshis, .. }
+                                                               if commitment_tx_output_idx == Some(htlc_commitment_tx_output_idx) => {
+                                                                       debug_assert!(htlc_update_pending.is_none());
+                                                                       htlc_update_pending =
+                                                                               Some((htlc_value_satoshis.unwrap(), event.confirmation_threshold()));
+                                                               },
+                                                               OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
+                                                               if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
+                                                                       debug_assert!(htlc_spend_pending.is_none());
+                                                                       htlc_spend_pending = Some((event.confirmation_threshold(), preimage.is_some()));
+                                                               },
+                                                               OnchainEvent::MaturingOutput {
+                                                                       descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(ref descriptor) }
+                                                               if descriptor.outpoint.index as u32 == htlc_commitment_tx_output_idx => {
+                                                                       debug_assert!(delayed_output_pending.is_none());
+                                                                       delayed_output_pending = Some(event.confirmation_threshold());
+                                                               },
+                                                               _ => {},
+                                                       }
+                                               }
+                                               let htlc_resolved = us.htlcs_resolved_on_chain.iter()
+                                                       .find(|v| v.commitment_tx_output_idx == htlc_commitment_tx_output_idx);
+                                               debug_assert!(htlc_update_pending.is_some() as u8 + htlc_spend_pending.is_some() as u8 + htlc_resolved.is_some() as u8 <= 1);
+
+                                               if let Some(conf_thresh) = delayed_output_pending {
                                                        debug_assert!($holder_commitment);
                                                        res.push(Balance::ClaimableAwaitingConfirmations {
                                                                claimable_amount_satoshis: htlc.amount_msat / 1000,
                                                                confirmation_height: conf_thresh,
                                                        });
-                                               } else if us.htlcs_resolved_on_chain.iter().any(|v| v.commitment_tx_output_idx == htlc_commitment_tx_output_idx) {
+                                               } else if htlc_resolved.is_some() {
                                                        // Funding transaction spends should be fully confirmed by the time any
                                                        // HTLC transactions are resolved, unless we're talking about a holder
                                                        // commitment tx, whose resolution is delayed until the CSV timeout is
                                                        // reached, even though HTLCs may be resolved after only
                                                        // ANTI_REORG_DELAY confirmations.
                                                        debug_assert!($holder_commitment || us.funding_spend_confirmed.is_some());
-                                               } else if htlc.offered == $holder_commitment {
-                                                       // If the payment was outbound, check if there's an HTLCUpdate
-                                                       // indicating we have spent this HTLC with a timeout, claiming it back
-                                                       // and awaiting confirmations on it.
-                                                       let htlc_update_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
-                                                               if let OnchainEvent::HTLCUpdate { commitment_tx_output_idx: Some(commitment_tx_output_idx), .. } = event.event {
-                                                                       if commitment_tx_output_idx == htlc_commitment_tx_output_idx {
-                                                                               Some(event.confirmation_threshold()) } else { None }
-                                                               } else { None }
-                                                       });
-                                                       if let Some(conf_thresh) = htlc_update_pending {
-                                                               res.push(Balance::ClaimableAwaitingConfirmations {
-                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
-                                                                       confirmation_height: conf_thresh,
-                                                               });
-                                                       } else {
-                                                               res.push(Balance::MaybeClaimableHTLCAwaitingTimeout {
-                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
-                                                                       claimable_height: htlc.cltv_expiry,
-                                                               });
-                                                       }
-                                               } else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
-                                                       // 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
-                                                       // preimage, we lost funds to our counterparty! We will then continue
-                                                       // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
-                                                       let htlc_spend_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
-                                                               if let OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } = event.event {
-                                                                       if commitment_tx_output_idx == htlc_commitment_tx_output_idx {
-                                                                               Some((event.confirmation_threshold(), preimage.is_some()))
-                                                                       } else { None }
-                                                               } else { None }
-                                                       });
-                                                       if let Some((conf_thresh, true)) = htlc_spend_pending {
-                                                               res.push(Balance::ClaimableAwaitingConfirmations {
-                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
-                                                                       confirmation_height: conf_thresh,
-                                                               });
-                                                       } else {
-                                                               res.push(Balance::ContentiousClaimable {
-                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
-                                                                       timeout_height: htlc.cltv_expiry,
-                                                               });
+                                               } else {
+                                                       if htlc.offered == $holder_commitment {
+                                                               // If the payment was outbound, check if there's an HTLCUpdate
+                                                               // indicating we have spent this HTLC with a timeout, claiming it back
+                                                               // and awaiting confirmations on it.
+                                                               if let Some((value, conf_thresh)) = htlc_update_pending {
+                                                                       res.push(Balance::ClaimableAwaitingConfirmations {
+                                                                               claimable_amount_satoshis: value,
+                                                                               confirmation_height: conf_thresh,
+                                                                       });
+                                                               } else {
+                                                                       res.push(Balance::MaybeClaimableHTLCAwaitingTimeout {
+                                                                               claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                               claimable_height: htlc.cltv_expiry,
+                                                                       });
+                                                               }
+                                                       } else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
+                                                               // 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
+                                                               // preimage, we lost funds to our counterparty! We will then continue
+                                                               // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
+                                                               debug_assert!(htlc_update_pending.is_none());
+                                                               if let Some((conf_thresh, true)) = htlc_spend_pending {
+                                                                       res.push(Balance::ClaimableAwaitingConfirmations {
+                                                                               claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                               confirmation_height: conf_thresh,
+                                                                       });
+                                                               } else {
+                                                                       res.push(Balance::ContentiousClaimable {
+                                                                               claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                               timeout_height: htlc.cltv_expiry,
+                                                                       });
+                                                               }
                                                        }
                                                }
                                        }