Description
I've been testing blinded payments between cln
v22.11 and eclair
and I have exciting news: there are a few minor issues and incompatibilities, but once I worked around them, everything was working very smoothly!
You can find more details about what tests I ran at the end of this issue, but I'll start with the list of things that should be fixed.
Bolt 12 feature bits
Currently cln
doesn't set any feature bit in Bolt 12 invoices.
This means that we don't know whether we can use MPP or not (so I had to force MPP usage in eclair
).
On the contrary, eclair
sets a few feature bits in its Bolt 12 invoices: var_onion_optin:mandatory
, option_route_blinding:mandatory
, basic_mpp:optional
(removed if MPP was deactivated).
The Bolt 12 invoices eclair
generates by default were rejected by cln
because of these feature bits.
We need to settle on what feature bits can be used here and clarify the Bolt 12 spec.
EDIT: the offers spec PR says that the MPP feature bit is the only feature bit allowed in Bolt 12 objects: eclair will be updated to match that in ACINQ/eclair#2386
update_add_htlc
's blinding point
The route blinding PR specifies that tlv field number 0
must be used when sending the blinding_point
in update_add_htlc
(inside a blinded route).
It looks like cln
is currently using tlv field 2
instead when relaying payments, that should be fixed?
total_amount_msat
field in onion payload
The route blinding PR made the total_amount_msat
field (tlv number 18
) mandatory when sending to a blinded route, but cln
currently doesn't set it.
Missing support for sending to a blinded route when the node is also its introduction point
We discussed that a while ago, this is a somewhat tricky edge case.
Eclair already supports this, but it looks like cln
doesn't, it replies to the pay
command with the following error:
This payment is destined for ourselves. Self-payments are not supported
Obsolete interpretation of blinded_payinfo
In the latest iterations, we decided to include one blinded_payinfo
per blinded path, that represents the aggregated payment information for the whole path.
It looks like cln
still expects one blinded_payinfo
per hop of every blinded path, since it returns the following warning when decoding invoices:
invoice does not have correct number of blinded_payinfo
Detailed tests report
This section details the e2e tests I ran on regtest
if someone wants to replay them or test other scenarios.
Note that it would be nice to have a way to generate "real" blinded paths from cln
(not only dummy hops) to do more testing.
For all the following tests, Alice and Bob are running eclair
and Carol and Dave are running cln
.
Dave creates Bolt12 invoice with just dummy hops, Bob pays it
We setup channels with the following balances:
+-----+ 150 000 sat 0 sat +------+
| Bob |--------------------------------| Dave |
+-----+ +------+
Test steps:
- Dave creates a 100 000 sat Bolt 12 invoice with a blinded dummy hop
- Bob pays that invoice
- A single HTLC is sent to the Bob -> Dave channel and is correctly fulfilled
Dave creates Bolt12 invoice with just dummy hops, Alice pays it using MPP
We setup channels with the following balances:
0 sat +-----+ 150 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
150 000 sat | | 0 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
150 000 sat | | 0 sat
| +-------+ |
+---------------------| Carol |----------------------+
0 sat +-------+ 150 000 sat
Test steps:
- Dave creates a 200 000 sat Bolt 12 invoice with a blinded dummy hop
- Alice pays that invoice
- HTLCs are sent through both the Bob -> Dave channel and the Carol -> Dave channel
- It may require a retry if the initial split sent too much through one of the channels: that retry correctly happens automatically
- All HTLCs are correctly fulfilled
Alice creates Bolt12 invoice with just dummy hops, Dave pays it
We setup channels with the following balances:
125 000 sat +-----+ 25 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
25 000 sat | | 125 000 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
25 000 sat | | 125 000 sat
| +-------+ |
+---------------------| Carol |----------------------+
125 000 sat +-------+ 25 000 sat
Test steps:
- Alice creates a 50 000 sat invoice with a blinded dummy hop
- Dave pays that invoice
- A single HTLC is sent, either through Bob or Carol
- The HTLC is correctly fulfilled
Alice creates Bolt12 invoice with just dummy hops, Carol pays it
We setup channels with the following balances:
125 000 sat +-----+ 25 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
25 000 sat | | 125 000 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
125 000 sat | | 25 000 sat
| +-------+ |
+---------------------| Carol |----------------------+
25 000 sat +-------+ 125 000 sat
Test steps:
- Alice creates a 10 000 sat invoice with a blinded dummy hop
- Carol pays that invoice
- A single HTLC is sent directly to Alice (not taking the long route through Dave)
- The HTLC is correctly fulfilled
Alice creates Bolt12 invoice with blinded hop Bob -> Alice, Bob pays it
We setup channels with the following balances:
+-------+ 25 000 sat 125 000 sat +-----+
| Alice |-------------------------------------| Bob |
+-------+ +-----+
Test steps:
- Alice creates a 100 000 sat Bolt 12 invoice with a blinded hop
Bob -> Alice
and dummy hops - Bob pays that invoice
- A single HTLC is sent directly to Alice and is correctly fulfilled
Alice creates Bolt12 invoice with blinded hop Carol -> Alice, Carol pays it
We setup channels with the following balances:
+-------+ 25 000 sat 125 000 sat +-------+
| Alice |-------------------------------------| Carol |
+-------+ +-------+
Test steps:
- Alice creates a 100 000 sat Bolt 12 invoice with a blinded hop
Carol -> Alice
and dummy hops - Carol pays that invoice
⚠️ this isn't supported yet bycln
and no payment is sent
Alice creates Bolt12 invoice with blinded hop Bob -> Alice, Dave pays it
We setup channels with the following balances:
125 000 sat +-----+ 25 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
25 000 sat | | 125 000 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
125 000 sat | | 25 000 sat
| +-------+ |
+---------------------| Carol |----------------------+
25 000 sat +-------+ 125 000 sat
Test steps:
- Alice creates a 25 000 sat Bolt 12 invoice with a blinded hop
Bob -> Alice
and dummy hops - Dave pays that invoice
- A single HTLC is sent on the Dave -> Bob channel and is correctly fulfilled
Alice creates Bolt12 invoice with blinded hops Bob -> Alice and Carol -> Alice, Dave pays it using MPP
We setup channels with the following balances:
125 000 sat +-----+ 25 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
25 000 sat | | 125 000 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
25 000 sat | | 125 000 sat
| +-------+ |
+---------------------| Carol |----------------------+
125 000 sat +-------+ 25 000 sat
Test steps:
- Alice creates a 200 000 sat Bolt 12 invoice with two blinded paths:
Bob -> Alice
and dummy hopsCarol -> Alice
and dummy hops
- Dave pays that invoice
- We expect multiple HTLCs to be sent through both Bob and Carol
⚠️ this currently fails because Carol doesn't use the right tlv field for theblinding_point
Dave creates Bolt12 invoice but not enough incoming liquidity, Alice tries to pay it
We setup channels with the following balances:
25 000 sat +-----+ 25 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
125 000 sat | | 125 000 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
125 000 sat | | 125 000 sat
| +-------+ |
+---------------------| Carol |----------------------+
25 000 sat +-------+ 25 000 sat
Test steps:
- Dave creates a 60 000 sat Bolt 12 invoice with a dummy hop
- Alice tries to pay it, but there is not enough liquidity towards Dave
⚠️ Dave returnsinvalid_onion_blinding
instead ofmpp_timeout
-> that should probably change, Dave isn't hiding itsnode_id
and could return a normal failure?⚠️ this test would be more interesting if Dave created blinded paths starting at Bob and Carol
Alice creates Bolt12 invoice but not enough incoming liquidity, Dave tries to pay it
We setup channels with the following balances:
25 000 sat +-----+ 25 000 sat
+----------------------| Bob |-----------------------+
| +-----+ |
125 000 sat | | 125 000 sat
| |
+-------+ +------+
| Alice | | Dave |
+-------+ +------+
| |
125 000 sat | | 125 000 sat
| +-------+ |
+---------------------| Carol |----------------------+
25 000 sat +-------+ 25 000 sat
Test steps:
- Alice creates a 60 000 sat Bolt 12 invoice with two blinded paths:
Bob -> Alice
and dummy hopsCarol -> Alice
and dummy hops
- Dave tries to pay it, but there is not enough liquidity towards Alice
- After a few attempts at splitting the payment, Dave gives up
- Dave only receives
invalid_onion_blinding
failures