@@ -1887,7 +1887,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1887
1887
1888
1888
for htlc_source in failed_htlcs. drain ( ..) {
1889
1889
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( * counterparty_node_id) , channel_id : * channel_id } ;
1890
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , htlc_source. 0 , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
1890
+ self . fail_htlc_backwards_internal ( htlc_source. 0 , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
1891
1891
}
1892
1892
1893
1893
let _ = handle_error ! ( self , result, * counterparty_node_id) ;
@@ -1945,7 +1945,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1945
1945
for htlc_source in failed_htlcs. drain ( ..) {
1946
1946
let ( source, payment_hash, counterparty_node_id, channel_id) = htlc_source;
1947
1947
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( counterparty_node_id) , channel_id : channel_id } ;
1948
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
1948
+ self . fail_htlc_backwards_internal ( source, & payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
1949
1949
}
1950
1950
if let Some ( ( funding_txo, monitor_update) ) = monitor_update_option {
1951
1951
// There isn't anything we can do if we get an update failure - we're already
@@ -3005,13 +3005,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3005
3005
let mut phantom_receives: Vec < ( u64 , OutPoint , Vec < ( PendingHTLCInfo , u64 ) > ) > = Vec :: new ( ) ;
3006
3006
let mut handle_errors = Vec :: new ( ) ;
3007
3007
{
3008
- let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
3009
- let channel_state = & mut * channel_state_lock;
3010
-
3011
3008
let mut forward_htlcs = HashMap :: new ( ) ;
3012
3009
mem:: swap ( & mut forward_htlcs, & mut self . forward_htlcs . lock ( ) . unwrap ( ) ) ;
3013
3010
3014
3011
for ( short_chan_id, mut pending_forwards) in forward_htlcs {
3012
+ let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
3013
+ let channel_state = & mut * channel_state_lock;
3015
3014
if short_chan_id != 0 {
3016
3015
let forward_chan_id = match channel_state. short_to_chan_info . get ( & short_chan_id) {
3017
3016
Some ( ( _cp_id, chan_id) ) => chan_id. clone ( ) ,
@@ -3409,7 +3408,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3409
3408
}
3410
3409
3411
3410
for ( htlc_source, payment_hash, failure_reason, destination) in failed_forwards. drain ( ..) {
3412
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , htlc_source, & payment_hash, failure_reason, destination) ;
3411
+ self . fail_htlc_backwards_internal ( htlc_source, & payment_hash, failure_reason, destination) ;
3413
3412
}
3414
3413
self . forward_htlcs ( & mut phantom_receives) ;
3415
3414
@@ -3633,7 +3632,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3633
3632
3634
3633
for htlc_source in timed_out_mpp_htlcs. drain ( ..) {
3635
3634
let receiver = HTLCDestination :: FailedPayment { payment_hash : htlc_source. 1 } ;
3636
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc_source. 0 . clone ( ) ) , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 23 , data : Vec :: new ( ) } , receiver ) ;
3635
+ self . fail_htlc_backwards_internal ( HTLCSource :: PreviousHopData ( htlc_source. 0 . clone ( ) ) , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 23 , data : Vec :: new ( ) } , receiver ) ;
3637
3636
}
3638
3637
3639
3638
for ( err, counterparty_node_id) in handle_errors. drain ( ..) {
@@ -3659,15 +3658,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3659
3658
pub fn fail_htlc_backwards ( & self , payment_hash : & PaymentHash ) {
3660
3659
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3661
3660
3662
- let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
3663
- let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( payment_hash) ;
3661
+ let removed_source = {
3662
+ let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
3663
+ channel_state. claimable_htlcs . remove ( payment_hash)
3664
+ } ;
3664
3665
if let Some ( ( _, mut sources) ) = removed_source {
3665
3666
for htlc in sources. drain ( ..) {
3666
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
3667
3667
let mut htlc_msat_height_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
3668
3668
htlc_msat_height_data. extend_from_slice ( & byte_utils:: be32_to_array (
3669
3669
self . best_block . read ( ) . unwrap ( ) . height ( ) ) ) ;
3670
- self . fail_htlc_backwards_internal ( channel_state . take ( ) . unwrap ( ) ,
3670
+ self . fail_htlc_backwards_internal (
3671
3671
HTLCSource :: PreviousHopData ( htlc. prev_hop ) , payment_hash,
3672
3672
HTLCFailReason :: Reason { failure_code : 0x4000 | 15 , data : htlc_msat_height_data } ,
3673
3673
HTLCDestination :: FailedPayment { payment_hash : * payment_hash } ) ;
@@ -3730,27 +3730,31 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3730
3730
counterparty_node_id : & PublicKey
3731
3731
) {
3732
3732
for ( htlc_src, payment_hash) in htlcs_to_fail. drain ( ..) {
3733
- let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
3734
3733
let ( failure_code, onion_failure_data) =
3735
- match channel_state. by_id . entry ( channel_id) {
3734
+ match self . channel_state . lock ( ) . unwrap ( ) . by_id . entry ( channel_id) {
3736
3735
hash_map:: Entry :: Occupied ( chan_entry) => {
3737
3736
self . get_htlc_inbound_temp_fail_err_and_data ( 0x1000 |7 , & chan_entry. get ( ) )
3738
3737
} ,
3739
3738
hash_map:: Entry :: Vacant ( _) => ( 0x4000 |10 , Vec :: new ( ) )
3740
3739
} ;
3741
3740
3742
3741
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( counterparty_node_id. clone ( ) ) , channel_id } ;
3743
- self . fail_htlc_backwards_internal ( channel_state , htlc_src, & payment_hash, HTLCFailReason :: Reason { failure_code, data : onion_failure_data } , receiver) ;
3742
+ self . fail_htlc_backwards_internal ( htlc_src, & payment_hash, HTLCFailReason :: Reason { failure_code, data : onion_failure_data } , receiver) ;
3744
3743
}
3745
3744
}
3746
3745
3747
3746
/// Fails an HTLC backwards to the sender of it to us.
3748
- /// Note that while we take a channel_state lock as input, we do *not* assume consistency here.
3749
- /// There are several callsites that do stupid things like loop over a list of payment_hashes
3750
- /// to fail and take the channel_state lock for each iteration (as we take ownership and may
3751
- /// drop it). In other words, no assumptions are made that entries in claimable_htlcs point to
3752
- /// still-available channels.
3753
- fn fail_htlc_backwards_internal ( & self , mut channel_state_lock : MutexGuard < ChannelHolder < Signer > > , source : HTLCSource , payment_hash : & PaymentHash , onion_error : HTLCFailReason , destination : HTLCDestination ) {
3747
+ /// Note that we do not assume that channels corresponding to failed HTLCs are still available.
3748
+ fn fail_htlc_backwards_internal ( & self , source : HTLCSource , payment_hash : & PaymentHash , onion_error : HTLCFailReason , destination : HTLCDestination ) {
3749
+ #[ cfg( debug_assertions) ]
3750
+ {
3751
+ // Ensure that the `channel_state` lock is not held when calling this function.
3752
+ // This ensures that future code doesn't introduce a lock_order requirement for
3753
+ // `forward_htlcs` to be locked after the `channel_state` lock, which calling this
3754
+ // function with the `channel_state` locked would.
3755
+ assert ! ( self . channel_state. try_lock( ) . is_ok( ) ) ;
3756
+ }
3757
+
3754
3758
//TODO: There is a timing attack here where if a node fails an HTLC back to us they can
3755
3759
//identify whether we sent it or not based on the (I presume) very different runtime
3756
3760
//between the branches here. We should make this async and move it into the forward HTLCs
@@ -3789,7 +3793,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3789
3793
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3790
3794
return ;
3791
3795
}
3792
- mem:: drop ( channel_state_lock) ;
3793
3796
let mut retry = if let Some ( payment_params_data) = payment_params {
3794
3797
let path_last_hop = path. last ( ) . expect ( "Outbound payments must have had a valid path" ) ;
3795
3798
Some ( RouteParameters {
@@ -3923,7 +3926,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3923
3926
}
3924
3927
}
3925
3928
mem:: drop ( forward_htlcs) ;
3926
- mem:: drop ( channel_state_lock) ;
3927
3929
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
3928
3930
if let Some ( time) = forward_event {
3929
3931
pending_events. push ( events:: Event :: PendingHTLCsForwardable {
@@ -3961,8 +3963,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3961
3963
3962
3964
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3963
3965
3964
- let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
3965
- let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) ;
3966
+ let removed_source = self . channel_state . lock ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) ;
3966
3967
if let Some ( ( payment_purpose, mut sources) ) = removed_source {
3967
3968
assert ! ( !sources. is_empty( ) ) ;
3968
3969
@@ -3980,8 +3981,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3980
3981
let mut claimable_amt_msat = 0 ;
3981
3982
let mut expected_amt_msat = None ;
3982
3983
let mut valid_mpp = true ;
3984
+ let mut errs = Vec :: new ( ) ;
3985
+ let mut claimed_any_htlcs = false ;
3986
+ let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
3987
+ let channel_state = & mut * channel_state_lock;
3983
3988
for htlc in sources. iter ( ) {
3984
- if let None = channel_state. as_ref ( ) . unwrap ( ) . short_to_chan_info . get ( & htlc. prev_hop . short_channel_id ) {
3989
+ if let None = channel_state. short_to_chan_info . get ( & htlc. prev_hop . short_channel_id ) {
3985
3990
valid_mpp = false ;
3986
3991
break ;
3987
3992
}
@@ -4014,21 +4019,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4014
4019
expected_amt_msat. unwrap( ) , claimable_amt_msat) ;
4015
4020
return ;
4016
4021
}
4017
-
4018
- let mut errs = Vec :: new ( ) ;
4019
- let mut claimed_any_htlcs = false ;
4020
- for htlc in sources. drain ( ..) {
4021
- if !valid_mpp {
4022
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
4023
- let mut htlc_msat_height_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
4024
- htlc_msat_height_data. extend_from_slice ( & byte_utils:: be32_to_array (
4025
- self . best_block . read ( ) . unwrap ( ) . height ( ) ) ) ;
4026
- self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) ,
4027
- HTLCSource :: PreviousHopData ( htlc. prev_hop ) , & payment_hash,
4028
- HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_height_data } ,
4029
- HTLCDestination :: FailedPayment { payment_hash } ) ;
4030
- } else {
4031
- match self . claim_funds_from_hop ( channel_state. as_mut ( ) . unwrap ( ) , htlc. prev_hop , payment_preimage) {
4022
+ if valid_mpp {
4023
+ for htlc in sources. drain ( ..) {
4024
+ match self . claim_funds_from_hop ( & mut channel_state_lock, htlc. prev_hop , payment_preimage) {
4032
4025
ClaimFundsFromHop :: MonitorUpdateFail ( pk, err, _) => {
4033
4026
if let msgs:: ErrorAction :: IgnoreError = err. err . action {
4034
4027
// We got a temporary failure updating monitor, but will claim the
@@ -4048,6 +4041,18 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4048
4041
}
4049
4042
}
4050
4043
}
4044
+ mem:: drop ( channel_state_lock) ;
4045
+ if !valid_mpp {
4046
+ for htlc in sources. drain ( ..) {
4047
+ let mut htlc_msat_height_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
4048
+ htlc_msat_height_data. extend_from_slice ( & byte_utils:: be32_to_array (
4049
+ self . best_block . read ( ) . unwrap ( ) . height ( ) ) ) ;
4050
+ self . fail_htlc_backwards_internal (
4051
+ HTLCSource :: PreviousHopData ( htlc. prev_hop ) , & payment_hash,
4052
+ HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_height_data } ,
4053
+ HTLCDestination :: FailedPayment { payment_hash } ) ;
4054
+ }
4055
+ }
4051
4056
4052
4057
if claimed_any_htlcs {
4053
4058
self . pending_events . lock ( ) . unwrap ( ) . push ( events:: Event :: PaymentClaimed {
@@ -4057,10 +4062,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4057
4062
} ) ;
4058
4063
}
4059
4064
4060
- // Now that we've done the entire above loop in one lock, we can handle any errors
4061
- // which were generated.
4062
- channel_state. take ( ) ;
4063
-
4065
+ // Now we can handle any errors which were generated.
4064
4066
for ( counterparty_node_id, err) in errs. drain ( ..) {
4065
4067
let res: Result < ( ) , _ > = Err ( err) ;
4066
4068
let _ = handle_error ! ( self , res, counterparty_node_id) ;
@@ -4307,7 +4309,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4307
4309
self . finalize_claims ( finalized_claims) ;
4308
4310
for failure in pending_failures. drain ( ..) {
4309
4311
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( counterparty_node_id) , channel_id : funding_txo. to_channel_id ( ) } ;
4310
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , failure. 0 , & failure. 1 , failure. 2 , receiver) ;
4312
+ self . fail_htlc_backwards_internal ( failure. 0 , & failure. 1 , failure. 2 , receiver) ;
4311
4313
}
4312
4314
}
4313
4315
@@ -4667,7 +4669,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4667
4669
} ;
4668
4670
for htlc_source in dropped_htlcs. drain ( ..) {
4669
4671
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( counterparty_node_id. clone ( ) ) , channel_id : msg. channel_id } ;
4670
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , htlc_source. 0 , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
4672
+ self . fail_htlc_backwards_internal ( htlc_source. 0 , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
4671
4673
}
4672
4674
4673
4675
let _ = handle_error ! ( self , result, * counterparty_node_id) ;
@@ -4869,7 +4871,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4869
4871
for & mut ( prev_short_channel_id, prev_funding_outpoint, ref mut pending_forwards) in per_source_pending_forwards {
4870
4872
let mut forward_event = None ;
4871
4873
if !pending_forwards. is_empty ( ) {
4872
- let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
4873
4874
let mut forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ;
4874
4875
if forward_htlcs. is_empty ( ) {
4875
4876
forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) )
@@ -4956,7 +4957,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4956
4957
{
4957
4958
for failure in pending_failures. drain ( ..) {
4958
4959
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( * counterparty_node_id) , channel_id : channel_outpoint. to_channel_id ( ) } ;
4959
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , failure. 0 , & failure. 1 , failure. 2 , receiver) ;
4960
+ self . fail_htlc_backwards_internal ( failure. 0 , & failure. 1 , failure. 2 , receiver) ;
4960
4961
}
4961
4962
self . forward_htlcs ( & mut [ ( short_channel_id, channel_outpoint, pending_forwards) ] ) ;
4962
4963
self . finalize_claims ( finalized_claim_htlcs) ;
@@ -5114,7 +5115,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
5114
5115
} else {
5115
5116
log_trace ! ( self . logger, "Failing HTLC with hash {} from our monitor" , log_bytes!( htlc_update. payment_hash. 0 ) ) ;
5116
5117
let receiver = HTLCDestination :: NextHopChannel { node_id : counterparty_node_id, channel_id : funding_outpoint. to_channel_id ( ) } ;
5117
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , htlc_update. source , & htlc_update. payment_hash , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
5118
+ self . fail_htlc_backwards_internal ( htlc_update. source , & htlc_update. payment_hash , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
5118
5119
}
5119
5120
} ,
5120
5121
MonitorEvent :: CommitmentTxConfirmed ( funding_outpoint) |
@@ -5848,7 +5849,7 @@ where
5848
5849
self . handle_init_event_channel_failures ( failed_channels) ;
5849
5850
5850
5851
for ( source, payment_hash, reason, destination) in timed_out_htlcs. drain ( ..) {
5851
- self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, reason, destination) ;
5852
+ self . fail_htlc_backwards_internal ( source, & payment_hash, reason, destination) ;
5852
5853
}
5853
5854
}
5854
5855
@@ -7210,7 +7211,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
7210
7211
for htlc_source in failed_htlcs. drain ( ..) {
7211
7212
let ( source, payment_hash, counterparty_node_id, channel_id) = htlc_source;
7212
7213
let receiver = HTLCDestination :: NextHopChannel { node_id : Some ( counterparty_node_id) , channel_id } ;
7213
- channel_manager. fail_htlc_backwards_internal ( channel_manager . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
7214
+ channel_manager. fail_htlc_backwards_internal ( source, & payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } , receiver) ;
7214
7215
}
7215
7216
7216
7217
//TODO: Broadcast channel update for closed channels, but only after we've made a
0 commit comments