@@ -1418,7 +1418,151 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
1418
1418
pub fn current_best_block ( & self ) -> BestBlock {
1419
1419
self . inner . lock ( ) . unwrap ( ) . best_block . clone ( )
1420
1420
}
1421
+ }
1422
+
1423
+ impl < Signer : Sign > ChannelMonitorImpl < Signer > {
1424
+ /// Helper for get_claimable_balances which does the work for an individual HTLC, generating up
1425
+ /// to one `Balance` for the HTLC.
1426
+ fn get_htlc_balance ( & self , htlc : & HTLCOutputInCommitment , holder_commitment : bool ,
1427
+ counterparty_revoked_commitment : bool , confirmed_txid : Option < Txid > )
1428
+ -> Option < Balance > {
1429
+ let htlc_commitment_tx_output_idx =
1430
+ if let Some ( v) = htlc. transaction_output_index { v } else { return None ; } ;
1431
+
1432
+
1433
+ let mut htlc_spend_txid_opt = None ;
1434
+ let mut holder_timeout_spend_pending = None ;
1435
+ let mut htlc_spend_pending = None ;
1436
+ let mut holder_delayed_output_pending = None ;
1437
+ for event in self . 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_spend_txid_opt. is_none( ) ) ;
1442
+ htlc_spend_txid_opt = event. transaction . as_ref ( ) . map ( |tx| tx. txid ( ) ) ;
1443
+ debug_assert ! ( holder_timeout_spend_pending. is_none( ) ) ;
1444
+ debug_assert_eq ! ( htlc_value_satoshis. unwrap( ) , htlc. amount_msat / 1000 ) ;
1445
+ holder_timeout_spend_pending = Some ( event. confirmation_threshold ( ) ) ;
1446
+ } ,
1447
+ OnchainEvent :: HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
1448
+ if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
1449
+ debug_assert ! ( htlc_spend_txid_opt. is_none( ) ) ;
1450
+ htlc_spend_txid_opt = event. transaction . as_ref ( ) . map ( |tx| tx. txid ( ) ) ;
1451
+ debug_assert ! ( htlc_spend_pending. is_none( ) ) ;
1452
+ htlc_spend_pending = Some ( ( event. confirmation_threshold ( ) , preimage. is_some ( ) ) ) ;
1453
+ } ,
1454
+ OnchainEvent :: MaturingOutput {
1455
+ descriptor : SpendableOutputDescriptor :: DelayedPaymentOutput ( ref descriptor) }
1456
+ if descriptor. outpoint . index as u32 == htlc_commitment_tx_output_idx => {
1457
+ debug_assert ! ( holder_delayed_output_pending. is_none( ) ) ;
1458
+ holder_delayed_output_pending = Some ( event. confirmation_threshold ( ) ) ;
1459
+ } ,
1460
+ _ => { } ,
1461
+ }
1462
+ }
1463
+ let htlc_resolved = self . htlcs_resolved_on_chain . iter ( )
1464
+ . find ( |v| if v. commitment_tx_output_idx == htlc_commitment_tx_output_idx {
1465
+ debug_assert ! ( htlc_spend_txid_opt. is_none( ) ) ;
1466
+ htlc_spend_txid_opt = v. resolving_txid ;
1467
+ true
1468
+ } else { false } ) ;
1469
+ debug_assert ! ( holder_timeout_spend_pending. is_some( ) as u8 + htlc_spend_pending. is_some( ) as u8 + htlc_resolved. is_some( ) as u8 <= 1 ) ;
1470
+
1471
+ let htlc_output_to_spend =
1472
+ if let Some ( txid) = htlc_spend_txid_opt {
1473
+ debug_assert ! (
1474
+ self . onchain_tx_handler. channel_transaction_parameters. opt_anchors. is_none( ) ,
1475
+ "This code needs updating for anchors" ) ;
1476
+ BitcoinOutPoint :: new ( txid, 0 )
1477
+ } else {
1478
+ BitcoinOutPoint :: new ( confirmed_txid. unwrap ( ) , htlc_commitment_tx_output_idx)
1479
+ } ;
1480
+ let htlc_output_spend_pending = self . onchain_tx_handler . is_output_spend_pending ( & htlc_output_to_spend) ;
1421
1481
1482
+ if let Some ( conf_thresh) = holder_delayed_output_pending {
1483
+ debug_assert ! ( holder_commitment) ;
1484
+ return Some ( Balance :: ClaimableAwaitingConfirmations {
1485
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1486
+ confirmation_height : conf_thresh,
1487
+ } ) ;
1488
+ } else if htlc_resolved. is_some ( ) && !htlc_output_spend_pending {
1489
+ // Funding transaction spends should be fully confirmed by the time any
1490
+ // HTLC transactions are resolved, unless we're talking about a holder
1491
+ // commitment tx, whose resolution is delayed until the CSV timeout is
1492
+ // reached, even though HTLCs may be resolved after only
1493
+ // ANTI_REORG_DELAY confirmations.
1494
+ debug_assert ! ( holder_commitment || self . funding_spend_confirmed. is_some( ) ) ;
1495
+ } else if counterparty_revoked_commitment {
1496
+ let htlc_output_claim_pending = self . onchain_events_awaiting_threshold_conf . iter ( ) . find_map ( |event| {
1497
+ if let OnchainEvent :: MaturingOutput {
1498
+ descriptor : SpendableOutputDescriptor :: StaticOutput { .. }
1499
+ } = & event. event {
1500
+ if event. transaction . as_ref ( ) . map ( |tx| tx. input . iter ( ) . any ( |inp| {
1501
+ if let Some ( htlc_spend_txid) = htlc_spend_txid_opt {
1502
+ Some ( tx. txid ( ) ) == htlc_spend_txid_opt ||
1503
+ inp. previous_output . txid == htlc_spend_txid
1504
+ } else {
1505
+ Some ( inp. previous_output . txid ) == confirmed_txid &&
1506
+ inp. previous_output . vout == htlc_commitment_tx_output_idx
1507
+ }
1508
+ } ) ) . unwrap_or ( false ) {
1509
+ Some ( ( ) )
1510
+ } else { None }
1511
+ } else { None }
1512
+ } ) ;
1513
+ if htlc_output_claim_pending. is_some ( ) {
1514
+ // We already push `Balance`s onto the `res` list for every
1515
+ // `StaticOutput` in a `MaturingOutput` in the revoked
1516
+ // counterparty commitment transaction case generally, so don't
1517
+ // need to do so again here.
1518
+ } else {
1519
+ debug_assert ! ( holder_timeout_spend_pending. is_none( ) ,
1520
+ "HTLCUpdate OnchainEvents should never appear for preimage claims" ) ;
1521
+ debug_assert ! ( !htlc. offered || htlc_spend_pending. is_none( ) || !htlc_spend_pending. unwrap( ) . 1 ,
1522
+ "We don't (currently) generate preimage claims against revoked outputs, where did you get one?!" ) ;
1523
+ return Some ( Balance :: CounterpartyRevokedOutputClaimable {
1524
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1525
+ } ) ;
1526
+ }
1527
+ } else if htlc. offered == holder_commitment {
1528
+ // If the payment was outbound, check if there's an HTLCUpdate
1529
+ // indicating we have spent this HTLC with a timeout, claiming it back
1530
+ // and awaiting confirmations on it.
1531
+ if let Some ( conf_thresh) = holder_timeout_spend_pending {
1532
+ return Some ( Balance :: ClaimableAwaitingConfirmations {
1533
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1534
+ confirmation_height : conf_thresh,
1535
+ } ) ;
1536
+ } else {
1537
+ return Some ( Balance :: MaybeClaimableHTLCAwaitingTimeout {
1538
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1539
+ claimable_height : htlc. cltv_expiry ,
1540
+ } ) ;
1541
+ }
1542
+ } else if self . payment_preimages . get ( & htlc. payment_hash ) . is_some ( ) {
1543
+ // Otherwise (the payment was inbound), only expose it as claimable if
1544
+ // we know the preimage.
1545
+ // Note that if there is a pending claim, but it did not use the
1546
+ // preimage, we lost funds to our counterparty! We will then continue
1547
+ // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
1548
+ debug_assert ! ( holder_timeout_spend_pending. is_none( ) ) ;
1549
+ if let Some ( ( conf_thresh, true ) ) = htlc_spend_pending {
1550
+ return Some ( Balance :: ClaimableAwaitingConfirmations {
1551
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1552
+ confirmation_height : conf_thresh,
1553
+ } ) ;
1554
+ } else {
1555
+ return Some ( Balance :: ContentiousClaimable {
1556
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1557
+ timeout_height : htlc. cltv_expiry ,
1558
+ } ) ;
1559
+ }
1560
+ }
1561
+ None
1562
+ }
1563
+ }
1564
+
1565
+ impl < Signer : Sign > ChannelMonitor < Signer > {
1422
1566
/// Gets the balances in this channel which are either claimable by us if we were to
1423
1567
/// force-close the channel now or which are claimable on-chain (possibly awaiting
1424
1568
/// confirmation).
@@ -1459,136 +1603,10 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
1459
1603
macro_rules! walk_htlcs {
1460
1604
( $holder_commitment: expr, $counterparty_revoked_commitment: expr, $htlc_iter: expr) => {
1461
1605
for htlc in $htlc_iter {
1462
- if let Some ( htlc_commitment_tx_output_idx) = htlc. transaction_output_index {
1463
- let mut htlc_spend_txid_opt = None ;
1464
- let mut htlc_update_pending = None ;
1465
- let mut htlc_spend_pending = None ;
1466
- let mut delayed_output_pending = None ;
1467
- for event in us. onchain_events_awaiting_threshold_conf. iter( ) {
1468
- match event. event {
1469
- OnchainEvent :: HTLCUpdate { commitment_tx_output_idx, htlc_value_satoshis, .. }
1470
- if commitment_tx_output_idx == Some ( htlc_commitment_tx_output_idx) => {
1471
- debug_assert!( htlc_spend_txid_opt. is_none( ) ) ;
1472
- htlc_spend_txid_opt = event. transaction. as_ref( ) . map( |tx| tx. txid( ) ) ;
1473
- debug_assert!( htlc_update_pending. is_none( ) ) ;
1474
- debug_assert_eq!( htlc_value_satoshis. unwrap( ) , htlc. amount_msat / 1000 ) ;
1475
- htlc_update_pending = Some ( event. confirmation_threshold( ) ) ;
1476
- } ,
1477
- OnchainEvent :: HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
1478
- if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
1479
- debug_assert!( htlc_spend_txid_opt. is_none( ) ) ;
1480
- htlc_spend_txid_opt = event. transaction. as_ref( ) . map( |tx| tx. txid( ) ) ;
1481
- debug_assert!( htlc_spend_pending. is_none( ) ) ;
1482
- htlc_spend_pending = Some ( ( event. confirmation_threshold( ) , preimage. is_some( ) ) ) ;
1483
- } ,
1484
- OnchainEvent :: MaturingOutput {
1485
- descriptor: SpendableOutputDescriptor :: DelayedPaymentOutput ( ref descriptor) }
1486
- if descriptor. outpoint. index as u32 == htlc_commitment_tx_output_idx => {
1487
- debug_assert!( delayed_output_pending. is_none( ) ) ;
1488
- delayed_output_pending = Some ( event. confirmation_threshold( ) ) ;
1489
- } ,
1490
- _ => { } ,
1491
- }
1492
- }
1493
- let htlc_resolved = us. htlcs_resolved_on_chain. iter( )
1494
- . find( |v| if v. commitment_tx_output_idx == htlc_commitment_tx_output_idx {
1495
- debug_assert!( htlc_spend_txid_opt. is_none( ) ) ;
1496
- htlc_spend_txid_opt = v. resolving_txid;
1497
- true
1498
- } else { false } ) ;
1499
- debug_assert!( htlc_update_pending. is_some( ) as u8 + htlc_spend_pending. is_some( ) as u8 + htlc_resolved. is_some( ) as u8 <= 1 ) ;
1500
-
1501
- let htlc_output_to_spend =
1502
- if let Some ( txid) = htlc_spend_txid_opt {
1503
- debug_assert!(
1504
- us. onchain_tx_handler. channel_transaction_parameters. opt_anchors. is_none( ) ,
1505
- "This code needs updating for anchors" ) ;
1506
- BitcoinOutPoint :: new( txid, 0 )
1507
- } else {
1508
- BitcoinOutPoint :: new( confirmed_txid. unwrap( ) , htlc_commitment_tx_output_idx)
1509
- } ;
1510
- let htlc_output_needs_spending = us. onchain_tx_handler. is_output_spend_pending( & htlc_output_to_spend) ;
1606
+ if htlc. transaction_output_index. is_some( ) {
1511
1607
1512
- if let Some ( conf_thresh) = delayed_output_pending {
1513
- debug_assert!( $holder_commitment) ;
1514
- res. push( Balance :: ClaimableAwaitingConfirmations {
1515
- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1516
- confirmation_height: conf_thresh,
1517
- } ) ;
1518
- } else if htlc_resolved. is_some( ) && !htlc_output_needs_spending {
1519
- // Funding transaction spends should be fully confirmed by the time any
1520
- // HTLC transactions are resolved, unless we're talking about a holder
1521
- // commitment tx, whose resolution is delayed until the CSV timeout is
1522
- // reached, even though HTLCs may be resolved after only
1523
- // ANTI_REORG_DELAY confirmations.
1524
- debug_assert!( $holder_commitment || us. funding_spend_confirmed. is_some( ) ) ;
1525
- } else if $counterparty_revoked_commitment {
1526
- let htlc_output_claim_pending = us. onchain_events_awaiting_threshold_conf. iter( ) . find_map( |event| {
1527
- if let OnchainEvent :: MaturingOutput {
1528
- descriptor: SpendableOutputDescriptor :: StaticOutput { .. }
1529
- } = & event. event {
1530
- if event. transaction. as_ref( ) . map( |tx| tx. input. iter( ) . any( |inp| {
1531
- if let Some ( htlc_spend_txid) = htlc_spend_txid_opt {
1532
- Some ( tx. txid( ) ) == htlc_spend_txid_opt ||
1533
- inp. previous_output. txid == htlc_spend_txid
1534
- } else {
1535
- Some ( inp. previous_output. txid) == confirmed_txid &&
1536
- inp. previous_output. vout == htlc_commitment_tx_output_idx
1537
- }
1538
- } ) ) . unwrap_or( false ) {
1539
- Some ( ( ) )
1540
- } else { None }
1541
- } else { None }
1542
- } ) ;
1543
- if htlc_output_claim_pending. is_some( ) {
1544
- // We already push `Balance`s onto the `res` list for every
1545
- // `StaticOutput` in a `MaturingOutput` in the revoked
1546
- // counterparty commitment transaction case generally, so don't
1547
- // need to do so again here.
1548
- } else {
1549
- debug_assert!( htlc_update_pending. is_none( ) ,
1550
- "HTLCUpdate OnchainEvents should never appear for preimage claims" ) ;
1551
- debug_assert!( !htlc. offered || htlc_spend_pending. is_none( ) || !htlc_spend_pending. unwrap( ) . 1 ,
1552
- "We don't (currently) generate preimage claims against revoked outputs, where did you get one?!" ) ;
1553
- res. push( Balance :: CounterpartyRevokedOutputClaimable {
1554
- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1555
- } ) ;
1556
- }
1557
- } else {
1558
- if htlc. offered == $holder_commitment {
1559
- // If the payment was outbound, check if there's an HTLCUpdate
1560
- // indicating we have spent this HTLC with a timeout, claiming it back
1561
- // and awaiting confirmations on it.
1562
- if let Some ( conf_thresh) = htlc_update_pending {
1563
- res. push( Balance :: ClaimableAwaitingConfirmations {
1564
- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1565
- confirmation_height: conf_thresh,
1566
- } ) ;
1567
- } else {
1568
- res. push( Balance :: MaybeClaimableHTLCAwaitingTimeout {
1569
- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1570
- claimable_height: htlc. cltv_expiry,
1571
- } ) ;
1572
- }
1573
- } else if us. payment_preimages. get( & htlc. payment_hash) . is_some( ) {
1574
- // Otherwise (the payment was inbound), only expose it as claimable if
1575
- // we know the preimage.
1576
- // Note that if there is a pending claim, but it did not use the
1577
- // preimage, we lost funds to our counterparty! We will then continue
1578
- // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
1579
- debug_assert!( htlc_update_pending. is_none( ) ) ;
1580
- if let Some ( ( conf_thresh, true ) ) = htlc_spend_pending {
1581
- res. push( Balance :: ClaimableAwaitingConfirmations {
1582
- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1583
- confirmation_height: conf_thresh,
1584
- } ) ;
1585
- } else {
1586
- res. push( Balance :: ContentiousClaimable {
1587
- claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1588
- timeout_height: htlc. cltv_expiry,
1589
- } ) ;
1590
- }
1591
- }
1608
+ if let Some ( bal) = us. get_htlc_balance( htlc, $holder_commitment, $counterparty_revoked_commitment, confirmed_txid) {
1609
+ res. push( bal) ;
1592
1610
}
1593
1611
}
1594
1612
}
0 commit comments