@@ -1449,67 +1449,82 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
14491449 ( $holder_commitment: expr, $htlc_iter: expr) => {
14501450 for htlc in $htlc_iter {
14511451 if let Some ( htlc_commitment_tx_output_idx) = htlc. transaction_output_index {
1452- if let Some ( conf_thresh) = us. onchain_events_awaiting_threshold_conf. iter( ) . find_map( |event| {
1453- if let OnchainEvent :: MaturingOutput { descriptor: SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) } = & event. event {
1454- if descriptor. outpoint. index as u32 == htlc_commitment_tx_output_idx { Some ( event. confirmation_threshold( ) ) } else { None }
1455- } else { None }
1456- } ) {
1452+ let mut htlc_update_pending = None ;
1453+ let mut htlc_spend_pending = None ;
1454+ let mut delayed_output_pending = None ;
1455+ for event in us. onchain_events_awaiting_threshold_conf. iter( ) {
1456+ match event. event {
1457+ OnchainEvent :: HTLCUpdate { commitment_tx_output_idx, htlc_value_satoshis, .. }
1458+ if commitment_tx_output_idx == Some ( htlc_commitment_tx_output_idx) => {
1459+ debug_assert!( htlc_update_pending. is_none( ) ) ;
1460+ htlc_update_pending =
1461+ Some ( ( htlc_value_satoshis. unwrap( ) , event. confirmation_threshold( ) ) ) ;
1462+ } ,
1463+ OnchainEvent :: HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
1464+ if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
1465+ debug_assert!( htlc_spend_pending. is_none( ) ) ;
1466+ htlc_spend_pending = Some ( ( event. confirmation_threshold( ) , preimage. is_some( ) ) ) ;
1467+ } ,
1468+ OnchainEvent :: MaturingOutput {
1469+ descriptor: SpendableOutputDescriptor :: DelayedPaymentOutput ( ref descriptor) }
1470+ if descriptor. outpoint. index as u32 == htlc_commitment_tx_output_idx => {
1471+ debug_assert!( delayed_output_pending. is_none( ) ) ;
1472+ delayed_output_pending = Some ( event. confirmation_threshold( ) ) ;
1473+ } ,
1474+ _ => { } ,
1475+ }
1476+ }
1477+ let htlc_resolved = us. htlcs_resolved_on_chain. iter( )
1478+ . find( |v| v. commitment_tx_output_idx == htlc_commitment_tx_output_idx) ;
1479+ debug_assert!( htlc_update_pending. is_some( ) as u8 + htlc_spend_pending. is_some( ) as u8 + htlc_resolved. is_some( ) as u8 <= 1 ) ;
1480+
1481+ if let Some ( conf_thresh) = delayed_output_pending {
14571482 debug_assert!( $holder_commitment) ;
14581483 res. push( Balance :: ClaimableAwaitingConfirmations {
14591484 claimable_amount_satoshis: htlc. amount_msat / 1000 ,
14601485 confirmation_height: conf_thresh,
14611486 } ) ;
1462- } else if us . htlcs_resolved_on_chain . iter ( ) . any ( |v| v . commitment_tx_output_idx == htlc_commitment_tx_output_idx ) {
1487+ } else if htlc_resolved . is_some ( ) {
14631488 // Funding transaction spends should be fully confirmed by the time any
14641489 // HTLC transactions are resolved, unless we're talking about a holder
14651490 // commitment tx, whose resolution is delayed until the CSV timeout is
14661491 // reached, even though HTLCs may be resolved after only
14671492 // ANTI_REORG_DELAY confirmations.
14681493 debug_assert!( $holder_commitment || us. funding_spend_confirmed. is_some( ) ) ;
1469- } else if htlc. offered == $holder_commitment {
1470- // If the payment was outbound, check if there's an HTLCUpdate
1471- // indicating we have spent this HTLC with a timeout, claiming it back
1472- // and awaiting confirmations on it.
1473- let htlc_update_pending = us. onchain_events_awaiting_threshold_conf. iter( ) . find_map( |event| {
1474- if let OnchainEvent :: HTLCUpdate { commitment_tx_output_idx: Some ( commitment_tx_output_idx) , .. } = event. event {
1475- if commitment_tx_output_idx == htlc_commitment_tx_output_idx {
1476- Some ( event. confirmation_threshold( ) ) } else { None }
1477- } else { None }
1478- } ) ;
1479- if let Some ( conf_thresh) = htlc_update_pending {
1480- res. push( Balance :: ClaimableAwaitingConfirmations {
1481- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1482- confirmation_height: conf_thresh,
1483- } ) ;
1484- } else {
1485- res. push( Balance :: MaybeClaimableHTLCAwaitingTimeout {
1486- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1487- claimable_height: htlc. cltv_expiry,
1488- } ) ;
1489- }
1490- } else if us. payment_preimages. get( & htlc. payment_hash) . is_some( ) {
1491- // Otherwise (the payment was inbound), only expose it as claimable if
1492- // we know the preimage.
1493- // Note that if there is a pending claim, but it did not use the
1494- // preimage, we lost funds to our counterparty! We will then continue
1495- // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
1496- let htlc_spend_pending = us. onchain_events_awaiting_threshold_conf. iter( ) . find_map( |event| {
1497- if let OnchainEvent :: HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } = event. event {
1498- if commitment_tx_output_idx == htlc_commitment_tx_output_idx {
1499- Some ( ( event. confirmation_threshold( ) , preimage. is_some( ) ) )
1500- } else { None }
1501- } else { None }
1502- } ) ;
1503- if let Some ( ( conf_thresh, true ) ) = htlc_spend_pending {
1504- res. push( Balance :: ClaimableAwaitingConfirmations {
1505- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1506- confirmation_height: conf_thresh,
1507- } ) ;
1508- } else {
1509- res. push( Balance :: ContentiousClaimable {
1510- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1511- timeout_height: htlc. cltv_expiry,
1512- } ) ;
1494+ } else {
1495+ if htlc. offered == $holder_commitment {
1496+ // If the payment was outbound, check if there's an HTLCUpdate
1497+ // indicating we have spent this HTLC with a timeout, claiming it back
1498+ // and awaiting confirmations on it.
1499+ if let Some ( ( value, conf_thresh) ) = htlc_update_pending {
1500+ res. push( Balance :: ClaimableAwaitingConfirmations {
1501+ claimable_amount_satoshis: value,
1502+ confirmation_height: conf_thresh,
1503+ } ) ;
1504+ } else {
1505+ res. push( Balance :: MaybeClaimableHTLCAwaitingTimeout {
1506+ claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1507+ claimable_height: htlc. cltv_expiry,
1508+ } ) ;
1509+ }
1510+ } else if us. payment_preimages. get( & htlc. payment_hash) . is_some( ) {
1511+ // Otherwise (the payment was inbound), only expose it as claimable if
1512+ // we know the preimage.
1513+ // Note that if there is a pending claim, but it did not use the
1514+ // preimage, we lost funds to our counterparty! We will then continue
1515+ // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
1516+ debug_assert!( htlc_update_pending. is_none( ) ) ;
1517+ if let Some ( ( conf_thresh, true ) ) = htlc_spend_pending {
1518+ res. push( Balance :: ClaimableAwaitingConfirmations {
1519+ claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1520+ confirmation_height: conf_thresh,
1521+ } ) ;
1522+ } else {
1523+ res. push( Balance :: ContentiousClaimable {
1524+ claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1525+ timeout_height: htlc. cltv_expiry,
1526+ } ) ;
1527+ }
15131528 }
15141529 }
15151530 }
0 commit comments