Skip to content

Commit

Permalink
Add Reputation Credentials: initial protocol sketch
Browse files Browse the repository at this point in the history
This includes modifications to few BOLT4/BOLT7 data structures.
  • Loading branch information
Antoine Riard committed Nov 21, 2022
1 parent b38156b commit 80214c8
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 0 deletions.
16 changes: 16 additions & 0 deletions 04-onion-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ This is formatted according to the Type-Length-Value format defined in [BOLT #1]
1. type: 16 (`payment_metadata`)
2. data:
* [`...*byte`:`payment_metadata`]
1. type: 54823733684 (`credentials_payload`)
2. data:
* [`32*byte`:`credentials`]
* [`signature`: `signature`]

`short_channel_id` is the ID of the outgoing channel used to route the
message; the receiving peer should operate the other end of this channel.
Expand All @@ -219,6 +223,11 @@ to both authenticate the information specified by the origin node, and
the parameters of the HTLC forwarded, and ensure the origin node is
using the current `cltv_expiry_delta` value.

`credentials_payload` is the random byte string issued by the routing hop
acoording to the hop's advertised routing policy (as described in
[BOLT #7](07-routing-gossip.md#routing_policy)). For each credential, a
signature should be attached.

If the values don't correspond, this indicates that either a
forwarding node has tampered with the intended HTLC values or that the
origin node has an obsolete `cltv_expiry_delta` value.
Expand Down Expand Up @@ -1002,6 +1011,13 @@ the decrypted byte stream.
The complete amount of the multi-part payment was not received within a
reasonable time.

1. type: 24 (`routing_policy_error`)
2. data:
* [`u16`: `len`]
* [`len*byte`: `routing_policy`]

The HTLC doesn't comply with the routing hop additional policy checks.

### Requirements

An _erring node_:
Expand Down
29 changes: 29 additions & 0 deletions 07-routing-gossip.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ To support channel and node discovery, three *gossip messages* are supported:
* [The `channel_announcement` Message](#the-channel_announcement-message)
* [The `node_announcement` Message](#the-node_announcement-message)
* [The `channel_update` Message](#the-channel_update-message)
* [The `routing_policy` Message](#the-routing-policy-message)
* [Query Messages](#query-messages)
* [Initial Sync](#initial-sync)
* [Rebroadcasting](#rebroadcasting)
Expand Down Expand Up @@ -426,6 +427,8 @@ of *relaying* payments, not *sending* payments. When making a payment
* [`u32`:`fee_base_msat`]
* [`u32`:`fee_proportional_millionths`]
* [`u64`:`htlc_maximum_msat`]
* [`u32`: `fee_base_blocks`]
* [`u32`] `fee_base_blocks_grace_threshold`]

The `channel_flags` bitfield is used to indicate the direction of the channel: it
identifies the node that this update originated from and signals various options
Expand Down Expand Up @@ -493,6 +496,10 @@ The origin node:
for any HTLC.
- MUST set `fee_proportional_millionths` to the amount (in millionths of a
satoshi) it will charge per transferred satoshi.
- MUST set `fee_base_block` to the amount (in millionths of a
satoshi) it will charge per block included in the CLTV duration.
- MUST set `fee_base_block_grace_threshold` to the CLTV duration under which
`fee_base_block` is not applied.
- SHOULD NOT create redundant `channel_update`s
- If it creates a new `channel_update` with updated channel parameters:
- SHOULD keep accepting the previous channel parameters for 10 minutes
Expand Down Expand Up @@ -570,6 +577,28 @@ The `must_be_one` field in `message_flags` was previously used to indicate
the presence of the `htlc_maximum_msat` field. This field must now always
be present, so `must_be_one` is a constant value, and ignored by receivers.

## The `routing_policy` Message

This gossip message contains additional policy checks enforced in the processing
of a HTLC forward, in additition ot the basic ones by BOLT4.

1. type: 258 (`routing_policy`)
2. data:
* [`acquisition*len`: `acquisition_method`]
* [`u32`: `acquisition_to_credential_rate`]
* [`u32`: `credential_to_liquidity_unit`]
* [`u32`: `credential_expiration_height`]
* [`bool`: `routing_check_enable`]

The origin node:
- MUST set `acquisition_method` to a credential acquisition method supported (e.g pre-paid fees).
- MUST set `acquisition_to_credential_rate` to the translation between how many credentials units are provided per acquisition units satisfied.
- MUST set `credential_to_liquidity_unit` to the translation between how many liquidity units
are provided per credentials unit provided (e.g 1 credential = 1 BTC per block).
- MUST set `credential_expiration_height` to the chain height at which all credentials issued
are considred as expired and as such invalid for HTLC forward.
- MUST set `routing_check_enable` to signal the additional routing policy checks are enabled. In period of low local channel congestion, the additional routing policy checks can be disabled.

## Query Messages

Negotiating the `gossip_queries` option via `init` enables a number
Expand Down
265 changes: 265 additions & 0 deletions www-reputation-credentials-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# Mitigating Channel Jamming with One-Shot HTLC Forward Reputation Credentials

Authors: Antoine Riard <btc@ariard.me>

Created: 2022-11-15

# Problem Statement

The channel jamming issue has been one of the longuest standing and unsolved issue affecting the
Lightning Network. Not only attack has been demonstrated in practice, but also theoritically

This comment has been minimized.

Copy link
@kristovatlas

kristovatlas Dec 11, 2022

s/theoritically/theoretically

[studied](https://jamming-dev.github.io/book/): "A channel jamming is when a malicious entity blocks up liquidity in the LN,
by making a payment to themselves, via third party channels and then never revealing the secret, such
that the payment never completes".

The channel jamming root cause comes from the following situation. A routed HTLC across multiple Lightning
hops is a chain of contracts among trust-minimized counterparties. The settlement of this chain of contracts
is uniform in its outcome (success/failure) across all the intermediary counterparties, however such counterparties
cannot influence the outcome, once the chain of contract is established. As setting up this chain of contracts
consume scarce resources (i.e the channel liquidity timevalue), there is a counterparty risk without guarantee
there is an adequate compensation. Indeed, the routing fees are only paid in case of success.

# Solution introduction

This counterparty risk can be solved straightforwardly by the introduction of a premimum fee carried on by
the HTLC sender. This jamming solution known as ["upfront fees"](https://github.com/t-bast/lightning-docs/blob/master/spam-prevention.md)
in the Lightning community, aims to a fair distribution of the HTLC forward risk among all the chain of
contracts counterparties. While there is a concern this risk distribution doesn't capture well the
shenanigans of a HTLC forward (e.g offline routing hop, spontaneously congestioned channel), there is a
major drawback as it introduces a permanent overhead fee for the network participants.

In contract, another type of reputation-based solution can be introduced by formalizing a new assumption

This comment has been minimized.

Copy link
@kristovatlas

kristovatlas Dec 11, 2022

s/contract/contrast

"Reputation incentives HTLC senders to behave-well, if there is an adequate proportion between the
acquisition cost and the amount of resources credited in function of said reputation". This assumption is
in fact analoguous to the one underpining routing scoring algorithms incentiving the routing hops reliability.
A reputation system attached to the HTLC forward, not only can protect against malicious jamming entity but
also can offer the traffic shapping tooling for node operators to improve the quality of their inbound HTLC
across time.

# Proposed solution

The proposed solution is to introduce a new reputation credentials system, where credentials
should be attached to each HTLC forward request. The credentials are issued locally by each
routing hop, there is no global credential system maintained for the whole Lightning Network.
The credentials represent channel liquidity lockup rights, covering both amount and CLTV duration.
The exact ratio between a quantity of credentials and the channel liquidity lockup rights is
a routing hop policy decision and can be adjusted in real-time in function of channel congestion
rate and other factors. This routing policy can be announced towards the LN network through
the public gossips mechanism.

The credentials are disseminated from the routing hops towards the HTLC senders through onion
communication channels. The credentials acquisition method and cost are defined by the routing
hops. For this version of the protocol, we propose upfront fees as a credential acquisition
method. Payment HTLC are sent to the routing hop and credentials are returned back to the sender
with a onion reply path. The credentials are counter-signed by the issuer to authenticate their
origin. The amount of satoshis and the corresponding quantity of credentials delivered is defined
by each routing hop as a routing policy decision, there is no global pricing of the channel liquidity.
Alternative acquisiton methods (e.g [proof-of-UTXO ownership](https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-November/002884.html))
can be experimented and deployed in a compatible fashion, without network-wide coordination.

Once a HTLC sender has bootstrapped the possession of sufficient credentials to route across
the network to reach its payee destination, payment paths can be drawn. For each hop in the path,
the HTLC onion payload should contain the correct amount of credentials, as requested by the
hop routing policy.

At reception of a HTLC forward, the credentials signatures should be verified and enforced against
the routing hop policy. If the HTLC sender has staked enough credentials to lockup outbound liquidity
for the request msat amount and CTLV duration, the HTLC forward should be committed on the outbound
channel, and the HTLC setup phase pursued until the destination payee is reached.

At HTLC settlement, if the HTLC is successful, the routing fees are paid accordingly to current
`channel_update`, a new set of credentials is issued and counter-signed by the hop and returned back
to the sender through [onion communication channels](https://github.com/lightning/bolts/pull/759).
A supplement of credentials can be joined, as reward of honoring the routing fees, and unlocking more
consequential liquidity lockups for future HTLC forwards.

If the HTLC is a failure, the reputation credentials are slashed. No new credentials are issued back
to the HTLC sender as a punishment. To limit reputation whitewashing, where the jamming damage is superior
to the reputation acquisition cost, a proportion sould be maintained between the credentials acquisition
cost (either from upfront fees or honored routing fees) and the channel liquidity lockup rights.

To preserve the confidentiality of the HTLC senders (or payers), the credentials should be anonymized,
a routing hop should not be able to link between a credential issuance at dissemination and its usage
at the reception of a HTLC forward request. A cryposystem satisfying those requirements could be to
leverage EC [blinded signatures](https://sceweb.sce.uhcl.edu/yang/teaching/csci5234WebSecurityFall2011/Chaum-blind-signatures.PDF).

Additionally, this proposal is extending the `channel_update` message to announce routing fees paid on the
CLTV duration, therefore allowing compensation of the routing hops for the transport of long-term held
class of packets (e.g [hold-invoice](https://github.com/lightningnetwork/lnd/pull/2022), [swaps](https://github.com/ElementsProject/peerswap/blob/master/docs/peer-protocol.md)).

# Protocol extensions

This proposal introduces modifications to the following existent BOLT data structures:
- one new TLV record `credentials_payload` is added to the BOLT4 onion payload
- one new failure message `routing_policy_error` is added in the list of BOLT4 error messages
- two new TLV records `fee_base_block_grace_threshold` and `fee_base_block` are added to `channel_update`

Two new data structures are introduced:
- a BOLT7 gossip message `routing_policy`
- a credential data format: a 32-byte string of random data

# Protocol Phase

This proposal introduces a completely new dissemination phase unknown from the current LN protocol
set of operations.

Additionally, this proposal modifies few other protocol operations:
- the routing & payment path construction
- the HTLC forward phase (i.e ["Accepting and Forwarding a Payment"](https://github.com/lightning/bolts/blob/master/04-onion-routing.md#accepting-and-forwarding-a-payment))
- the HTLC settlement phase (i.e ["Removing an HTLC"](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#removing-an-htlc-update_fulfill_htlc-update_fail_htlc-and-update_fail_malformed_htlc))

## Credentials dissemination phase

The dissemination phase consists of the satisfaction of an acquisition method announced by the
routing hop by the HTLC sender.

```
2.
BOLT-12 offers
-------------------------------------------
/ 3. \
___V_____ HTLC _________ HTLC _____\____
| |---------->| |---------->| |
| | | | | |
| Alice | 1. | Bob | | Caroll |
| | gossips | | gossips | |
|_________|<----------|_________|<----------|__________|
^ /
\ /
------------------------------------
onions(credentials)
4.
```

In this diagram:
1. Alice discovers Caroll's `routing_policy` gossip.
2. Alice fetches an offer from Caroll to pay the `credential_to_liquidity_unit` announced.
3. Alice sends a HTLC to Caroll, the onion payload contains unsigned credentials.
4. Caroll receives the HTLC, counter-signed the credentials and send them back to Alice by onions.

The [reply_path](https://github.com/lightning/bolts/pull/765) between Alice-Caroll to transfer back
the finalized credentials could be communicated during the offer exchage or the HTLC send.

In this topology, Bob is Alice's LSP and credentials to route through him is assumed to be have been
acquired by Alice in a prelimary dissemination phase. Alternatively, Bob could confer a set of free
credentials to Alice due to the LSP-spoke trust-enhanced relationship.

## Building credentials-enhanced payment paths

The introduction of credentials assigned to each routing hops require some modification in the
payment path construction algorithms.

```
_______
| | channel_update::fee_base_msat: 10
| Bob |
|_______| routing_policy::credential_to_liquidity_unit: 2
_________ Bob: 100 credentials _________
| | / ________ | |
| |/ | | channel_update::fee_base_msat: 10 | |
| Alice |---- Caroll: 30 credentials | Caroll | | Eve |
| |\ |________| routing_policy::credential_to_liquidity_unit: 3 | |
|_________| \ |_________|
Dave: 250 credentials
________
| | channel_update::fee_base_msat: 10
| Dave |
|________| routing_policy::credential_to_liquidity_unit: 1
```

In this diagram, Alice would like to send a 1 BTC HTLC to Eve. Bob, Caroll, Dave are all intermediary valid
routing hops. Each routing hop has both channel with Alice and Eve (non-represented). Alice have been through
3 dissemination phases, one with each of them, to collect credentials. The `fee_base_msat` are equivalent
among the 3 routing hops.

With her stack of credentials, Alice has 3 options:
- She can locks the Bob-Eve link for `100 / 2 = 50` blocks.
- She can locks the Caroll-Eve link for `30 / 3 = 10` blocks.
- She can locks the Dave-Eve link for `250 / 1 = 250` blocks.

Assuming the credentials acquisition cost is uniform across the routing hops, if Alice wishes for the maximum
of `min_final_cltv_expiry_delta`, the Dave option is the optimum. She can build a payment path Alice-Dave-Eve,
wraps Dave credentials into Dave onion, then send him an `update_add_htlc`.

The `credential_to_liquidity_unit` currently represents both the liquidity capacity and the CLTV duration, it's
left as a subject of research if there should be two translation from credentials to channel liquidity lockup units.
(i.e `credentials` -> `liquidity_capacity` and `credentials` -> `CLTV duration`).

## Checking HTLC forward request

Accepting and forwarding a payment as described in BOLT 4 is modified. A routing hop requiring reputation credentials
should enforce additional checks.

```
2.
routing_policy(credentials)?
_________ 1. _________ __________
| | | | 3a. | |
| | HTLC + onions(credentials) | | yes HTLC | |
| Alice |--------------------------------->| Bob |------------------------------------->| Caroll |
| | | | | |
|_________| 3b. |_________| |__________|
^ no /
\ fail_htlc /
\_________________________________/
```

In this diagram:
1. Alice sends a HTLC+credentials to Bob.
2. Bob extracts the credentials, verifies the signature and validate the credentials against his own `routing_policy`.
3a. The routing checks are successful, Bob forwards the HTLC along the Bob-Caroll link.
4a. Bob stores the backward credentials into the local state until the HTLC settlement.
3b. The routing checks are unsuccessful, Bob rejects the HTLC.

The credentials are wrapped inside the HTLC onion `credentials_payload`. There are two types of credentials: forward/backward.
The forward credentials are covering the ongoing HTLC forward, they should have been counter-signed by the target routing hop
during the dissemination phase or a previous HTLC forward/settlement pahse with the same target routing hop. The backward
credentials are also wrapped into the HTLC onion, however they're not signed and should be blinded. If the settlement is successful,
those backward credentials should be the "forward" credentials for Alice's future HTLC sends.

## Signing or slashing credentials during HTLC Settlement

The current HTLC settlement does not encompass any routing checks processing by routing hops, whatever the outcome `update_fulfill_htlc`/
`update_fail_htlc`.

```
2. HTLC success ?
2a. yes, sign backward credentials
2b. no, slash forward credentials
_________ 3a. HTLC + onions(signed_credentials) _________ __________
| |<----------------------------------------| | 1. | |
| | | | HTLC settlement | |
| Alice | | Bob |<---------------------------------------| Caroll |
| | 3b. HTLC | | | |
|_________|<----------------------------------------|_________| |__________|
```

In this diagram:
1. Caroll settles the HTLC back to Bob with either a success or a failure.
2a. If it's a success, Bob sign the blinded backward credentials stored during the previous phase.
3a. If it's a failure, Bob slashes the forward credentials. There is no backward credentials return back to Alice.

To prevent replay usage of slashed forward credentials or previously used forward credentials, the signature should be
logged by the routing hop in an [accumulator data structure](https://link.springer.com/content/pdf/10.1007/3-540-48285-7_24.pdf),
allowing efficient test membership. Merkle tree can constitute such accumulator. To limit the growing size of this accumulator,
all credentials issued can be expired according to a `routing_gossip::credential_expiration_height` field.

Once Alice receives the countersigned and still blinded backward credentials, she can unblind them and rely on them
for future payment path construction.

# Security & Privacy considerations

Credentials temporary storage could constitute memory-DoS vectors.

Credentials signing and accumulator test membership could constitute CPU-DoS vectors.

Credentials issuance and usage timing could be leveraged for deanonymization attacks.

0 comments on commit 80214c8

Please sign in to comment.