From dc137bed8bb66ebfdbc1a4d6bd40772dfe385285 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 8 Apr 2022 06:28:43 +0800 Subject: [PATCH] channel: move deprecated log handling into the new file --- channeldb/channel.go | 26 +------- channeldb/revocation_log.go | 120 ++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 24 deletions(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index 4c3390747..e6dc31b45 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -117,16 +117,6 @@ var ( // TODO(roasbeef): rename to commit chain? commitDiffKey = []byte("commit-diff-key") - // revocationLogBucketDeprecated is dedicated for storing the necessary - // delta state between channel updates required to re-construct a past - // state in order to punish a counterparty attempting a non-cooperative - // channel closure. This key should be accessed from within the - // sub-bucket of a target channel, identified by its channel point. - // - // NOTE: deprecated. This bucket is kept for read-only in case the user - // choose not to migrate the old data. - revocationLogBucketDeprecated = []byte("revocation-log-key") - // frozenChanKey is the key where we store the information for any // active "frozen" channels. This key is present only in the leaf // bucket for a given channel. @@ -2682,7 +2672,7 @@ func (c *OpenChannel) FindPreviousState(updateNum uint64) (*ChannelCommitment, e return ErrNoPastDeltas } - c, err := fetchChannelLogEntry(logBucket, updateNum) + c, err := fetchOldRevocationLog(logBucket, updateNum) if err != nil { return err } @@ -3653,6 +3643,7 @@ func makeLogKey(updateNum uint64) [8]byte { return key } +// TODO: delete func appendChannelLogEntry(log kvdb.RwBucket, commit *ChannelCommitment) error { @@ -3665,19 +3656,6 @@ func appendChannelLogEntry(log kvdb.RwBucket, return log.Put(logEntrykey[:], b.Bytes()) } -func fetchChannelLogEntry(log kvdb.RBucket, - updateNum uint64) (ChannelCommitment, error) { - - logEntrykey := makeLogKey(updateNum) - commitBytes := log.Get(logEntrykey[:]) - if commitBytes == nil { - return ChannelCommitment{}, ErrLogEntryNotFound - } - - commitReader := bytes.NewReader(commitBytes) - return deserializeChanCommit(commitReader) -} - func fetchThawHeight(chanBucket kvdb.RBucket) (uint32, error) { var height uint32 diff --git a/channeldb/revocation_log.go b/channeldb/revocation_log.go index 316f59198..61a6521e0 100644 --- a/channeldb/revocation_log.go +++ b/channeldb/revocation_log.go @@ -15,6 +15,16 @@ import ( const OutputIndexEmpty = math.MaxUint16 var ( + // revocationLogBucketDeprecated is dedicated for storing the necessary + // delta state between channel updates required to re-construct a past + // state in order to punish a counterparty attempting a non-cooperative + // channel closure. This key should be accessed from within the + // sub-bucket of a target channel, identified by its channel point. + // + // Deprecated: This bucket is kept for read-only in case the user + // choose not to migrate the old data. + revocationLogBucketDeprecated = []byte("revocation-log-key") + // revocationLogBucket is a sub-bucket under openChannelBucket. This // sub-bucket is dedicated for storing the minimal info required to // re-construct a past state in order to punish a counterparty @@ -369,3 +379,113 @@ func readTlvStream(r io.Reader, s *tlv.Stream) error { lr := io.LimitReader(r, int64(bodyLen)) return s.Decode(lr) } + +// fetchOldRevocationLog finds the revocation log from the deprecated +// sub-bucket. +func fetchOldRevocationLog(log kvdb.RBucket, + updateNum uint64) (ChannelCommitment, error) { + + logEntrykey := makeLogKey(updateNum) + commitBytes := log.Get(logEntrykey[:]) + if commitBytes == nil { + return ChannelCommitment{}, ErrLogEntryNotFound + } + + commitReader := bytes.NewReader(commitBytes) + return deserializeChanCommit(commitReader) +} + +// fetchRevocationLogCompatible finds the revocation log from both the +// revocationLogBucket and revocationLogBucketDeprecated for compatibility +// concern. It returns three values, +// - RevocationLog, if this is non-nil, it means we've found the log in the +// new bucket. +// - ChannelCommitment, if this is non-nil, it means we've found the log in the +// old bucket. +// - error, this can happen if the log cannot be found in neither buckets. +func fetchRevocationLogCompatible(chanBucket kvdb.RBucket, + updateNum uint64) (*RevocationLog, *ChannelCommitment, error) { + + // Look into the new bucket first. + logBucket := chanBucket.NestedReadBucket(revocationLogBucket) + if logBucket != nil { + rl, err := fetchRevocationLog(logBucket, updateNum) + // We've found the record, no need to visit the old bucket. + if err == nil { + return &rl, nil, nil + } + + // Return the error if it doesn't say the log cannot be found. + if err != ErrLogEntryNotFound { + return nil, nil, err + } + } + + // Otherwise, look into the old bucket and try to find the log there. + oldBucket := chanBucket.NestedReadBucket(revocationLogBucketDeprecated) + if oldBucket != nil { + c, err := fetchOldRevocationLog(oldBucket, updateNum) + if err != nil { + return nil, nil, err + } + + // Found an old record and return it. + return nil, &c, nil + } + + // If both the buckets are nil, then the sub-buckets haven't been + // created yet. + if logBucket == nil && oldBucket == nil { + return nil, nil, ErrNoPastDeltas + } + + // Otherwise, we've tried to query the new bucket but the log cannot be + // found. + return nil, nil, ErrLogEntryNotFound +} + +// fetchLogBucket returns a read bucket by visiting both the new and the old +// bucket. +func fetchLogBucket(chanBucket kvdb.RBucket) (kvdb.RBucket, error) { + logBucket := chanBucket.NestedReadBucket(revocationLogBucket) + if logBucket == nil { + logBucket = chanBucket.NestedReadBucket( + revocationLogBucketDeprecated, + ) + if logBucket == nil { + return nil, ErrNoPastDeltas + } + } + + return logBucket, nil +} + +// deleteLogBucket deletes the both the new and old revocation log buckets. +func deleteLogBucket(chanBucket kvdb.RwBucket) error { + // Check if the bucket exists and delete it. + logBucket := chanBucket.NestedReadWriteBucket( + revocationLogBucket, + ) + if logBucket != nil { + err := chanBucket.DeleteNestedBucket(revocationLogBucket) + if err != nil { + return err + } + } + + // We also check whether the old revocation log bucket exists + // and delete it if so. + oldLogBucket := chanBucket.NestedReadWriteBucket( + revocationLogBucketDeprecated, + ) + if oldLogBucket != nil { + err := chanBucket.DeleteNestedBucket( + revocationLogBucketDeprecated, + ) + if err != nil { + return err + } + } + + return nil +}