Introduce new commitment format to enforce channel lease expirations in scripts#5549
Introduce new commitment format to enforce channel lease expirations in scripts#5549wpaulino wants to merge 29 commits intolightningnetwork:masterfrom wpaulino:channel-lease-script-enforcement
Conversation
Roasbeef
left a comment
There was a problem hiding this comment.
Really happy to see that all the refactoring we did before/during the anchor output saga helped to guide and compress the final diff off this new channel type! Completed an initial pass, but will do a few more takes, with one of the focusing primarily on the itests, as well as the sweeper bug fix (?) inserted within the diff.
lnwire/accept_channel.go
Outdated
There was a problem hiding this comment.
Not something we need to do right now, but thinking in the future we might want to create sort of embedded sub-structs that house all the unique params for a given channel type. This way things get less cluttered as more channel tyupes are added overtime.
guggero
left a comment
There was a problem hiding this comment.
Did a high-level pass, still need to digest and think about the implications of those changes a bit more.
Great work on everything I've seen so far! Commits read well and diff is comparatively small for all it achieves.
lncfg/protocol.go
Outdated
There was a problem hiding this comment.
I assume at one point we'd require any Pool maker to have this turned off?
There was a problem hiding this comment.
It's off by default, but yes. Funding a script enforced channel with this flag enabled will fail.
lnwallet/commitment.go
Outdated
There was a problem hiding this comment.
nit: move error outside of switch too?
In this commit, we add a new TLV record that's intended to be used as an explicit channel commitment type for a new form of funding negotiation, and later on a dynamic commitment upgrade protocol. As defined, we have 3 channel types: base (the OG), tweakless, and anchors w/ zero fee HTLCs. We omit the original variant of anchors as it was never truly deployed from the PoV of lnd.
In this commit, we add a new ChannelType field as a new TLV record to the OpenChannel message. During this change, we make a few tweaks to the generic TLV encode/decode methods for the ExtraOpaqueData struct to have it work on the level of tlv.RecordProducer instead of tlv.Record, as this reduces line noise a bit. We also partially undo existing logic that would attempt to "prepend" any new TLV records to the end of the ExtraOpaqueData if one was already present within the struct. This is based on the assumption that if we've read a message from disk to order to re-send/transmit it, then the ExtraOpaqueData is fully populated so we'll write that as is. Otherwise, a message is being encoded for the first time, and we expect all fields that are known TLV fields to be specified within the struct itself. This change required the unit tests to be modified slightly, as we'll always encode a fresh set of TLV records if none was already specified within the struct.
If these bits are present, then both sides can examine the new CommitmentType TLV field that's present and use this in place of the existing implicit commiment type negotiation. With this change, it's now possible to actually deprecate old unsupported commitment types properly.
This field will be examined later down the stack along with the set of feature bits to determine if explicit channel commitment type negotiation is possible or not.
This commit adds the ability for a channel initiator/responder to determine whether the channel to be opened can use a specific commitment type through explicit negotiation. It also includes the existing implicit negotiation logic to fall back on if explicit negotiation is not supported.
In this commit, we modify the existing logic that defaults to implicit commitment type negotiation to support explicit negotiation if the new feature bit is set. This change allows us to ditch the notion of a "default" commitment type, as we'll now use feature bits to signal our understanding of a commiment type, but allow peers to select which commitment type they actually wish to use. In addition, this explicit negotiation removes the need for using the required bit of any commitment types. Instead, if an implementation wishes to no longer support a commitment type, they should simply stop advertising the optional bit.
The new commitment type consists of adding an additional CLTV requirement to guarantee a leased channel's expiration on any commitment and HTLC outputs that pay directly to the channel initiator.
This witness generators and weight estimates added only apply for the new script-enforced leased channel commitment type.
This commit modifies the channel state machine to be able to derive the proper commitment and second-level HTLC output scripts required by the new script-enforced leased channel commitment type.
In order to sweep the commitment and HTLC outputs belonging to a script-enforced leased channel, each resolver must know whether the additional CLTV clause on the channel initiator applies to them. To do so, we retrieve the historical channel state stored within the database and supplement it to the resolvers to provide them with what's needed in order to sweep the necessary outputs and resolve their respective contracts.
This aims to cover an edge case and also serves as an optimization of what happens when an input that was offered to the Sweeper with an exclusive group is re-offered without one. This happens every time we attempt to sweep the different possible anchors of a channel at the time of broadcast, as we don't know which commitment transaction will end up confirming in the chain. Once the commitment transaction confirms however, we know which anchor output to act upon and re-offer it to the Sweeper without an exclusive group. At this point, the Sweeper will continue to attempt sweeping the other anchor output versions even know we know they are not valid.
We update several of our integration tests that exercise different scenarios with regards to the broadcast of a channel commitment transaction with HTLCs in-flight to use the new commitment type for channel leases. We do this to ensure we have complete coverage of said channel commitment type. This required changing several assumptions throughout the tests based on when we should expect sweeps to happen.
|
The dep PR has landed, will remake this one (rebased) so we can continue review+testing there. |
|
Rebased version: #5709 |
This PR introduces a new commitment format that's intended for use by channels resulting from Lightning Pool leases. This new commitment format builds upon the recently proposed anchors with zero HTLC fees commitment format, with an additional constraint on any outputs that pay directly to the channel initiator (also known as the channel seller in Pool). This additional constraints consists of an additional CLTV that requires a channel lease's expiration to be met before the channel initiator is able to claim their funds back from the channel. This unfortunately doesn't serve as a guarantee that the channel purchased cannot be closed prematurely, as we still need to allow the commitment transaction to be broadcast to resolve in-flight HTLCs, but instead serves as an incentive to prevent the channel initiator from prematurely closing out a channel as they won't be able to claim their funds until the lease expires.
This additional CLTV requirement for the channel initiator is found within the following three witness scripts in commitment transactions with anchors:
to_localoutput witness script:to_remoteoutput witness script:Note that this constraint only applies to the channel initiator, so given Alice (initiator) & Bob have a leased channel using this new commitment type:
to_local:OP_IF <revocation_pubkey> OP_ELSE <lease_maturity> OP_CHECKLOCKTIMEVERIFY OP_DROP <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP <local_delayed_pubkey> OP_ENDIF OP_CHECKSIGto_remote:<remote_pubkey> OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFYto_local:OP_IF <revocation_pubkey> OP_ELSE <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP <local_delayed_pubkey> OP_ENDIF OP_CHECKSIGto_remote:<remote_pubkey> OP_CHECKSIGVERIFY <lease_maturity> OP_CHECKLOCKTIMEVERIFY OP_DROP 1 OP_CHECKSEQUENCEVERIFYDepends on #5373.