Skip to content

Commit

Permalink
multi: add resource bucketing for HTLC slots and liquidity
Browse files Browse the repository at this point in the history
  • Loading branch information
carlaKC committed May 11, 2023
1 parent a049b79 commit db043e9
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
11 changes: 10 additions & 1 deletion 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,10 @@ is destined, is described in [BOLT #4](04-onion-routing.md).
1. type: 0 (`blinding_point`)
2. data:
* [`point`:`blinding`]

1. type: 1 (`endorsed`)
2. data:
* [`byte`:`endorsed`]

#### Requirements

A sending node:
Expand Down Expand Up @@ -1033,6 +1036,10 @@ A sending node:
- MUST increase the value of `id` by 1 for each successive offer.
- if it is relaying a payment inside a blinded route:
- MUST set `blinding_point` (see [Route Blinding](04-onion-routing.md#route-blinding))
- if it is the original source of the HTLC:
- SHOULD set `endorsed` to `1`.
- otherwise:
- SHOULD set `endorsed` as described in [Bolt 4](04-onion-routing.md#resource-bucketing).

`id` MUST NOT be reset to 0 after the update is complete (i.e. after `revoke_and_ack` has
been received). It MUST continue incrementing instead.
Expand All @@ -1059,6 +1066,8 @@ A receiving node:
`error` and fail the channel.
- if `blinding_point` is provided:
- MUST use the corresponding blinded private key to decrypt the `onion_routing_packet` (see [Route Blinding](04-onion-routing.md#route-blinding))
- if `endorsed` is provided:
- SHOULD interpret `endorsed` as described in [Bolt 4](04-onion-routing.md#resource-bucketing).

The `onion_routing_packet` contains an obfuscated list of hops and instructions for each hop along the path.
It commits to the HTLC by setting the `payment_hash` as associated data, i.e. includes the `payment_hash` in the computation of HMACs.
Expand Down
85 changes: 85 additions & 0 deletions 04-onion-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ A node:
* [Route Blinding](#route-blinding)
* [Accepting and Forwarding a Payment](#accepting-and-forwarding-a-payment)
* [Non-strict Forwarding](#non-strict-forwarding)
* [Resource Bucketing](#resource-bucketing)
* [Payload for the Last Node](#payload-for-the-last-node)
* [Shared Secret](#shared-secret)
* [Blinding Ephemeral Keys](#blinding-ephemeral-keys)
Expand All @@ -62,6 +63,7 @@ A node:
* [Returning Errors](#returning-errors)
* [Failure Messages](#failure-messages)
* [Receiving Failure Codes](#receiving-failure-codes)
* [Recommendations for Reputation](#recommendations-for-reputation)
* [Test Vector](#test-vector)
* [Returning Errors](#returning-errors)
* [References](#references)
Expand Down Expand Up @@ -635,6 +637,35 @@ Alternatively, implementations may choose to apply non-strict forwarding only to
like-policy channels to ensure their expected fee revenue does not deviate by
using an alternate channel.

## Resource Bucketing

When making the decision to forward a payment on its outgoing channel, a node
MAY choose to limit its exposure to HTLCs that put it at risk of a denial of
service attack.
* `unknown_allocation_slots`: defines the number of HTLC slots allocated to
unknown traffic (default: 50% of remote peer's `max_accepted_htlcs`).
* `unknown_allocation_liquidity`: defines the amount of the channel balance
that is allocated to unknown traffic (default: 50% of remote peer's
`max_htlc_value_in_flight_msat`.

A node implementing resource bucketing limits exposure on its outgoing channel:
- MUST choose `unknown_allocation_slots` <= the remote channel peer's
`max_accepted_htlcs`.
- MUST choose `unknown_allocation_liquidity` <= the remote channel peer's
`max_htlc_value_in_flight_msat`.
- If `endorsed` is set to 1 in the incoming `update_add_htlc` AND the HTLC
is from a node that the forwarding node considers to have good local
reputation (see [Recommendations for Reputation](#recommendations-for-reputation)):
- SHOULD proceed with forwarding the HTLC.
- SHOULD set `endorsed` to 1 in the outgoing `update_add_htlc`.
- Otherwise, the HTLC is classified as `unknown`:
- If `unknown_allocation_slots` HTLC slots are occupied by other `unknown` HTLCs:
- SHOULD return `temporary_channel_failure` as specified in [Failure Messages](#failure-messages).
- If `unknown_allocation_liquidity` satoshis of liquidity are locked in
other `unknown` HTLCs:
- SHOULD return `temporary_channel_failure` as specified in [Failure Messages](#failure-messages).
- SHOULD set `endorsed` to 0 in the outgoing `update_add_htlc`.

## Payload for the Last Node

When building the route, the origin node MUST use a payload for
Expand Down Expand Up @@ -1407,6 +1438,60 @@ The _origin node_:
- MAY use the data specified in the various failure types for debugging
purposes.

## Recommendations for Reputation

Local reputation is used by forwarding nodes to decide whether to endorse a HTLC
on their outgoing link. Nodes MAY use any metric of their choosing to classify
a peer as having "good" reputation, though a poor choice of reputation scoring
metric will affect their downstream reputation.

- `resolution_time`: the time elapsed between `update_add_htlc` and its
resolution (`update_fulfill_hltc` / `update_fail_hltc` /
`update_fail_malformed_htlc`).
- `resolution_threshold`: the resolution time threshold that is considered
"good" behavior (default: 10 seconds).
- `fees`: the fees paid by a forwarded HTLC (as described in [BOLT #7](07-routing-gossip.md#htlc-fees),
equal to 0 if the HTLC was failed).

For every incoming HLTC a peer has forwarded through a node, its `effective_fees`
are calculated as follows:
- if `endorsed` = 1 in `update_add_htlc`:
- if the HTLC was settled with `update_fulfill_hltc`:
- `effective_fees` = `fees` - ceil( (`resolution_time` - `resolution_threshold`) / `resolution_threshold`) * `fees`
- otherwise:
- `effective_fees` = - ceil( (`resolution_time` - `resolution_threshold`) / `resolution_threshold`) * `fees`
- otherwise:
- if successfully resolved AND `resolution_time` <= `resolution_threshold`
- `effective_fees` = `fees`
- otherwise:
- `effective_fees` = 0

The sum of the `effective_fees` for each HTLC that a peer has forwarded over
a sliding window of time is used to assess local reputation.

- `maximum_hold`: the maximum amount of time that a HTLC can be locked in a
node's commitment.
- `reputation_window`: the period of time over which we assess revenue
(recommended default = 10 * `maximum_hold`)
- `revenue`: the total routing revenue generated by the node over `maximum_hold`
- `reputation_revenue`: the total `effective_fees` of HTLCs forwarded by the peer
and resolved within `reputation_window`.

The local reputation that a peer has earned is compared to total revenue to
classify reputation as good or neutral.

- if `reputation_revenue` over `reputation_window` >= `revenue` over `maximum_hold`
- a peer should be considered to have good local reputation.
- otherwise, the peer should be considered to have neutral local reputation.

### Rationale
If a HTLC is endorsed by a peer they have signaled that they expect the HTLC
to resolve honestly, so will be held accountable for the manner in which they
resolve. By contrast, if a HTLC was not endorsed by the upstream peer, it
should not have a negative impact on reputation. In the case where one of
these "unknown" HTLCs succeeds within the reasonable resolution threshold, the
peer is still credited with fees because the HTLC resolved desirably.

# Test Vector

## Returning Errors
Expand Down

0 comments on commit db043e9

Please sign in to comment.