Skip to content

Commit c1a0a00

Browse files
committed
Scan onchain_events_awaiting_threshold_conf once in balance calc
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.
1 parent 32f834c commit c1a0a00

File tree

1 file changed

+65
-50
lines changed

1 file changed

+65
-50
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 65 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,67 +1438,82 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
14381438
($holder_commitment: expr, $htlc_iter: expr) => {
14391439
for htlc in $htlc_iter {
14401440
if let Some(htlc_commitment_tx_output_idx) = htlc.transaction_output_index {
1441-
if let Some(conf_thresh) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
1442-
if let OnchainEvent::MaturingOutput { descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) } = &event.event {
1443-
if descriptor.outpoint.index as u32 == htlc_commitment_tx_output_idx { Some(event.confirmation_threshold()) } else { None }
1444-
} else { None }
1445-
}) {
1441+
let mut htlc_update_pending = None;
1442+
let mut htlc_spend_pending = None;
1443+
let mut delayed_output_pending = None;
1444+
for event in us.onchain_events_awaiting_threshold_conf.iter() {
1445+
match event.event {
1446+
OnchainEvent::HTLCUpdate { commitment_tx_output_idx, htlc_value_satoshis, .. }
1447+
if commitment_tx_output_idx == Some(htlc_commitment_tx_output_idx) => {
1448+
debug_assert!(htlc_update_pending.is_none());
1449+
htlc_update_pending =
1450+
Some((htlc_value_satoshis.unwrap(), event.confirmation_threshold()));
1451+
},
1452+
OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
1453+
if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
1454+
debug_assert!(htlc_spend_pending.is_none());
1455+
htlc_spend_pending = Some((event.confirmation_threshold(), preimage.is_some()));
1456+
},
1457+
OnchainEvent::MaturingOutput {
1458+
descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(ref descriptor) }
1459+
if descriptor.outpoint.index as u32 == htlc_commitment_tx_output_idx => {
1460+
debug_assert!(delayed_output_pending.is_none());
1461+
delayed_output_pending = Some(event.confirmation_threshold());
1462+
},
1463+
_ => {},
1464+
}
1465+
}
1466+
let htlc_resolved = us.htlcs_resolved_on_chain.iter()
1467+
.find(|v| v.commitment_tx_output_idx == htlc_commitment_tx_output_idx);
1468+
debug_assert!(htlc_update_pending.is_some() as u8 + htlc_spend_pending.is_some() as u8 + htlc_resolved.is_some() as u8 <= 1);
1469+
1470+
if let Some(conf_thresh) = delayed_output_pending {
14461471
debug_assert!($holder_commitment);
14471472
res.push(Balance::ClaimableAwaitingConfirmations {
14481473
claimable_amount_satoshis: htlc.amount_msat / 1000,
14491474
confirmation_height: conf_thresh,
14501475
});
1451-
} else if us.htlcs_resolved_on_chain.iter().any(|v| v.commitment_tx_output_idx == htlc_commitment_tx_output_idx) {
1476+
} else if htlc_resolved.is_some() {
14521477
// Funding transaction spends should be fully confirmed by the time any
14531478
// HTLC transactions are resolved, unless we're talking about a holder
14541479
// commitment tx, whose resolution is delayed until the CSV timeout is
14551480
// reached, even though HTLCs may be resolved after only
14561481
// ANTI_REORG_DELAY confirmations.
14571482
debug_assert!($holder_commitment || us.funding_spend_confirmed.is_some());
1458-
} else if htlc.offered == $holder_commitment {
1459-
// If the payment was outbound, check if there's an HTLCUpdate
1460-
// indicating we have spent this HTLC with a timeout, claiming it back
1461-
// and awaiting confirmations on it.
1462-
let htlc_update_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
1463-
if let OnchainEvent::HTLCUpdate { commitment_tx_output_idx: Some(commitment_tx_output_idx), .. } = event.event {
1464-
if commitment_tx_output_idx == htlc_commitment_tx_output_idx {
1465-
Some(event.confirmation_threshold()) } else { None }
1466-
} else { None }
1467-
});
1468-
if let Some(conf_thresh) = htlc_update_pending {
1469-
res.push(Balance::ClaimableAwaitingConfirmations {
1470-
claimable_amount_satoshis: htlc.amount_msat / 1000,
1471-
confirmation_height: conf_thresh,
1472-
});
1473-
} else {
1474-
res.push(Balance::MaybeClaimableHTLCAwaitingTimeout {
1475-
claimable_amount_satoshis: htlc.amount_msat / 1000,
1476-
claimable_height: htlc.cltv_expiry,
1477-
});
1478-
}
1479-
} else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
1480-
// Otherwise (the payment was inbound), only expose it as claimable if
1481-
// we know the preimage.
1482-
// Note that if there is a pending claim, but it did not use the
1483-
// preimage, we lost funds to our counterparty! We will then continue
1484-
// to show it as ContentiousClaimable until ANTI_REORG_DELAY.
1485-
let htlc_spend_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
1486-
if let OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } = event.event {
1487-
if commitment_tx_output_idx == htlc_commitment_tx_output_idx {
1488-
Some((event.confirmation_threshold(), preimage.is_some()))
1489-
} else { None }
1490-
} else { None }
1491-
});
1492-
if let Some((conf_thresh, true)) = htlc_spend_pending {
1493-
res.push(Balance::ClaimableAwaitingConfirmations {
1494-
claimable_amount_satoshis: htlc.amount_msat / 1000,
1495-
confirmation_height: conf_thresh,
1496-
});
1497-
} else {
1498-
res.push(Balance::ContentiousClaimable {
1499-
claimable_amount_satoshis: htlc.amount_msat / 1000,
1500-
timeout_height: htlc.cltv_expiry,
1501-
});
1483+
} else {
1484+
if htlc.offered == $holder_commitment {
1485+
// If the payment was outbound, check if there's an HTLCUpdate
1486+
// indicating we have spent this HTLC with a timeout, claiming it back
1487+
// and awaiting confirmations on it.
1488+
if let Some((value, conf_thresh)) = htlc_update_pending {
1489+
res.push(Balance::ClaimableAwaitingConfirmations {
1490+
claimable_amount_satoshis: value,
1491+
confirmation_height: conf_thresh,
1492+
});
1493+
} else {
1494+
res.push(Balance::MaybeClaimableHTLCAwaitingTimeout {
1495+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1496+
claimable_height: htlc.cltv_expiry,
1497+
});
1498+
}
1499+
} else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
1500+
// Otherwise (the payment was inbound), only expose it as claimable if
1501+
// we know the preimage.
1502+
// Note that if there is a pending claim, but it did not use the
1503+
// preimage, we lost funds to our counterparty! We will then continue
1504+
// to show it as ContentiousClaimable until ANTI_REORG_DELAY.
1505+
debug_assert!(htlc_update_pending.is_none());
1506+
if let Some((conf_thresh, true)) = htlc_spend_pending {
1507+
res.push(Balance::ClaimableAwaitingConfirmations {
1508+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1509+
confirmation_height: conf_thresh,
1510+
});
1511+
} else {
1512+
res.push(Balance::ContentiousClaimable {
1513+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1514+
timeout_height: htlc.cltv_expiry,
1515+
});
1516+
}
15021517
}
15031518
}
15041519
}

0 commit comments

Comments
 (0)