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: store bool to determine retransmission ordering #4915

Merged
merged 2 commits into from
Feb 4, 2021
Merged
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
61 changes: 53 additions & 8 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var (
// previously open, but now closed channels.
closedChannelBucket = []byte("closed-chan-bucket")

// openChanBucket stores all the currently open channels. This bucket
// openChannelBucket stores all the currently open channels. This bucket
// has a second, nested bucket which is keyed by a node's ID. Within
// that node ID bucket, all attributes required to track, update, and
// close a channel are stored.
Expand Down Expand Up @@ -128,6 +128,11 @@ var (
// active "frozen" channels. This key is present only in the leaf
// bucket for a given channel.
frozenChanKey = []byte("frozen-chans")

// lastWasRevokeKey is a key that stores true when the last update we sent
// was a revocation and false when it was a commitment signature. This is
// nil in the case of new channels with no updates exchanged.
lastWasRevokeKey = []byte("last-was-revoke")
)

var (
Expand Down Expand Up @@ -225,7 +230,7 @@ const (
// funded symmetrically or asymmetrically.
DualFunderBit ChannelType = 1 << 0

// SingleFunderTweakless is similar to the basic SingleFunder channel
// SingleFunderTweaklessBit is similar to the basic SingleFunder channel
// type, but it omits the tweak for one's key in the commitment
// transaction of the remote party.
SingleFunderTweaklessBit ChannelType = 1 << 1
Expand Down Expand Up @@ -710,6 +715,10 @@ type OpenChannel struct {
// interpreted as a relative height, or an absolute height otherwise.
ThawHeight uint32

// LastWasRevoke is a boolean that determines if the last update we sent
// was a revocation (true) or a commitment signature (false).
LastWasRevoke bool

// TODO(roasbeef): eww
Db *DB

Expand Down Expand Up @@ -1526,6 +1535,17 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
"updates: %v", err)
}

// Since we have just sent the counterparty a revocation, store true
// under lastWasRevokeKey.
var b2 bytes.Buffer
if err := WriteElements(&b2, true); err != nil {
return err
}

if err := chanBucket.Put(lastWasRevokeKey, b2.Bytes()); err != nil {
Crypt-iQ marked this conversation as resolved.
Show resolved Hide resolved
return err
}

// Persist the remote unsigned local updates that are not included
// in our new commitment.
updateBytes := chanBucket.Get(remoteUnsignedLocalUpdatesKey)
Expand All @@ -1548,13 +1568,13 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
}
}

var b2 bytes.Buffer
err = serializeLogUpdates(&b2, validUpdates)
var b3 bytes.Buffer
err = serializeLogUpdates(&b3, validUpdates)
if err != nil {
return fmt.Errorf("unable to serialize log updates: %v", err)
}

err = chanBucket.Put(remoteUnsignedLocalUpdatesKey, b2.Bytes())
err = chanBucket.Put(remoteUnsignedLocalUpdatesKey, b3.Bytes())
if err != nil {
return fmt.Errorf("unable to restore chanbucket: %v", err)
}
Expand Down Expand Up @@ -2091,15 +2111,25 @@ func (c *OpenChannel) AppendRemoteCommitChain(diff *CommitDiff) error {
return err
}

// We are sending a commitment signature so lastWasRevokeKey should
// store false.
var b bytes.Buffer
if err := WriteElements(&b, false); err != nil {
return err
}
if err := chanBucket.Put(lastWasRevokeKey, b.Bytes()); err != nil {
return err
}

// TODO(roasbeef): use seqno to derive key for later LCP

// With the bucket retrieved, we'll now serialize the commit
// diff itself, and write it to disk.
var b bytes.Buffer
if err := serializeCommitDiff(&b, diff); err != nil {
var b2 bytes.Buffer
if err := serializeCommitDiff(&b2, diff); err != nil {
return err
}
return chanBucket.Put(commitDiffKey, b.Bytes())
return chanBucket.Put(commitDiffKey, b2.Bytes())
}, func() {})
}

Expand Down Expand Up @@ -3419,6 +3449,21 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
return err
}

// Retrieve the boolean stored under lastWasRevokeKey.
lastWasRevokeBytes := chanBucket.Get(lastWasRevokeKey)
if lastWasRevokeBytes == nil {
// If nothing has been stored under this key, we store false in the
// OpenChannel struct.
channel.LastWasRevoke = false
} else {
// Otherwise, read the value into the LastWasRevoke field.
revokeReader := bytes.NewReader(lastWasRevokeBytes)
err := ReadElements(revokeReader, &channel.LastWasRevoke)
if err != nil {
return err
}
}

channel.Packager = NewChannelPackager(channel.ShortChannelID)

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