Skip to content

Commit 53dc48c

Browse files
committed
Refactor push_htlc_failure out from fail_htlcs_backwards_internal
We plan to fail back HTLCs that have not been forwarded yet, so we refactored some of the failure event push logic out into it's own helper to reuse it.
1 parent c1ee493 commit 53dc48c

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

lightning/src/ln/channelmanager.rs

+33-29
Original file line numberDiff line numberDiff line change
@@ -5284,15 +5284,6 @@ where
52845284
/// Fails an HTLC backwards to the sender of it to us.
52855285
/// Note that we do not assume that channels corresponding to failed HTLCs are still available.
52865286
fn fail_htlc_backwards_internal(&self, source: &HTLCSource, payment_hash: &PaymentHash, onion_error: &HTLCFailReason, destination: HTLCDestination) {
5287-
// Ensure that no peer state channel storage lock is held when calling this function.
5288-
// This ensures that future code doesn't introduce a lock-order requirement for
5289-
// `forward_htlcs` to be locked after the `per_peer_state` peer locks, which calling
5290-
// this function with any `per_peer_state` peer lock acquired would.
5291-
#[cfg(debug_assertions)]
5292-
for (_, peer) in self.per_peer_state.read().unwrap().iter() {
5293-
debug_assert_ne!(peer.held_by_thread(), LockHeldState::HeldByThread);
5294-
}
5295-
52965287
//TODO: There is a timing attack here where if a node fails an HTLC back to us they can
52975288
//identify whether we sent it or not based on the (I presume) very different runtime
52985289
//between the branches here. We should make this async and move it into the forward HTLCs
@@ -5340,28 +5331,41 @@ where
53405331
}
53415332
};
53425333

5343-
let mut push_forward_ev = false;
5344-
let mut forward_htlcs = self.forward_htlcs.lock().unwrap();
5345-
if forward_htlcs.is_empty() {
5346-
push_forward_ev = true;
5347-
}
5348-
match forward_htlcs.entry(*short_channel_id) {
5349-
hash_map::Entry::Occupied(mut entry) => {
5350-
entry.get_mut().push(failure);
5351-
},
5352-
hash_map::Entry::Vacant(entry) => {
5353-
entry.insert(vec!(failure));
5354-
}
5355-
}
5356-
mem::drop(forward_htlcs);
5357-
if push_forward_ev { self.push_pending_forwards_ev(); }
5358-
let mut pending_events = self.pending_events.lock().unwrap();
5359-
pending_events.push_back((events::Event::HTLCHandlingFailed {
5360-
prev_channel_id: outpoint.to_channel_id(),
5361-
failed_next_destination: destination,
5362-
}, None));
5334+
self.push_htlc_failure(*short_channel_id, outpoint.to_channel_id(), failure, destination);
5335+
}
5336+
}
5337+
}
5338+
5339+
fn push_htlc_failure(&self, short_channel_id: u64, channel_id: ChannelId, failure: HTLCForwardInfo, destination: HTLCDestination) {
5340+
// Ensure that no peer state channel storage lock is held when calling this function.
5341+
// This ensures that future code doesn't introduce a lock-order requirement for
5342+
// `forward_htlcs` to be locked after the `per_peer_state` peer locks, which calling
5343+
// this function with any `per_peer_state` peer lock acquired would.
5344+
#[cfg(debug_assertions)]
5345+
for (_, peer) in self.per_peer_state.read().unwrap().iter() {
5346+
debug_assert_ne!(peer.held_by_thread(), LockHeldState::HeldByThread);
5347+
}
5348+
5349+
let mut push_forward_ev = false;
5350+
let mut forward_htlcs = self.forward_htlcs.lock().unwrap();
5351+
if forward_htlcs.is_empty() {
5352+
push_forward_ev = true;
5353+
}
5354+
match forward_htlcs.entry(short_channel_id) {
5355+
hash_map::Entry::Occupied(mut entry) => {
5356+
entry.get_mut().push(failure);
53635357
},
5358+
hash_map::Entry::Vacant(entry) => {
5359+
entry.insert(vec!(failure));
5360+
}
53645361
}
5362+
mem::drop(forward_htlcs);
5363+
if push_forward_ev { self.push_pending_forwards_ev(); }
5364+
let mut pending_events = self.pending_events.lock().unwrap();
5365+
pending_events.push_back((events::Event::HTLCHandlingFailed {
5366+
prev_channel_id: channel_id,
5367+
failed_next_destination: destination,
5368+
}, None));
53655369
}
53665370

53675371
/// Provides a payment preimage in response to [`Event::PaymentClaimable`], generating any

0 commit comments

Comments
 (0)