4656a00705
This changes the database access APIs and each of the "manager" packages (waddrmgr/wstakemgr) so that transactions are opened (only) by the wallet package and the namespace buckets that each manager expects to operate on are passed in as parameters. This helps improve the atomicity situation as it means that many calls to these APIs can be grouped together into a single database transaction. This change does not attempt to completely fix the "half-processed" block problem. Mined transactions are still added to the wallet database under their own database transaction as this is how they are notified by the consensus JSON-RPC server (as loose transactions, without the rest of the block that contains them). It will make updating to a fixed notification model significantly easier, as the same "manager" APIs can still be used, but grouped into a single atomic transaction.
115 lines
2.1 KiB
Go
115 lines
2.1 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/walletdb"
|
|
_ "github.com/btcsuite/btcwallet/walletdb/bdb"
|
|
"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)
|
|
}
|
|
}
|
|
|
|
// Namespace keys.
|
|
var (
|
|
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 wtxmgr namespace")
|
|
err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
|
return tx.DeleteTopLevelBucket(wtxmgrNamespace)
|
|
})
|
|
if err != nil && err != walletdb.ErrBucketNotFound {
|
|
fmt.Println("Failed to drop namespace:", err)
|
|
return 1
|
|
}
|
|
|
|
return 0
|
|
}
|