From 3b2c807288b1b7f40d609533c1e96a510ac5fa6d Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Fri, 14 Sep 2018 12:35:00 -0700 Subject: [PATCH] channeldb: fix bug in migration from 0.4 to 0.5 In this commit, we fix a bug in the latest database migration when migrating from 0.4 to 0.5. There's an issue in bolt db where if one deletes a bucket that has a key with a nil value, it thinks that's a sub bucket and attempts a bucket deletion. This will fail as it's not actually a sub-bucket. We get around this by using a cursor to manually delete items in the bucket. Fixes #1907. --- channeldb/migrations.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/channeldb/migrations.go b/channeldb/migrations.go index c87e4079..948d8249 100644 --- a/channeldb/migrations.go +++ b/channeldb/migrations.go @@ -479,7 +479,8 @@ func migratePruneEdgeUpdateIndex(tx *bolt.Tx) error { } // Retrieve some buckets that will be needed later on. These should - // already exist given the assumption that the buckets above do as well. + // already exist given the assumption that the buckets above do as + // well. edgeIndex, err := edges.CreateBucketIfNotExists(edgeIndexBucket) if edgeIndex == nil { return fmt.Errorf("unable to create/fetch edge index " + @@ -515,16 +516,15 @@ func migratePruneEdgeUpdateIndex(tx *bolt.Tx) error { // With the existing edge policies gathered, we'll recreate the index // and populate it with the correct entries. - if err := edges.DeleteBucket(edgeUpdateIndexBucket); err != nil { - return fmt.Errorf("unable to remove existing edge update "+ - "index: %v", err) - } - edgeUpdateIndex, err = edges.CreateBucketIfNotExists( - edgeUpdateIndexBucket, - ) - if err != nil { - return fmt.Errorf("unable to recreate edge update index: %v", - err) + // + // NOTE: In bolt DB, calling Delete() on an iterator will actually move + // it to the NEXT item. As a result, we call First() here again to go + // back to the front after the item has been deleted. + updateCursor := edgeUpdateIndex.Cursor() + for k, _ := updateCursor.First(); k != nil; k, _ = updateCursor.First() { + if err := updateCursor.Delete(); err != nil { + return err + } } // For each edge key, we'll retrieve the policy, deserialize it, and