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

Explicitly add a way for the splice receiving node to reject a splice #3

Open
wants to merge 11 commits into
base: guilt/splice
Choose a base branch
from
Open
4 changes: 4 additions & 0 deletions .aspell.en.pws
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,7 @@ csv
CHECKSIGVERIFY
IFDUP
sats
quiesce
quiescing
SomeThing
commitsigs
227 changes: 223 additions & 4 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ operation, and closing.
* [The `funding_created` Message](#the-funding_created-message)
* [The `funding_signed` Message](#the-funding_signed-message)
* [The `funding_locked` Message](#the-funding_locked-message)
* [Channel Quiescence](#channel-quiescence)
* [Channel Close](#channel-close)
* [Closing Initiation: `shutdown`](#closing-initiation-shutdown)
* [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed)
Expand Down Expand Up @@ -445,6 +446,182 @@ to broadcast the commitment transaction to get his funds back and open a new
channel. To avoid this, the funder should ensure the funding transaction
confirms in the next 2016 blocks.

## Channel Quiescence

Various fundamental changes, in particular protocol upgrades, are
easiest on channels where both commitment transactions match, and no
pending updates are in flight. We define a protocol to quiesce the
channel by indicating that "SomeThing Fundamental is Underway".

### `stfu`

1. type: 2 (`stfu`)
2. data:
* [`channel_id`:`channel_id`]
* [`u8`:`initiator`]

### Requirements

The sender of `stfu`:
- MUST NOT send `stfu` if any of the sender's htlc additions, htlc removals
or fee updates are pending for either peer.
- MUST NOT send `stfu` twice.
- if it is replying to an `stfu`:
- MUST set `initiator` to 0
- otherwise:
- MUST set `initiator` to 1
- MUST set `channel_id` to the id of the channel to quiesce.
- MUST now consider the channel to be quiescing.
- MUST NOT send an update message after `stfu`.

The receiver of `stfu`:
- if it has sent `stfu` then:
- MUST now consider the channel to be quiescent
- otherwise:
- SHOULD NOT send any more update messages.
- MUST reply with `stfu` once it can do so.

Upon disconnection:
- the channel is no longer considered quiescent.

### Rationale

The normal use would be to cease sending updates, then wait for all
the current updates to be acknowledged by both peers, then start
quiescence. For some protocols, choosing the initiator matters,
so this flag is sent.

If both sides send `stfu` simultaneously, they will both set
`initiator` to `1`, in which case the "initiator" is arbitrarily
considered to be the channel funder (the sender of `open_channel`).
The quiescence effect is exactly the same as if one had replied to the
other.

## Splicing

Splicing is the term given for replacing the funding transaction with
a new one. For simplicity, splicing takes place once a channel is
[quiescent](#channel-quiescence).

Operation returns to normal once negotiation is done (while waiting
for the splice transaction(s) to confirm).

The splice is finally terminated when both sides send
`splice_complete` to indicate that one of the splice transactions
reached acceptable depth.

### The `splice` Message

1. type: 74 (`splice`)
2. data:
* [`chain_hash`:`chain_hash`]
* [`channel_id`:`channel_id`]
* [`u32`:`funding_feerate_perkw`]
* [`point`:`funding_pubkey`]

1. type: 76 (`splice_ack`)
2. data:
* [`chain_hash`:`chain_hash`]
* [`channel_id`:`channel_id`]
* [`point`:`funding_pubkey`]

#### Requirements

The sender of `splice`:
- MUST have successfully initiated quiescence.
- MUST NOT send `splice` before sending and receiving `funding_locked`.
- MUST NOT send `splice` while a splice is being negotiated.
- If any splice is in progress:
- MUST NOT send a splice message with `funding_feerate_perkw` which is less than 1.25 the previous `funding_feerate_perkw` (rounded down).

The receiver of `splice`:
- SHOULD fail the connection if there is an ongoing splice, and the `funding_feerate_perkw` is not at least 1.25 the previous `funding_feerate_perkw` (rounded down).
- MUST respond with `splice_ack` containing its own `funding_pubkey`.
- MUST begin splice negotiation.

The receiver of `splice_ack`:
- MUST begin splice negotiation.


#### Rationale

There is no harm in agreeing to a splice with a high feerate
(presumably the recipient will not contribute to the splice which they
consider to be overpaying).

## Splice Negotiation

The splice negotiation is very similar to the `init_rbf` negotiation:
both sides alternate sending `tx_add_input` and `tx_add_output` until
they both send consecutive `tx_complete`.

### Requirements

(Note that many of these messages have their own, additional
requirements detailed elsewhere).

The initiator:
- MUST `tx_add_input` an input which spends the current funding transaction output.
- MUST `tx_add_output` a zero-value output which pays to the two funding keys using the higher of the two `generation` fields.
- MUST pay for the common fields.

Upon receipt of consecutive `tx_complete`s, each node:
- MUST fail negotiation if there is not exactly one input spending the current funding transaction.
- MUST fail negotiation if there is not exactly one output with zero value paying to the two funding keys (a.k.a. the new channel funding output)
- MUST calculate the channel capacity for each side:
- Start with the previous balance
- Add that side's new inputs (excluding the one spending the current funding transaction)
- Subtracting each sides new outputs (except the zero-value one paying to the funding keys)
- Subtract the total fee that side is paying for the splice transaction.
- MUST replace the zero-value funding output amount with the total channel capacity.
- MUST calculate the channel balance for each side:
- Subtract any outstanding HTLCs offered by that side.
- if either side has added an output other than the new channel funding output:
- MUST fail the negotiation if the balance for that side is less than 1% of the total channel capacity.
- SHOULD NOT fail if the splice transaction is nonstandard.
- MUST increment the commitment number and send `commitment_signed`, including the signatures for the splice transaction.

- Upon receipt of `revoke_and_ack` for the previous commitment:
- MUST send `tx_signatures` for the splice transaction.

- Upon receipt of `tx_signatures` for the splice transaction:
- MUST consider splice negotiation complete.
- MUST consider the connection no longer quiescent.

- Upon receipt of `tx_abort` for the splice transaction:
- MUST NOT have sent `tx_signatures`.
- MUST consider the connection no longer quiescent.
- MUST forget the in progress splice transaction.

On reconnection:
- MUST retransmit the last splice `tx_signatures` (if any).
- MUST ignore any redundant `tx_signatures` it receives.

### Rationale

If a side does not meet the reserve requirements, that's OK: but if
they take funds out of the channel, they must ensure that they do meet
them. If your peer adds a massive amount to the channel, then you
only have to add more reserve if you want to contribute to the splice
(and you can use `tx_remove_output` and/or `tx_remove_input` part-way
through if this happens).

## Splice Completion

Each node:
- if any splice transaction reaches depth 6:
- MUST send `splice_locked`.

Once a node has received and sent `splice_locked`:
- MUST consider the successful splice to be the new funding
transaction for all future `commitment_signed` and splice operations.
- MUST discard the previous funding transaction and other splice operations.
- MUST send a new `commitment_signed` (with no `splice_commitsigs`).

On reconnection:
- MUST retransmit the last `splice_locked` if the peer did not
acknowledge the `commitment_signed`.

## Channel Close

Nodes can negotiate a mutual close of the connection, which unlike a
Expand Down Expand Up @@ -488,10 +665,13 @@ A sending node:
- MAY send a `shutdown` before a `funding_locked`, i.e. before the funding transaction has reached `minimum_depth`.
- if there are updates pending on the receiving node's commitment transaction:
- MUST NOT send a `shutdown`.
- if there is an ongoing splice:
- MUST NOT send a `shutdown`.
- MUST NOT send an `update_add_htlc` after a `shutdown`.
- if no HTLCs remain in either commitment transaction:
- MUST NOT send any `update` message after a `shutdown`.
- SHOULD fail to route any HTLC added after it has sent `shutdown`.
- MUST NOT initiate a new splice if none are already in progress after a `shutdown`.
- if it sent a non-zero-length `shutdown_scriptpubkey` in `open_channel` or `accept_channel`:
- MUST send the same value in `scriptpubkey`.
- MUST set `scriptpubkey` in one of the following forms:
Expand All @@ -509,8 +689,9 @@ A receiving node:
- SHOULD fail the connection.
- if it hasn't sent a `funding_locked` yet:
- MAY reply to a `shutdown` message with a `shutdown`
- once there are no outstanding updates on the peer, UNLESS it has already sent a `shutdown`:
- once there are no outstanding updates on the peer and no ongoing splice, UNLESS it has already sent a `shutdown`:
- MUST reply to a `shutdown` message with a `shutdown`
- MUST NOT initiate a new splice if none are already in progress.
- if both nodes advertised the `option_upfront_shutdown_script` feature, and the receiving node received a non-zero-length `shutdown_scriptpubkey` in `open_channel` or `accept_channel`, and that `shutdown_scriptpubkey` is not equal to `scriptpubkey`:
- MUST fail the connection.

Expand Down Expand Up @@ -539,6 +720,12 @@ of the receiving node to change the `scriptpubkey`.

The `shutdown` response requirement implies that the node sends `commitment_signed` to commit any outstanding changes before replying; however, it could theoretically reconnect instead, which would simply erase all outstanding uncommitted changes.

`shutdown` requires that there be no splice in progress, but if there
is already a splice in progress, it might require another splice to
"unstick" it (if the first splice was invalid, double-spent, or simply
had too low a fee), so in this case initiating another splice is legal
even after sending a shutdown.

### Closing Negotiation: `closing_signed`

Once shutdown is complete and the channel is empty of HTLCs, the final
Expand Down Expand Up @@ -834,7 +1021,7 @@ A sending node:
between implementations.
- if it is _not responsible_ for paying the Bitcoin fee:
- SHOULD NOT offer `amount_msat` if, once the remote node adds that HTLC to
its commitment transaction, it cannot pay the fee for the updated local or
any of its commitment transactions, it cannot pay the fee for the updated local or
remote transaction at the current `feerate_per_kw` while maintaining its
channel reserve.
- MUST offer `amount_msat` greater than 0.
Expand Down Expand Up @@ -911,6 +1098,9 @@ maintaining its channel reserve (because of the increased weight of the
commitment transaction), resulting in a degraded channel. See [#728](https://github.com/lightningnetwork/lightning-rfc/issues/728)
for more details.

If splicing is supported, there can be more than one commitment transaction
at a time: proposed changes must be valid for all of them.

### Removing an HTLC: `update_fulfill_htlc`, `update_fail_htlc`, and `update_fail_malformed_htlc`

For simplicity, a node can only remove HTLCs added by the other node.
Expand Down Expand Up @@ -1006,12 +1196,26 @@ sign the resulting transaction (as defined in [BOLT #3](03-transactions.md)), an
* [`signature`:`signature`]
* [`u16`:`num_htlcs`]
* [`num_htlcs*signature`:`htlc_signature`]
* [`commitment_signed_tlvs`:`tlvs`]

1. `tlv_stream`: `commitment_signed_tlvs`
2. types:
1. type: 0 (`splice_commitsigs`)
2. data:
* [`...*commitsigs`:`sigs`]

1. subtype: `commitsigs`
2. data:
* [`signature`:`commit_signature`]
* [`u16`:`num_htlcs`]
* [`num_htlcs*signature`:`htlc_signature`]


#### Requirements

A sending node:
- MUST NOT send a `commitment_signed` message that does not include any
updates.
updates, or add or remove splices.
- MAY send a `commitment_signed` message that only
alters the fee.
- MAY send a `commitment_signed` message that doesn't
Expand All @@ -1022,6 +1226,7 @@ fee changes).
to the ordering of the commitment transaction (see [BOLT #3](03-transactions.md#transaction-input-and-output-ordering)).
- if it has not recently received a message from the remote node:
- SHOULD use `ping` and await the reply `pong` before sending `commitment_signed`.
- MUST send a `commitsigs` for each splice in progress, in increasing feerate order.

A receiving node:
- once all pending updates are applied:
Expand All @@ -1032,6 +1237,10 @@ A receiving node:
- MUST fail the channel.
- if any `htlc_signature` is not valid for the corresponding HTLC transaction OR non-compliant with LOW-S-standard rule <sup>[LOWS](https://github.com/bitcoin/bitcoin/pull/6769)</sup>:
- MUST fail the channel.
- if there is not exactly one `commitsigs` for each splice in progress:
- MUST fail the channel.
- if `commit_signature`, `num_htlcs` or `htlc_signature` is not correct as specified above for each splice:
- MUST fail the channel.
- MUST respond with a `revoke_and_ack` message.

#### Rationale
Expand All @@ -1051,6 +1260,11 @@ Note that the `htlc_signature` implicitly enforces the time-lock mechanism in th

The `option_anchor_outputs` allows HTLC transactions to "bring their own fees" by attaching other inputs and outputs, hence the modified signature flags.

Splicing requires us to send and receive redundant signatures, as we
don't know which (if any) of the splice transactions will end up being
the new channel. Increasing feerate order is also the order in which
splices were negotiated (since each must increase the feerate).

### Completing the Transition to the Updated State: `revoke_and_ack`

Once the recipient of `commitment_signed` checks the signature and knows
Expand Down Expand Up @@ -1119,6 +1333,8 @@ given in [BOLT #3](03-transactions.md#fee-calculation).
The node _responsible_ for paying the Bitcoin fee:
- SHOULD send `update_fee` to ensure the current fee rate is sufficient (by a
significant margin) for timely processing of the commitment transaction.
- MUST NOT set `feerate_per_kw` in excess of what it can afford on any of the receiving node's
current commitment transactions.

The node _not responsible_ for paying the Bitcoin fee:
- MUST NOT send `update_fee`.
Expand All @@ -1129,7 +1345,7 @@ A receiving node:
- if the sender is not responsible for paying the Bitcoin fee:
- MUST fail the channel.
- if the sender cannot afford the new fee rate on the receiving node's
current commitment transaction:
current commitment transactions:
- SHOULD fail the channel,
- but MAY delay this check until the `update_fee` is committed.

Expand All @@ -1155,6 +1371,9 @@ it's simplest to only allow it to set fee levels; however, as the same
fee rate applies to HTLC transactions, the receiving node must also
care about the reasonableness of the fee.

If splicing is supported, there can be more than one commitment transaction
at a time: proposed changes must be valid for all of them.

## Message Retransmission

Because communication transports are unreliable, and may need to be
Expand Down
11 changes: 11 additions & 0 deletions 07-routing-gossip.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ A node:
- MUST send the `announcement_signatures` message.
- MUST NOT send `announcement_signatures` messages until `funding_locked`
has been sent and received AND the funding transaction has at least six confirmations.
- MUST send `announcement_signatures` message after `splice_locked`
has been sent and received.
- otherwise:
- MUST NOT send the `announcement_signatures` message.
- upon reconnection (once the above timing requirements have been met):
Expand Down Expand Up @@ -418,6 +420,7 @@ individual bits:
| ------------- | ----------- | -------------------------------- |
| 0 | `direction` | Direction this update refers to. |
| 1 | `disable` | Disable the channel. |
| 2 | `splicing` | Temporarily ignore channel spend.|

The `message_flags` bitfield is used to indicate the presence of optional
fields in the `channel_update` message:
Expand Down Expand Up @@ -485,6 +488,7 @@ The origin node:
- MUST set `fee_proportional_millionths` to the amount (in millionths of a
satoshi) it will charge per transferred satoshi.
- SHOULD NOT create redundant `channel_update`s
- SHOULD set `splicing` in all `channel_update` once splicing has been negotiated for a channel.

The receiving node:
- if the `short_channel_id` does NOT match a previous `channel_announcement`,
Expand Down Expand Up @@ -559,6 +563,11 @@ the channel when the peer reestablishes contact. Because gossip
messages are batched and replace previous ones, the result may be a
single seemingly-redundant update.

The simple `splicing` flag warns nodes that this channel will be
replaced; it tells them to give a grace period for the new channel to
appear (it can't be announced until it's 6 blocks deep) during which
it can use the old channel id.

## Query Messages

Negotiating the `gossip_queries` option via `init` enables a number
Expand Down Expand Up @@ -967,6 +976,8 @@ A node:
- SHOULD monitor the funding transactions in the blockchain, to identify
channels that are being closed.
- if the funding output of a channel is being spent:
- if a `channel_update` had `splicing` in the `channel_flags`:
- SHOULD delay 10 blocks considering the output spent.
- SHOULD be removed from the local network view AND be considered closed.
- if the announced node no longer has any associated open channels:
- MAY prune nodes added through `node_announcement` messages from their
Expand Down