Skip to content

Commit 56d6a2c

Browse files
Move claimable_htlcs to separate lock
1 parent d15b7cb commit 56d6a2c

File tree

1 file changed

+54
-48
lines changed

1 file changed

+54
-48
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,6 @@ pub(super) struct ChannelHolder<Signer: Sign> {
401401
/// SCIDs being added once the funding transaction is confirmed at the channel's required
402402
/// confirmation depth.
403403
pub(super) short_to_chan_info: HashMap<u64, (PublicKey, [u8; 32])>,
404-
/// Map from payment hash to the payment data and any HTLCs which are to us and can be
405-
/// failed/claimed by the user.
406-
///
407-
/// Note that while this is held in the same mutex as the channels themselves, no consistency
408-
/// guarantees are made about the channels given here actually existing anymore by the time you
409-
/// go to read them!
410-
claimable_htlcs: HashMap<PaymentHash, (events::PaymentPurpose, Vec<ClaimableHTLC>)>,
411404
/// Messages to send to peers - pushed to in the same lock that they are generated in (except
412405
/// for broadcast messages, where ordering isn't as strict).
413406
pub(super) pending_msg_events: Vec<MessageSendEvent>,
@@ -691,6 +684,8 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManage
691684
// | |
692685
// | |__`pending_inbound_payments`
693686
// | |
687+
// | |__`claimable_htlcs`
688+
// | |
694689
// | |__`pending_outbound_payments`
695690
// | |
696691
// | |__`best_block`
@@ -762,6 +757,15 @@ pub struct ChannelManager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
762757
#[cfg(not(test))]
763758
forward_htlcs: Mutex<HashMap<u64, Vec<HTLCForwardInfo>>>,
764759

760+
/// Map from payment hash to the payment data and any HTLCs which are to us and can be
761+
/// failed/claimed by the user.
762+
///
763+
/// Note that, no consistency guarantees are made about the channels given here actually
764+
/// existing anymore by the time you go to read them!
765+
///
766+
/// See `ChannelManager` struct-level documentation for lock order requirements.
767+
claimable_htlcs: Mutex<HashMap<PaymentHash, (events::PaymentPurpose, Vec<ClaimableHTLC>)>>,
768+
765769
/// The set of outbound SCID aliases across all our channels, including unconfirmed channels
766770
/// and some closed channels which reached a usable state prior to being closed. This is used
767771
/// only to avoid duplicates, and is not persisted explicitly to disk, but rebuilt from the
@@ -1645,13 +1649,13 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
16451649
channel_state: Mutex::new(ChannelHolder{
16461650
by_id: HashMap::new(),
16471651
short_to_chan_info: HashMap::new(),
1648-
claimable_htlcs: HashMap::new(),
16491652
pending_msg_events: Vec::new(),
16501653
}),
16511654
outbound_scid_aliases: Mutex::new(HashSet::new()),
16521655
pending_inbound_payments: Mutex::new(HashMap::new()),
16531656
pending_outbound_payments: Mutex::new(HashMap::new()),
16541657
forward_htlcs: Mutex::new(HashMap::new()),
1658+
claimable_htlcs: Mutex::new(HashMap::new()),
16551659
id_to_peer: Mutex::new(HashMap::new()),
16561660

16571661
our_network_key: keys_manager.get_node_secret(Recipient::Node).unwrap(),
@@ -3065,9 +3069,9 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
30653069
mem::swap(&mut forward_htlcs, &mut self.forward_htlcs.lock().unwrap());
30663070

30673071
for (short_chan_id, mut pending_forwards) in forward_htlcs {
3068-
let mut channel_state_lock = self.channel_state.lock().unwrap();
3069-
let channel_state = &mut *channel_state_lock;
30703072
if short_chan_id != 0 {
3073+
let mut channel_state_lock = self.channel_state.lock().unwrap();
3074+
let channel_state = &mut *channel_state_lock;
30713075
let forward_chan_id = match channel_state.short_to_chan_info.get(&short_chan_id) {
30723076
Some((_cp_id, chan_id)) => chan_id.clone(),
30733077
None => {
@@ -3348,7 +3352,8 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
33483352
payment_secret: $payment_data.payment_secret,
33493353
}
33503354
};
3351-
let (_, htlcs) = channel_state.claimable_htlcs.entry(payment_hash)
3355+
let mut claimable_htlcs = self.claimable_htlcs.lock().unwrap();
3356+
let (_, htlcs) = claimable_htlcs.entry(payment_hash)
33523357
.or_insert_with(|| (purpose(), Vec::new()));
33533358
if htlcs.len() == 1 {
33543359
if let OnionPayload::Spontaneous(_) = htlcs[0].onion_payload {
@@ -3416,7 +3421,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
34163421
check_total_value!(payment_data, payment_preimage);
34173422
},
34183423
OnionPayload::Spontaneous(preimage) => {
3419-
match channel_state.claimable_htlcs.entry(payment_hash) {
3424+
match self.claimable_htlcs.lock().unwrap().entry(payment_hash) {
34203425
hash_map::Entry::Vacant(e) => {
34213426
let purpose = events::PaymentPurpose::SpontaneousPayment(preimage);
34223427
e.insert((purpose.clone(), vec![claimable_htlc]));
@@ -3669,7 +3674,9 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
36693674
true
36703675
});
36713676

3672-
channel_state.claimable_htlcs.retain(|payment_hash, (_, htlcs)| {
3677+
mem::drop(channel_state_lock);
3678+
3679+
self.claimable_htlcs.lock().unwrap().retain(|payment_hash, (_, htlcs)| {
36733680
if htlcs.is_empty() {
36743681
// This should be unreachable
36753682
debug_assert!(false);
@@ -3720,10 +3727,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
37203727
pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) {
37213728
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
37223729

3723-
let removed_source = {
3724-
let mut channel_state = self.channel_state.lock().unwrap();
3725-
channel_state.claimable_htlcs.remove(payment_hash)
3726-
};
3730+
let removed_source = self.claimable_htlcs.lock().unwrap().remove(payment_hash);
37273731
if let Some((_, mut sources)) = removed_source {
37283732
for htlc in sources.drain(..) {
37293733
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
@@ -4025,7 +4029,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
40254029

40264030
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
40274031

4028-
let removed_source = self.channel_state.lock().unwrap().claimable_htlcs.remove(&payment_hash);
4032+
let removed_source = self.claimable_htlcs.lock().unwrap().remove(&payment_hash);
40294033
if let Some((payment_purpose, mut sources)) = removed_source {
40304034
assert!(!sources.is_empty());
40314035

@@ -5908,28 +5912,28 @@ where
59085912
}
59095913
true
59105914
});
5915+
}
59115916

5912-
if let Some(height) = height_opt {
5913-
channel_state.claimable_htlcs.retain(|payment_hash, (_, htlcs)| {
5914-
htlcs.retain(|htlc| {
5915-
// If height is approaching the number of blocks we think it takes us to get
5916-
// our commitment transaction confirmed before the HTLC expires, plus the
5917-
// number of blocks we generally consider it to take to do a commitment update,
5918-
// just give up on it and fail the HTLC.
5919-
if height >= htlc.cltv_expiry - HTLC_FAIL_BACK_BUFFER {
5920-
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
5921-
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(height));
5922-
5923-
timed_out_htlcs.push((HTLCSource::PreviousHopData(htlc.prev_hop.clone()), payment_hash.clone(), HTLCFailReason::Reason {
5924-
failure_code: 0x4000 | 15,
5925-
data: htlc_msat_height_data
5926-
}, HTLCDestination::FailedPayment { payment_hash: payment_hash.clone() }));
5927-
false
5928-
} else { true }
5929-
});
5930-
!htlcs.is_empty() // Only retain this entry if htlcs has at least one entry.
5917+
if let Some(height) = height_opt {
5918+
self.claimable_htlcs.lock().unwrap().retain(|payment_hash, (_, htlcs)| {
5919+
htlcs.retain(|htlc| {
5920+
// If height is approaching the number of blocks we think it takes us to get
5921+
// our commitment transaction confirmed before the HTLC expires, plus the
5922+
// number of blocks we generally consider it to take to do a commitment update,
5923+
// just give up on it and fail the HTLC.
5924+
if height >= htlc.cltv_expiry - HTLC_FAIL_BACK_BUFFER {
5925+
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
5926+
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(height));
5927+
5928+
timed_out_htlcs.push((HTLCSource::PreviousHopData(htlc.prev_hop.clone()), payment_hash.clone(), HTLCFailReason::Reason {
5929+
failure_code: 0x4000 | 15,
5930+
data: htlc_msat_height_data
5931+
}, HTLCDestination::FailedPayment { payment_hash: payment_hash.clone() }));
5932+
false
5933+
} else { true }
59315934
});
5932-
}
5935+
!htlcs.is_empty() // Only retain this entry if htlcs has at least one entry.
5936+
});
59335937
}
59345938

59355939
self.handle_init_event_channel_failures(failed_channels);
@@ -6664,16 +6668,18 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelMana
66646668
}
66656669
}
66666670

6667-
let channel_state = self.channel_state.lock().unwrap();
6668-
let mut htlc_purposes: Vec<&events::PaymentPurpose> = Vec::new();
6669-
(channel_state.claimable_htlcs.len() as u64).write(writer)?;
6670-
for (payment_hash, (purpose, previous_hops)) in channel_state.claimable_htlcs.iter() {
6671-
payment_hash.write(writer)?;
6672-
(previous_hops.len() as u64).write(writer)?;
6673-
for htlc in previous_hops.iter() {
6674-
htlc.write(writer)?;
6671+
let mut htlc_purposes: Vec<events::PaymentPurpose> = Vec::new();
6672+
{
6673+
let claimable_htlcs = self.claimable_htlcs.lock().unwrap();
6674+
(claimable_htlcs.len() as u64).write(writer)?;
6675+
for (payment_hash, (purpose, previous_hops)) in claimable_htlcs.iter() {
6676+
payment_hash.write(writer)?;
6677+
(previous_hops.len() as u64).write(writer)?;
6678+
for htlc in previous_hops.iter() {
6679+
htlc.write(writer)?;
6680+
}
6681+
htlc_purposes.push(purpose.clone());
66756682
}
6676-
htlc_purposes.push(purpose);
66776683
}
66786684

66796685
let per_peer_state = self.per_peer_state.write().unwrap();
@@ -7279,14 +7285,14 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
72797285
channel_state: Mutex::new(ChannelHolder {
72807286
by_id,
72817287
short_to_chan_info,
7282-
claimable_htlcs,
72837288
pending_msg_events: Vec::new(),
72847289
}),
72857290
inbound_payment_key: expanded_inbound_key,
72867291
pending_inbound_payments: Mutex::new(pending_inbound_payments),
72877292
pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()),
72887293

72897294
forward_htlcs: Mutex::new(forward_htlcs),
7295+
claimable_htlcs: Mutex::new(claimable_htlcs),
72907296
outbound_scid_aliases: Mutex::new(outbound_scid_aliases),
72917297
id_to_peer: Mutex::new(id_to_peer),
72927298
fake_scid_rand_bytes: fake_scid_rand_bytes.unwrap(),

0 commit comments

Comments
 (0)