@@ -525,6 +525,56 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
525
525
} ,
526
526
) ;
527
527
528
+ /// Details about the balance available for claim once the channel appears on chain.
529
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
530
+ #[ cfg_attr( test, derive( PartialOrd , Ord ) ) ]
531
+ pub enum ClaimableBalance {
532
+ /// The channel is not yet closed (or the initial commitment or closing transaction has not yet
533
+ /// been confirmed). The given balance is claimable (less on-chain fees) if the channel is
534
+ /// force-closed now.
535
+ ClaimableOnChannelClose {
536
+ /// The amount available to claim, in satoshis, ignoring the on-chain fees which will be
537
+ /// required to do so.
538
+ claimable_amount_satoshis : u64 ,
539
+ } ,
540
+ /// The channel has been closed, and the given balance is ours but awaiting confirmations until
541
+ /// we consider it spendable.
542
+ ClaimableAwaitingConfirmations {
543
+ /// The amount available to claim, in satoshis, possibly ignoring the on-chain fees which
544
+ /// were spent in broadcasting the transaction.
545
+ claimable_amount_satoshis : u64 ,
546
+ /// The height at which an [`Event::SpendableOutputs`] event will be generated for this
547
+ /// amount.
548
+ confirmation_height : u32 ,
549
+ } ,
550
+ /// The channel has been closed, and the given balance should be ours but awaiting spending
551
+ /// transaction confirmation. If the spending transaction does not confirm in time, it is
552
+ /// possible our counterparty can take the funds by broadcasting an HTLC timeout on-chain.
553
+ ///
554
+ /// Once the spending transaction confirms, before it has reached enough confirmations to be
555
+ /// considered safe from chain reorganizations, the balance will instead be provided via
556
+ /// [`ClaimableBalance::ClaimableAwaitingConfirmations`].
557
+ ContentiousClaimable {
558
+ /// The amount available to claim, in satoshis, ignoring the on-chain fees which will be
559
+ /// required to do so.
560
+ claimable_amount_satoshis : u64 ,
561
+ /// The height at which the counterparty may be able to claim the balance if we have not
562
+ /// done so.
563
+ timeout_height : u32 ,
564
+ } ,
565
+ /// HTLCs which we sent to our counterparty which are claimable after a timeout (less on-chain
566
+ /// fees) if the counterparty does not know the preimage for the HTLCs. These are somewhat
567
+ /// likely to be claimed by our counterparty before we do.
568
+ PossiblyClaimableHTLCAwaitingTimeout {
569
+ /// The amount available to claim, in satoshis, ignoring the on-chain fees which will be
570
+ /// required to do so.
571
+ claimable_amount_satoshis : u64 ,
572
+ /// The height at which we will be able to claim the balance if our counterparty has not
573
+ /// done so.
574
+ claimable_height : u32 ,
575
+ } ,
576
+ }
577
+
528
578
/// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY.
529
579
#[ derive( PartialEq ) ]
530
580
struct HTLCIrrevocablyResolved {
@@ -1291,6 +1341,107 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
1291
1341
pub fn current_best_block ( & self ) -> BestBlock {
1292
1342
self . inner . lock ( ) . unwrap ( ) . best_block . clone ( )
1293
1343
}
1344
+
1345
+ /// Gets the balances in this channel which are either claimable by us if we were to
1346
+ /// force-close the channel now or which are claimable on-chain or claims which are awaiting
1347
+ /// confirmation.
1348
+ ///
1349
+ /// Any balances in the channel which are available on-chain (ignoring on-chain fees) are
1350
+ /// included here until an [`Event::SpendableOutputs`] event has been generated for the
1351
+ /// balance, or until our counterparty has claimed the balance and accrued several
1352
+ /// confirmations on the claim transaction.
1353
+ ///
1354
+ /// See [`ClaimableBalance`] for additional details on the types of claimable balances which
1355
+ /// may be returned here and their meanings.
1356
+ pub fn get_claimable_balances ( & self ) -> Vec < ClaimableBalance > {
1357
+ let mut res = Vec :: new ( ) ;
1358
+ let us = self . inner . lock ( ) . unwrap ( ) ;
1359
+
1360
+ let mut confirmed_txid = us. funding_spend_confirmed ;
1361
+ if let Some ( ( txid, conf_thresh) ) = us. onchain_events_awaiting_threshold_conf . iter ( ) . find_map ( |event| {
1362
+ if let OnchainEvent :: FundingSpendConfirmation { txid, .. } = event. event {
1363
+ Some ( ( txid, event. confirmation_threshold ( ) ) )
1364
+ } else { None }
1365
+ } ) {
1366
+ debug_assert ! ( us. funding_spend_confirmed. is_none( ) , "We have a pending funding spend awaiting confirmation, we can't have confirmed it already!" ) ;
1367
+ confirmed_txid = Some ( txid) ;
1368
+ res. push ( ClaimableBalance :: ClaimableAwaitingConfirmations {
1369
+ claimable_amount_satoshis : us. current_holder_commitment_tx . to_self_value_sat ,
1370
+ confirmation_height : conf_thresh,
1371
+ } ) ;
1372
+ }
1373
+
1374
+ macro_rules! walk_htlcs {
1375
+ ( $holder_commitment: expr, $htlc_iter: expr) => {
1376
+ for htlc in $htlc_iter {
1377
+ if let Some ( htlc_input_idx) = htlc. transaction_output_index {
1378
+ if us. htlcs_resolved_on_chain. iter( ) . any( |v| v. input_idx == htlc_input_idx) {
1379
+ assert!( us. funding_spend_confirmed. is_some( ) ) ;
1380
+ } else if htlc. offered == $holder_commitment {
1381
+ res. push( ClaimableBalance :: PossiblyClaimableHTLCAwaitingTimeout {
1382
+ claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1383
+ claimable_height: htlc. cltv_expiry,
1384
+ } ) ;
1385
+ } else {
1386
+ if us. payment_preimages. get( & htlc. payment_hash) . is_some( ) {
1387
+ if let Some ( conf_thresh) = us. onchain_events_awaiting_threshold_conf. iter( ) . find_map( |event| {
1388
+ if let OnchainEvent :: HTLCSpendConfirmation { input_idx, .. } = event. event {
1389
+ if input_idx == htlc_input_idx { Some ( event. confirmation_threshold( ) ) } else { None }
1390
+ } else { None }
1391
+ } ) {
1392
+ res. push( ClaimableBalance :: ClaimableAwaitingConfirmations {
1393
+ claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1394
+ confirmation_height: conf_thresh,
1395
+ } ) ;
1396
+ } else {
1397
+ res. push( ClaimableBalance :: ContentiousClaimable {
1398
+ claimable_amount_satoshis: htlc. amount_msat / 1000 ,
1399
+ timeout_height: htlc. cltv_expiry,
1400
+ } ) ;
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+ }
1406
+ }
1407
+ }
1408
+
1409
+ if let Some ( txid) = confirmed_txid {
1410
+ if Some ( txid) == us. current_counterparty_commitment_txid || Some ( txid) == us. prev_counterparty_commitment_txid {
1411
+ walk_htlcs ! ( false , us. counterparty_claimable_outpoints. get( & txid) . unwrap( ) . iter( ) . map( |( a, _) | a) ) ;
1412
+ } else if txid == us. current_holder_commitment_tx . txid {
1413
+ walk_htlcs ! ( true , us. current_holder_commitment_tx. htlc_outputs. iter( ) . map( |( a, _, _) | a) ) ;
1414
+ } else if let Some ( prev_commitment) = & us. prev_holder_signed_commitment_tx {
1415
+ if txid == prev_commitment. txid {
1416
+ walk_htlcs ! ( true , prev_commitment. htlc_outputs. iter( ) . map( |( a, _, _) | a) ) ;
1417
+ }
1418
+ }
1419
+ // TODO: Add logic to provide claimable balances for counterparty broadcasting revoked
1420
+ // outputs.
1421
+ // Otherwise assume we closed with a cooperative close which only needs the
1422
+ // `ClaimableAwaitingConfirmations` balance pushed first.
1423
+ } else {
1424
+ let mut claimable_inbound_htlc_value_sat = 0 ;
1425
+ for ( htlc, _, _) in us. current_holder_commitment_tx . htlc_outputs . iter ( ) {
1426
+ if htlc. transaction_output_index . is_none ( ) { continue ; }
1427
+ if htlc. offered {
1428
+ res. push ( ClaimableBalance :: PossiblyClaimableHTLCAwaitingTimeout {
1429
+ claimable_amount_satoshis : htlc. amount_msat / 1000 ,
1430
+ claimable_height : htlc. cltv_expiry ,
1431
+ } ) ;
1432
+ } else {
1433
+ if us. payment_preimages . get ( & htlc. payment_hash ) . is_some ( ) {
1434
+ claimable_inbound_htlc_value_sat += htlc. amount_msat / 1000 ;
1435
+ }
1436
+ }
1437
+ }
1438
+ res. push ( ClaimableBalance :: ClaimableOnChannelClose {
1439
+ claimable_amount_satoshis : us. current_holder_commitment_tx . to_self_value_sat + claimable_inbound_htlc_value_sat,
1440
+ } ) ;
1441
+ }
1442
+
1443
+ res
1444
+ }
1294
1445
}
1295
1446
1296
1447
/// Compares a broadcasted commitment transaction's HTLCs with those in the latest state,
0 commit comments