Skip to content

Conversation

t-bast
Copy link
Collaborator

@t-bast t-bast commented Jan 25, 2021

Trampoline routing uses layered onions to trustlessly and privately offload the calculation of parts of a payment route to remote trampoline nodes.

A normal onion contains a smaller onion for the last hop of the route, and that smaller onion contains routing information about the next trampoline hop.

Intermediate trampoline nodes "fill the gap" by finding a route to the next trampoline node, and sending it the peeled trampoline onion, until that reaches the final destination.

This PR details the onion construction and requirements for supporting nodes. I advise readers to also have a look at #829 which gives a more high-level view of the different components, how they interact, and provides nice diagrams that help understand the low-level details.

Copy link
Collaborator

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

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

I like it, but I'm not sure I understand the purpose of the payment_secret except inside the internal onion for the final node?

@rustyrussell rustyrussell changed the title Trampoline onion format Trampoline onion format (Feature 24/25) Mar 1, 2021
Copy link
Contributor

@lightning-developer lightning-developer left a comment

Choose a reason for hiding this comment

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

I believe the spec should make a recommendation for CLTV and fee budgets that senders of trampoline onions should use for each trampoline to reduce the usage of temporary_trampoline_failure.

Also it seems reasonable to just reply with a single fee_budget_msat instead of * [u32:fee_base_msat] and [u32:fee_proportional_millionths] as those fields seem not to make sense in the context of trampolines.

Trampolines could announce the fee_budget_msat and cltv_budget (in case you like the new name) that they believe to be sufficient in their node announcements?

t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Apr 2, 2025
We update the trampoline feature to match the official specification
from lightning/bolts#836.

We remove support for the previous version of trampoline, which means
that when paying nodes that use the experimental version, we will use
the trampoline-to-non-trampoline flow instead. Similarly, when older
nodes pay updated nodes, they won't understand the new trampoline
feature bit and will use the trampoline-to-non-trampoline flow.

We update the trampoline-to-non-trampoline flow to remove the unused
trampoline payload in the onion, which saves some space. Note that we
don't want to officially specify this scenario, as it leaks some data
about the recipient to the trampoline node. We rather wait for nodes
to either support trampoline or blinded paths, which fixes this issue.
t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Apr 2, 2025
We update our trampoline payments to blinded paths to match the official
specification from lightning/bolts#836.

The blinded paths and recipient features are included in the trampoline
onion, which potentially allows using multiple trampoline hops.

That was already what we were doing with experimental TLVs, so we simply
update the TLV values to match the spec values.
t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Apr 2, 2025
We add the ability to pay recipients that support trampoline *and*
blinded paths. We include the blinded path data in the trampoline
payloads for each node inside the blinded path. This doesn't reveal
unnecessary information to the trampoline node: this is specified in
details in lightning/bolts#836.
t-bast added a commit to ACINQ/eclair that referenced this pull request Apr 3, 2025
We add support for the official version of trampoline payments, as
specified in lightning/bolts#836.

We keep supporting trampoline payments that use the legacy protocol
to allow a smooth transition. We hardcode the legacy feature bit 149
in a few places to make this work, which is a bit hacky but simple
and should be removed 6 months after releasing the official version.

We also keep supporting payments from trampoline wallets to nodes that
don't support trampoline: this is bad from a privacy standpoint, but
will be fixed when recipients start supporting Bolt 12.
There is no identified scenario where intermediate trampoline nodes use
a blinded path to reach the next trampoline node, since they know the
identity of that next node. We thus disallow this case by specifying
that the `current_path_key` can only be set in either the outer onion
or the trampoline onion (for the introduction node).
t-bast added a commit to ACINQ/eclair that referenced this pull request Jun 12, 2025
We add support for the official version of trampoline payments, as
specified in lightning/bolts#836.

We keep supporting trampoline payments that use the legacy protocol
to allow a smooth transition. We hardcode the legacy feature bit 149
in a few places to make this work, which is a bit hacky but simple
and should be removed 6 months after releasing the official version.

We also keep supporting payments from trampoline wallets to nodes that
don't support trampoline: this is bad from a privacy standpoint, but
will be fixed when recipients start supporting Bolt 12.
t-bast added a commit to ACINQ/eclair that referenced this pull request Jun 24, 2025
We add support for the official version of trampoline payments, as
specified in lightning/bolts#836.

We keep supporting trampoline payments that use the legacy protocol
to allow a smooth transition. We hardcode the legacy feature bit 149
in a few places to make this work, which is a bit hacky but simple
and should be removed 6 months after releasing the official version.

We also keep supporting payments from trampoline wallets to nodes that
don't support trampoline: this is bad from a privacy standpoint, but
will be fixed when recipients start supporting Bolt 12.
t-bast added a commit to ACINQ/eclair that referenced this pull request Jun 30, 2025
We add support for the official version of trampoline payments, as
specified in lightning/bolts#836.

We keep supporting trampoline payments that use the legacy protocol
to allow a smooth transition. We hardcode the legacy feature bit 149
in a few places to make this work, which is a bit hacky but simple
and should be removed 6 months after releasing the official version.

We also keep supporting payments from trampoline wallets to nodes that
don't support trampoline: this is bad from a privacy standpoint, but
will be fixed when recipients start supporting Bolt 12.
trampoline node, they may replace it with their own error for the origin node,
otherwise they must encrypt on top of the next trampoline node's error.

Intermediate trampoline hops apply the obfuscation step twice: first with the
Copy link

@a-mpch a-mpch Sep 15, 2025

Choose a reason for hiding this comment

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

It is no clear to me that whenever the receiver is the first trampoline and something fails, should the receiver node just use the outer onion shared secret or would it use the double obfuscation?
It could be seen in different perspectives:

  1. payment reaches the trampoline and then try to route it, figuring out it is itself.
  2. Before trying to route it as trampoline, payment is received.

I didn't find a test case for this in eclair (don't know much of Scala tho)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You're right, there is some subtlety here, this depends on who the error is encrypted for:

  • if the failing trampoline node wants the error to be for the previous trampoline node, they use the outer onion shared secret: this is used for example when the payment is using MPP but not all parts were received in time, which is an error made by the previous trampoline node which could (probably should) retry, so we don't want the error to go all the way back to the sender
  • if the failing trampoline node wants the error to be for the sender, they use the double obfuscation, which forces the previous trampoline node to relay the error upstream: this is used for example when receiving a payment that an invoice that was already paid, or that has a trampoline expiry that is too close

I don't think we can list all cases in the spec, but we probably should better explain the distinction between those two cases. Is that clear enough? Otherwise feel free to suggest the wording you'd like to see in the spec that would make this clear.

Copy link

Choose a reason for hiding this comment

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

I think that wording makes sense. Thanks!

docker-lordvf6ik added a commit to docker-lordvf6ik/lightning-kmp that referenced this pull request Sep 28, 2025
We previously supported having multiple channels with our peer, because
we didn't yet support splicing. Now that we support splicing, we always
have at most one active channel with our peer. This lets us simplify
greatly the outgoing payment state machine: payments are always made
with a single outgoing HTLC instead of potentially multiple HTLCs (MPP).

We don't need any kind of path-finding: we simply need to check the
balance of our active channel, if any.

We may introduce support for connecting to multiple peers in the future.
When that happens, we will still have a single active channel per peer,
but we may allow splitting outgoing payments across our peers. We will
need to re-work the outgoing payment state machine when this happens,
but it is too early to support this now anyway.

This refactoring makes it easier to create payment onion, by creating
the trampoline onion *and* the outer onion in the same function call.
This will make it simpler to migrate to the version of trampoline
that is currently specified in lightning/bolts#836
where some fields will be included in the payment onion instead of the
trampoline onion.

Co-authored-by: Thomas HUET <[email protected]>
ebonyschneider462359 added a commit to ebonyschneider462359/lightning-kmp that referenced this pull request Oct 10, 2025
We previously supported having multiple channels with our peer, because
we didn't yet support splicing. Now that we support splicing, we always
have at most one active channel with our peer. This lets us simplify
greatly the outgoing payment state machine: payments are always made
with a single outgoing HTLC instead of potentially multiple HTLCs (MPP).

We don't need any kind of path-finding: we simply need to check the
balance of our active channel, if any.

We may introduce support for connecting to multiple peers in the future.
When that happens, we will still have a single active channel per peer,
but we may allow splitting outgoing payments across our peers. We will
need to re-work the outgoing payment state machine when this happens,
but it is too early to support this now anyway.

This refactoring makes it easier to create payment onion, by creating
the trampoline onion *and* the outer onion in the same function call.
This will make it simpler to migrate to the version of trampoline
that is currently specified in lightning/bolts#836
where some fields will be included in the payment onion instead of the
trampoline onion.

Co-authored-by: Thomas HUET <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.