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

multi: implement spec-compliant coop close #6760

Closed
wants to merge 14 commits into from
Closed
Changes from 1 commit
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
70 changes: 70 additions & 0 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ const (
// A tlv type definition used to serialize and deserialize the
// confirmed ShortChannelID for a zero-conf channel.
realScidType tlv.Type = 4

// A tlv type definition used to serialize and deserialize the
// sentShutdown bool.
sentShutdownType tlv.Type = 5
)

// indexStatus is an enum-like type that describes what state the
Expand Down Expand Up @@ -818,6 +822,10 @@ type OpenChannel struct {
// default ShortChannelID. This is only set for zero-conf channels.
confirmedScid lnwire.ShortChannelID

// sentShutdown denotes whether or not we've sent the Shutdown message
// for this channel.
sentShutdown bool
Crypt-iQ marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

Can alternatively store a nested TLV here that can be extended to store the: delivery script sent, fee range, last offer, etc.


// TODO(roasbeef): eww
Db *ChannelStateDB

Expand Down Expand Up @@ -1360,6 +1368,51 @@ func (c *OpenChannel) SecondCommitmentPoint() (*btcec.PublicKey, error) {
return input.ComputeCommitmentPoint(revocation[:]), nil
}

// MarkShutdownSent is used to mark that we've sent a Shutdown message for this
// channel. This is so that we can retransmit Shutdown upon reconnection.
func (c *OpenChannel) MarkShutdownSent() error {
c.Lock()
defer c.Unlock()

if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
chanBucket, err := fetchChanBucketRw(
tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
)
if err != nil {
return err
}

channel, err := fetchOpenChannel(
chanBucket, &c.FundingOutpoint,
)
if err != nil {
return err
}

channel.sentShutdown = true

return putOpenChannel(chanBucket, channel)
}, func() {}); err != nil {
return err
}

c.sentShutdown = true

return nil
}

// HasSentShutdown returns whether or not we've ever sent Shutdown for this
// channel. For nodes upgrading to 0.16.0, this will initially be false even if
// a Shutdown has been sent. This doesn't matter since this function is only
// used when restarting a ChannelLink and pre-0.16.0 nodes only sent Shutdown
// after the link was permanently stopped.
Crypt-iQ marked this conversation as resolved.
Show resolved Hide resolved
func (c *OpenChannel) HasSentShutdown() bool {
c.RLock()
defer c.RUnlock()

return c.sentShutdown
}

// PersistDeliveryScript is used during the cooperative close flow to persist
// a script sent in Shutdown when we did not set an upfront shutdown script
// during the funding flow.
Expand Down Expand Up @@ -3673,6 +3726,12 @@ func putChanInfo(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
localBalance := uint64(channel.InitialLocalBalance)
remoteBalance := uint64(channel.InitialRemoteBalance)

// Convert sentShutdown to a uint8.
var sentShutdownVal uint8
if channel.sentShutdown {
sentShutdownVal = 1
}

// Create the tlv stream.
tlvStream, err := tlv.NewStream(
// Write the RevocationKeyLocator as the first entry in a tlv
Expand All @@ -3687,6 +3746,9 @@ func putChanInfo(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
initialRemoteBalanceType, &remoteBalance,
),
MakeScidRecord(realScidType, &channel.confirmedScid),
tlv.MakePrimitiveRecord(
sentShutdownType, &sentShutdownVal,
),
)
if err != nil {
return err
Expand Down Expand Up @@ -3888,6 +3950,8 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
var (
localBalance uint64
remoteBalance uint64

sentShutdownVal uint8
)

// Create the tlv stream.
Expand All @@ -3904,6 +3968,9 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
initialRemoteBalanceType, &remoteBalance,
),
MakeScidRecord(realScidType, &channel.confirmedScid),
tlv.MakePrimitiveRecord(
sentShutdownType, &sentShutdownVal,
),
)
if err != nil {
return err
Expand All @@ -3917,6 +3984,9 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
channel.InitialLocalBalance = lnwire.MilliSatoshi(localBalance)
channel.InitialRemoteBalance = lnwire.MilliSatoshi(remoteBalance)

// Populate the sentShutdown field.
channel.sentShutdown = sentShutdownVal == 1

channel.Packager = NewChannelPackager(channel.ShortChannelID)

// Finally, read the optional shutdown scripts.
Expand Down