@@ -4111,8 +4111,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4111
4111
4112
4112
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
4113
4113
4114
- let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
4115
- let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) ;
4114
+ let removed_source = self . channel_state . lock ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) ;
4116
4115
if let Some ( ( payment_purpose, mut sources) ) = removed_source {
4117
4116
assert ! ( !sources. is_empty( ) ) ;
4118
4117
@@ -4130,72 +4129,77 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4130
4129
let mut claimable_amt_msat = 0 ;
4131
4130
let mut expected_amt_msat = None ;
4132
4131
let mut valid_mpp = true ;
4133
- for htlc in sources. iter ( ) {
4134
- if let None = channel_state. as_ref ( ) . unwrap ( ) . short_to_chan_info . get ( & htlc. prev_hop . short_channel_id ) {
4135
- valid_mpp = false ;
4136
- break ;
4137
- }
4138
- if expected_amt_msat. is_some ( ) && expected_amt_msat != Some ( htlc. total_msat ) {
4139
- log_error ! ( self . logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!" ) ;
4140
- debug_assert ! ( false ) ;
4141
- valid_mpp = false ;
4142
- break ;
4143
- }
4144
- expected_amt_msat = Some ( htlc. total_msat ) ;
4145
- if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
4146
- // We don't currently support MPP for spontaneous payments, so just check
4147
- // that there's one payment here and move on.
4148
- if sources. len ( ) != 1 {
4149
- log_error ! ( self . logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!" ) ;
4132
+ let mut errs = Vec :: new ( ) ;
4133
+ let mut claimed_any_htlcs = false ;
4134
+ {
4135
+ let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
4136
+ let channel_state = & mut * channel_state_lock;
4137
+ for htlc in sources. iter ( ) {
4138
+ if let None = channel_state. short_to_chan_info . get ( & htlc. prev_hop . short_channel_id ) {
4139
+ valid_mpp = false ;
4140
+ break ;
4141
+ }
4142
+ if expected_amt_msat. is_some ( ) && expected_amt_msat != Some ( htlc. total_msat ) {
4143
+ log_error ! ( self . logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!" ) ;
4150
4144
debug_assert ! ( false ) ;
4151
4145
valid_mpp = false ;
4152
4146
break ;
4153
4147
}
4154
- }
4148
+ expected_amt_msat = Some ( htlc. total_msat ) ;
4149
+ if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
4150
+ // We don't currently support MPP for spontaneous payments, so just check
4151
+ // that there's one payment here and move on.
4152
+ if sources. len ( ) != 1 {
4153
+ log_error ! ( self . logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!" ) ;
4154
+ debug_assert ! ( false ) ;
4155
+ valid_mpp = false ;
4156
+ break ;
4157
+ }
4158
+ }
4155
4159
4156
- claimable_amt_msat += htlc. value ;
4157
- }
4158
- if sources. is_empty ( ) || expected_amt_msat. is_none ( ) {
4159
- log_info ! ( self . logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!" ) ;
4160
- return ;
4161
- }
4162
- if claimable_amt_msat != expected_amt_msat. unwrap ( ) {
4163
- log_info ! ( self . logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim." ,
4164
- expected_amt_msat. unwrap( ) , claimable_amt_msat) ;
4165
- return ;
4160
+ claimable_amt_msat += htlc. value ;
4161
+ }
4162
+ if sources. is_empty ( ) || expected_amt_msat. is_none ( ) {
4163
+ log_info ! ( self . logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!" ) ;
4164
+ return ;
4165
+ }
4166
+ if claimable_amt_msat != expected_amt_msat. unwrap ( ) {
4167
+ log_info ! ( self . logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim." ,
4168
+ expected_amt_msat. unwrap( ) , claimable_amt_msat) ;
4169
+ return ;
4170
+ }
4171
+ if valid_mpp {
4172
+ for htlc in sources. drain ( ..) {
4173
+ match self . claim_funds_from_hop ( & mut channel_state_lock, htlc. prev_hop , payment_preimage) {
4174
+ ClaimFundsFromHop :: MonitorUpdateFail ( pk, err, _) => {
4175
+ if let msgs:: ErrorAction :: IgnoreError = err. err . action {
4176
+ // We got a temporary failure updating monitor, but will claim the
4177
+ // HTLC when the monitor updating is restored (or on chain).
4178
+ log_error ! ( self . logger, "Temporary failure claiming HTLC, treating as success: {}" , err. err. err) ;
4179
+ claimed_any_htlcs = true ;
4180
+ } else { errs. push ( ( pk, err) ) ; }
4181
+ } ,
4182
+ ClaimFundsFromHop :: PrevHopForceClosed => unreachable ! ( "We already checked for channel existence, we can't fail here!" ) ,
4183
+ ClaimFundsFromHop :: DuplicateClaim => {
4184
+ // While we should never get here in most cases, if we do, it likely
4185
+ // indicates that the HTLC was timed out some time ago and is no longer
4186
+ // available to be claimed. Thus, it does not make sense to set
4187
+ // `claimed_any_htlcs`.
4188
+ } ,
4189
+ ClaimFundsFromHop :: Success ( _) => claimed_any_htlcs = true ,
4190
+ }
4191
+ }
4192
+ }
4166
4193
}
4167
-
4168
- let mut errs = Vec :: new ( ) ;
4169
- let mut claimed_any_htlcs = false ;
4170
- for htlc in sources. drain ( ..) {
4171
- if !valid_mpp {
4172
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
4194
+ if !valid_mpp {
4195
+ for htlc in sources. drain ( ..) {
4173
4196
let mut htlc_msat_height_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
4174
4197
htlc_msat_height_data. extend_from_slice ( & byte_utils:: be32_to_array (
4175
- self . best_block . read ( ) . unwrap ( ) . height ( ) ) ) ;
4198
+ self . best_block . read ( ) . unwrap ( ) . height ( ) ) ) ;
4176
4199
self . fail_htlc_backwards_internal (
4177
- HTLCSource :: PreviousHopData ( htlc. prev_hop ) , & payment_hash,
4178
- HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_height_data } ,
4179
- HTLCDestination :: FailedPayment { payment_hash } ) ;
4180
- } else {
4181
- match self . claim_funds_from_hop ( channel_state. as_mut ( ) . unwrap ( ) , htlc. prev_hop , payment_preimage) {
4182
- ClaimFundsFromHop :: MonitorUpdateFail ( pk, err, _) => {
4183
- if let msgs:: ErrorAction :: IgnoreError = err. err . action {
4184
- // We got a temporary failure updating monitor, but will claim the
4185
- // HTLC when the monitor updating is restored (or on chain).
4186
- log_error ! ( self . logger, "Temporary failure claiming HTLC, treating as success: {}" , err. err. err) ;
4187
- claimed_any_htlcs = true ;
4188
- } else { errs. push ( ( pk, err) ) ; }
4189
- } ,
4190
- ClaimFundsFromHop :: PrevHopForceClosed => unreachable ! ( "We already checked for channel existence, we can't fail here!" ) ,
4191
- ClaimFundsFromHop :: DuplicateClaim => {
4192
- // While we should never get here in most cases, if we do, it likely
4193
- // indicates that the HTLC was timed out some time ago and is no longer
4194
- // available to be claimed. Thus, it does not make sense to set
4195
- // `claimed_any_htlcs`.
4196
- } ,
4197
- ClaimFundsFromHop :: Success ( _) => claimed_any_htlcs = true ,
4198
- }
4200
+ HTLCSource :: PreviousHopData ( htlc. prev_hop ) , & payment_hash,
4201
+ HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_height_data } ,
4202
+ HTLCDestination :: FailedPayment { payment_hash } ) ;
4199
4203
}
4200
4204
}
4201
4205
@@ -4207,10 +4211,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4207
4211
} ) ;
4208
4212
}
4209
4213
4210
- // Now that we've done the entire above loop in one lock, we can handle any errors
4211
- // which were generated.
4212
- channel_state. take ( ) ;
4213
-
4214
+ // Now we can handle any errors which were generated.
4214
4215
for ( counterparty_node_id, err) in errs. drain ( ..) {
4215
4216
let res: Result < ( ) , _ > = Err ( err) ;
4216
4217
let _ = handle_error ! ( self , res, counterparty_node_id) ;
0 commit comments