Skip to content

Commit a39c03d

Browse files
committed
Use Hop instead of InboundOnionPayload
For pending HTLC info processing, we will later need to access both the outer and the Trampoline payloads. Thanks to the refactor eliminating invalid Hop states, this is now possible by accessing the Hop struct, which will carry both outer and Trampoline payload data when applicable.
1 parent 4cd446e commit a39c03d

File tree

2 files changed

+70
-88
lines changed

2 files changed

+70
-88
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 50 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4453,37 +4453,24 @@ where
44534453
}
44544454
match decoded_hop {
44554455
onion_utils::Hop::Receive { .. } | onion_utils::Hop::BlindedReceive { .. } => {
4456-
let inbound_onion_payload = match decoded_hop {
4457-
onion_utils::Hop::Receive { hop_data, .. } => msgs::InboundOnionPayload::Receive(hop_data),
4458-
onion_utils::Hop::BlindedReceive { hop_data, .. } => msgs::InboundOnionPayload::BlindedReceive(hop_data),
4459-
_ => unreachable!()
4460-
};
4461-
44624456
// OUR PAYMENT!
44634457
let current_height: u32 = self.best_block.read().unwrap().height;
4464-
match create_recv_pending_htlc_info(inbound_onion_payload, shared_secret, msg.payment_hash,
4458+
match create_recv_pending_htlc_info(decoded_hop, shared_secret, msg.payment_hash,
44654459
msg.amount_msat, msg.cltv_expiry, None, allow_underpay, msg.skimmed_fee_msat,
44664460
current_height)
44674461
{
44684462
Ok(info) => {
44694463
// Note that we could obviously respond immediately with an update_fulfill_htlc
44704464
// message, however that would leak that we are the recipient of this payment, so
44714465
// instead we stay symmetric with the forwarding case, only responding (after a
4472-
// delay) once they've send us a commitment_signed!
4466+
// delay) once they've sent us a commitment_signed!
44734467
PendingHTLCStatus::Forward(info)
44744468
},
44754469
Err(InboundHTLCErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
44764470
}
44774471
},
4478-
onion_utils::Hop::Forward { next_hop_data, next_hop_hmac, new_packet_bytes, .. } => {
4479-
match create_fwd_pending_htlc_info(msg, msgs::InboundOnionPayload::Forward(next_hop_data), next_hop_hmac,
4480-
new_packet_bytes, shared_secret, next_packet_pubkey_opt) {
4481-
Ok(info) => PendingHTLCStatus::Forward(info),
4482-
Err(InboundHTLCErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
4483-
}
4484-
},
4485-
onion_utils::Hop::BlindedForward { next_hop_data, next_hop_hmac, new_packet_bytes, .. } => {
4486-
match create_fwd_pending_htlc_info(msg, msgs::InboundOnionPayload::BlindedForward(next_hop_data), next_hop_hmac,
4472+
onion_utils::Hop::Forward { next_hop_hmac, new_packet_bytes, .. } | onion_utils::Hop::BlindedForward { next_hop_hmac, new_packet_bytes, .. } => {
4473+
match create_fwd_pending_htlc_info(msg, decoded_hop, next_hop_hmac,
44874474
new_packet_bytes, shared_secret, next_packet_pubkey_opt) {
44884475
Ok(info) => PendingHTLCStatus::Forward(info),
44894476
Err(InboundHTLCErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
@@ -5899,14 +5886,9 @@ where
58995886
failed_payment!(err_msg, err_code, Vec::new(), Some(phantom_shared_secret));
59005887
},
59015888
};
5902-
let (inbound_onion_payload, shared_secret) = match next_hop {
5903-
onion_utils::Hop::Receive { hop_data, shared_secret } => (msgs::InboundOnionPayload::Receive(hop_data), shared_secret),
5904-
onion_utils::Hop::BlindedReceive { hop_data, shared_secret } => (msgs::InboundOnionPayload::BlindedReceive(hop_data), shared_secret),
5905-
_ => panic!()
5906-
};
5907-
let phantom_shared_secret = shared_secret.secret_bytes();
5889+
let phantom_shared_secret = next_hop.shared_secret().secret_bytes();
59085890
let current_height: u32 = self.best_block.read().unwrap().height;
5909-
match create_recv_pending_htlc_info(inbound_onion_payload,
5891+
match create_recv_pending_htlc_info(next_hop,
59105892
incoming_shared_secret, payment_hash, outgoing_amt_msat,
59115893
outgoing_cltv_value, Some(phantom_shared_secret), false, None,
59125894
current_height)
@@ -14853,13 +14835,15 @@ mod tests {
1485314835
use bitcoin::hashes::Hash;
1485414836
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
1485514837
use core::sync::atomic::Ordering;
14838+
use bitcoin::secp256k1::ecdh::SharedSecret;
1485614839
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
1485714840
use crate::ln::types::ChannelId;
1485814841
use crate::types::payment::{PaymentPreimage, PaymentHash, PaymentSecret};
1485914842
use crate::ln::channelmanager::{create_recv_pending_htlc_info, inbound_payment, ChannelConfigOverrides, HTLCForwardInfo, InterceptId, PaymentId, RecipientOnionFields};
1486014843
use crate::ln::functional_test_utils::*;
1486114844
use crate::ln::msgs::{self, AcceptChannel, ErrorAction};
1486214845
use crate::ln::msgs::ChannelMessageHandler;
14846+
use crate::ln::onion_utils;
1486314847
use crate::ln::outbound_payment::Retry;
1486414848
use crate::prelude::*;
1486514849
use crate::routing::router::{PaymentParameters, RouteParameters, find_route};
@@ -15950,17 +15934,20 @@ mod tests {
1595015934
let node = create_network(1, &node_cfg, &node_chanmgr);
1595115935
let sender_intended_amt_msat = 100;
1595215936
let extra_fee_msat = 10;
15953-
let hop_data = msgs::InboundOnionPayload::Receive(msgs::InboundOnionReceivePayload {
15954-
sender_intended_htlc_amt_msat: 100,
15955-
cltv_expiry_height: 42,
15956-
payment_metadata: None,
15957-
keysend_preimage: None,
15958-
payment_data: Some(msgs::FinalOnionHopData {
15959-
payment_secret: PaymentSecret([0; 32]),
15960-
total_msat: sender_intended_amt_msat,
15961-
}),
15962-
custom_tlvs: Vec::new(),
15963-
});
15937+
let hop_data = onion_utils::Hop::Receive {
15938+
hop_data: msgs::InboundOnionReceivePayload {
15939+
sender_intended_htlc_amt_msat: 100,
15940+
cltv_expiry_height: 42,
15941+
payment_metadata: None,
15942+
keysend_preimage: None,
15943+
payment_data: Some(msgs::FinalOnionHopData {
15944+
payment_secret: PaymentSecret([0; 32]),
15945+
total_msat: sender_intended_amt_msat,
15946+
}),
15947+
custom_tlvs: Vec::new(),
15948+
},
15949+
shared_secret: SharedSecret::from_bytes([0; 32]),
15950+
};
1596415951
// Check that if the amount we received + the penultimate hop extra fee is less than the sender
1596515952
// intended amount, we fail the payment.
1596615953
let current_height: u32 = node[0].node.best_block.read().unwrap().height;
@@ -15973,17 +15960,20 @@ mod tests {
1597315960
} else { panic!(); }
1597415961

1597515962
// If amt_received + extra_fee is equal to the sender intended amount, we're fine.
15976-
let hop_data = msgs::InboundOnionPayload::Receive(msgs::InboundOnionReceivePayload { // This is the same payload as above, InboundOnionPayload doesn't implement Clone
15977-
sender_intended_htlc_amt_msat: 100,
15978-
cltv_expiry_height: 42,
15979-
payment_metadata: None,
15980-
keysend_preimage: None,
15981-
payment_data: Some(msgs::FinalOnionHopData {
15982-
payment_secret: PaymentSecret([0; 32]),
15983-
total_msat: sender_intended_amt_msat,
15984-
}),
15985-
custom_tlvs: Vec::new(),
15986-
});
15963+
let hop_data = onion_utils::Hop::Receive {
15964+
hop_data: msgs::InboundOnionReceivePayload { // This is the same payload as above, InboundOnionPayload doesn't implement Clone
15965+
sender_intended_htlc_amt_msat: 100,
15966+
cltv_expiry_height: 42,
15967+
payment_metadata: None,
15968+
keysend_preimage: None,
15969+
payment_data: Some(msgs::FinalOnionHopData {
15970+
payment_secret: PaymentSecret([0; 32]),
15971+
total_msat: sender_intended_amt_msat,
15972+
}),
15973+
custom_tlvs: Vec::new(),
15974+
},
15975+
shared_secret: SharedSecret::from_bytes([0; 32]),
15976+
};
1598715977
let current_height: u32 = node[0].node.best_block.read().unwrap().height;
1598815978
assert!(create_recv_pending_htlc_info(hop_data, [0; 32], PaymentHash([0; 32]),
1598915979
sender_intended_amt_msat - extra_fee_msat, 42, None, true, Some(extra_fee_msat),
@@ -15998,17 +15988,20 @@ mod tests {
1599815988
let node = create_network(1, &node_cfg, &node_chanmgr);
1599915989

1600015990
let current_height: u32 = node[0].node.best_block.read().unwrap().height;
16001-
let result = create_recv_pending_htlc_info(msgs::InboundOnionPayload::Receive(msgs::InboundOnionReceivePayload {
16002-
sender_intended_htlc_amt_msat: 100,
16003-
cltv_expiry_height: 22,
16004-
payment_metadata: None,
16005-
keysend_preimage: None,
16006-
payment_data: Some(msgs::FinalOnionHopData {
16007-
payment_secret: PaymentSecret([0; 32]),
16008-
total_msat: 100,
16009-
}),
16010-
custom_tlvs: Vec::new(),
16011-
}), [0; 32], PaymentHash([0; 32]), 100, 23, None, true, None, current_height);
15991+
let result = create_recv_pending_htlc_info(onion_utils::Hop::Receive {
15992+
hop_data: msgs::InboundOnionReceivePayload {
15993+
sender_intended_htlc_amt_msat: 100,
15994+
cltv_expiry_height: 22,
15995+
payment_metadata: None,
15996+
keysend_preimage: None,
15997+
payment_data: Some(msgs::FinalOnionHopData {
15998+
payment_secret: PaymentSecret([0; 32]),
15999+
total_msat: 100,
16000+
}),
16001+
custom_tlvs: Vec::new(),
16002+
},
16003+
shared_secret: SharedSecret::from_bytes([0; 32]),
16004+
}, [0; 32], PaymentHash([0; 32]), 100, 23, None, true, None, current_height);
1601216005

1601316006
// Should not return an error as this condition:
1601416007
// https://github.com/lightning/bolts/blob/4dcc377209509b13cf89a4b91fde7d478f5b46d8/04-onion-routing.md?plain=1#L334

lightning/src/ln/onion_payment.rs

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::ln::channelmanager::{BlindedFailure, BlindedForward, CLTV_FAR_FAR_AWA
1515
use crate::types::features::BlindedHopFeatures;
1616
use crate::ln::msgs;
1717
use crate::ln::onion_utils;
18-
use crate::ln::onion_utils::{Hop, HTLCFailReason, INVALID_ONION_BLINDING};
18+
use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
1919
use crate::sign::{NodeSigner, Recipient};
2020
use crate::util::logger::Logger;
2121

@@ -61,7 +61,7 @@ fn check_blinded_forward(
6161
}
6262

6363
pub(super) fn create_fwd_pending_htlc_info(
64-
msg: &msgs::UpdateAddHTLC, hop_data: msgs::InboundOnionPayload, hop_hmac: [u8; 32],
64+
msg: &msgs::UpdateAddHTLC, hop_data: onion_utils::Hop, hop_hmac: [u8; 32],
6565
new_packet_bytes: [u8; onion_utils::ONION_DATA_LEN], shared_secret: [u8; 32],
6666
next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>
6767
) -> Result<PendingHTLCInfo, InboundHTLCErr> {
@@ -77,12 +77,12 @@ pub(super) fn create_fwd_pending_htlc_info(
7777
short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
7878
next_blinding_override
7979
) = match hop_data {
80-
msgs::InboundOnionPayload::Forward(msgs::InboundOnionForwardPayload { short_channel_id, amt_to_forward, outgoing_cltv_value }) =>
80+
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionForwardPayload { short_channel_id, amt_to_forward, outgoing_cltv_value }, .. } =>
8181
(short_channel_id, amt_to_forward, outgoing_cltv_value, None, None),
82-
msgs::InboundOnionPayload::BlindedForward(msgs::InboundOnionBlindedForwardPayload {
82+
onion_utils::Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload {
8383
short_channel_id, payment_relay, payment_constraints, intro_node_blinding_point, features,
8484
next_blinding_override,
85-
}) => {
85+
}, .. } => {
8686
let (amt_to_forward, outgoing_cltv_value) = check_blinded_forward(
8787
msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features
8888
).map_err(|()| {
@@ -97,7 +97,7 @@ pub(super) fn create_fwd_pending_htlc_info(
9797
(short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
9898
next_blinding_override)
9999
},
100-
msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
100+
onion_utils::Hop::Receive { .. } | onion_utils::Hop::BlindedReceive { .. } =>
101101
return Err(InboundHTLCErr {
102102
msg: "Final Node OnionHopData provided for us as an intermediary node",
103103
err_code: 0x4000 | 22,
@@ -129,7 +129,7 @@ pub(super) fn create_fwd_pending_htlc_info(
129129
}
130130

131131
pub(super) fn create_recv_pending_htlc_info(
132-
hop_data: msgs::InboundOnionPayload, shared_secret: [u8; 32], payment_hash: PaymentHash,
132+
hop_data: onion_utils::Hop, shared_secret: [u8; 32], payment_hash: PaymentHash,
133133
amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>, allow_underpay: bool,
134134
counterparty_skimmed_fee_msat: Option<u64>, current_height: u32
135135
) -> Result<PendingHTLCInfo, InboundHTLCErr> {
@@ -138,17 +138,17 @@ pub(super) fn create_recv_pending_htlc_info(
138138
payment_metadata, payment_context, requires_blinded_error, has_recipient_created_payment_secret,
139139
invoice_request
140140
) = match hop_data {
141-
msgs::InboundOnionPayload::Receive(msgs::InboundOnionReceivePayload {
141+
onion_utils::Hop::Receive { hop_data: msgs::InboundOnionReceivePayload {
142142
payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
143143
cltv_expiry_height, payment_metadata, ..
144-
}) =>
144+
}, .. } =>
145145
(payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
146146
cltv_expiry_height, payment_metadata, None, false, keysend_preimage.is_none(), None),
147-
msgs::InboundOnionPayload::BlindedReceive(msgs::InboundOnionBlindedReceivePayload {
147+
onion_utils::Hop::BlindedReceive { hop_data: msgs::InboundOnionBlindedReceivePayload {
148148
sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
149149
intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage,
150150
custom_tlvs, invoice_request
151-
}) => {
151+
}, .. } => {
152152
check_blinded_payment_constraints(
153153
sender_intended_htlc_amt_msat, cltv_expiry, &payment_constraints
154154
)
@@ -164,20 +164,20 @@ pub(super) fn create_recv_pending_htlc_info(
164164
sender_intended_htlc_amt_msat, cltv_expiry_height, None, Some(payment_context),
165165
intro_node_blinding_point.is_none(), true, invoice_request)
166166
}
167-
msgs::InboundOnionPayload::Forward { .. } => {
167+
onion_utils::Hop::Forward { .. } => {
168168
return Err(InboundHTLCErr {
169169
err_code: 0x4000|22,
170170
err_data: Vec::new(),
171171
msg: "Got non final data with an HMAC of 0",
172172
})
173173
},
174-
msgs::InboundOnionPayload::BlindedForward { .. } => {
174+
onion_utils::Hop::BlindedForward { .. } => {
175175
return Err(InboundHTLCErr {
176176
err_code: INVALID_ONION_BLINDING,
177177
err_data: vec![0; 32],
178178
msg: "Got blinded non final data with an HMAC of 0",
179179
})
180-
}
180+
},
181181
};
182182
// final_incorrect_cltv_expiry
183183
if onion_cltv_expiry > cltv_expiry {
@@ -297,12 +297,6 @@ where
297297
Ok(match hop {
298298
onion_utils::Hop::Forward { shared_secret, next_hop_hmac, new_packet_bytes, .. } |
299299
onion_utils::Hop::BlindedForward { shared_secret, next_hop_hmac, new_packet_bytes, .. } => {
300-
let inbound_onion_payload = match hop {
301-
onion_utils::Hop::Forward { next_hop_data, .. } => msgs::InboundOnionPayload::Forward(next_hop_data),
302-
onion_utils::Hop::BlindedForward { next_hop_data, .. } => msgs::InboundOnionPayload::BlindedForward(next_hop_data),
303-
_ => unreachable!()
304-
};
305-
306300
let NextPacketDetails {
307301
next_packet_pubkey, outgoing_amt_msat: _, outgoing_scid: _, outgoing_cltv_value
308302
} = match next_packet_details_opt {
@@ -328,19 +322,14 @@ where
328322
// TODO: If this is potentially a phantom payment we should decode the phantom payment
329323
// onion here and check it.
330324
create_fwd_pending_htlc_info(
331-
msg, inbound_onion_payload, next_hop_hmac, new_packet_bytes, shared_secret.secret_bytes(),
325+
msg, hop, next_hop_hmac, new_packet_bytes, shared_secret.secret_bytes(),
332326
Some(next_packet_pubkey),
333327
)?
334328
},
335-
onion_utils::Hop::Receive { hop_data, shared_secret } => {
336-
create_recv_pending_htlc_info(
337-
msgs::InboundOnionPayload::Receive(hop_data), shared_secret.secret_bytes(), msg.payment_hash, msg.amount_msat, msg.cltv_expiry,
338-
None, allow_skimmed_fees, msg.skimmed_fee_msat, cur_height,
339-
)?
340-
},
341-
onion_utils::Hop::BlindedReceive { hop_data, shared_secret } => {
329+
_ => {
330+
let shared_secret = hop.shared_secret().secret_bytes();
342331
create_recv_pending_htlc_info(
343-
msgs::InboundOnionPayload::BlindedReceive(hop_data), shared_secret.secret_bytes(), msg.payment_hash, msg.amount_msat, msg.cltv_expiry,
332+
hop, shared_secret, msg.payment_hash, msg.amount_msat, msg.cltv_expiry,
344333
None, allow_skimmed_fees, msg.skimmed_fee_msat, cur_height,
345334
)?
346335
}
@@ -422,15 +411,15 @@ where
422411
};
423412

424413
let next_packet_details = match next_hop {
425-
Hop::Forward { next_hop_data: msgs::InboundOnionForwardPayload { short_channel_id, amt_to_forward, outgoing_cltv_value }, shared_secret, .. } => {
414+
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionForwardPayload { short_channel_id, amt_to_forward, outgoing_cltv_value }, shared_secret, .. } => {
426415
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
427416
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
428417
Some(NextPacketDetails {
429418
next_packet_pubkey, outgoing_scid: short_channel_id,
430419
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
431420
})
432421
}
433-
Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload { short_channel_id, ref payment_relay, ref payment_constraints, ref features, .. }, shared_secret, .. } => {
422+
onion_utils::Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload { short_channel_id, ref payment_relay, ref payment_constraints, ref features, .. }, shared_secret, .. } => {
434423
let (amt_to_forward, outgoing_cltv_value) = match check_blinded_forward(
435424
msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features
436425
) {

0 commit comments

Comments
 (0)