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

Feature 106/107: option_simplified_update. #867

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
120 changes: 120 additions & 0 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ operation, and closing.
* [Closing Initiation: `shutdown`](#closing-initiation-shutdown)
* [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed)
* [Normal Operation](#normal-operation)
* [Simplified Operation](#simplified-operation)
* [Forwarding HTLCs](#forwarding-htlcs)
* [`cltv_expiry_delta` Selection](#cltv_expiry_delta-selection)
* [Adding an HTLC: `update_add_htlc`](#adding-an-htlc-update_add_htlc)
Expand Down Expand Up @@ -644,6 +645,118 @@ transactions may be out of sync indefinitely. This is not concerning:
what matters is whether both sides have irrevocably committed to a
particular update or not (the final state, above).

### Simplified Operation

If `option_simplified_update` is negotiated, a subset of the previous
protocol is used, where each side takes turns to propose updates,
which are synchronized before the other side has a turn:

+-------+ +-------+
| |--(1)---- update_add_htlc ---->| |
| |--(2)---- update_add_htlc ---->| |
| |--(3)--- commitment_signed --->| |
| A |<-(4)---- revoke_and_ack ------| B |
| |<-(5)--- commitment_signed ----| |
| |--(6)---- revoke_and_ack ----->| |
| | | |
| |<-(7)---- update_add_htlc -----| |
| |<-(8)--- commitment_signed ----| |
| |--(9)---- revoke_and_ack ----->| |
| |--(10)-- commitment_signed --->| |
| |<-(11)--- revoke_and_ack ------| |
+-------+ +-------+

If one side sends an update when it is not its turn, the other side
can either ignore it (in favor of its own update), or reply with a
`yield` message to hand the turn over.

#### Swapping turns: `yield` and `update_noop`

1. type: 129 (`update_noop`) (`option_simplified_update`)
2. data:
* [`channel_id`:`channel_id`]

1. type: 138 (`yield`) (`option_simplified_update`)
2. data:
* [`channel_id`:`channel_id`]

#### Requirements

A node:
- MUST NOT send `yield` unless `option_simplified_update` is negotiated.
- MUST track whose turn it is, starting with the peer with the lesser SEC1-encoded node_id.
- MUST give up its turn when:
- sending `revoke_and_ack`
- sending a `yield`
- MUST accept its turn when:
- receiving `revoke_and_ack`
- receiving a `yield`
- During this node's turn:
- if it receives an update message or `commitment_signed`:
- if it has sent its own update or `commitment_signed`:
- MUST ignore the message
Copy link
Contributor

@instagibbs instagibbs Apr 28, 2022

Choose a reason for hiding this comment

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

the remote node sends a commitment_signed during the local node's turn, after the local node has sent a commitment_signed message though? diagram, step (5) and the response (6)...

- otherwise:
- MUST reply with `yield` and process the message.
- if it received `update_noop`:
- MUST otherwise ignore the message
- During the other node's turn:
- if it has not received an update message or `commitment_signed`:
- MAY send one or more update message or `commitment_signed`:
- MUST NOT include those changes if it receives an update message or `commitment_signed` in reply.
- MUST include those changes if it receives a `yield` in reply.

Upon reconnection when `channel_reestablish` is exchanged and
`option_simplified_update` is negotiated:
- If it has sent `commitment_signed` on the other peer's turn without receiving `yield`:
- MUST NOT consider that `commitment_signed` sent.
- If a node sent `next_commitment_number` which exceeds its received
`next_revocation_number`, that node's turn is unfinished.
- If exactly one node's turn is unfinished, it is their turn,
otherwise the turn starts with the peer with the lesser
SEC1-encoded node_id.
- If a node's turn was unfinished:
- That node MUST retransmit the same updates as their previous turn.
- The receiving node MAY close the channel if it receives different updates
to the previously unfinished turn.

#### Rationale

A simple implementation can send an update message out-of-turn and
wait for a `yield` before sending `commitment_signed`: this ensures
that there only ever one commitment state at any time, at cost of
round-trip latency for any out-of-turn changes.

For simplicity, an `update_noop` can be used to prompt a `yield` with
no other effects.

A more complex implementation can optimistically send a complete set
of updates and `commitment_signed`, but must handle the possibility of
that commitment being spent on-chain even if the peer does not yield.

Note that the reconnection logic is similarly simplified for an
implementation which always waits for `yield`: both nodes cannot have
a commitment in flight simultanously, so if messages are lost due to
disconnection that is detectable and it simply replays its turn. If
an implementation optimistically sends `commitment_signed`, then it
assumes was either lost and does not apply, or the `yield` reply was
lost and the `next_commitment_number` test will correctly indicate its
turn.

The requirement for exact replay again means that commitments at the
same height will always match.

Note that if a channel always uses `option_simplified_update` then the
revocation and commitment numbers will be equal on both sides (except
when an update is in progress), but this is not true if a channel
previously operated without this option. However, the "more
commitments sent than revocations received" test will still indicate
which side has uncommitted changes.

Since upgrading to enable `option_simplified_update` will require a
quiescent period, there can be no issue with retransmission from
before `option_simplified_update` applied.


### Forwarding HTLCs

In general, a node offers HTLCs for two reasons: to initiate a payment of its own,
Expand Down Expand Up @@ -1119,6 +1232,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.
- if `option_simplified_update` is negotiated:
- MUST NOT mix `update_fee` with other updates in the same commitment.
Copy link
Contributor

Choose a reason for hiding this comment

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

does this mean any other updates, including other update_fee messages in same turn, or just update_fee vs all other update types?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good q! I think it means the former, but should be more explicit!


The node _not responsible_ for paying the Bitcoin fee:
- MUST NOT send `update_fee`.
Expand Down Expand Up @@ -1155,6 +1270,11 @@ 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.

With `option_simplified_update` the fee logic is again simplified for
implementations, such that there is no question of the HTLC state when
the fee change is proposed.


## Message Retransmission

Because communication transports are unreliable, and may need to be
Expand Down
1 change: 1 addition & 0 deletions 09-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ The Context column decodes as follows:
| 18/19 | `option_support_large_channel` | Can create large channels | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) |
| 20/21 | `option_anchor_outputs` | Anchor outputs | IN | `option_static_remotekey` | [BOLT #3](03-transactions.md) |
| 22/23 | `option_anchors_zero_fee_htlc_tx` | Anchor commitment type with zero fee HTLC transactions | IN | | [BOLT #3][bolt03-htlc-tx], [lightning-dev][ml-sighash-single-harmful]|
| 106/107 | `option_simplified_update` | Simplified commitment negotiation | IN | | |

## Requirements

Expand Down