@@ -664,6 +664,10 @@ pub enum Balance {
664664 claimable_height : u32 ,
665665 /// The payment hash whose preimage our counterparty needs to claim this HTLC.
666666 payment_hash : PaymentHash ,
667+ /// Whether this HTLC represents a payment which was sent outbound from us. Otherwise it
668+ /// represents an HTLC which was forwarded (and should, thus, have a corresponding inbound
669+ /// edge on another channel).
670+ outbound_payment : bool ,
667671 } ,
668672 /// HTLCs which we received from our counterparty which are claimable with a preimage which we
669673 /// do not currently have. This will only be claimable if we receive the preimage from the node
@@ -693,9 +697,15 @@ pub enum Balance {
693697}
694698
695699impl Balance {
696- /// The amount claimable, in satoshis. This excludes balances that we are unsure if we are able
697- /// to claim, this is because we are waiting for a preimage or for a timeout to expire. For more
698- /// information on these balances see [`Balance::MaybeTimeoutClaimableHTLC`] and
700+ /// The amount claimable, in satoshis.
701+ ///
702+ /// For outbound payments, this excludes the balance from the possible HTLC timeout.
703+ ///
704+ /// For forwarded payments, this includes the balance from the possible HTLC timeout as
705+ /// (to be conservative) that balance does not include routing fees we'd earn if we'd claim
706+ /// the balance from a preimage in a successful forward.
707+ ///
708+ /// For more information on these balances see [`Balance::MaybeTimeoutClaimableHTLC`] and
699709 /// [`Balance::MaybePreimageClaimableHTLC`].
700710 ///
701711 /// On-chain fees required to claim the balance are not included in this amount.
@@ -706,9 +716,9 @@ impl Balance {
706716 Balance :: ContentiousClaimable { amount_satoshis, .. } |
707717 Balance :: CounterpartyRevokedOutputClaimable { amount_satoshis, .. }
708718 => * amount_satoshis,
709- Balance :: MaybeTimeoutClaimableHTLC { .. } |
710- Balance :: MaybePreimageClaimableHTLC { .. }
711- => 0 ,
719+ Balance :: MaybeTimeoutClaimableHTLC { amount_satoshis , outbound_payment , .. }
720+ => if * outbound_payment { 0 } else { * amount_satoshis } ,
721+ Balance :: MaybePreimageClaimableHTLC { .. } => 0 ,
712722 }
713723 }
714724}
@@ -1960,9 +1970,10 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
19601970impl < Signer : EcdsaChannelSigner > ChannelMonitorImpl < Signer > {
19611971 /// Helper for get_claimable_balances which does the work for an individual HTLC, generating up
19621972 /// to one `Balance` for the HTLC.
1963- fn get_htlc_balance ( & self , htlc : & HTLCOutputInCommitment , holder_commitment : bool ,
1964- counterparty_revoked_commitment : bool , confirmed_txid : Option < Txid > )
1965- -> Option < Balance > {
1973+ fn get_htlc_balance ( & self , htlc : & HTLCOutputInCommitment , source : Option < & HTLCSource > ,
1974+ holder_commitment : bool , counterparty_revoked_commitment : bool ,
1975+ confirmed_txid : Option < Txid >
1976+ ) -> Option < Balance > {
19661977 let htlc_commitment_tx_output_idx =
19671978 if let Some ( v) = htlc. transaction_output_index { v } else { return None ; } ;
19681979
@@ -2099,10 +2110,19 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
20992110 confirmation_height : conf_thresh,
21002111 } ) ;
21012112 } else {
2113+ let outbound_payment = match source {
2114+ None => {
2115+ debug_assert ! ( false , "Outbound HTLCs should have a source" ) ;
2116+ true
2117+ } ,
2118+ Some ( & HTLCSource :: PreviousHopData ( _) ) => false ,
2119+ Some ( & HTLCSource :: OutboundRoute { .. } ) => true ,
2120+ } ;
21022121 return Some ( Balance :: MaybeTimeoutClaimableHTLC {
21032122 amount_satoshis : htlc. amount_msat / 1000 ,
21042123 claimable_height : htlc. cltv_expiry ,
21052124 payment_hash : htlc. payment_hash ,
2125+ outbound_payment,
21062126 } ) ;
21072127 }
21082128 } else if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
@@ -2175,10 +2195,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
21752195
21762196 macro_rules! walk_htlcs {
21772197 ( $holder_commitment: expr, $counterparty_revoked_commitment: expr, $htlc_iter: expr) => {
2178- for htlc in $htlc_iter {
2198+ for ( htlc, source ) in $htlc_iter {
21792199 if htlc. transaction_output_index. is_some( ) {
21802200
2181- if let Some ( bal) = us. get_htlc_balance( htlc, $holder_commitment, $counterparty_revoked_commitment, confirmed_txid) {
2201+ if let Some ( bal) = us. get_htlc_balance(
2202+ htlc, source, $holder_commitment, $counterparty_revoked_commitment, confirmed_txid
2203+ ) {
21822204 res. push( bal) ;
21832205 }
21842206 }
@@ -2209,9 +2231,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
22092231 }
22102232 }
22112233 if Some ( txid) == us. current_counterparty_commitment_txid || Some ( txid) == us. prev_counterparty_commitment_txid {
2212- walk_htlcs ! ( false , false , counterparty_tx_htlcs. iter( ) . map( |( a, _ ) | a ) ) ;
2234+ walk_htlcs ! ( false , false , counterparty_tx_htlcs. iter( ) . map( |( a, b ) | ( a , b . as_ref ( ) . map ( |b| & * * b ) ) ) ) ;
22132235 } else {
2214- walk_htlcs ! ( false , true , counterparty_tx_htlcs. iter( ) . map( |( a, _ ) | a ) ) ;
2236+ walk_htlcs ! ( false , true , counterparty_tx_htlcs. iter( ) . map( |( a, b ) | ( a , b . as_ref ( ) . map ( |b| & * * b ) ) ) ) ;
22152237 // The counterparty broadcasted a revoked state!
22162238 // Look for any StaticOutputs first, generating claimable balances for those.
22172239 // If any match the confirmed counterparty revoked to_self output, skip
@@ -2251,7 +2273,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
22512273 }
22522274 found_commitment_tx = true ;
22532275 } else if txid == us. current_holder_commitment_tx . txid {
2254- walk_htlcs ! ( true , false , us. current_holder_commitment_tx. htlc_outputs. iter( ) . map( |( a, _, _ ) | a ) ) ;
2276+ walk_htlcs ! ( true , false , us. current_holder_commitment_tx. htlc_outputs. iter( ) . map( |( a, _, c ) | ( a , c . as_ref ( ) ) ) ) ;
22552277 if let Some ( conf_thresh) = pending_commitment_tx_conf_thresh {
22562278 res. push ( Balance :: ClaimableAwaitingConfirmations {
22572279 amount_satoshis : us. current_holder_commitment_tx . to_self_value_sat ,
@@ -2261,7 +2283,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
22612283 found_commitment_tx = true ;
22622284 } else if let Some ( prev_commitment) = & us. prev_holder_signed_commitment_tx {
22632285 if txid == prev_commitment. txid {
2264- walk_htlcs ! ( true , false , prev_commitment. htlc_outputs. iter( ) . map( |( a, _, _ ) | a ) ) ;
2286+ walk_htlcs ! ( true , false , prev_commitment. htlc_outputs. iter( ) . map( |( a, _, c ) | ( a , c . as_ref ( ) ) ) ) ;
22652287 if let Some ( conf_thresh) = pending_commitment_tx_conf_thresh {
22662288 res. push ( Balance :: ClaimableAwaitingConfirmations {
22672289 amount_satoshis : prev_commitment. to_self_value_sat ,
@@ -2284,13 +2306,22 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
22842306 }
22852307 } else {
22862308 let mut claimable_inbound_htlc_value_sat = 0 ;
2287- for ( htlc, _, _ ) in us. current_holder_commitment_tx . htlc_outputs . iter ( ) {
2309+ for ( htlc, _, source ) in us. current_holder_commitment_tx . htlc_outputs . iter ( ) {
22882310 if htlc. transaction_output_index . is_none ( ) { continue ; }
22892311 if htlc. offered {
2312+ let outbound_payment = match source {
2313+ None => {
2314+ debug_assert ! ( false , "Outbound HTLCs should have a source" ) ;
2315+ true
2316+ } ,
2317+ Some ( HTLCSource :: PreviousHopData ( _) ) => false ,
2318+ Some ( HTLCSource :: OutboundRoute { .. } ) => true ,
2319+ } ;
22902320 res. push ( Balance :: MaybeTimeoutClaimableHTLC {
22912321 amount_satoshis : htlc. amount_msat / 1000 ,
22922322 claimable_height : htlc. cltv_expiry ,
22932323 payment_hash : htlc. payment_hash ,
2324+ outbound_payment,
22942325 } ) ;
22952326 } else if us. payment_preimages . get ( & htlc. payment_hash ) . is_some ( ) {
22962327 claimable_inbound_htlc_value_sat += htlc. amount_msat / 1000 ;
0 commit comments