Skip to content

Commit 2f5e940

Browse files
committed
Move receiving HTLCs to a receive_htlcs field
Previously, we'd store receiving HTLCs side-by-side with HTLCs forwards in the `forwards_htlcs` field under SCID 0. Here, we opt to split out a separate `receive_htlcs` field, also omitting the 0 magic value.
1 parent b8baee9 commit 2f5e940

File tree

2 files changed

+105
-72
lines changed

2 files changed

+105
-72
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,6 +2462,8 @@ where
24622462
// | |
24632463
// | |__`pending_intercepted_htlcs`
24642464
// |
2465+
// |__`receive_htlcs`
2466+
// |
24652467
// |__`decode_update_add_htlcs`
24662468
// |
24672469
// |__`per_peer_state`
@@ -2537,7 +2539,7 @@ pub struct ChannelManager<
25372539
/// See `ChannelManager` struct-level documentation for lock order requirements.
25382540
pending_outbound_payments: OutboundPayments,
25392541

2540-
/// SCID/SCID Alias -> forward infos. Key of 0 means payments received.
2542+
/// SCID/SCID Alias -> forward infos.
25412543
///
25422544
/// Note that because we may have an SCID Alias as the key we can have two entries per channel,
25432545
/// though in practice we probably won't be receiving HTLCs for a channel both via the alias
@@ -2556,7 +2558,13 @@ pub struct ChannelManager<
25562558
///
25572559
/// See `ChannelManager` struct-level documentation for lock order requirements.
25582560
pending_intercepted_htlcs: Mutex<HashMap<InterceptId, PendingAddHTLCInfo>>,
2559-
2561+
/// Storage for HTLCs that are meant for us.
2562+
///
2563+
/// See `ChannelManager` struct-level documentation for lock order requirements.
2564+
#[cfg(test)]
2565+
pub(super) receive_htlcs: Mutex<Vec<HTLCForwardInfo>>,
2566+
#[cfg(not(test))]
2567+
receive_htlcs: Mutex<Vec<HTLCForwardInfo>>,
25602568
/// SCID/SCID Alias -> pending `update_add_htlc`s to decode.
25612569
///
25622570
/// Note that because we may have an SCID Alias as the key we can have two entries per channel,
@@ -3738,6 +3746,7 @@ where
37383746
outbound_scid_aliases: Mutex::new(new_hash_set()),
37393747
pending_outbound_payments: OutboundPayments::new(new_hash_map()),
37403748
forward_htlcs: Mutex::new(new_hash_map()),
3749+
receive_htlcs: Mutex::new(Vec::new()),
37413750
decode_update_add_htlcs: Mutex::new(new_hash_map()),
37423751
claimable_payments: Mutex::new(ClaimablePayments { claimable_payments: new_hash_map(), pending_claiming_payments: new_hash_map() }),
37433752
pending_intercepted_htlcs: Mutex::new(new_hash_map()),
@@ -6355,6 +6364,9 @@ where
63556364
if !self.forward_htlcs.lock().unwrap().is_empty() {
63566365
return true;
63576366
}
6367+
if !self.receive_htlcs.lock().unwrap().is_empty() {
6368+
return true;
6369+
}
63586370
if !self.decode_update_add_htlcs.lock().unwrap().is_empty() {
63596371
return true;
63606372
}
@@ -6402,22 +6414,18 @@ where
64026414

64036415
for (short_chan_id, mut pending_forwards) in forward_htlcs {
64046416
should_persist = NotifyOption::DoPersist;
6405-
if short_chan_id != 0 {
6406-
self.process_forward_htlcs(
6407-
short_chan_id,
6408-
&mut pending_forwards,
6409-
&mut failed_forwards,
6410-
&mut phantom_receives,
6411-
);
6412-
} else {
6413-
self.process_receive_htlcs(
6414-
&mut pending_forwards,
6415-
&mut new_events,
6416-
&mut failed_forwards,
6417-
);
6418-
}
6417+
self.process_forward_htlcs(
6418+
short_chan_id,
6419+
&mut pending_forwards,
6420+
&mut failed_forwards,
6421+
&mut phantom_receives,
6422+
);
64196423
}
64206424

6425+
let mut receive_htlcs = Vec::new();
6426+
mem::swap(&mut receive_htlcs, &mut self.receive_htlcs.lock().unwrap());
6427+
self.process_receive_htlcs(receive_htlcs, &mut new_events, &mut failed_forwards);
6428+
64216429
let best_block_height = self.best_block.read().unwrap().height;
64226430
let needs_persist = self.pending_outbound_payments.check_retry_payments(
64236431
&self.router,
@@ -6929,11 +6937,11 @@ where
69296937
}
69306938

69316939
fn process_receive_htlcs(
6932-
&self, pending_forwards: &mut Vec<HTLCForwardInfo>,
6940+
&self, receive_htlcs: Vec<HTLCForwardInfo>,
69336941
new_events: &mut VecDeque<(Event, Option<EventCompletionAction>)>,
69346942
failed_forwards: &mut Vec<FailedHTLCForward>,
69356943
) {
6936-
'next_forwardable_htlc: for forward_info in pending_forwards.drain(..) {
6944+
'next_forwardable_htlc: for forward_info in receive_htlcs.into_iter() {
69376945
match forward_info {
69386946
HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
69396947
prev_short_channel_id,
@@ -10346,8 +10354,21 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1034610354
let scid = match forward_info.routing {
1034710355
PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id,
1034810356
PendingHTLCRouting::TrampolineForward { .. } => 0,
10349-
PendingHTLCRouting::Receive { .. } => 0,
10350-
PendingHTLCRouting::ReceiveKeysend { .. } => 0,
10357+
PendingHTLCRouting::Receive { .. }
10358+
| PendingHTLCRouting::ReceiveKeysend { .. } => {
10359+
self.receive_htlcs.lock().unwrap().push(HTLCForwardInfo::AddHTLC(
10360+
PendingAddHTLCInfo {
10361+
prev_short_channel_id,
10362+
prev_counterparty_node_id,
10363+
prev_funding_outpoint,
10364+
prev_channel_id,
10365+
prev_htlc_id,
10366+
prev_user_channel_id,
10367+
forward_info,
10368+
},
10369+
));
10370+
continue;
10371+
},
1035110372
};
1035210373
// Pull this now to avoid introducing a lock order with `forward_htlcs`.
1035310374
let is_our_scid = self.short_to_chan_info.read().unwrap().contains_key(&scid);
@@ -15091,6 +15112,8 @@ where
1509115112
}
1509215113
}
1509315114

15115+
let receive_htlcs = self.receive_htlcs.lock().unwrap();
15116+
1509415117
let mut decode_update_add_htlcs_opt = None;
1509515118
let decode_update_add_htlcs = self.decode_update_add_htlcs.lock().unwrap();
1509615119
if !decode_update_add_htlcs.is_empty() {
@@ -15258,6 +15281,7 @@ where
1525815281
(17, in_flight_monitor_updates, option),
1525915282
(19, peer_storage_dir, optional_vec),
1526015283
(21, self.flow.writeable_async_receive_offer_cache(), required),
15284+
(23, *receive_htlcs, required_vec),
1526115285
});
1526215286

1526315287
Ok(())
@@ -15818,6 +15842,7 @@ where
1581815842
const MAX_ALLOC_SIZE: usize = 1024 * 64;
1581915843
let forward_htlcs_count: u64 = Readable::read(reader)?;
1582015844
let mut forward_htlcs = hash_map_with_capacity(cmp::min(forward_htlcs_count as usize, 128));
15845+
let mut legacy_receive_htlcs: Vec<HTLCForwardInfo> = Vec::new();
1582115846
for _ in 0..forward_htlcs_count {
1582215847
let short_channel_id = Readable::read(reader)?;
1582315848
let pending_forwards_count: u64 = Readable::read(reader)?;
@@ -15826,7 +15851,26 @@ where
1582615851
MAX_ALLOC_SIZE / mem::size_of::<HTLCForwardInfo>(),
1582715852
));
1582815853
for _ in 0..pending_forwards_count {
15829-
pending_forwards.push(Readable::read(reader)?);
15854+
let pending_htlc = Readable::read(reader)?;
15855+
// Prior to LDK 0.2, Receive HTLCs used to be stored in `forward_htlcs` under SCID == 0. Here we migrate
15856+
// the old data if necessary.
15857+
if short_channel_id == 0 {
15858+
match pending_htlc {
15859+
HTLCForwardInfo::AddHTLC(ref htlc_info) => {
15860+
if matches!(
15861+
htlc_info.forward_info.routing,
15862+
PendingHTLCRouting::Receive { .. }
15863+
| PendingHTLCRouting::ReceiveKeysend { .. }
15864+
) {
15865+
legacy_receive_htlcs.push(pending_htlc);
15866+
continue;
15867+
}
15868+
},
15869+
_ => {},
15870+
}
15871+
}
15872+
15873+
pending_forwards.push(pending_htlc);
1583015874
}
1583115875
forward_htlcs.insert(short_channel_id, pending_forwards);
1583215876
}
@@ -15943,6 +15987,7 @@ where
1594315987
let mut inbound_payment_id_secret = None;
1594415988
let mut peer_storage_dir: Option<Vec<(PublicKey, Vec<u8>)>> = None;
1594515989
let mut async_receive_offer_cache: AsyncReceiveOfferCache = AsyncReceiveOfferCache::new();
15990+
let mut receive_htlcs = None;
1594615991
read_tlv_fields!(reader, {
1594715992
(1, pending_outbound_payments_no_retry, option),
1594815993
(2, pending_intercepted_htlcs, option),
@@ -15961,8 +16006,10 @@ where
1596116006
(17, in_flight_monitor_updates, option),
1596216007
(19, peer_storage_dir, optional_vec),
1596316008
(21, async_receive_offer_cache, (default_value, async_receive_offer_cache)),
16009+
(23, receive_htlcs, optional_vec),
1596416010
});
1596516011
let mut decode_update_add_htlcs = decode_update_add_htlcs.unwrap_or_else(|| new_hash_map());
16012+
let receive_htlcs = receive_htlcs.unwrap_or_else(|| legacy_receive_htlcs);
1596616013
let peer_storage_dir: Vec<(PublicKey, Vec<u8>)> = peer_storage_dir.unwrap_or_else(Vec::new);
1596716014
if fake_scid_rand_bytes.is_none() {
1596816015
fake_scid_rand_bytes = Some(args.entropy_source.get_secure_random_bytes());
@@ -16791,6 +16838,7 @@ where
1679116838
pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),
1679216839

1679316840
forward_htlcs: Mutex::new(forward_htlcs),
16841+
receive_htlcs: Mutex::new(receive_htlcs),
1679416842
decode_update_add_htlcs: Mutex::new(decode_update_add_htlcs),
1679516843
claimable_payments: Mutex::new(ClaimablePayments {
1679616844
claimable_payments,

lightning/src/ln/payment_tests.rs

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -636,30 +636,23 @@ fn test_reject_mpp_keysend_htlc_mismatching_secret() {
636636
nodes[3].node.process_pending_update_add_htlcs();
637637

638638
assert!(nodes[3].node.get_and_clear_pending_msg_events().is_empty());
639-
assert_eq!(nodes[3].node.forward_htlcs.lock().unwrap().len(), 1);
640-
if let Some((_, pending_forwards)) =
641-
nodes[3].node.forward_htlcs.lock().unwrap().iter_mut().next()
642-
{
643-
assert_eq!(pending_forwards.len(), 1);
644-
match pending_forwards.get_mut(0).unwrap() {
645-
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { ref mut forward_info, .. }) => {
646-
match forward_info.routing {
647-
PendingHTLCRouting::ReceiveKeysend { ref mut payment_data, .. } => {
648-
*payment_data = Some(msgs::FinalOnionHopData {
649-
payment_secret: PaymentSecret([42; 32]),
650-
total_msat: amount * 2,
651-
});
652-
},
653-
_ => panic!("Expected PendingHTLCRouting::ReceiveKeysend"),
654-
}
655-
},
656-
_ => {
657-
panic!("Unexpected HTLCForwardInfo");
658-
},
659-
}
660-
} else {
661-
panic!("Expected pending receive");
662-
};
639+
assert_eq!(nodes[3].node.receive_htlcs.lock().unwrap().len(), 1);
640+
match nodes[3].node.receive_htlcs.lock().unwrap().get_mut(0).unwrap() {
641+
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { ref mut forward_info, .. }) => {
642+
match forward_info.routing {
643+
PendingHTLCRouting::ReceiveKeysend { ref mut payment_data, .. } => {
644+
*payment_data = Some(msgs::FinalOnionHopData {
645+
payment_secret: PaymentSecret([42; 32]),
646+
total_msat: amount * 2,
647+
});
648+
},
649+
_ => panic!("Expected PendingHTLCRouting::ReceiveKeysend"),
650+
}
651+
},
652+
_ => {
653+
panic!("Unexpected HTLCForwardInfo");
654+
},
655+
}
663656
nodes[3].node.process_pending_htlc_forwards();
664657

665658
// Pay along nodes[2]
@@ -687,34 +680,26 @@ fn test_reject_mpp_keysend_htlc_mismatching_secret() {
687680
let update_add_3 = update_3.update_add_htlcs[0].clone();
688681
nodes[3].node.handle_update_add_htlc(node_c_id, &update_add_3);
689682
commitment_signed_dance!(nodes[3], nodes[2], update_3.commitment_signed, false, true);
690-
expect_htlc_failure_conditions(nodes[3].node.get_and_clear_pending_events(), &[]);
691-
nodes[3].node.process_pending_update_add_htlcs();
692-
683+
assert!(nodes[3].node.get_and_clear_pending_events().is_empty());
693684
assert!(nodes[3].node.get_and_clear_pending_msg_events().is_empty());
694-
assert_eq!(nodes[3].node.forward_htlcs.lock().unwrap().len(), 1);
695-
if let Some((_, pending_forwards)) =
696-
nodes[3].node.forward_htlcs.lock().unwrap().iter_mut().next()
697-
{
698-
assert_eq!(pending_forwards.len(), 1);
699-
match pending_forwards.get_mut(0).unwrap() {
700-
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { ref mut forward_info, .. }) => {
701-
match forward_info.routing {
702-
PendingHTLCRouting::ReceiveKeysend { ref mut payment_data, .. } => {
703-
*payment_data = Some(msgs::FinalOnionHopData {
704-
payment_secret: PaymentSecret([43; 32]), // Doesn't match the secret used above
705-
total_msat: amount * 2,
706-
});
707-
},
708-
_ => panic!("Expected PendingHTLCRouting::ReceiveKeysend"),
709-
}
710-
},
711-
_ => {
712-
panic!("Unexpected HTLCForwardInfo");
713-
},
714-
}
715-
} else {
716-
panic!("Expected pending receive");
717-
};
685+
nodes[3].node.process_pending_update_add_htlcs();
686+
assert_eq!(nodes[3].node.receive_htlcs.lock().unwrap().len(), 1);
687+
match nodes[3].node.receive_htlcs.lock().unwrap().get_mut(0).unwrap() {
688+
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { ref mut forward_info, .. }) => {
689+
match forward_info.routing {
690+
PendingHTLCRouting::ReceiveKeysend { ref mut payment_data, .. } => {
691+
*payment_data = Some(msgs::FinalOnionHopData {
692+
payment_secret: PaymentSecret([43; 32]), // Doesn't match the secret used above
693+
total_msat: amount * 2,
694+
});
695+
},
696+
_ => panic!("Expected PendingHTLCRouting::ReceiveKeysend"),
697+
}
698+
},
699+
_ => {
700+
panic!("Unexpected HTLCForwardInfo");
701+
},
702+
}
718703
nodes[3].node.process_pending_htlc_forwards();
719704
let fail_type = HTLCHandlingFailureType::Receive { payment_hash };
720705
expect_and_process_pending_htlcs_and_htlc_handling_failed(&nodes[3], &[fail_type]);

0 commit comments

Comments
 (0)