Skip to content

Handle receiving payments via Trampoline #3670

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

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lightning/src/ln/onion_payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ where
{
let encode_malformed_error = |message: &str, err_code: u16| {
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", message);
let (sha256_of_onion, failure_code) = if msg.blinding_point.is_some() {
let (sha256_of_onion, failure_code) = if msg.blinding_point.is_some() || err_code == INVALID_ONION_BLINDING {
([0; 32], INVALID_ONION_BLINDING)
} else {
(Sha256::hash(&msg.onion_routing_packet.hop_data).to_byte_array(), err_code)
Expand Down
64 changes: 54 additions & 10 deletions lightning/src/ln/onion_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1821,16 +1821,60 @@ where
trampoline_shared_secret,
),
}),
Ok((_, None)) => Err(OnionDecodeErr::Malformed {
err_msg: "Non-final Trampoline onion data provided to us as last hop",
// todo: find more suitable error code
err_code: 0x4000 | 22,
}),
Ok((_, Some(_))) => Err(OnionDecodeErr::Malformed {
err_msg: "Final Trampoline onion data provided to us as intermediate hop",
// todo: find more suitable error code
err_code: 0x4000 | 22,
}),
Ok((msgs::InboundTrampolinePayload::BlindedForward(hop_data), None)) => {
if hop_data.intro_node_blinding_point.is_some() {
return Err(OnionDecodeErr::Relay {
err_msg: "Non-final intro node Trampoline onion data provided to us as last hop",
err_code: INVALID_ONION_BLINDING,
Comment on lines +1826 to +1828
Copy link
Contributor

@carlaKC carlaKC Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that using the combination of Relay + INVALID_ONION_BLINDING here will result in sending an invalid_onion_blinding message with no sha256_of_onion data attached because the caller always sets empty data for the Relay type.

Although the spec allows zero values here, my understanding is that we still need to include the empty data?

We don't hit an issue in the code today because there isn't an assertion in reason for INVALID_ONION_BLINDING. I ran into this during a rebase for #3601 which adds an assertion that there is 32 bytes of data present for this error code.

Also totally possible that I'm missing some trampoline context, and that check should just not be added in the first place!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was ultimately resolved by switching to InvalidOnionPayloadrather than InvalidOnionBlinding.

shared_secret,
trampoline_shared_secret: Some(SharedSecret::from_bytes(
trampoline_shared_secret,
)),
});
}
Err(OnionDecodeErr::Malformed {
err_msg: "Non-final Trampoline onion data provided to us as last hop",
err_code: INVALID_ONION_BLINDING,
})
},
Ok((msgs::InboundTrampolinePayload::BlindedReceive(hop_data), Some(_))) => {
if hop_data.intro_node_blinding_point.is_some() {
return Err(OnionDecodeErr::Relay {
err_msg: "Final Trampoline intro node onion data provided to us as intermediate hop",
err_code: 0x4000 | 22,
shared_secret,
trampoline_shared_secret: Some(SharedSecret::from_bytes(
trampoline_shared_secret,
)),
});
}
Err(OnionDecodeErr::Malformed {
err_msg:
"Final Trampoline onion data provided to us as intermediate hop",
err_code: INVALID_ONION_BLINDING,
})
},
Ok((msgs::InboundTrampolinePayload::Forward(_), None)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that these variants are spelled out explicitly now, reads more obviously correct 👍

Err(OnionDecodeErr::Relay {
err_msg: "Non-final Trampoline onion data provided to us as last hop",
err_code: 0x4000 | 22,
shared_secret,
trampoline_shared_secret: Some(SharedSecret::from_bytes(
trampoline_shared_secret,
)),
})
},
Ok((msgs::InboundTrampolinePayload::Receive(_), Some(_))) => {
Err(OnionDecodeErr::Relay {
err_msg:
"Final Trampoline onion data provided to us as intermediate hop",
err_code: 0x4000 | 22,
shared_secret,
trampoline_shared_secret: Some(SharedSecret::from_bytes(
trampoline_shared_secret,
)),
})
},
Err(e) => Err(e),
}
},
Expand Down