From f710cd4a9245674a5362d9060be493505ae40028 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Fri, 5 Jul 2019 13:16:01 -0700 Subject: [PATCH] cmd/dropwtxmgr+waddrmgr: handle constraint when resetting synced state We update the dropwtxmgr utility tool to take into account that the wallet only stores MaxReorgDepth blocks, which introduced an additional constraint when updating the wallet's synced state. The constraint ensures that the previous block exists when updating the wallet's synced state, but this does not hold for the birthday block since it's the first block we'll store. --- cmd/dropwtxmgr/main.go | 12 +++++++++++- waddrmgr/db.go | 18 ++++++++++++++++-- waddrmgr/migrations.go | 2 +- waddrmgr/migrations_test.go | 2 +- waddrmgr/sync.go | 2 +- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/cmd/dropwtxmgr/main.go b/cmd/dropwtxmgr/main.go index 3dc414f..164e6c0 100644 --- a/cmd/dropwtxmgr/main.go +++ b/cmd/dropwtxmgr/main.go @@ -135,7 +135,17 @@ func mainInt() int { return waddrmgr.PutSyncedTo(ns, startBlock) } - return waddrmgr.PutSyncedTo(ns, &birthdayBlock) + // We'll need to remove our birthday block first because it + // serves as a barrier when updating our state to detect reorgs + // due to the wallet not storing all block hashes of the chain. + if err := waddrmgr.DeleteBirthdayBlock(ns); err != nil { + return err + } + + if err := waddrmgr.PutSyncedTo(ns, &birthdayBlock); err != nil { + return err + } + return waddrmgr.PutBirthdayBlock(ns, birthdayBlock) }) if err != nil { fmt.Println("Failed to drop and re-create namespace:", err) diff --git a/waddrmgr/db.go b/waddrmgr/db.go index 7e9069f..97ecc5a 100644 --- a/waddrmgr/db.go +++ b/waddrmgr/db.go @@ -2060,13 +2060,27 @@ func FetchBirthdayBlock(ns walletdb.ReadBucket) (BlockStamp, error) { return block, nil } -// putBirthdayBlock stores the provided birthday block to the database. +// DeleteBirthdayBlock removes the birthday block from the database. +// +// NOTE: This does not alter the birthday block verification state. +func DeleteBirthdayBlock(ns walletdb.ReadWriteBucket) error { + bucket := ns.NestedReadWriteBucket(syncBucketName) + if err := bucket.Delete(birthdayBlockName); err != nil { + str := "failed to remove birthday block" + return managerError(ErrDatabase, str, err) + } + return nil +} + +// PutBirthdayBlock stores the provided birthday block to the database. // // The block is serialized as follows: // [0:4] block height // [4:36] block hash // [36:44] block timestamp -func putBirthdayBlock(ns walletdb.ReadWriteBucket, block BlockStamp) error { +// +// NOTE: This does not alter the birthday block verification state. +func PutBirthdayBlock(ns walletdb.ReadWriteBucket, block BlockStamp) error { var birthdayBlock [44]byte binary.BigEndian.PutUint32(birthdayBlock[:4], uint32(block.Height)) copy(birthdayBlock[4:36], block.Hash[:]) diff --git a/waddrmgr/migrations.go b/waddrmgr/migrations.go index bf73c63..95e1f98 100644 --- a/waddrmgr/migrations.go +++ b/waddrmgr/migrations.go @@ -354,7 +354,7 @@ func populateBirthdayBlock(ns walletdb.ReadWriteBucket) error { // NOTE: The timestamp of the birthday block isn't set since we do not // store each block's timestamp. - return putBirthdayBlock(ns, BlockStamp{ + return PutBirthdayBlock(ns, BlockStamp{ Height: birthdayHeight, Hash: *birthdayHash, }) diff --git a/waddrmgr/migrations_test.go b/waddrmgr/migrations_test.go index 9e8a870..92696c0 100644 --- a/waddrmgr/migrations_test.go +++ b/waddrmgr/migrations_test.go @@ -247,7 +247,7 @@ func TestMigrationResetSyncedBlockToBirthday(t *testing.T) { Hash: *birthdayHash, Height: birthdayHeight, } - return putBirthdayBlock(ns, birthdayBlock) + return PutBirthdayBlock(ns, birthdayBlock) } afterMigration := func(ns walletdb.ReadWriteBucket) error { diff --git a/waddrmgr/sync.go b/waddrmgr/sync.go index 1163c6f..3472ddb 100644 --- a/waddrmgr/sync.go +++ b/waddrmgr/sync.go @@ -128,7 +128,7 @@ func (m *Manager) BirthdayBlock(ns walletdb.ReadBucket) (BlockStamp, bool, error func (m *Manager) SetBirthdayBlock(ns walletdb.ReadWriteBucket, block BlockStamp, verified bool) error { - if err := putBirthdayBlock(ns, block); err != nil { + if err := PutBirthdayBlock(ns, block); err != nil { return err } return putBirthdayBlockVerification(ns, verified)