Skip to content

Commit 0a86510

Browse files
f convert already_forwarded_htlcs to a hashmap
1 parent 7aac803 commit 0a86510

1 file changed

Lines changed: 72 additions & 47 deletions

File tree

lightning/src/ln/channelmanager.rs

Lines changed: 72 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -18612,17 +18612,24 @@ impl<
1861218612
// edge or (b) removed from the outbound edge via claim. If it's in neither of these states, we
1861318613
// infer that it was removed from the outbound edge via fail, and fail it backwards to ensure
1861418614
// that it is handled.
18615-
let mut already_forwarded_htlcs = Vec::new();
18616-
let prune_forwarded_htlc =
18617-
|already_forwarded_htlcs: &mut Vec<(PaymentHash, HTLCPreviousHopData, u64)>,
18618-
prev_hop: &HTLCPreviousHopData| {
18619-
if let Some(idx) = already_forwarded_htlcs.iter().position(|(_, htlc, _)| {
18620-
prev_hop.htlc_id == htlc.htlc_id
18621-
&& prev_hop.prev_outbound_scid_alias == htlc.prev_outbound_scid_alias
18622-
}) {
18623-
already_forwarded_htlcs.swap_remove(idx);
18615+
let mut already_forwarded_htlcs: HashMap<
18616+
ChannelId,
18617+
Vec<(PaymentHash, HTLCPreviousHopData, u64)>,
18618+
> = new_hash_map();
18619+
let prune_forwarded_htlc = |already_forwarded_htlcs: &mut HashMap<
18620+
ChannelId,
18621+
Vec<(PaymentHash, HTLCPreviousHopData, u64)>,
18622+
>,
18623+
prev_hop: &HTLCPreviousHopData| {
18624+
if let hash_map::Entry::Occupied(mut entry) =
18625+
already_forwarded_htlcs.entry(prev_hop.channel_id)
18626+
{
18627+
entry.get_mut().retain(|(_, htlc, _)| prev_hop.htlc_id != htlc.htlc_id);
18628+
if entry.get().is_empty() {
18629+
entry.remove();
1862418630
}
18625-
};
18631+
}
18632+
};
1862618633
{
1862718634
// If we're tracking pending payments, ensure we haven't lost any by looking at the
1862818635
// ChannelMonitor data for any channels for which we do not have authorative state
@@ -18667,11 +18674,23 @@ impl<
1866718674
hop_data,
1866818675
outbound_amt_msat,
1866918676
} => {
18670-
already_forwarded_htlcs.push((
18671-
payment_hash,
18672-
hop_data,
18673-
outbound_amt_msat,
18674-
));
18677+
match already_forwarded_htlcs.entry(hop_data.channel_id)
18678+
{
18679+
hash_map::Entry::Occupied(mut entry) => {
18680+
entry.get_mut().push((
18681+
payment_hash,
18682+
hop_data,
18683+
outbound_amt_msat,
18684+
));
18685+
},
18686+
hash_map::Entry::Vacant(entry) => {
18687+
entry.insert(vec![(
18688+
payment_hash,
18689+
hop_data,
18690+
outbound_amt_msat,
18691+
)]);
18692+
},
18693+
}
1867518694
},
1867618695
InboundUpdateAdd::Legacy => {
1867718696
return Err(DecodeError::InvalidValue)
@@ -19371,44 +19390,50 @@ impl<
1937119390

1937219391
let mut processed_claims: HashSet<Vec<MPPClaimHTLCSource>> = new_hash_set();
1937319392
for (channel_id, monitor) in args.channel_monitors.iter() {
19393+
let counterparty_node_id = monitor.get_counterparty_node_id();
1937419394
for (payment_hash, (payment_preimage, payment_claims)) in monitor.get_stored_preimages()
1937519395
{
1937619396
// If we have unresolved inbound committed HTLCs that were already forwarded to the
1937719397
// outbound edge and removed via claim, we need to make sure to claim them backwards via
1937819398
// adding them to `pending_claims_to_replay`.
19379-
for (hash, hop_data, outbound_amt_msat) in
19380-
mem::take(&mut already_forwarded_htlcs).drain(..)
19399+
if let hash_map::Entry::Occupied(mut entry) =
19400+
already_forwarded_htlcs.entry(*channel_id)
1938119401
{
19382-
if hash != payment_hash {
19383-
already_forwarded_htlcs.push((hash, hop_data, outbound_amt_msat));
19384-
continue;
19385-
}
19386-
let new_pending_claim = !pending_claims_to_replay.iter().any(|(src, _, _, _, _, _, _)| {
19387-
matches!(src, HTLCSource::PreviousHopData(hop) if hop.htlc_id == hop_data.htlc_id && hop.prev_outbound_scid_alias == hop_data.prev_outbound_scid_alias)
19388-
});
19389-
if new_pending_claim {
19390-
let counterparty_node_id = monitor.get_counterparty_node_id();
19391-
let is_channel_closed = channel_manager
19392-
.per_peer_state
19393-
.read()
19394-
.unwrap()
19395-
.get(&counterparty_node_id)
19396-
.map_or(true, |peer_state_mtx| {
19397-
!peer_state_mtx
19398-
.lock()
19399-
.unwrap()
19400-
.channel_by_id
19401-
.contains_key(channel_id)
19402+
for (hash, hop_data, outbound_amt_msat) in mem::take(entry.get_mut()) {
19403+
if hash != payment_hash {
19404+
entry.get_mut().push((hash, hop_data, outbound_amt_msat));
19405+
continue;
19406+
}
19407+
let new_pending_claim =
19408+
!pending_claims_to_replay.iter().any(|(src, _, _, _, _, _, _)| {
19409+
matches!(src, HTLCSource::PreviousHopData(hop) if hop.htlc_id == hop_data.htlc_id && hop.channel_id == hop_data.channel_id)
1940219410
});
19403-
pending_claims_to_replay.push((
19404-
HTLCSource::PreviousHopData(hop_data),
19405-
payment_preimage,
19406-
outbound_amt_msat,
19407-
is_channel_closed,
19408-
counterparty_node_id,
19409-
monitor.get_funding_txo(),
19410-
*channel_id,
19411-
));
19411+
if new_pending_claim {
19412+
let is_channel_closed = channel_manager
19413+
.per_peer_state
19414+
.read()
19415+
.unwrap()
19416+
.get(&counterparty_node_id)
19417+
.map_or(true, |peer_state_mtx| {
19418+
!peer_state_mtx
19419+
.lock()
19420+
.unwrap()
19421+
.channel_by_id
19422+
.contains_key(channel_id)
19423+
});
19424+
pending_claims_to_replay.push((
19425+
HTLCSource::PreviousHopData(hop_data),
19426+
payment_preimage,
19427+
outbound_amt_msat,
19428+
is_channel_closed,
19429+
counterparty_node_id,
19430+
monitor.get_funding_txo(),
19431+
*channel_id,
19432+
));
19433+
}
19434+
}
19435+
if entry.get().is_empty() {
19436+
entry.remove();
1941219437
}
1941319438
}
1941419439
if !payment_claims.is_empty() {
@@ -19652,7 +19677,7 @@ impl<
1965219677
channel_manager
1965319678
.fail_htlc_backwards_internal(&source, &hash, &reason, receiver, ev_action);
1965419679
}
19655-
for (hash, htlc, _) in already_forwarded_htlcs {
19680+
for (hash, htlc, _) in already_forwarded_htlcs.into_values().flatten() {
1965619681
let channel_id = htlc.channel_id;
1965719682
let node_id = htlc.counterparty_node_id;
1965819683
let source = HTLCSource::PreviousHopData(htlc);

0 commit comments

Comments
 (0)