From b89c14616c921a6c887bb33b960f9e66da00f187 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 9 Nov 2017 20:46:20 -0800 Subject: [PATCH] channeldb: add new RemoteCommitChainTip method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit, we add a new method: RemoteCommitChainTip. This method allows callers to poll the database state to check if we have an un-acked commitment for the remote party. If so, then it should be retransmitted once a communication channel has been re-established with the channel peer. This method will return ErrNoPendingCommit if we don’t currently have a dangling commitment. --- channeldb/channel.go | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index ac775345..d7a7bd03 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -871,32 +871,40 @@ func (c *OpenChannel) AppendRemoteCommitChain(diff *CommitDiff) error { }) } -// FetchCommitDiff... -func FetchCommitDiff(db *DB, fundingOutpoint *wire.OutPoint) (*CommitDiff, error) { - var diff *CommitDiff - err := db.View(func(tx *bolt.Tx) error { - bucket := tx.Bucket(commitDiffBucket) - if bucket == nil { - return errors.New("commit diff bucket haven't been found") - } - - var outpoint bytes.Buffer - if err := writeOutpoint(&outpoint, fundingOutpoint); err != nil { +// RemoteCommitChainTip returns the "tip" of the current remote commitment +// chain. This value will be non-nil iff, we've created a new commitment for +// the remote party that they haven't yet ACK'd. In this case, their commitment +// chain will have a length of two: their current unrevoked commitment, and +// this new pending commitment. Once they revoked their prior state, we'll swap +// these pointers, causing the tip and the tail to point to the same entry. +func (c *OpenChannel) RemoteCommitChainTip() (*CommitDiff, error) { + var cd *CommitDiff + err := c.Db.View(func(tx *bolt.Tx) error { + chanBucket, err := readChanBucket(tx, c.IdentityPub, + &c.FundingOutpoint, c.ChainHash) + if err != nil { return err } - key := []byte("cdf") - key = append(key, outpoint.Bytes()...) - data := bucket.Get(key) - if data == nil { - return errors.New("unable to find commit diff") + tipBytes := chanBucket.Get(commitDiffKey) + if tipBytes == nil { + return ErrNoPendingCommit } - diff = &CommitDiff{} - return diff.encode(bytes.NewReader(data)) - }) + tipReader := bytes.NewReader(tipBytes) + dcd, err := deserializeCommitDiff(tipReader) + if err != nil { + return err + } - return diff, err + cd = dcd + return nil + }) + if err != nil { + return nil, err + } + + return cd, err } // InsertNextRevocation inserts the _next_ commitment point (revocation) into