-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parse inbound Trampoline onions #3620
base: main
Are you sure you want to change the base?
Parse inbound Trampoline onions #3620
Conversation
Don't see any issues right now with that. I'm wondering where the pathfinding to the next trampoline hop part is going to go? |
4d145a3
to
d22e0fe
Compare
Rebased this onto #3626 so CI should no longer be failing. |
f64afa4
to
3013c22
Compare
392bc6d
to
913970f
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3620 +/- ##
==========================================
+ Coverage 88.59% 90.13% +1.54%
==========================================
Files 151 152 +1
Lines 118454 126851 +8397
Branches 118454 126851 +8397
==========================================
+ Hits 104941 114335 +9394
+ Misses 10994 10060 -934
+ Partials 2519 2456 -63 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looks good, a few nits and one or two real comments.
(16, payment_metadata, option), | ||
(18, total_msat, (option, encoding: (u64, HighZeroBytesDroppedBigSize))), | ||
(20, trampoline_onion_packet, option), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, and the 14 above, should we use placeholder values (ie high numbers) for now until the BOLT PR gets merged?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can, and I think we briefly used to in 3386, though Eclair's already been using these type IDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay, probably fine, then?
@@ -3000,6 +3092,15 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh | |||
amt_to_forward: amt.ok_or(DecodeError::InvalidValue)?, | |||
outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?, | |||
})) | |||
} else if let Some(outgoing_node_id) = outgoing_node_id { | |||
if payment_data.is_some() || payment_metadata.is_some() || encrypted_tlvs_opt.is_some() || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update the other branches to check that outgoing_node_id
is none (man there's gotta be an easier way to write this pattern....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great point!
lightning/src/ln/msgs.rs
Outdated
@@ -3036,16 +3048,6 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh | |||
amt_to_forward: amt.ok_or(DecodeError::InvalidValue)?, | |||
outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?, | |||
})) | |||
} else if let Some(trampoline_onion_packet) = trampoline_onion_packet { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets not move code we just introduced in the previous commit? Maybe just squash these two...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I moved the second commit here for easy either squashing or dismissal
lightning/src/ln/msgs.rs
Outdated
@@ -1811,6 +1811,23 @@ mod fuzzy_internal_msgs { | |||
pub outgoing_cltv_value: u32, | |||
} | |||
|
|||
#[allow(unused)] | |||
pub struct InboundTrampolineForwardPayload { | |||
pub outgoing_node_id: NodeId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"outgoing node id" implies to me that this is the next hop from us, rather than "next hop node id" which I think is what was meant here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would next_node_id
be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, or maybe next_trampoline?
lightning/src/ln/msgs.rs
Outdated
|
||
#[allow(unused)] | ||
pub struct InboundTrampolineBlindedForwardPayload { | ||
pub outgoing_node_id: NodeId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
lightning/src/ln/msgs.rs
Outdated
@@ -1842,9 +1870,17 @@ mod fuzzy_internal_msgs { | |||
|
|||
pub enum InboundOnionPayload { | |||
Forward(InboundOnionForwardPayload), | |||
#[allow(unused)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for this kind of thing I'd much rather #[cfg(trampoline)]
than #[allow(unused)]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would imply cfg-based behavioral changes inside InboundOnionPayload's read implementation, but happy to change if that's ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think thats fine?
@@ -344,6 +363,9 @@ impl UnauthenticatedReceiveTlvs { | |||
pub(crate) enum BlindedPaymentTlvs { | |||
/// This blinded payment data is for a forwarding node. | |||
Forward(ForwardTlvs), | |||
/// This blinded payment data is for a forwarding Trampoline node. | |||
#[allow(unused)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used tho?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
used, but never constructed
lightning/src/ln/msgs.rs
Outdated
Receive(InboundOnionReceivePayload), | ||
BlindedForward(InboundOnionBlindedForwardPayload), | ||
BlindedReceive(InboundOnionBlindedReceivePayload), | ||
|
||
// These payloads should be seen inside an inner Trampoline onion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these go through a different enum/decode method since they shouldn't appear in the same context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
certainly an option. I think we already discussed this, it would just be a lot of code duplication
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh? There's not that much code for InboundOnionPayload
to begin with? What would get duplicated aside from the one decode_tlv_stream
call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just pushed a version with the duplicated read implementation. The receive variants, being identical to the ones we'd expect in the outer onion, naturally also increase the duplication
cd67a23
to
7631640
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good, just have some nits here!
lightning/src/ln/msgs.rs
Outdated
pub struct InboundTrampolineEntrypointPayload { | ||
pub amt_to_forward: u64, | ||
pub outgoing_cltv_value: u32, | ||
pub multipath_trampoline_data: Option<FinalOnionHopData>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a comment for why this is optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, actually, you're right. Per https://github.com/lightning/bolts/blob/079f761bf68caa48544bd6bf0a29591d43425b0b/04-onion-routing.md#requirements-2 it's mandatory
@@ -167,6 +273,8 @@ pub(super) fn create_recv_pending_htlc_info( | |||
sender_intended_htlc_amt_msat, cltv_expiry_height, None, Some(payment_context), | |||
intro_node_blinding_point.is_none(), true, invoice_request) | |||
} | |||
#[cfg(trampoline)] | |||
onion_utils::Hop::TrampolineReceive { .. } | onion_utils::Hop::TrampolineBlindedReceive { .. } => todo!(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the todo
left intentionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, will handle receiving and add error decoding tests in next PR
lightning/src/ln/onion_utils.rs
Outdated
); | ||
match decoded_trampoline_hop { | ||
Ok(( | ||
next_trampoline_hop_data, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: the indentation is a bit intense below, do you think we could avoid the nested match
es?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm looking into this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you match on
Ok((InboundTrampolinePayload::Forward, Some(..))) => { .. },
Ok((InboundTrampolinePayload::BlindedForward, Some(..))) => { .. },
Ok((InboundTrampolinePayload::Receive, None)) => { .. },
... etc
and just have a catch-all for forward-encoded-as-receive error and vice versa?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, sure. I thought you wanted some more depth removed, but this works nicely, thanks
7631640
to
226a6e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM, feel free to squash the fixup and @valentinewallace can let us know if we can land it.
@@ -1860,6 +1905,18 @@ mod fuzzy_internal_msgs { | |||
multipath_trampoline_data: Option<FinalOnionHopData>, | |||
trampoline_packet: TrampolineOnionPacket, | |||
}, | |||
/// This is used for Trampoline hops that are not the blinded path intro hop. | |||
/// We would only ever construct this variant when we are a Trampoline node forwarding a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, I'm confused here. So we construct this when we're forwarding a trampoline and the next trampoline hop we want to use is not the blinded path entry point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exactly right, we do this when we're already inside the blinded path, either when we're the intro node, or the intro node was already behind us. We do so because we cannot necessarily provide the blinding point in the update_add message given that the next Trampoline hop is not necessarily our next peer.
lightning/src/ln/onion_payment.rs
Outdated
}, | ||
#[cfg(trampoline)] | ||
Trampoline { | ||
next_trampoline: NodeId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: might be nice to use a PublicKey
here rather than a NodeId
since we're happy to fail-back if the pk isn't valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would you like the msgs.rs parsing to also read a PublicKey, but store it as a NodeId in the inbound payload structs, or shall I just change all of them to PublicKey instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume PublicKey
? The only place we don't use a PublicKey
is in update_add_htlc
parsing cause then we'd disconnect our immediate peer just because the sender provided an invalid pk. Anywhere else should be a PublicKey
cause we generally actually need to use it for crypto things, and we need a PublicKey
for that anyway (except network graph, where full keys are too slow).
226a6e3
to
6852765
Compare
Oops needs rebase :/ |
ba373d2
to
5850d83
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
5850d83
to
05b142b
Compare
Grr looks like this needs rebased again. |
Given that blinded Trampoline hops cannot use blinded intermediate hops between each other, the `current_path_key` used for decrypting the blinded Trampoline onion cannot be included in the update_add_htlc message due to the potential presence of intermediate hops. That means that when we're not the payment initiator, but a Trampoline hop forwarding a payment along a blinded path, we must include the blinding point inside the outer onion, which this commit will allow us to do.
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.
Check inbound onion payloads for the presence of an inner onion, which we will later also need to decrypt to handle Trampoline payments.
We will be using the same logic for decoding onion payloads for outer and for Trampoline onions. To accommodate the Trampoline payloads, we parse a next node ID rather than an SCID.
When encrypting errors, we currently have the ability to use two shared secrets for Phantom Node payments. Trampoline also requires the re-encryption of encrypted errors, first using the Trampoline shared secret, and then using the outer one. Given these two cryptographically equivalent use cases, we're renaming the phantom_shared_secret parameter to secondary_shared_secret, and explaining the now two contexts in which it will be applicable.
When parsing inbound HTLCs, we need to provide supplemental information about potential outgoing hops, which hitherto always required the next SCID. However, Trampoline uproots the approach because the sender did not specify the SCID; rather, they rely on us to do the intermediate routing. Thus we now need to distinguish between SCID-based and node- ID-based outgoing routing.
In this commit, we start decrypting the inner onion we receive, and lay some groundwork towards handling the subsequent routing or payment receipt.
05b142b
to
0fe9da1
Compare
Initially seeking concept ACK due to the refactor of passing Hop instead of InboundOnionPayload to create_receive_ and create_fwd_pending_htlc_info, which we need in order to have access to both the outer and inner onions for Trampoline handling.