Skip to content

Commit 39f3c99

Browse files
committed
recommendations: add local resource conservation
1 parent 0539ad8 commit 39f3c99

File tree

2 files changed

+340
-2
lines changed

2 files changed

+340
-2
lines changed

02-peer-protocol.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,8 @@ A sending node:
10461046
HTLCs it has forwarded.
10471047
- otherwise:
10481048
- if `endorsed` is present and non-zero for the corresponding incoming HTLC
1049-
AND the incoming peer is considered to have sufficient local reputation:
1049+
AND the incoming peer is considered to have sufficient local reputation
1050+
(see [Local Reputation](recommendations/local-resource-conservation.md#local-reputation)):
10501051
- SHOULD set `endorsed` to `1`
10511052
- otherwise:
10521053
- SHOULD set `endorsed` to `0`.
@@ -1078,7 +1079,8 @@ A receiving node:
10781079
- MUST use the corresponding blinded private key to decrypt the `onion_routing_packet` (see [Route Blinding](04-onion-routing.md#route-blinding))
10791080
- if `endorsed` is not provided OR `endorsed` is zero:
10801081
- MAY choose to limit the liquidity and slots available to forward the
1081-
corresponding outgoing HTLC in `onion_routing_packet`, if any.
1082+
corresponding outgoing HTLC in `onion_routing_packet`, if any
1083+
(see [Resource Bucketing](recommendations/local-resource-conservation.md#resource-bucketing)):
10821084

10831085
The `onion_routing_packet` contains an obfuscated list of hops and instructions for each hop along the path.
10841086
It commits to the HTLC by setting the `payment_hash` as associated data, i.e. includes the `payment_hash` in the computation of HMACs.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
# Local Resource Conservation
2+
3+
## Table of Contents
4+
* [Introduction](#introduction)
5+
* [Overview](#overview)
6+
* [Local Reputation](#local-reputation)
7+
* [Recommendations for Reputation Scoring](#recommendations-for-reputation-scoring)
8+
* [Effective HTLC Fees](#effective-htlc-fees)
9+
* [Outgoing Channel Revenue](#outgoing-channel-revenue)
10+
* [Incoming Channel Revenue](#incoming-channel-revenue)
11+
* [In Flight HTLC Risk](#in-flight-htlc-risk)
12+
* [Resource Bucketing](#resource-bucketing)
13+
* [Implementation Notes](#implementation-notes)
14+
* [Decaying Average](#decaying-average)
15+
* [Multiple Channels](#multiple-channels)
16+
17+
## Introduction
18+
Channel jamming is a known denial-of-service attack against the Lightning
19+
Network. An attacker that controls both ends of a payment route can disrupt
20+
usage of a channel by sending payments that are destined to fail through a
21+
target route. Fees are currently only paid to routing nodes on successful
22+
completion of a payment, so this attack is virtually free - the attacker pays
23+
only for the costs of running a node, funding channels on-chain and the
24+
opportunity cost of capital committed to the attack.
25+
26+
A channel can be fully jammed by depleting its available HTLC slots by holding
27+
`max_accepted_htlcs` or its available liquidity by holding the
28+
`max_htlc_value_in_flight`. An economically rational attacker will pursue the
29+
attack method with the lowest cost and highest utility. An attack can exhaust
30+
the resources along the target route in two ways, though the difference
31+
between the two behaviors is not rigorously defined:
32+
* Quick Jamming: sending a continuous stream of payments through a route that
33+
are quickly resolved, but block all of the liquidity or HTLC slots along the
34+
route.
35+
* Slow Jamming: sending a slow stream of payments through a route and only
36+
failing them at the latest possible timeout, blocking all of the liquidity
37+
or HTLC slots along the route for the duration.
38+
39+
This document outlines recommendations for implementing local resource
40+
conservation to mitigate slow jamming attacks. It is part of a hybrid solution
41+
to mitigating channel jamming, intended to be followed by the introduction of
42+
unconditional fees to mitigate fast jamming.
43+
44+
## Overview
45+
Local resource conservation combines the following elements to provide nodes
46+
with a mechanism to protect themselves against slow-jamming attacks:
47+
48+
* [HTLC Endorsement](#../02-peer-protocol.md#adding-an-htlc-update_add_htlc):
49+
propagation of a signal along the payment route that indicates whether the
50+
node sending `update_add_htlc` recommends that the HTLC should be granted
51+
access to downstream resources (and that it will stake its reputation on the
52+
fast resolution of the HTLC).
53+
* [Local Reputation](#local-reputation): local tracking of the historical
54+
forwarding behavior of channel peers, used to decide whether to grant
55+
incoming HTLCs full access to local resources and whether to propagate
56+
endorsement downstream.
57+
* [Resource Bucketing](#resource-bucketing): reservation of a portion of
58+
"protected" liquidity and slots for endorsed HTLCs that have been forwarded
59+
by high reputation nodes.
60+
61+
Sequence:
62+
* The `update_add_htlc` is sent by an upstream peer.
63+
* If the sending peer has sufficient local reputation (per the receiving
64+
peer's view) AND the incoming HTLC was sent with a non-zero `endorsed` TLV:
65+
* The HTLC will be allowed access to the "protected" bucket, so will have
66+
full access to the channel's liquidity and slots,
67+
* The corresponding outgoing HTLC (if present) will be forwarded with
68+
`endorsed` set to `1`.
69+
* Otherwise:
70+
* The HTLC will be limited to the remaining "general" slots and liquidity,
71+
and will be failed if there are no resources remaining in this bucket.
72+
* The corresponding outgoing HTLC (if present) will be forwarded with
73+
`endorsed` set to `0`.
74+
75+
In the steady state when Lightning is being used as expected, there should be
76+
no need for use of protected resources as channels are not saturated during
77+
regular operation. Should the network come under attack, honest nodes that
78+
have built up reputation over time will still be able to utilize protected
79+
resources to process payments in the network.
80+
81+
## Local Reputation
82+
83+
### Recommendations for Reputation Scoring
84+
Local reputation can be used by forwarding nodes to decide whether to allocate
85+
resources to and signal endorsement of a HTLC on the outgoing channel. Nodes MAY
86+
use any metric of their choosing to classify a peer as having sufficient
87+
reputation, though a poor choice of reputation scoring metric may affect their
88+
reputation with their downstream peers.
89+
90+
The goal of this reputation metric is to ensure that the cost to obtain
91+
sufficient reputation for a HTLC to be endorsed on the outgoing channel is
92+
greater than the damage that a node can inflict by abusing the access that it
93+
is granted. This algorithm uses forwarding fees to measure damage, as this value
94+
is observable within the protocol. It is reasonable to expect an adversary to
95+
"about turn" - to behave perfectly to build up reputation, then alter their
96+
behavior to abuse it. For this reason, in-flight HTLCs have a temporary
97+
negative impact on reputation until they are resolved.
98+
99+
If granted full access to a node's liquidity and slots, the maximum amount of
100+
damage that can be inflicted on the targeted node is bounded by the largest
101+
cltv delta from the current block height that it will allow a HTLC to set
102+
before failing it with [expiry_too_far](../04-onion-routing.md#failure-messages).
103+
This value is typically 2016 blocks (~2 weeks) at the time of writing.
104+
105+
Upon receipt of `update_add_htlc`, the local node considers the following to
106+
determine whether the sender is classified as having sufficient reputation:
107+
* Outgoing channel revenue: the total routing fees over the maximum allowed HTLC
108+
hold period (~2 weeks) that the outgoing channel has earned the local node,
109+
considering both incoming and outgoing HTLCs that have used the channel.
110+
* Incoming channel revenue: the total routing fees that the incoming channel has
111+
earned the local node, considering only incoming HTLCs on the channel.
112+
* In-flight HTLCs risk: any endorsed HTLC that the incoming channel has
113+
in-flight on the requested outgoing channel negatively affect reputation,
114+
based on the assumption that they will be held until just before their
115+
expiry height.
116+
117+
On a per-HTLC basis, the local node will classify the sending node's
118+
reputation for the offered HTLC as follows:
119+
* if `incoming_channel_revenue - in_flight_risk >= outgoing_channel_revenue`:
120+
* the sending node is considered to have *sufficient* reputation for the
121+
offered HTLC.
122+
* otherwise, the sending node is considered to have *insufficient* reputation
123+
for the offered HTLC.
124+
125+
The sections that follow provide details of how to calculate the components of
126+
the inequality.
127+
128+
#### Effective HTLC Fees
129+
The contribution that the fees paid by a HTLC make to reputation standings is
130+
adjusted by the amount of time that a HTLC took to resolve. By accounting for
131+
the "opportunity cost" of HTLCs that are held for longer periods of time, the
132+
reputation score rewards fast resolving, successful payments and penalizes
133+
slow resolving payments (regardless of successful resolution).
134+
135+
We define the following parameters:
136+
* `resolution_period`: the amount of time a HTLC is allowed to resolve in that
137+
classifies as "good" behavior, expressed in seconds. The recommended default
138+
is 90 seconds (given that the protocol allows for a 60 second MPP timeout).
139+
* `resolution_time`: the amount of time elapsed in seconds between a HTLC being
140+
added to and removed from the local node's commitment transaction.
141+
* `fees`: the fees that are offered to the local node to forward the HTLC,
142+
expressed in milli-satoshis.
143+
144+
We define the `opportunity_cost` of the time a HTLC takes to resolve:
145+
`opportunity_cost`: `ceil ( (resolution_time - resolution_period) / resolution_period) * fees`
146+
147+
Given that `resolution_time` will be > 0 in practice, `opportunity_cost` is 0
148+
for HTLCs that resolve within `resolution_period`, and charges the `fees` that
149+
the HTLC would have earned per period it is held thereafter. This cost accounts
150+
for the slot and liquidity that could have otherwise been paid for by
151+
successful, fast resolving HTLCs during the `resolution_time` the HTLC was
152+
locked in the channel.
153+
154+
Each HTLC's contribution to reputation is expressed by its `effective_fee`
155+
which is determined by its endorsement, resolution time and outcome:
156+
* if `endorsed` is non-zero in `update_add_htlc`:
157+
* if successfully resolved with `update_fulfill_htlc`:
158+
* `effective_fees` = `fees` - `opportunity_cost`
159+
* otherwise:
160+
* `effective_fees` = -`opportunity_cost`
161+
* otherwise:
162+
* if successfully resolved AND `resolution_time` <= `resolution_period`
163+
* `effective_fees` = `fees`
164+
* otherwise:
165+
* `effective_fees` = 0
166+
167+
##### Rationale
168+
Reputation is negatively affected by slow-resolving HTLCs (regardless of whether
169+
they are settled or failed) to ensure that reputation scoring reacts to bad
170+
behavior. HTLCs that resolve within a period of time that is considered
171+
reasonable do not decrease reputation, as some rate of failure is natural in
172+
the network.
173+
174+
The resolution of HTLCs with `endorsed` set to `0` do not have a negative
175+
impact on reputation because the forwarding node made no promises about their
176+
behavior. They are allowed to build reputation when they resolve successfully
177+
within the specified `resolution_period` to allow new nodes in the network to
178+
bootstrap reputation.
179+
180+
#### Outgoing Channel Revenue
181+
Outgoing channel revenue measures the damage to the local node (ie, the loss in
182+
forwarding fees) that a slow jamming attack can incur. For an individual
183+
channel, this is equal to the total revenue forwarded in both directions over
184+
the maximum allowed HTLC hold time.
185+
186+
We define the following parameters:
187+
* `outgoing_revenue_window`: the largest cltv delta from the current block
188+
height that a node will allow a HTLC to set before failing it with
189+
[expiry_too_far](../04-onion-routing.md#failure-messages), expressed in
190+
seconds (assuming 10 minute blocks).
191+
192+
We define the `outgoing_channel_revenue`:
193+
* for each `update_add_htlc` processed on the outgoing channel over the rolling
194+
window [`now` - `outgoing_revenue_window`; `now`]:
195+
* if the HTLC has been resolved:
196+
* `outgoing_channel_revenue` += `fee`
197+
198+
##### Rationale
199+
We consider bi-directional HTLC forwards on the outgoing channel to properly
200+
account for the potential loss of a jamming attack - even when fees don't
201+
accrue on the channel, it is pairwise valuable to the local node. In flight
202+
HTLCs have no impact on outgoing channel revenue, as their fee contribution is
203+
unknown.
204+
205+
#### Incoming Channel Revenue
206+
Incoming channel revenue measures the unforgeable history that the incoming
207+
channel has built with the local node via payment of forwarding fees. As this
208+
value aims to capture the contribution of the channel (rather than its value
209+
to the local node), only incoming HTLCs are considered.
210+
211+
We define the following parameters:
212+
* `incoming_revenue_multiplier`: a multiplier applied to
213+
`outgoing_revenue_window` to determine the rolling window over which the
214+
incoming channel's forwarding history is considered (default 10).
215+
216+
We define the `incoming_channel_revenue`:
217+
* for each incoming `update_add_htlc` processed on the incoming channel over
218+
the rolling window [`now` - `outgoing_channel_window` *
219+
`incoming_channel_multiplier`; `now`]:
220+
* if the HTLC has been resolved:
221+
* `incoming_channel_revenue` += `effective_fee(HTLC)`
222+
223+
##### Rationale
224+
For the incoming channel, only HTLCs that they have forwarded to the local
225+
node count torwards their unforegable contribution to building reputation, as
226+
they push fees to the local node. While the incoming channel may be valuable
227+
as a sink (or predominantly outgoing) channel, the HTLCs that the local node
228+
has forwarded outwards do not represent fees paid by a potential attacker.
229+
230+
#### In Flight HTLC Risk
231+
Whenever a HTLC is forwarded, we assume that it will resolve with the worst
232+
case off-chain resolution time and dock reputation accordingly. This decrease
233+
will be temporary in the case of fast resolution, and preemptively slash
234+
reputation in the case where the HTLC is used as part of a slow jamming attack.
235+
236+
We define the following parameters:
237+
* `height_added`: the block height at which the HTLC was irrevocably committed
238+
to by the local node.
239+
240+
We define the `outstanding_risk` of in-flight HTLCs:
241+
* `outstanding_risk` = `fees` * (`cltv_expiry` - `height_added` * 10 * 60) / `resolution_period`
242+
243+
We define the `in_flight_htlc_risk` for an incoming channel sending
244+
`update_add_htlc`:
245+
* `in_flight_htlc_risk` = `outstanding_risk(proposed update_add_htlc)`
246+
* for each HTLC originating on the incoming channel, forwarded over the
247+
requested outgoing channel:
248+
* if `endorsed` is non-zero:
249+
* `in_flight_htlc_risk` += `outstanding_risk(HTLC)`
250+
251+
##### Rationale
252+
In flight HTLC are included in reputation scoring to account for sudden changes
253+
in a peer's behavior. Even when sufficient reputation is obtained, each HTLC
254+
choosing to take advantage of that reputation is treated as if it will be used
255+
to inflict maximum damage. The expiry height of each incoming in flight HTLC is
256+
considered so that risk is directly related to the amount of time the HTLC
257+
could be held in the channel. Ten minute blocks are assumed for simplicity.
258+
259+
## Resource Bucketing
260+
When making the decision to forward a HTLC on its outgoing channel, a node
261+
MAY choose to limit its exposure to HTLCs that put it at risk of a denial of
262+
service attack.
263+
264+
We define the following parameters:
265+
* `protected_slot_count`: defines the number of HTLC slots that are reserved
266+
for endorsed HTLCs from peers with sufficient reputation (default: 0.5 *
267+
remote peer's `max_accepted_htlcs`).
268+
* `protected_liquidity_portion`: defines the portion of liquidity that is
269+
reserved for endorsed HTLCs from peers with sufficient reputation (default:
270+
0.5).
271+
272+
A node implementing resource bucketing limits exposure on its outgoing channel:
273+
* MUST choose `protected_slot_count` <= the remote channel peer's
274+
`max_accepted_htlcs`.
275+
* MUST choose `protected_liquidity_portion` in [0;1].
276+
277+
For each `update_add_htlc` proposed by an incoming channel:
278+
* If `endorsed` is non-zero AND the incoming channel has sufficient local
279+
reputation for the HTLC (see [Recommendations for Reputation Scoring](#recommendations-for-reputation-scoring)):
280+
* SHOULD forward the HTLC as usual.
281+
* SHOULD set `endorsed` to 1 in the outgoing `update_add_htlc`.
282+
* Otherwise:
283+
* SHOULD reduce the remote peer's `max_accepted_htlcs` by
284+
`protected_slot_count` for the purposes of the proposed HTLC.
285+
* SHOULD reduce the `max_htlc_value_in_flight` by
286+
`protected_liquidity_portion` * `max_htlc_value_in_flight`.
287+
* SHOULD set `endorsed` to `0` in the outgoing `update_add_htlc`.
288+
289+
## Implementation Notes
290+
291+
### Decaying Average
292+
Rolling windows specified in this write up may be implemented as a decaying
293+
average to minimize the amount of data that needs to be stored per-channel. In
294+
flight HTLCs can be accounted for separately to this calculation, as the node
295+
will already have data for these HTLCs available.
296+
297+
Track the following values for each rolling window:
298+
* `last_update`: stores the timestamp of the last update to the decaying
299+
average, expressed in seconds.
300+
* `decaying_average`: stores the value of the decaying average.
301+
* `decay_rate`: a constant rate of decay based on the rolling window chosen,
302+
calculated as: `((1/2)^(2/window_length_seconds))`.
303+
304+
To update the `decaying_average` at time `t`:
305+
* `last_update_diff` = `now` - `last_update`.
306+
* `decaying_average` = `decaying_average` * `decay_rate` ^ `last_update_diff`.
307+
* `last_update` = `t`.
308+
309+
When assessing whether a peer has sufficient reputation for a HTLC:
310+
* MUST update `decaying_average` as described above.
311+
312+
When updating the `decaying_average` to add the `effective_fee` of a newly
313+
resolved HTLC at timestamp `t`:
314+
* MUST update `decaying_average` as described above.
315+
* `decaying_average` = `decaying_average` + `effective_fee`
316+
317+
318+
### Bootstrapping Outgoing Channel Revenue
319+
New channels with no revenue history:
320+
* MAY choose not to endorse any HTLCs in their first two weeks of operation
321+
to establish baseline revenue.
322+
* MAY choose to use `outgoing_channel_revenue` for a similar channel as a
323+
default starting point for scoring reputation.
324+
325+
### Multiple Channels
326+
If the local node has multiple channels open with the incoming and outgoing
327+
peers:
328+
* MAY consider `incoming_channel_revenue` across all channels with the peer
329+
when assessing reputation, but MUST include all in-flight HTLCs originating
330+
from the peer in `in_flight_htlc_risk` if doing so.
331+
* MAY consider `outgoing_channel_revenue` for all channels with the outgoing
332+
peer, but SHOULD take care to [bootstrap](#bootstrapping-outgoing-channel-revenue)
333+
new channels so they do not lower the reputation threshold for existing ones.
334+
* SHOULD calculate `outgoing_channel_revenue` for the channel that is selected
335+
for [non-strict-forwarding](../04-onion-routing.md#non-strict-forwarding)
336+
forwarding.

0 commit comments

Comments
 (0)