Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peers need to check each other's dust limit #894

Merged
merged 4 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,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)).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we drop this? I believe c-lightning and lnd both don't implement this at all today, and I'm not sure if we need to?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it's still useful, and I kept a lower bound on eclair, because you may want to avoid letting your peer create a commit tx that you think will not easily propagate through the bitcoin network because it doesn't satisfy default policy settings.

If you think you'll rely on their commit tx with option_dataloss_protect, you want to be sure their commit tx can get to miners' mempools, don't you?

Copy link
Collaborator

Choose a reason for hiding this comment

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

If you think you'll rely on their commit tx with option_dataloss_protect, you want to be sure their commit tx can get to miners' mempools, don't you?

Yea, that's a good point. Should we clarify that a suggested lower-bound is 330 (which IIRC is the exact current network dust threshold)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in f16ea99

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Update: I instead added a list of the network dust threshold in 40cfede which implementers can refer to when deciding what lower bound they want to enforce.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think that's really sufficient - there needs to be guidance in what implementations should be allowed to set the dust limit to, as otherwise we end up back where we are today where some nodes arbitrarily force-closed based on dust limit and there isn't a consensus. I'd strongly prefer if we either agree to set it to the max value for a standard output, or we set it to 330 and then fix the close negotiation logic via #896.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right, I agree with that. Both options have pros and cons:

Note that an alternative to #896 which would also fix the issue would be to disallow non-segwit scripts in shutdown. Now that segwit is widely supported, this would fix a few headaches.

I'd like feedback from other implementers on this choice, @rustyrussell @Roasbeef what do you think?

Copy link
Collaborator

@TheBlueMatt TheBlueMatt Aug 27, 2021

Choose a reason for hiding this comment

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

Yea, if we can get agreement on it, I'd love to just say "segwit-only shutdown", drop 896 and then set dust limit to be the segwit lower bound (354, I think? check my math). Do any implementations in practice do non-segwit closing scripts today? It would mean you can't open a channel with that output which seems incredibly restrictive.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You can close to cold storage, I guess, which may be old skool. But simplicity FTW: you can always unilaterally close so I've never considered it a big deal whatever we do here.

IOW, I'm happy with adding "mutual quickclose must be segwit" in #847

Copy link
Collaborator Author

@t-bast t-bast Aug 31, 2021

Choose a reason for hiding this comment

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

I opened an issue to discuss the dust_limit_satoshis lower bounds in #905

I'd like to treat this in a separate PR than this one, which fixes a different issue that we should have fixed a long time ago (adding a higher bound on our peer's dust_limit_satoshis).

If my calculations of the various dust thresholds imposed by Bitcoin Core are correct, I believe we can merge this PR as the need to impose a higher bound on remote dust should be obvious to everyone?

- 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.
Expand All @@ -279,7 +280,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.

Expand All @@ -295,6 +296,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
Expand Down Expand Up @@ -353,7 +358,6 @@ The receiver:
- if `channel_type` is set, and `channel_type` was set in `open_channel`, and they are not equal types:
- MUST reject the channel.


Other fields have the same requirements as their counterparts in `open_channel`.

### The `funding_created` Message
Expand Down
108 changes: 108 additions & 0 deletions 03-transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -484,6 +486,112 @@ 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
- unknown segwit versions: 354 satoshis

The rationale of this calculation (implemented [here](https://github.com/bitcoin/bitcoin/blob/0.21/src/policy/policy.cpp))
is explained in the following sections.

In all these sections, the calculations are done with a feerate of 3000 sat/kB
as per Bitcoin Core's implementation.

### Pay to pubkey hash (p2pkh)

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
t-bast marked this conversation as resolved.
Show resolved Hide resolved
- 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`

### Pay to script hash (p2sh)

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`

### Pay to witness pubkey hash (p2wpkh)

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
t-bast marked this conversation as resolved.
Show resolved Hide resolved
- 4 bytes for the sequence
- 26 bytes for the witness (with the 75% segwit discount applied):
t-bast marked this conversation as resolved.
Show resolved Hide resolved
- 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`

### Pay to witness script hash (p2wsh)

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`

### Unknown segwit versions

Unknown segwit outputs are at most 51 bytes:

- 8 bytes for the output amount
- 1 byte for the script length
- 42 bytes for the script (`OP_1` through `OP_16` inclusive, followed by a single push of 2 to 40 bytes)

The input doesn't have a fixed size, since it depends on the underlying
script, so we use 67 bytes as a lower bound.

The unknown segwit version dust threshold is then `(51 + 67) * 3000 / 1000 = 354 satoshis`

## Commitment Transaction Construction

This section ties the previous sections together to detail the
Expand Down