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