bolts icon indicating copy to clipboard operation
bolts copied to clipboard

Does `blinded_payinfo` refer to the recipient or the intro node

Open TheBlueMatt opened this issue 9 months ago • 10 comments

Its not specified, and it turns out we were inconsistent between what we generated and what our pathfinder used (yay fuzzing!).

TheBlueMatt avatar Apr 10 '25 15:04 TheBlueMatt

I'm not sure what you mean by "refer to"? Do you mean in which node's payload this is included? Or which node_id it points to?

t-bast avatar Apr 16 '25 16:04 t-bast

Ha, sorry, this was indeed unclear. I meant "which node in the path has to meet the provided htlc_min/htlc_max/cltv_expiry". The spec doesn't specify.

TheBlueMatt avatar Apr 22 '25 17:04 TheBlueMatt

For path-finding, a blinded path is equivalent to a single channel. And just like a channel, it has fees, minimum and maximum amounts, and CLTV expiry delta, that's blinded_payinfo. A HTLC that arrives at the first node of the blinded path must satisfy the requirements of blinded_payinfo or it will be rejected.

thomash-acinq avatar Apr 23 '25 08:04 thomash-acinq

Gotcha, that's clearer! Indeed, we should clarify that this applies to the whole blinded path: the htlc_min and htlc_max apply to every channel in that blinded path, and the cltv_expiry as well (every node in the blinded path must ensure that the HTLC's expiry is lower than the cltv_expiry).

t-bast avatar Apr 23 '25 08:04 t-bast

Wait, the two of you just said different things, though - @thomash-acinq said that the HTLC that arrives at the first node must satisfy the requirements but then @t-bast said that the values apply to "every channel in the blinded path". Those are different.

TheBlueMatt avatar Apr 28 '25 18:04 TheBlueMatt

The specific case where it came up for us may be illustrative - we are treating the blinded path as a single hop for pathfinding purposes, but our fuzzer decided that this was an invalid path. Specifically, the fuzzer was looking at the total in-flight over the blinded path (including the fee, since the fee could be taken by a later hop) and making sure it doesn't exceed the blinded path's htlc-max. But, for a normal hop, we wouldn't do that - the fee is always taken directly by the node in question, so we wouldn't include the fee in the in-flight amount over the outbound edge.

TheBlueMatt avatar Apr 28 '25 18:04 TheBlueMatt

In your specific case, the total in-flight should not include the fee. It is the responsibility of the creator of the blinded route to make sure that it behaves exactly like a single channel would. For instance if you want to blind the route A -> B -> C where A -> B has htlc-max=100 and fee-base=2, and B -> C has htlc-max=1000 and fee-base=5 (we assume no proportional fee for simplicity), then blinded_payinfo for the whole route would be htlc-max=95 and fee-base=7. In practice, to preserve privacy, you would set htlc-max a bit lower (let's say 90) and hide the true fee-base too (in eclair we can set it to 0 and pay the fees ourselves).

thomash-acinq avatar Apr 29 '25 07:04 thomash-acinq

Sure, that was my understanding as well, but I was noting that the BOLTs are unclear and wanted to make sure people were doing the same thing (and it sounds like @t-bast at least was on a different page!).

TheBlueMatt avatar Apr 29 '25 19:04 TheBlueMatt

Either way, point is the BOLTs need to be clarified.

TheBlueMatt avatar Apr 29 '25 19:04 TheBlueMatt

it sounds like @t-bast at least was on a different page!

Unless I'm missing something, we are on the same page, I discussed that with Thomas offline and we agree on the behavior, I just probably poorly explained it in english, code (or spec) is easier to express that!

t-bast avatar Apr 30 '25 09:04 t-bast