177e31c0b3
In this commit, we modify the dropwtxmgr tool to force a rescan upon restart from the wallet's birthday block, rather than the chain's genesis block. We can safely do this as we expect that no on-chain events relevant to the wallet should happen before this block. For older wallets which do not have their birthday block set, the rescan should start from the genesis block.
146 lines
2.8 KiB
Go
146 lines
2.8 KiB
Go
// Copyright (c) 2015-2016 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
|
"github.com/btcsuite/btcwallet/walletdb"
|
|
_ "github.com/btcsuite/btcwallet/walletdb/bdb"
|
|
"github.com/btcsuite/btcwallet/wtxmgr"
|
|
"github.com/jessevdk/go-flags"
|
|
)
|
|
|
|
const defaultNet = "mainnet"
|
|
|
|
var datadir = btcutil.AppDataDir("btcwallet", false)
|
|
|
|
// Flags.
|
|
var opts = struct {
|
|
Force bool `short:"f" description:"Force removal without prompt"`
|
|
DbPath string `long:"db" description:"Path to wallet database"`
|
|
}{
|
|
Force: false,
|
|
DbPath: filepath.Join(datadir, defaultNet, "wallet.db"),
|
|
}
|
|
|
|
func init() {
|
|
_, err := flags.Parse(&opts)
|
|
if err != nil {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
var (
|
|
// Namespace keys.
|
|
waddrmgrNamespace = []byte("waddrmgr")
|
|
wtxmgrNamespace = []byte("wtxmgr")
|
|
)
|
|
|
|
func yes(s string) bool {
|
|
switch s {
|
|
case "y", "Y", "yes", "Yes":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func no(s string) bool {
|
|
switch s {
|
|
case "n", "N", "no", "No":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
os.Exit(mainInt())
|
|
}
|
|
|
|
func mainInt() int {
|
|
fmt.Println("Database path:", opts.DbPath)
|
|
_, err := os.Stat(opts.DbPath)
|
|
if os.IsNotExist(err) {
|
|
fmt.Println("Database file does not exist")
|
|
return 1
|
|
}
|
|
|
|
for !opts.Force {
|
|
fmt.Print("Drop all btcwallet transaction history? [y/N] ")
|
|
|
|
scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
|
|
if !scanner.Scan() {
|
|
// Exit on EOF.
|
|
return 0
|
|
}
|
|
err := scanner.Err()
|
|
if err != nil {
|
|
fmt.Println()
|
|
fmt.Println(err)
|
|
return 1
|
|
}
|
|
resp := scanner.Text()
|
|
if yes(resp) {
|
|
break
|
|
}
|
|
if no(resp) || resp == "" {
|
|
return 0
|
|
}
|
|
|
|
fmt.Println("Enter yes or no.")
|
|
}
|
|
|
|
db, err := walletdb.Open("bdb", opts.DbPath)
|
|
if err != nil {
|
|
fmt.Println("Failed to open database:", err)
|
|
return 1
|
|
}
|
|
defer db.Close()
|
|
|
|
fmt.Println("Dropping btcwallet transaction history")
|
|
|
|
err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
|
err := tx.DeleteTopLevelBucket(wtxmgrNamespace)
|
|
if err != nil && err != walletdb.ErrBucketNotFound {
|
|
return err
|
|
}
|
|
ns, err := tx.CreateTopLevelBucket(wtxmgrNamespace)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = wtxmgr.Create(ns)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ns = tx.ReadWriteBucket(waddrmgrNamespace)
|
|
birthdayBlock, err := waddrmgr.FetchBirthdayBlock(ns)
|
|
if err != nil {
|
|
fmt.Println("Wallet does not have a birthday block " +
|
|
"set, falling back to rescan from genesis")
|
|
|
|
startBlock, err := waddrmgr.FetchStartBlock(ns)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return waddrmgr.PutSyncedTo(ns, startBlock)
|
|
}
|
|
|
|
return waddrmgr.PutSyncedTo(ns, &birthdayBlock)
|
|
})
|
|
if err != nil {
|
|
fmt.Println("Failed to drop and re-create namespace:", err)
|
|
return 1
|
|
}
|
|
|
|
return 0
|
|
}
|