[Lightning-dev] Dynamic Commitments: Upgrading Channels Without On-Chain Transactions

Antoine Riard antoine.riard at gmail.com
Tue Jul 21 23:47:27 UTC 2020


Hi Laolu,

I think that's a must before we introduce a bunch of new features and the
number of channels explodes. The de-synchronized side could be underscored
more as any scheduled, automatic, massive upgrade for security forcing
chain writes can be exploited to launch  mempool-congestion attacks.

> Finally, the ability to update the commitment format itself will also
allow
> us to re-parametrize portions of the channels which are currently set in
> stone. As an example, right now the # of max allowed outstanding HTLCs is
> set in stone once the channel has opened. With the ability to also swap
out
> commitment _parameters_, we can start to experiment with flow-control like
> ideas such as limiting a new channel peer to only a handful of HTLC slots,
> which is then progressively increased based on "good behavior" (or the
other
> way around as well). Beyond just updating the channel parameters, it's
also
> possible to "change the rules" of a channel on the fly. An example of this
> variant would be creating a new psuedo-type that implements a fee policy
> other than "the initiator pays all fees".

Yes, there is a wide scope of events for which you want to upgrade:
* fine-grained security policies, like scaling your
`channel_reserve_satoshis`/`to_self_delay` based on my balance increasing
* fee-market adjustments, like increasing `dust_limit_satoshis` or
`feerate_per_kw`
* new features deployments, scoping channel types, commitment types, new
channel attributes (`max_dust_value`), new packets types (DLC/PTLC)
* basepoints rotation, as a good practice you may want to swap them every X
* routing strategies adjustments, increase `max_accepted_htlcs` to attract
more traffic

Given complexity negotiation, we should cleanly dissociate the signaling of
upgraded component  ("I want to update output type") from the upgrade
rational ("I want to update because my fee-estimator sees a feerate
increase"). Former should be obviously part of the spec, latter should be
left as a client-side policy, beyond avoiding footgunish behaviors.

> To solve this existing ambiguity in the channel type negotiation, we'll
> need to make the channel type used for funding _explicit_. Thankfully, we
> recently modified the message format to be forwarding looking in order to
> allow _TLV extensions_ to be added for all existing message types. A new
> `channel_type` (type #???) TLV would be added which makes the channel type
> used in funding explicit, with the existing feature bit advertisement
system
> being kept in place.

I think we may need more than channel_type, like
commitment_type/output_type. Or else we may have factorial complexity to
check every features combination. As you said, TLV should make it easy.

> As we add more types, there may not be a "default" type, so making this
process explicit is important to future exploration and extensibility.

We may want a "default" type based on the most secure/private one to avoid
downgrade attack a la TLS between implementations. If we introduce dynamic
negotiation, Alice supporting type X,Y,Z with X being the less secure, Bob
a malicious routing node only signals X to force a X channel opening. To
avoid this, we may deprecate from negotiation older types once newer ones
are widely deployed. Maybe that you meant by "`channel_type transition
isn't allowed". Experimental/advanced features can stay in allowed
negotiation range but feature-gated behind some flags.


> An alternative to attaching the `channel_type` message to the `commit_sig`
> and having _that_ kick off the commitment upgrade, we could instead
possibly
> add a _new_ update message (like `update_fee`) to make the process more
> explicit. In either case, we may want to restrict things a bit by only
> allowing the initiator to trigger a commitment format update.

I favor this alternative, as your new channel type may imply a channel
data/round-trip extension  (like signatures round-trip for PTLCs). Or if
you constrain channel-flow policy, your added HTLCs might in fact be
unlawful. We should avoid dependencies where validity of upgrades depend on
channel state.

Moving forward, we may want to start with a minimal first-step with just
introducing a new `upgrade_channel` message and its handling flow + new TLV
in `open/accept`. And then slowly increase scope of what you can actually
upgrade/negotiate.

Overall, that's a really cool proposal, dynamic commitment doesn't say
enough on scope, maybe "flexible channels" :) ?

Antoine

Le lun. 20 juil. 2020 à 21:18, Olaoluwa Osuntokun <laolu32 at gmail.com> a
écrit :

> Hi y'all,
>
> In this post, I'd like to share an early version of an extension to the
> spec
> and channel state machine that would allow for on-the-fly commitment
> _format/type_ changes. Notably, this would allow for us to _upgrade_
> commitment types without any on-chain activity, executed in a
> de-synchronized and distributed manner. The core realization these proposal
> is based on the fact that the funding output is the _only_ component of a
> channel that's actually set in stone (requires an on-chain transaction to
> modify).
>
>
> # Motivation
>
> (you can skip this section if you already know why something like this is
> important)
>
> First, some motivation. As y'all are likely aware, the current deployed
> commitment format has changed once so far: to introduce the
> `static_remote_key` variant which makes channels safer by sending the funds
> of the party that was force closed on to a plain pubkey w/o any extra
> tweaks
> or derivation. This makes channel recovery safer, as the party that may
> have
> lost data (or can't continue the channel), no longer needs to learn of a
> secret value sent to them by the other party to be able to claim their
> funds. However, as this new format was introduced sometime after the
> initial
> bootstrapping phase of the network, most channels in the wild today _are
> not_ using this safer format.  Transitioning _all_ the existing channels to
> this new format as is, would require closing them _all_, generating tens of
> thousands of on-chain transactions (to close, then re-open), not to mention
> chain fees.
>
> With dynamic commitments, users will be able to upgrade their _existing_
> channels to new safer types, without any new on-chain transactions!
>
> Anchor output based commitments represent another step forward in making
> channels safer as they allow users/software to no longer have to predict
> chain fees ahead of time, and also bump up the fee of a
> commitment/2nd-level-htlc-transaction, which is extremely important when it
> comes to timely on-chain resolution of HTLC contracts. This upgrade process
> (as touched on below) can either be manually triggered, or automatically
> triggered once the software updates and finds a new preferable default
> commitment format is available.
>
> As many of us are aware, the addition of schnorr and taproot to the Bitcoin
> protocol dramatically increases the design space for channels as a whole.
> It
> may take some time to explore this design space, particularly as entirely
> new channel/commitment formats [1] continue to be discovered. The roll out
> of dynamic commitments allows us to defer the concrete design of the future
> commitment formats, yet still benefit from the immediate improvement that
> comes with morphing the funding output to be a single-key (non-p2wsh,
> though
> the line starts to blur w/ taproot) output. With this new funding output
> format in place, users/software will then be able to update to the latest
> and greatest commitment format that starts to utilize all the new tools
> available (scriptless script based htlcs, etc) at a later date.
>
> Finally, the ability to update the commitment format itself will also allow
> us to re-parametrize portions of the channels which are currently set in
> stone. As an example, right now the # of max allowed outstanding HTLCs is
> set in stone once the channel has opened. With the ability to also swap out
> commitment _parameters_, we can start to experiment with flow-control like
> ideas such as limiting a new channel peer to only a handful of HTLC slots,
> which is then progressively increased based on "good behavior" (or the
> other
> way around as well). Beyond just updating the channel parameters, it's also
> possible to "change the rules" of a channel on the fly. An example of this
> variant would be creating a new psuedo-type that implements a fee policy
> other than "the initiator pays all fees".
>
>
> # Protocol Changes
>
> With the motivation/background set up, let's dig into some potential ways
> the protocol can be modified to support this new meta-feature. As this
> change is more of a meta-change, AFAICT, the amount of protocol changes
> doesn't appear to be _too_ invasive ;). Most of the heavy lifting is done
> by
> the wondrous TLV message field extensions.
>
> ## Explicit Channel Type Negotiation
>
> Right now in the protocol, as new channel types are introduced (static key,
> and now anchors) we add a new feature bit. If both nodes have the feature
> bit set, then that new channel type is to be used. Notice how this is an
> _implicit_ upgrade: there's no explicit signalling during the _funding_
> process that a new channel type is to be used. This works OK, if there's
> one
> major accepted "official" channel type, but not as new types are introduced
> for specific use cases or applications. The implicit negotiation also makes
> things a bit ambiguous at times. As an example, if both nodes have the
> `static_remote_key` _and_ anchor outputs feature bit set, which channel
> type
> should they open?
>
> To resolve this existing ambiguity in the channel type negotiation, we'll
> need to make the channel type used for funding _explicit_. Thankfully, we
> recently modified the message format to be forwarding looking in order to
> allow _TLV extensions_ to be added for all existing message types. A new
> `channel_type` (type #???) TLV would be added which makes the channel type
> used in funding explicit, with the existing feature bit advertisement
> system
> being kept in place.
>
> A draft of the changes in this area would be something like:
>
>   * `open_channel` and `accept_channel` gain a new `channel_type` TLV
> field.
>   * retroactively the OG commitment format is numbered as `channel_type=0`,
>     `static_remote_key`, as `channel_type=1`, and anchors as
>     `channel_type=2`
>   * if one receives an `open_channel`, or `accept_channel` message with an
>     unknown `channel_type`, they're to fail the funding flow
>   * nodes MUST NOT send an `open_channel` or `accept_channel` message with
> a
>     `channel_type` that isn't covered by their existing advertise feature
>     bits
>   * a mapping between feature bits and expected `channel_type` values would
>     then be added
>   * during funding negotiation, the _commitment_ type itself is
> parametrized
>     based on the `channel_type` value
>       * as we've all implemented `static_remote_key` commitments at this
>         point, I assume the necessary code-level abstractions are already
>         in-place
>
> ## Commitment State Machine Changes
>
> With the changes described in the above section, we're now able to
> explicitly identify _which_ channel type we want to enter a funding flow
> for. As we add more types, there may not be a "default" type, so making
> this
> process explicit is important to future exploration and extensibility.  In
> this section, we'll introduce a series of small changes to the
> `commit_sig`,
> and `revoke_and_ack` messages which'll allow us to implement the "dynamic"
> portion of this proposal.
>
> Relying once again on the wondrous power of TLV message extensions we'll
> carry over the `channel_type` TLV (just the name, # may be diff since this
> is a diff message context) to the `commit_sig`, and `revoke_and_ack`
> messages. The following guidelines on inclusion and interpretation would
> then be applied:
>
>   * the `channel_type` specified on a given `commit_sig` message should be
>     the `channel_type` of the _new_ commitment being _created_
>   * when receiving a `commit_sig` with a `channel_type` that differs from
>     the `channel_type` of one's on revoked commitment:
>      * if the `channel_type` is unknown (or the `channel_type` transition
>        isn't allowed or defined), then the _p2p_ connection should be
>        aborted
>      * otherwise, using the `channel_type` as a parameter for commitment
>        transaction construction, a new commitment adhering to the rules of
>        the `channel_type` should be constructed
>   * the `channel_type` sent in the `revoke_and_ack` message should be the
>     `channel_type` of the commitment that's being _revoked_
>
> With the above new rules, let's say Alice and Bob upgrade to new versions
> of
> their LN software that support a new channel type `1`, while they're on
> channel type `0`. Either triggered automatically, or manually (by either
> side), the commitment flow would look something like:
>
>   1. sig_c_1   ->
>   2.          <- revoke_c_0
>   3.          <- sig_c_1
>   4. revoke_c_0 ->
>
> By exchanging 4 messages, both sides are able to upgrade to a new
> commitment
> format. However, one issue with the above flow is that it currently isn't
> allowed by the spec, since we disallow sending a `commit_sig` message that
> doesn't cover any updates. If we end up going with this route, then we'd
> have to relax that constraint to something like:
>
>   * an empty `commit_sig` message (one that covers no updates) is
>     disallowed, unless the `commit_sig` has a `channel_type`, `c_n` that
>     differs from the channel type of the prior commitment, `c_n-1`.
>
> It would then be up to _new protocol extension documents_ to define _how_
> to
> construct those new channel types, and also any changes to the on-chain
> handling that are required by those channel types. Also certain transitions
> may be disallowed. As an example, implementations may want to prevent a
> user
> from going back to the non-static remote key channels from the
> `static_remote_key` format.
>
> In order to prepare for these changes, implementations need to be able to
> handle "holding" unrevoked commitments of heterogeneous types, as if either
> of them hit the chain, they'll need to be able to resolve all contracts
> properly.
>
> An alternative to attaching the `channel_type` message to the `commit_sig`
> and having _that_ kick off the commitment upgrade, we could instead
> possibly
> add a _new_ update message (like `update_fee`) to make the process more
> explicit. In either case, we may want to restrict things a bit by only
> allowing the initiator to trigger a commitment format update.
>
> ## Further Channel Type Parameterization
>
> With the above protocol sketch, we're able to handle "simple" upgrades,
> where some/all of the parameters of the channel are hard coded and/or have
> been negotiated out of band. More complex channel types may require the
> exchange of additional keys or parameters which need to be known in order
> to
> reconstruct the _new_ commitment format and verify the new signature. This
> additional information can possibly be piggy-backed on the `commit_sig`
> message in the form of a _nested TLV_ type:
>
>   * a msg-local TLV type `channel_params` is added
>   * the value of this TLV type is a nested TLV blob, that contains all the
>     necessary fields and values needed to properly handle the channel
> switch
>     over
>
> Returning to the flow control example earlier in this post, the new limits
> for `max_allowed_htlcs`, can be included in this blob. More complex channel
> types could send information such as new keys to be used, or other
> parameters
> that govern how a commitment is to be constructed (like the size of the
> anchor outputs).
>
> # Conclusion
>
> Summarizing, in this post we've proposed a series of protocol modifications
> (with TLV fields doing most of the heavy lifting) that allows LN nodes to
> upgrade their commitments _without any on-chain_ transactions. Depending on
> the architecture of a node, new types may even be added/removed without
> actual downtime.
>
> The ability to upgrade commitments after the fact lessens the pressure of
> newer possibly experimental channel types to get all the details (and
> explore the rather large design space) correct up front. Once Taproot rolls
> around, we can simply update the funding output, roll that out, then
> continue to hash out the details on the possibly new channel type(s) that
> take advantage of all the new tools.
>
> Allowing channel types to be upgraded on the fly let's us update the
> network
> to the new _safer_ channel types in a de-synchronized, distributed manner
> that doesn't require any on-chain transactions! Dynamic commitments as a
> whole also creates another point of extensibility in the protocol so we can
> start to explore all the variants on channels as we know them that exist.
>
> I'm keen to gather feedback, as internally for `lnd` we've committed to
> exploring this direction so we can start to upgrade _all_ the existing
> lnd-involved channels to the new anchor commitment format, which is the
> safest format yet.
>
> [1]: https://eprint.iacr.org/2020/476
>
> -- Laolu
> _______________________________________________
> Lightning-dev mailing list
> Lightning-dev at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20200721/b9ce80c7/attachment-0001.html>


More information about the Lightning-dev mailing list