Skip to content

Commit 917e707

Browse files
committed
Split only-receive/forward data out of PendingHTLCInfo into an enum
This should avoid blowing up the size of the struct when we add additional data that is only relevant for receive.
1 parent 7df042b commit 917e707

File tree

1 file changed

+67
-27
lines changed

1 file changed

+67
-27
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,20 @@ use std::ops::Deref;
6868
// Alternatively, we can fill an outbound HTLC with a HTLCSource::OutboundRoute indicating this is
6969
// our payment, which we can use to decode errors or inform the user that the payment was sent.
7070

71+
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
72+
enum PendingForwardReceiveHTLCInfo {
73+
Forward {
74+
onion_packet: msgs::OnionPacket,
75+
short_channel_id: u64, // This should be NonZero<u64> eventually
76+
},
77+
Receive {},
78+
}
79+
7180
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
7281
pub(super) struct PendingHTLCInfo {
73-
onion_packet: Option<msgs::OnionPacket>,
82+
forward_or_receive: PendingForwardReceiveHTLCInfo,
7483
incoming_shared_secret: [u8; 32],
7584
payment_hash: PaymentHash,
76-
short_channel_id: u64,
7785
pub(super) amt_to_forward: u64,
7886
pub(super) outgoing_cltv_value: u32,
7987
}
@@ -985,9 +993,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
985993
// delay) once they've send us a commitment_signed!
986994

987995
PendingHTLCStatus::Forward(PendingHTLCInfo {
988-
onion_packet: None,
996+
forward_or_receive: PendingForwardReceiveHTLCInfo::Receive {},
989997
payment_hash: msg.payment_hash.clone(),
990-
short_channel_id: 0,
991998
incoming_shared_secret: shared_secret,
992999
amt_to_forward: next_hop_data.amt_to_forward,
9931000
outgoing_cltv_value: next_hop_data.outgoing_cltv_value,
@@ -1031,24 +1038,29 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
10311038
let short_channel_id = match next_hop_data.format {
10321039
msgs::OnionHopDataFormat::Legacy { short_channel_id } => short_channel_id,
10331040
msgs::OnionHopDataFormat::NonFinalNode { short_channel_id } => short_channel_id,
1034-
msgs::OnionHopDataFormat::FinalNode => {
1041+
msgs::OnionHopDataFormat::FinalNode { .. } => {
10351042
return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0;0]);
10361043
},
10371044
};
10381045

10391046
PendingHTLCStatus::Forward(PendingHTLCInfo {
1040-
onion_packet: Some(outgoing_packet),
1047+
forward_or_receive: PendingForwardReceiveHTLCInfo::Forward {
1048+
onion_packet: outgoing_packet,
1049+
short_channel_id: short_channel_id,
1050+
},
10411051
payment_hash: msg.payment_hash.clone(),
1042-
short_channel_id: short_channel_id,
10431052
incoming_shared_secret: shared_secret,
10441053
amt_to_forward: next_hop_data.amt_to_forward,
10451054
outgoing_cltv_value: next_hop_data.outgoing_cltv_value,
10461055
})
10471056
};
10481057

10491058
channel_state = Some(self.channel_state.lock().unwrap());
1050-
if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref onion_packet, ref short_channel_id, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info {
1051-
if onion_packet.is_some() { // If short_channel_id is 0 here, we'll reject them in the body here
1059+
if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref forward_or_receive, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info {
1060+
// If short_channel_id is 0 here, we'll reject them in the body here (which is
1061+
// important as various things later assume we are a ::Receive if short_channel_id is
1062+
// non-0.
1063+
if let &PendingForwardReceiveHTLCInfo::Forward { ref short_channel_id, .. } = forward_or_receive {
10521064
let id_option = channel_state.as_ref().unwrap().short_to_id.get(&short_channel_id).cloned();
10531065
let forwarding_id = match id_option {
10541066
None => { // unknown_next_peer
@@ -1435,22 +1447,25 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
14351447
let mut fail_htlc_msgs = Vec::new();
14361448
for forward_info in pending_forwards.drain(..) {
14371449
match forward_info {
1438-
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
1439-
log_trace!(self, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(forward_info.payment_hash.0), prev_short_channel_id, short_chan_id);
1450+
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
1451+
forward_or_receive: PendingForwardReceiveHTLCInfo::Forward {
1452+
onion_packet, ..
1453+
}, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value }, } => {
1454+
log_trace!(self, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(payment_hash.0), prev_short_channel_id, short_chan_id);
14401455
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
14411456
short_channel_id: prev_short_channel_id,
14421457
htlc_id: prev_htlc_id,
1443-
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
1458+
incoming_packet_shared_secret: incoming_shared_secret,
14441459
});
1445-
match chan.get_mut().send_htlc(forward_info.amt_to_forward, forward_info.payment_hash, forward_info.outgoing_cltv_value, htlc_source.clone(), forward_info.onion_packet.unwrap()) {
1460+
match chan.get_mut().send_htlc(amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet) {
14461461
Err(e) => {
14471462
if let ChannelError::Ignore(msg) = e {
1448-
log_trace!(self, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(forward_info.payment_hash.0), msg);
1463+
log_trace!(self, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(payment_hash.0), msg);
14491464
} else {
14501465
panic!("Stated return value requirements in send_htlc() were not met");
14511466
}
14521467
let chan_update = self.get_channel_update(chan.get()).unwrap();
1453-
failed_forwards.push((htlc_source, forward_info.payment_hash, 0x1000 | 7, Some(chan_update)));
1468+
failed_forwards.push((htlc_source, payment_hash, 0x1000 | 7, Some(chan_update)));
14541469
continue;
14551470
},
14561471
Ok(update_add) => {
@@ -1469,6 +1484,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
14691484
}
14701485
}
14711486
},
1487+
HTLCForwardInfo::AddHTLC { .. } => {
1488+
panic!("short_channel_id != 0 should imply any pending_forward entries are of type Forward");
1489+
},
14721490
HTLCForwardInfo::FailHTLC { htlc_id, err_packet } => {
14731491
log_trace!(self, "Failing HTLC back to channel with short id {} after delay", short_chan_id);
14741492
match chan.get_mut().get_update_fail_htlc(htlc_id, err_packet) {
@@ -1548,21 +1566,26 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
15481566
} else {
15491567
for forward_info in pending_forwards.drain(..) {
15501568
match forward_info {
1551-
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
1569+
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
1570+
forward_or_receive: PendingForwardReceiveHTLCInfo::Receive { },
1571+
incoming_shared_secret, payment_hash, amt_to_forward, .. }, } => {
15521572
let prev_hop_data = HTLCPreviousHopData {
15531573
short_channel_id: prev_short_channel_id,
15541574
htlc_id: prev_htlc_id,
1555-
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
1575+
incoming_packet_shared_secret: incoming_shared_secret,
15561576
};
1557-
match channel_state.claimable_htlcs.entry(forward_info.payment_hash) {
1558-
hash_map::Entry::Occupied(mut entry) => entry.get_mut().push((forward_info.amt_to_forward, prev_hop_data)),
1559-
hash_map::Entry::Vacant(entry) => { entry.insert(vec![(forward_info.amt_to_forward, prev_hop_data)]); },
1577+
match channel_state.claimable_htlcs.entry(payment_hash) {
1578+
hash_map::Entry::Occupied(mut entry) => entry.get_mut().push((amt_to_forward, prev_hop_data)),
1579+
hash_map::Entry::Vacant(entry) => { entry.insert(vec![(amt_to_forward, prev_hop_data)]); },
15601580
};
15611581
new_events.push(events::Event::PaymentReceived {
1562-
payment_hash: forward_info.payment_hash,
1563-
amt: forward_info.amt_to_forward,
1582+
payment_hash: payment_hash,
1583+
amt: amt_to_forward,
15641584
});
15651585
},
1586+
HTLCForwardInfo::AddHTLC { .. } => {
1587+
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
1588+
},
15661589
HTLCForwardInfo::FailHTLC { .. } => {
15671590
panic!("Got pending fail of our own HTLC");
15681591
}
@@ -2377,7 +2400,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
23772400
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS))
23782401
}
23792402
for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
2380-
match channel_state.forward_htlcs.entry(forward_info.short_channel_id) {
2403+
match channel_state.forward_htlcs.entry(match forward_info.forward_or_receive {
2404+
PendingForwardReceiveHTLCInfo::Forward { short_channel_id, .. } => short_channel_id,
2405+
PendingForwardReceiveHTLCInfo::Receive { .. } => 0,
2406+
}) {
23812407
hash_map::Entry::Occupied(mut entry) => {
23822408
entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info });
23832409
},
@@ -3119,10 +3145,18 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
31193145

31203146
impl Writeable for PendingHTLCInfo {
31213147
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
3122-
self.onion_packet.write(writer)?;
3148+
match &self.forward_or_receive {
3149+
&PendingForwardReceiveHTLCInfo::Forward { ref onion_packet, ref short_channel_id } => {
3150+
0u8.write(writer)?;
3151+
onion_packet.write(writer)?;
3152+
short_channel_id.write(writer)?;
3153+
},
3154+
&PendingForwardReceiveHTLCInfo::Receive { } => {
3155+
1u8.write(writer)?;
3156+
},
3157+
}
31233158
self.incoming_shared_secret.write(writer)?;
31243159
self.payment_hash.write(writer)?;
3125-
self.short_channel_id.write(writer)?;
31263160
self.amt_to_forward.write(writer)?;
31273161
self.outgoing_cltv_value.write(writer)?;
31283162
Ok(())
@@ -3132,10 +3166,16 @@ impl Writeable for PendingHTLCInfo {
31323166
impl Readable for PendingHTLCInfo {
31333167
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<PendingHTLCInfo, DecodeError> {
31343168
Ok(PendingHTLCInfo {
3135-
onion_packet: Readable::read(reader)?,
3169+
forward_or_receive: match Readable::read(reader)? {
3170+
0u8 => PendingForwardReceiveHTLCInfo::Forward {
3171+
onion_packet: Readable::read(reader)?,
3172+
short_channel_id: Readable::read(reader)?,
3173+
},
3174+
1u8 => PendingForwardReceiveHTLCInfo::Receive { },
3175+
_ => return Err(DecodeError::InvalidValue),
3176+
},
31363177
incoming_shared_secret: Readable::read(reader)?,
31373178
payment_hash: Readable::read(reader)?,
3138-
short_channel_id: Readable::read(reader)?,
31393179
amt_to_forward: Readable::read(reader)?,
31403180
outgoing_cltv_value: Readable::read(reader)?,
31413181
})

0 commit comments

Comments
 (0)