lnd icon indicating copy to clipboard operation
lnd copied to clipboard

[bug]: can't send payment to blinded path when setting custom data records

Open ZZiigguurraatt opened this issue 1 year ago • 8 comments

Background

can't send payment to blinded path when setting custom data records

Your environment

lnd version 0.18.3-beta commit=v0.18.3-beta

Actual behaviour

On node A generate an invoice:

$ lncli addinvoice --blind --amt 5

Then go to node B and pay the invoice:

lncli sendpayment --amp -f --data 3438382=0a21ff --pay_req=.....

but it fails with messages (edited for privacy):

+----------------------------------+--------------+--------------+--------------+-------+----------+--------------------+-----------------------------------------------------+
| HTLC_STATE                       | ATTEMPT_TIME | RESOLVE_TIME | RECEIVER_AMT | FEE   | TIMELOCK | CHAN_OUT           | ROUTE                                               |
+----------------------------------+--------------+--------------+--------------+-------+----------+--------------------+-----------------------------------------------------+
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_KEY @ 1st hop     
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
| INVALID_ONION_BLINDING @ 3rd hop
+----------------------------------+--------------+--------------+--------------+-------+----------+--------------------+-----------------------------------------------------+

Payment status: FAILED, reason: FAILURE_REASON_TIMEOUT
[lncli] FAILED

Notes:

  • If I remove --data 3438382=0a21ff, the payment routes.
  • lncli sendpayment -h|grep data is where I got the test value for --data 3438382=0a21ff from.

Expected behaviour

Payment should route

ZZiigguurraatt avatar Nov 06 '24 22:11 ZZiigguurraatt

Actually, I just realized I accidentally included an --amp flag in the example above, but when removing it, the same result still occurs.

ZZiigguurraatt avatar Nov 06 '24 22:11 ZZiigguurraatt

It looks like route blinding is incompatible with sending custom records, see https://github.com/lightning/bolts/blob/master/04-onion-routing.md#requirements:

If it is the final node:

    MUST return an error if the payload contains other tlv fields than encrypted_recipient_data, current_path_key, amt_to_forward, outgoing_cltv_value and total_amount_msat.

bitromortac avatar Nov 07 '24 08:11 bitromortac

Interesting. LNDK has the ability to send a note when paying BOLT12 offers using blinded paths. I wonder how that works. Here is an excerpt from the documentation. I've tested it with phoenix wallet and it shows the PAYER_NOTE on the recipient's phoenix wallet.

$ ./lndk-cli --network=mainnet pay-offer --help
	PayOffer pays a BOLT 12 offer, provided as a 'lno'-prefaced offer string

	Usage: lndk-cli pay-offer [OPTIONS] <OFFER_STRING> [AMOUNT] [PAYER_NOTE]

	Arguments:
	  <OFFER_STRING>  The offer string
	  [AMOUNT]        Amount the user would like to pay. If this isn't set, we'll assume the user is paying whatever the offer amount is
	  [PAYER_NOTE]    A payer-provided note which will be seen by the recipient

ZZiigguurraatt avatar Nov 07 '24 09:11 ZZiigguurraatt

What is the encrypted_recipient_data? Could that be the PAYER_NOTE that LNDK exposes?

ZZiigguurraatt avatar Nov 07 '24 09:11 ZZiigguurraatt

encrypted_recipient_data is a tlv that's encrypted by the receiver to detail how the routing should be done for each hop in the blinded route (see example in https://github.com/lightning/bolts/blob/master/proposals/route-blinding.md#blinded-payments). So a sender should not be able to append to that data.

I'm not sure, maybe in the BOLT12 flow, the note is sent to the recipient via the onion message and persisted, or included in an encrypted data field generated by the receiver for it to read once the payment arrives?

bitromortac avatar Nov 07 '24 10:11 bitromortac

LNDK maintainer here 👋🏼, TLVs invreq_payer_note in the Bolt12 flow let you add info when paying

a-mpch avatar Jun 03 '25 16:06 a-mpch

So the invreq_payer_note then becomes a tlv in a tlv ?

@ZZiigguurraatt I wonder why such a request ended in such a loop tho, was the tried amount always decreased ?

ziggie1984 avatar Nov 07 '25 09:11 ziggie1984

So the invreq_payer_note then becomes a tlv in a tlv ?

@ZZiigguurraatt I wonder why such a request ended in such a loop tho, was the tried amount always decreased ?

not sure, would have to look into it again.

ZZiigguurraatt avatar Nov 07 '25 16:11 ZZiigguurraatt