From 374cab7467dd95abb9b5dc6b4e63df1fcce9bcae Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 9 Nov 2017 20:47:57 -0800 Subject: [PATCH] channeldb: rename AppendToRevocationLog to AdvanceCommitChainTail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit, in addition to the renaming we’ve modified the behavior of AdvanceCommitChainTail as follows: this method now will simply atomically advance the commitment tail, set the new commitment to the prior dangling commitment, and update the on-disk revocation log. The macho expects the new revocation state to already be stored within the channel. This method is to be called once the remote party revokes their current commitment state. --- channeldb/channel.go | 89 ++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 33 deletions(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index d7a7bd034..e4dabf8d6 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -936,62 +936,85 @@ func (c *OpenChannel) InsertNextRevocation(revKey *btcec.PublicKey) error { return nil } -// AppendToRevocationLog records the new state transition within an on-disk +// AdvanceCommitChainTail records the new state transition within an on-disk // append-only log which records all state transitions by the remote peer. In // the case of an uncooperative broadcast of a prior state by the remote peer, // this log can be consulted in order to reconstruct the state needed to -// rectify the situation. -func (c *OpenChannel) AppendToRevocationLog(delta *ChannelDelta) error { - return c.Db.Update(func(tx *bolt.Tx) error { - chanBucket, err := tx.CreateBucketIfNotExists(openChannelBucket) - if err != nil { - return err - } +// rectify the situation. This method will add the current commitment for the +// remote party to the revocation log, and promote the current pending +// commitment to the current remove commitment. +func (c *OpenChannel) AdvanceCommitChainTail() error { + c.Lock() + defer c.Unlock() - id := c.IdentityPub.SerializeCompressed() - nodeChanBucket, err := chanBucket.CreateBucketIfNotExists(id) + var newRemoteCommit *ChannelCommitment + + err := c.Db.Update(func(tx *bolt.Tx) error { + chanBucket, err := readChanBucket(tx, c.IdentityPub, + &c.FundingOutpoint, c.ChainHash) if err != nil { return err } // Persist the latest preimage state to disk as the remote peer - // has just added to our local preimage store, and - // given us a new pending revocation key. - if err := putChanRevocationState(nodeChanBucket, c); err != nil { + // has just added to our local preimage store, and given us a + // new pending revocation key. + if err := putChanRevocationState(chanBucket, c); err != nil { return err } // With the current preimage producer/store state updated, - // append a new log entry recording this the delta of this state - // transition. + // append a new log entry recording this the delta of this + // state transition. + // // TODO(roasbeef): could make the deltas relative, would save // space, but then tradeoff for more disk-seeks to recover the // full state. - logKey := channelLogBucket - logBucket, err := nodeChanBucket.CreateBucketIfNotExists(logKey) + logKey := revocationLogBucket + logBucket, err := chanBucket.CreateBucketIfNotExists(logKey) if err != nil { return err } - // ... - diffBucket := tx.Bucket(commitDiffBucket) - if diffBucket != nil { - var outpoint bytes.Buffer - if err := writeOutpoint(&outpoint, &c.FundingOutpoint); err != nil { - return err - } - - key := []byte("cdf") - key = append(key, outpoint.Bytes()...) - if diffBucket.Get(key) != nil { - if err := diffBucket.Delete(key); err != nil { - return err - } - } + // Before we append this revoked state to the revocation log, + // we'll swap out what's currently the tail of the commit tip, + // with the current locked-in commitment for the remote party. + tipBytes := chanBucket.Get(commitDiffKey) + tipReader := bytes.NewReader(tipBytes) + newCommit, err := deserializeCommitDiff(tipReader) + if err != nil { + return err + } + err = putChanCommitment(chanBucket, &newCommit.Commitment, false) + if err != nil { + return err + } + if err := chanBucket.Delete(commitDiffKey); err != nil { + return err } - return appendChannelLogEntry(logBucket, delta, &c.FundingOutpoint) + // With the commitment pointer swapped, we can now add the + // revoked (prior) state to the revocation log. + // + // TODO(roasbeef): store less + err = appendChannelLogEntry(logBucket, &c.RemoteCommitment) + if err != nil { + return err + } + + newRemoteCommit = &newCommit.Commitment + return nil }) + if err != nil { + return err + } + + // With the db transaction complete, we'll swap over the in-memory + // pointer of the new remote commitment, which was previously the tip + // of the commit chain. + c.RemoteCommitment = *newRemoteCommit + + return nil } // RevocationLogTail returns the "tail", or the end of the current revocation