-
Notifications
You must be signed in to change notification settings - Fork 473
trampoline: accumulate inbound trampoline htlcs #4493
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
Changes from all commits
8925925
6168bed
b9c3601
d2ece0d
e253953
3d0309f
0cae5b5
07d3248
f25382b
163da0a
8bc2e85
764458a
7fce959
33a2e6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,6 +111,9 @@ enum RoutingInfo { | |
| next_hop_hmac: [u8; 32], | ||
| shared_secret: SharedSecret, | ||
| current_path_key: Option<PublicKey>, | ||
| incoming_multipath_data: Option<msgs::FinalOnionHopData>, | ||
| next_trampoline_amt_msat: u64, | ||
| next_trampoline_cltv: u32, | ||
| }, | ||
| } | ||
|
|
||
|
|
@@ -167,24 +170,31 @@ pub(super) fn create_fwd_pending_htlc_info( | |
| reason: LocalHTLCFailureReason::InvalidOnionPayload, | ||
| err_data: Vec::new(), | ||
| }), | ||
| onion_utils::Hop::TrampolineForward { next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => { | ||
| onion_utils::Hop::TrampolineForward { outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => { | ||
| ( | ||
| RoutingInfo::Trampoline { | ||
| next_trampoline: next_trampoline_hop_data.next_trampoline, | ||
| new_packet_bytes: new_trampoline_packet_bytes, | ||
| next_hop_hmac: next_trampoline_hop_hmac, | ||
| shared_secret: trampoline_shared_secret, | ||
| current_path_key: None | ||
| current_path_key: None, | ||
| incoming_multipath_data: outer_hop_data.multipath_trampoline_data, | ||
| next_trampoline_amt_msat: next_trampoline_hop_data.amt_to_forward, | ||
| next_trampoline_cltv: next_trampoline_hop_data.outgoing_cltv_value, | ||
| }, | ||
| next_trampoline_hop_data.amt_to_forward, | ||
| next_trampoline_hop_data.outgoing_cltv_value, | ||
| outer_hop_data.amt_to_forward, | ||
| outer_hop_data.outgoing_cltv_value, | ||
| None, | ||
| None | ||
| ) | ||
| }, | ||
| onion_utils::Hop::TrampolineBlindedForward { outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => { | ||
| let (amt_to_forward, outgoing_cltv_value) = check_blinded_forward( | ||
| msg.amount_msat, msg.cltv_expiry, &next_trampoline_hop_data.payment_relay, &next_trampoline_hop_data.payment_constraints, &next_trampoline_hop_data.features | ||
| // The blinded path's payment_relay and payment_constraints apply to the aggregate | ||
| // amount that the trampoline node will forward onward, not the individual amount that | ||
| // arrives in a single (incoming MPP) HTLC. We used the desired total amount to | ||
| // calculate our outbound values. | ||
| let (next_hop_amount, next_hop_cltv) = check_blinded_forward( | ||
| outer_hop_data.multipath_trampoline_data.as_ref().map(|f| f.total_msat).unwrap_or(msg.amount_msat), msg.cltv_expiry, &next_trampoline_hop_data.payment_relay, &next_trampoline_hop_data.payment_constraints, &next_trampoline_hop_data.features | ||
| ).map_err(|()| { | ||
| // We should be returning malformed here if `msg.blinding_point` is set, but this is | ||
| // unreachable right now since we checked it in `decode_update_add_htlc_onion`. | ||
|
|
@@ -200,10 +210,13 @@ pub(super) fn create_fwd_pending_htlc_info( | |
| new_packet_bytes: new_trampoline_packet_bytes, | ||
| next_hop_hmac: next_trampoline_hop_hmac, | ||
| shared_secret: trampoline_shared_secret, | ||
| current_path_key: outer_hop_data.current_path_key | ||
| current_path_key: outer_hop_data.current_path_key, | ||
| incoming_multipath_data: outer_hop_data.multipath_trampoline_data, | ||
| next_trampoline_amt_msat: next_hop_amount, | ||
| next_trampoline_cltv: next_hop_cltv, | ||
| }, | ||
| amt_to_forward, | ||
| outgoing_cltv_value, | ||
| outer_hop_data.amt_to_forward, | ||
| outer_hop_data.outgoing_cltv_value, | ||
| next_trampoline_hop_data.intro_node_blinding_point, | ||
| next_trampoline_hop_data.next_blinding_override | ||
| ) | ||
|
|
@@ -233,7 +246,7 @@ pub(super) fn create_fwd_pending_htlc_info( | |
| }), | ||
| } | ||
| } | ||
| RoutingInfo::Trampoline { next_trampoline, new_packet_bytes, next_hop_hmac, shared_secret, current_path_key } => { | ||
| RoutingInfo::Trampoline { next_trampoline, new_packet_bytes, next_hop_hmac, shared_secret, current_path_key, incoming_multipath_data, next_trampoline_amt_msat, next_trampoline_cltv } => { | ||
| let next_trampoline_packet_pubkey = match next_packet_pubkey_opt { | ||
| Some(Ok(pubkey)) => pubkey, | ||
| _ => return Err(InboundHTLCErr { | ||
|
|
@@ -260,7 +273,11 @@ pub(super) fn create_fwd_pending_htlc_info( | |
| failure: intro_node_blinding_point | ||
| .map(|_| BlindedFailure::FromIntroductionNode) | ||
| .unwrap_or(BlindedFailure::FromBlindedNode), | ||
| }) | ||
| }), | ||
| incoming_multipath_data, | ||
| next_trampoline_amt_msat, | ||
| next_trampoline_cltv_expiry: next_trampoline_cltv, | ||
|
|
||
| } | ||
| } | ||
| }; | ||
|
|
@@ -683,33 +700,24 @@ pub(super) fn decode_incoming_update_add_htlc_onion<NS: NodeSigner, L: Logger, T | |
|
|
||
| Some(NextPacketDetails { next_packet_pubkey, outgoing_connector: HopConnector::Dummy, outgoing_amt_msat: amt_to_forward, outgoing_cltv_value }) | ||
| } | ||
| onion_utils::Hop::TrampolineForward { next_trampoline_hop_data: msgs::InboundTrampolineForwardPayload { amt_to_forward, outgoing_cltv_value, next_trampoline }, trampoline_shared_secret, incoming_trampoline_public_key, .. } => { | ||
| onion_utils::Hop::TrampolineForward { next_trampoline_hop_data: msgs::InboundTrampolineForwardPayload { next_trampoline, .. }, ref outer_hop_data, trampoline_shared_secret, incoming_trampoline_public_key, .. } => { | ||
| let next_trampoline_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx, | ||
| incoming_trampoline_public_key, &trampoline_shared_secret.secret_bytes()); | ||
| Some(NextPacketDetails { | ||
| next_packet_pubkey: next_trampoline_packet_pubkey, | ||
| outgoing_connector: HopConnector::Trampoline(next_trampoline), | ||
| outgoing_amt_msat: amt_to_forward, | ||
| outgoing_cltv_value, | ||
| outgoing_amt_msat: outer_hop_data.amt_to_forward, | ||
| outgoing_cltv_value: outer_hop_data.outgoing_cltv_value, | ||
| }) | ||
| } | ||
| onion_utils::Hop::TrampolineBlindedForward { next_trampoline_hop_data: msgs::InboundTrampolineBlindedForwardPayload { next_trampoline, ref payment_relay, ref payment_constraints, ref features, .. }, outer_shared_secret, trampoline_shared_secret, incoming_trampoline_public_key, .. } => { | ||
| let (amt_to_forward, outgoing_cltv_value) = match check_blinded_forward( | ||
| msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features | ||
| ) { | ||
| Ok((amt, cltv)) => (amt, cltv), | ||
| Err(()) => { | ||
| return encode_relay_error("Underflow calculating outbound amount or cltv value for blinded trampoline forward", | ||
| LocalHTLCFailureReason::InvalidOnionBlinding, outer_shared_secret.secret_bytes(), Some(trampoline_shared_secret.secret_bytes()), &[0; 32]); | ||
| } | ||
| }; | ||
| onion_utils::Hop::TrampolineBlindedForward { next_trampoline_hop_data: msgs::InboundTrampolineBlindedForwardPayload { next_trampoline, .. }, ref outer_hop_data, trampoline_shared_secret, incoming_trampoline_public_key, .. } => { | ||
| let next_trampoline_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx, | ||
| incoming_trampoline_public_key, &trampoline_shared_secret.secret_bytes()); | ||
| Some(NextPacketDetails { | ||
| next_packet_pubkey: next_trampoline_packet_pubkey, | ||
| outgoing_connector: HopConnector::Trampoline(next_trampoline), | ||
| outgoing_amt_msat: amt_to_forward, | ||
| outgoing_cltv_value, | ||
| outgoing_amt_msat: outer_hop_data.amt_to_forward, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are there spec requirements on the outer hop and inner hop here? This reads right in the sense that the inner onion is basically "at its end", but what does that mean the inner onion's value even means? Should we be checking here that its set in some sensible way? |
||
| outgoing_cltv_value: outer_hop_data.outgoing_cltv_value, | ||
| }) | ||
| } | ||
| _ => None | ||
|
|
||
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 changes the input to
check_blinded_forwardfrommsg.amount_msat(single HTLC amount) to the MPPtotal_msat. This is significant: the fee computation inamt_to_forward_msatand thecheck_blinded_payment_constraints(includinghtlc_minimum_msatcheck) now operate on the total MPP amount rather than the per-HTLC amount.For the fee computation, this is correct — the blinded relay parameters are designed to be applied to the total amount, not per-part. But
check_blinded_payment_constraintsat line 69 of this file callscheck_blinded_payment_constraints(inbound_amt_msat, ...)which checks againsthtlc_minimum_msat. Using the total here means a per-HTLC amount belowhtlc_minimum_msatwould still pass if the total is above it. Is that the intended behavior for trampoline MPP?If
multipath_trampoline_dataisNone, this falls back tomsg.amount_msatwhich is the per-HTLC amount (non-MPP case) — that's correct.