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