@@ -77,7 +77,7 @@ use crate::util::ser::{
77
77
use crate :: prelude:: * ;
78
78
79
79
use crate :: io:: { self , Error } ;
80
- use crate :: sync:: { LockTestExt , Mutex } ;
80
+ use crate :: sync:: Mutex ;
81
81
use core:: ops:: Deref ;
82
82
use core:: { cmp, mem} ;
83
83
@@ -1376,18 +1376,30 @@ macro_rules! holder_commitment_htlcs {
1376
1376
/// Transaction outputs to watch for on-chain spends.
1377
1377
pub type TransactionOutputs = ( Txid , Vec < ( u32 , TxOut ) > ) ;
1378
1378
1379
+ // Because we have weird workarounds for `ChannelMonitor` equality checks in `OnchainTxHandler` and
1380
+ // `PackageTemplate` the equality implementation isn't really fit for public consumption. Instead,
1381
+ // we only expose it during tests.
1382
+ #[ cfg( any( feature = "_test_utils" , test) ) ]
1379
1383
impl < Signer : EcdsaChannelSigner > PartialEq for ChannelMonitor < Signer >
1380
1384
where
1381
1385
Signer : PartialEq ,
1382
1386
{
1383
- #[ rustfmt:: skip]
1384
1387
fn eq ( & self , other : & Self ) -> bool {
1388
+ use crate :: sync:: LockTestExt ;
1385
1389
// We need some kind of total lockorder. Absent a better idea, we sort by position in
1386
1390
// memory and take locks in that order (assuming that we can't move within memory while a
1387
1391
// lock is held).
1388
1392
let ord = ( ( self as * const _ ) as usize ) < ( ( other as * const _ ) as usize ) ;
1389
- let a = if ord { self . inner . unsafe_well_ordered_double_lock_self ( ) } else { other. inner . unsafe_well_ordered_double_lock_self ( ) } ;
1390
- let b = if ord { other. inner . unsafe_well_ordered_double_lock_self ( ) } else { self . inner . unsafe_well_ordered_double_lock_self ( ) } ;
1393
+ let a = if ord {
1394
+ self . inner . unsafe_well_ordered_double_lock_self ( )
1395
+ } else {
1396
+ other. inner . unsafe_well_ordered_double_lock_self ( )
1397
+ } ;
1398
+ let b = if ord {
1399
+ other. inner . unsafe_well_ordered_double_lock_self ( )
1400
+ } else {
1401
+ self . inner . unsafe_well_ordered_double_lock_self ( )
1402
+ } ;
1391
1403
a. eq ( & b)
1392
1404
}
1393
1405
}
@@ -2995,33 +3007,147 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
2995
3007
/// This is similar to [`Self::get_pending_or_resolved_outbound_htlcs`] except it includes
2996
3008
/// HTLCs which were resolved on-chain (i.e. where the final HTLC resolution was done by an
2997
3009
/// event from this `ChannelMonitor`).
2998
- #[ rustfmt:: skip]
2999
- pub ( crate ) fn get_all_current_outbound_htlcs ( & self ) -> HashMap < HTLCSource , ( HTLCOutputInCommitment , Option < PaymentPreimage > ) > {
3010
+ pub ( crate ) fn get_all_current_outbound_htlcs (
3011
+ & self ,
3012
+ ) -> HashMap < HTLCSource , ( HTLCOutputInCommitment , Option < PaymentPreimage > ) > {
3000
3013
let mut res = new_hash_map ( ) ;
3001
3014
// Just examine the available counterparty commitment transactions. See docs on
3002
3015
// `fail_unbroadcast_htlcs`, below, for justification.
3003
3016
let us = self . inner . lock ( ) . unwrap ( ) ;
3004
- macro_rules! walk_counterparty_commitment {
3005
- ( $txid: expr) => {
3006
- if let Some ( ref latest_outpoints) = us. funding. counterparty_claimable_outpoints. get( $txid) {
3007
- for & ( ref htlc, ref source_option) in latest_outpoints. iter( ) {
3008
- if let & Some ( ref source) = source_option {
3009
- res. insert( ( * * source) . clone( ) , ( htlc. clone( ) ,
3010
- us. counterparty_fulfilled_htlcs. get( & SentHTLCId :: from_source( source) ) . cloned( ) ) ) ;
3011
- }
3017
+ let mut walk_counterparty_commitment = |txid| {
3018
+ if let Some ( latest_outpoints) = us. funding . counterparty_claimable_outpoints . get ( txid) {
3019
+ for & ( ref htlc, ref source_option) in latest_outpoints. iter ( ) {
3020
+ if let & Some ( ref source) = source_option {
3021
+ let htlc_id = SentHTLCId :: from_source ( source) ;
3022
+ let preimage_opt = us. counterparty_fulfilled_htlcs . get ( & htlc_id) . cloned ( ) ;
3023
+ res. insert ( ( * * source) . clone ( ) , ( htlc. clone ( ) , preimage_opt) ) ;
3012
3024
}
3013
3025
}
3014
3026
}
3015
- }
3027
+ } ;
3016
3028
if let Some ( ref txid) = us. funding . current_counterparty_commitment_txid {
3017
- walk_counterparty_commitment ! ( txid) ;
3029
+ walk_counterparty_commitment ( txid) ;
3018
3030
}
3019
3031
if let Some ( ref txid) = us. funding . prev_counterparty_commitment_txid {
3020
- walk_counterparty_commitment ! ( txid) ;
3032
+ walk_counterparty_commitment ( txid) ;
3021
3033
}
3022
3034
res
3023
3035
}
3024
3036
3037
+ /// Gets the set of outbound HTLCs which hit the chain and ultimately were claimed by us via
3038
+ /// the timeout path and reached [`ANTI_REORG_DELAY`] confirmations. This is used to determine
3039
+ /// if an HTLC has failed without the `ChannelManager` having seen it prior to being persisted.
3040
+ pub ( crate ) fn get_onchain_failed_outbound_htlcs ( & self ) -> HashMap < HTLCSource , PaymentHash > {
3041
+ let mut res = new_hash_map ( ) ;
3042
+ let us = self . inner . lock ( ) . unwrap ( ) ;
3043
+
3044
+ // We only want HTLCs with ANTI_REORG_DELAY confirmations, which implies the commitment
3045
+ // transaction has least ANTI_REORG_DELAY confirmations for any dependent HTLC transactions
3046
+ // to have been confirmed.
3047
+ let confirmed_txid = us. funding_spend_confirmed . or_else ( || {
3048
+ us. onchain_events_awaiting_threshold_conf . iter ( ) . find_map ( |event| {
3049
+ if let OnchainEvent :: FundingSpendConfirmation { .. } = event. event {
3050
+ if event. height + ANTI_REORG_DELAY - 1 <= us. best_block . height {
3051
+ Some ( event. txid )
3052
+ } else {
3053
+ None
3054
+ }
3055
+ } else {
3056
+ None
3057
+ }
3058
+ } )
3059
+ } ) ;
3060
+
3061
+ let confirmed_txid = if let Some ( txid) = confirmed_txid {
3062
+ txid
3063
+ } else {
3064
+ return res;
3065
+ } ;
3066
+
3067
+ macro_rules! walk_htlcs {
3068
+ ( $htlc_iter: expr) => {
3069
+ let mut walk_candidate_htlcs = |htlcs| {
3070
+ for & ( ref candidate_htlc, ref candidate_source) in htlcs {
3071
+ let candidate_htlc: & HTLCOutputInCommitment = & candidate_htlc;
3072
+ let candidate_source: & Option <Box <HTLCSource >> = & candidate_source;
3073
+
3074
+ let source: & HTLCSource = if let Some ( source) = candidate_source {
3075
+ source
3076
+ } else {
3077
+ continue ;
3078
+ } ;
3079
+ let confirmed = $htlc_iter. find( |( _, conf_src) | Some ( source) == * conf_src) ;
3080
+ if let Some ( ( confirmed_htlc, _) ) = confirmed {
3081
+ let filter = |v: &&IrrevocablyResolvedHTLC | {
3082
+ v. commitment_tx_output_idx
3083
+ == confirmed_htlc. transaction_output_index
3084
+ } ;
3085
+
3086
+ // The HTLC was included in the confirmed commitment transaction, so we
3087
+ // need to see if it has been irrevocably failed yet.
3088
+ if confirmed_htlc. transaction_output_index. is_none( ) {
3089
+ // Dust HTLCs are always implicitly failed once the commitment
3090
+ // transaction reaches ANTI_REORG_DELAY confirmations.
3091
+ res. insert( source. clone( ) , confirmed_htlc. payment_hash) ;
3092
+ } else if let Some ( state) =
3093
+ us. htlcs_resolved_on_chain. iter( ) . filter( filter) . next( )
3094
+ {
3095
+ if state. payment_preimage. is_none( ) {
3096
+ res. insert( source. clone( ) , confirmed_htlc. payment_hash) ;
3097
+ }
3098
+ }
3099
+ } else {
3100
+ // The HTLC was not included in the confirmed commitment transaction,
3101
+ // which has now reached ANTI_REORG_DELAY confirmations and thus the
3102
+ // HTLC has been failed.
3103
+ res. insert( source. clone( ) , candidate_htlc. payment_hash) ;
3104
+ }
3105
+ }
3106
+ } ;
3107
+
3108
+ // We walk the set of HTLCs in the unrevoked counterparty commitment transactions (see
3109
+ // `fail_unbroadcast_htlcs` for a description of why).
3110
+ if let Some ( ref txid) = us. funding. current_counterparty_commitment_txid {
3111
+ let htlcs = us. funding. counterparty_claimable_outpoints. get( txid) ;
3112
+ walk_candidate_htlcs( htlcs. expect( "Missing tx info for latest tx" ) ) ;
3113
+ }
3114
+ if let Some ( ref txid) = us. funding. prev_counterparty_commitment_txid {
3115
+ let htlcs = us. funding. counterparty_claimable_outpoints. get( txid) ;
3116
+ walk_candidate_htlcs( htlcs. expect( "Missing tx info for previous tx" ) ) ;
3117
+ }
3118
+ } ;
3119
+ }
3120
+
3121
+ let funding = get_confirmed_funding_scope ! ( us) ;
3122
+
3123
+ if Some ( confirmed_txid) == funding. current_counterparty_commitment_txid
3124
+ || Some ( confirmed_txid) == funding. prev_counterparty_commitment_txid
3125
+ {
3126
+ let htlcs = funding. counterparty_claimable_outpoints . get ( & confirmed_txid) . unwrap ( ) ;
3127
+ walk_htlcs ! ( htlcs. iter( ) . filter_map( |( a, b) | {
3128
+ if let & Some ( ref source) = b {
3129
+ Some ( ( a, Some ( & * * source) ) )
3130
+ } else {
3131
+ None
3132
+ }
3133
+ } ) ) ;
3134
+ } else if confirmed_txid == funding. current_holder_commitment_tx . trust ( ) . txid ( ) {
3135
+ walk_htlcs ! ( holder_commitment_htlcs!( us, CURRENT_WITH_SOURCES ) ) ;
3136
+ } else if let Some ( prev_commitment_tx) = & funding. prev_holder_commitment_tx {
3137
+ if confirmed_txid == prev_commitment_tx. trust ( ) . txid ( ) {
3138
+ walk_htlcs ! ( holder_commitment_htlcs!( us, PREV_WITH_SOURCES ) . unwrap( ) ) ;
3139
+ } else {
3140
+ let htlcs_confirmed: & [ ( & HTLCOutputInCommitment , _ ) ] = & [ ] ;
3141
+ walk_htlcs ! ( htlcs_confirmed. iter( ) ) ;
3142
+ }
3143
+ } else {
3144
+ let htlcs_confirmed: & [ ( & HTLCOutputInCommitment , _ ) ] = & [ ] ;
3145
+ walk_htlcs ! ( htlcs_confirmed. iter( ) ) ;
3146
+ }
3147
+
3148
+ res
3149
+ }
3150
+
3025
3151
/// Gets the set of outbound HTLCs which are pending resolution in this channel or which were
3026
3152
/// resolved with a preimage from our counterparty.
3027
3153
///
@@ -5829,6 +5955,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5829
5955
on_to_local_output_csv : None ,
5830
5956
} ,
5831
5957
} ) ;
5958
+ self . counterparty_fulfilled_htlcs . insert ( SentHTLCId :: from_source ( & source) , payment_preimage) ;
5832
5959
self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
5833
5960
source,
5834
5961
payment_preimage : Some ( payment_preimage) ,
@@ -5852,6 +5979,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5852
5979
on_to_local_output_csv : None ,
5853
5980
} ,
5854
5981
} ) ;
5982
+ self . counterparty_fulfilled_htlcs . insert ( SentHTLCId :: from_source ( & source) , payment_preimage) ;
5855
5983
self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
5856
5984
source,
5857
5985
payment_preimage : Some ( payment_preimage) ,
0 commit comments