Skip to content
15 changes: 15 additions & 0 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,12 @@ To supply the preimage:
* [`channel_id`:`channel_id`]
* [`u64`:`id`]
* [`32*byte`:`payment_preimage`]
1. `tlv_stream`: `update_fulfill_htlc_tlvs`
2. types:
1. type: 1 (`attribution_data`)
2. data:
* [`20*u32`:`htlc_hold_times`]
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand the goal of this field here.

  • If people are dishonest, which they have incentives to, given there's no penalty to lie here, then this value becomes useless.
  • If people are honest, this value creates privacy leaks and side channel attacks, people can use it to fingerprint software or hardware, detect node latency, or its internal state. And for the blinded path this can be used to probe?

Choose a reason for hiding this comment

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

If people are dishonest, which they have incentives to, given there's no penalty to lie here, then this value becomes useless.

Keep in mind that this value is guarded by 2 more reported values. For example, if we have a path A->B->C->D->E over which A pays to E, let's assume Alice gets the hold times as 4 / 3 / 2 / 1 for B C D & E respectively. Also A keeps track of the real elapsed time.

If C wants to lie, he can try to report a value other than 3, but is at the same time guarded by B and D's values, which are 4 and 2. He can under-report or over-report, and he also doesn't know what the actual values for B and D are. If he crosses the neighboring values then the sender can detect the invalid hold time and normalize/penalize accordingly.

If people are honest, this value creates privacy leaks and side channel attacks, people can use it to fingerprint software or hardware, detect node latency, or its internal state. And for the blinded path this can be used to probe?

That was the whole rationale for the 100ms buckets discussion. This (partially) helps with mitigating fingerprinting (i.e the LND 50ms batch ticker now becomes invisible) and also pushes away from over-optimizing pathfinding around low latency nodes.

For blinded paths (at least on LND) we don't populate the attribution data.

Copy link
Contributor

Choose a reason for hiding this comment

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

If he crosses the neighboring values then the sender can detect the invalid hold time and normalize/penalize accordingly.

B can also be dishonest here. It's likely A will see 0.4/0.3/0.2/0.1 while the measured duration is 4 seconds, so this info alone cannot be used to penalize nodes. With a more sophisticated algo and historical data A can start recognizing patterns, assuming there are incentives to stay honest.

That was the whole rationale for the 100ms buckets discussion.

That helps, but note that there's no perfect hiding as long as you are giving the info. For blinded paths this enables a side channel attack as you can get the hold time from the intro node, then you can maybe dos the suspected node in the blinded path to slow down its processing time and measure again the blinded path. This is already doable, but with the hold time it gives a much clearer signal.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

B can also be dishonest here. It's likely A will see 0.4/0.3/0.2/0.1 while the measured duration is 4 seconds, so this info alone cannot be used to penalize nodes. With a more sophisticated algo and historical data A can start recognizing patterns, assuming there are incentives to stay honest.

With this info, A knows that there is at least something slow on its connection to B and A can penalize B. The others got away this time, but in a next round - where B is no longer used - they may also receive a penalty.

* [`210*sha256[..4]`:`truncated_hmacs`]

For a timed out or route-failed HTLC:

Expand All @@ -2359,6 +2365,12 @@ For a timed out or route-failed HTLC:
* [`u64`:`id`]
* [`u16`:`len`]
* [`len*byte`:`reason`]
1. `tlv_stream`: `update_fail_htlc_tlvs`
2. types:
1. type: 1 (`attribution_data`)
2. data:
* [`20*u32`:`htlc_hold_times`]
* [`210*sha256[..4]`:`truncated_hmacs`]

The `reason` field is an opaque encrypted blob for the benefit of the
original HTLC initiator, as defined in [BOLT #4](04-onion-routing.md);
Expand Down Expand Up @@ -2397,6 +2409,9 @@ A node:
`invalid_onion_blinding` failure code for any local or downstream errors.
- SHOULD use the `sha256_of_onion` of the onion it received.
- MAY use an all zero `sha256_of_onion`.
- When supporting `option_attribution_data`:
- if `path_key` is not set in the incoming `update_add_htlc`:
- MUST initialize `attribution_data` and include it in `update_fail_htlc` and `update_fulfill_htlc`. See [BOLT04](04-onion-routing.md).

A receiving node:
- if the `id` does not correspond to an HTLC in its current commitment transaction:
Expand Down
Loading