From 58e7ec049ede387a6b244125d9225bebe3bc157d Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 11 Aug 2021 09:34:47 +0200 Subject: [PATCH 1/3] Peers need to check each other's dust limit Since HTLCs below this amount will not appear in the commitment tx, they are effectively converted to miner fees. The peer could use this to grief you by broadcasting its commitment once it contains a lot of dust HTLCs. Fixes #696 --- 02-peer-protocol.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index f61bd3cca..f090b3cdc 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -239,6 +239,7 @@ The receiving node MAY fail the channel if: - it considers `channel_reserve_satoshis` too large. - it considers `max_accepted_htlcs` too small. - it considers `dust_limit_satoshis` too small and plans to rely on the sending node publishing its commitment transaction in the event of a data loss (see [message-retransmission](02-peer-protocol.md#message-retransmission)). + - it considers `dust_limit_satoshis` too large. The receiving node MUST fail the channel if: - the `chain_hash` value is set to a hash of a chain that is unknown to the receiver. @@ -258,7 +259,7 @@ The receiving node MUST NOT: #### Rationale -The requirement for `funding_satoshis` to be less than 2^24 satoshi was a temporary self-imposed limit while implementations were not yet considered stable, it can be lifted by advertising `option_support_large_channel`. +The requirement for `funding_satoshis` to be less than 2^24 satoshi was a temporary self-imposed limit while implementations were not yet considered stable, it can be lifted by advertising `option_support_large_channel`. The *channel reserve* is specified by the peer's `channel_reserve_satoshis`: 1% of the channel total is suggested. Each side of a channel maintains this reserve so it always has something to lose if it were to try to broadcast an old, revoked commitment transaction. Initially, this reserve may not be met, as only one side has funds; but the protocol ensures that there is always progress toward meeting this reserve, and once met, it is maintained. @@ -274,6 +275,10 @@ would be eliminated as dust. The similar requirements in `accept_channel` ensure that both sides' `channel_reserve_satoshis` are above both `dust_limit_satoshis`. +The receiver should not accept large `dust_limit_satoshis`, as this could be +used in griefing attacks, where the peer publishes its commitment with a lot +of dust htlcs, which effectively become miner fees. + Details for how to handle a channel failure can be found in [BOLT 5:Failing a Channel](05-onchain.md#failing-a-channel). ### The `accept_channel` Message @@ -321,9 +326,9 @@ The receiver: - if `minimum_depth` is unreasonably large: - MAY reject the channel. - if `channel_reserve_satoshis` is less than `dust_limit_satoshis` within the `open_channel` message: - - MUST reject the channel. + - MUST reject the channel. - if `channel_reserve_satoshis` from the `open_channel` message is less than `dust_limit_satoshis`: - - MUST reject the channel. + - MUST reject the channel. Other fields have the same requirements as their counterparts in `open_channel`. ### The `funding_created` Message From 40cfede1b7f325949f8cb565cb724fdd71cf7cfc Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 18 Aug 2021 14:12:50 +0200 Subject: [PATCH 2/3] Add network dust thresholds As implemented in Bitcoin Core's default relay policy. --- 03-transactions.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/03-transactions.md b/03-transactions.md index 92aa89301..64d73d98f 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -21,6 +21,8 @@ This details the exact format of on-chain transactions, which both sides need to * [Fees](#fees) * [Fee Calculation](#fee-calculation) * [Fee Payment](#fee-payment) + * [Dust Limits](#dust-limits) + * [Commitment Transaction Construction](#commitment-transaction-construction) * [Keys](#keys) * [Key Derivation](#key-derivation) * [`localpubkey`, `remotepubkey`, `local_htlcpubkey`, `remote_htlcpubkey`, `local_delayedpubkey`, and `remote_delayedpubkey` Derivation](#localpubkey-remotepubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) @@ -480,6 +482,70 @@ A node: - if the resulting fee rate is too low: - MAY fail the channel. +## Dust Limits + +The `dust_limit_satoshis` parameter is used to configure the threshold below +which nodes will not produce on-chain transaction outputs. + +There is no consensus rule in Bitcoin that makes outputs below dust thresholds +invalid or unspendable, but policy rules in popular implementations will prevent +relaying transactions that contain such outputs. + +Bitcoin Core defines the following dust thresholds: + +- pay to pubkey hash (p2pkh): 546 satoshis +- pay to script hash (p2sh): 540 satoshis +- pay to witness pubkey hash (p2wpkh): 294 satoshis +- pay to witness script hash (p2wsh): 330 satoshis + +Details of this calculation (implemented [here](https://github.com/bitcoin/bitcoin/blob/0.21/src/policy/policy.cpp)): + +- the feerate is set to 3000 sat/kB +- a p2wpkh output is 31 bytes: + - 8 bytes for the output amount + - 1 byte for the script length + - 22 bytes for the script (`OP_0` `20` 20-bytes) +- a p2wpkh input is at least 67 bytes (depending on the signature length): + - 36 bytes for the previous output (32 bytes hash + 4 bytes index) + - 1 byte for the script sig length + - 4 bytes for the sequence + - 26 bytes for the witness (with the 75% segwit discount applied): + - 1 byte for the items count + - 1 byte for the signature length + - 71 bytes for the signature + - 1 byte for the public key length + - 33 bytes for the public key +- the p2wpkh dust threshold is then `(31 + 67) * 3000 / 1000 = 294 satoshis` +- a p2wsh output is 43 bytes: + - 8 bytes for the output amount + - 1 byte for the script length + - 34 bytes for the script (`OP_0` `32` 32-bytes) +- a p2wsh input doesn't have a fixed size, since it depends on the underlying + script, so we use 67 bytes as a lower bound +- the p2wsh dust threshold is then `(43 + 67) * 3000 / 1000 = 330 satoshis` +- a p2pkh output is 34 bytes: + - 8 bytes for the output amount + - 1 byte for the script length + - 25 bytes for the script (`OP_DUP` `OP_HASH160` `20` 20-bytes `OP_EQUALVERIFY` `OP_CHECKSIG`) +- a p2pkh input is at least 148 bytes: + - 36 bytes for the previous output (32 bytes hash + 4 bytes index) + - 1 byte for the script sig length + - 4 bytes for the sequence + - 107 bytes for the script sig: + - 1 byte for the items count + - 1 byte for the signature length + - 71 bytes for the signature + - 1 byte for the public key length + - 33 bytes for the public key +- the p2pkh dust threshold is then `(34 + 148) * 3000 / 1000 = 546 satoshis` +- a p2sh output is 32 bytes: + - 8 bytes for the output amount + - 1 byte for the script length + - 23 bytes for the script (`OP_HASH160` `20` 20-bytes `OP_EQUAL`) +- a p2sh input doesn't have a fixed size, since it depends on the underlying + script, so we use 148 bytes as a lower bound +- the p2sh dust threshold is then `(32 + 148) * 3000 / 1000 = 540 satoshis` + ## Commitment Transaction Construction This section ties the previous sections together to detail the From 8ba77455dda3bbc1549937f3b53abfcca9353800 Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 18 Aug 2021 15:32:19 +0200 Subject: [PATCH 3/3] Trim closing output below network dust threshold When `dust_limit_satoshis` are below 546 sats, we may create closing txs that won't propagate (e.g. if one of the closing scripts is not using segwit). This isn't a critical issue since the channel can be force-closed and the commit should always propagate, but we can do better. Signers should remove their output if it causes the transaction to fail propagation. This is backwards-compatible because they already had the option to remove their own output (and receivers should check the signature against both potential closing transactions). --- 03-transactions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/03-transactions.md b/03-transactions.md index 64d73d98f..ddf8521d2 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -366,7 +366,10 @@ Each node offering a signature: - MUST round each output down to whole satoshis. - MUST subtract the fee given by `fee_satoshis` from the output to the funder. - MUST remove any output below its own `dust_limit_satoshis`. - - MAY eliminate its own output. + - if its own output is below the network's dust threshold (see the [dust limits section](#dust-limits)): + - MUST eliminate its own output. + - otherwise: + - MAY eliminate its own output. ### Rationale @@ -383,9 +386,6 @@ reason for the other side to fail the closing protocol; so this is explicitly allowed. The signature indicates which variant has been used. -There will be at least one output, if the funding amount is greater -than twice `dust_limit_satoshis`. - ## Fees ### Fee Calculation