wallet/wallet: use new migration logic for waddrmgr and wtxmgr

In this commit, we modify the wallet to use the new migration logic
provided by the recently introduced migration package. Additionally,
we'll also perform all of our upgrades within the same database
transaction to guarantee fault-tolerance of the wallet.
This commit is contained in:
Wilmer Paulino 2018-11-02 18:43:15 -07:00
parent c523ccd192
commit 69cb45e3e7
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F

View file

@ -23,8 +23,6 @@ import (
"github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
"github.com/btcsuite/btcwallet/chain" "github.com/btcsuite/btcwallet/chain"
@ -32,7 +30,9 @@ import (
"github.com/btcsuite/btcwallet/wallet/txauthor" "github.com/btcsuite/btcwallet/wallet/txauthor"
"github.com/btcsuite/btcwallet/wallet/txrules" "github.com/btcsuite/btcwallet/wallet/txrules"
"github.com/btcsuite/btcwallet/walletdb" "github.com/btcsuite/btcwallet/walletdb"
"github.com/btcsuite/btcwallet/walletdb/migration"
"github.com/btcsuite/btcwallet/wtxmgr" "github.com/btcsuite/btcwallet/wtxmgr"
"github.com/davecgh/go-spew/spew"
) )
const ( const (
@ -3375,58 +3375,49 @@ func Create(db walletdb.DB, pubPass, privPass, seed []byte, params *chaincfg.Par
func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks, func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
params *chaincfg.Params, recoveryWindow uint32) (*Wallet, error) { params *chaincfg.Params, recoveryWindow uint32) (*Wallet, error) {
err := walletdb.View(db, func(tx walletdb.ReadTx) error { var (
waddrmgrBucket := tx.ReadBucket(waddrmgrNamespaceKey) addrMgr *waddrmgr.Manager
if waddrmgrBucket == nil { txMgr *wtxmgr.Store
)
// Before attempting to open the wallet, we'll check if there are any
// database upgrades for us to proceed. We'll also create our references
// to the address and transaction managers, as they are backed by the
// database.
err := walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
addrMgrBucket := tx.ReadWriteBucket(waddrmgrNamespaceKey)
if addrMgrBucket == nil {
return errors.New("missing address manager namespace") return errors.New("missing address manager namespace")
} }
wtxmgrBucket := tx.ReadBucket(wtxmgrNamespaceKey) txMgrBucket := tx.ReadWriteBucket(wtxmgrNamespaceKey)
if wtxmgrBucket == nil { if txMgrBucket == nil {
return errors.New("missing transaction manager namespace") return errors.New("missing transaction manager namespace")
} }
addrMgrUpgrader := waddrmgr.NewMigrationManager(addrMgrBucket)
txMgrUpgrader := wtxmgr.NewMigrationManager(txMgrBucket)
err := migration.Upgrade(txMgrUpgrader, addrMgrUpgrader)
if err != nil {
return err
}
addrMgr, err = waddrmgr.Open(addrMgrBucket, pubPass, params)
if err != nil {
return err
}
txMgr, err = wtxmgr.Open(txMgrBucket, params)
if err != nil {
return err
}
return nil return nil
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Perform upgrades as necessary. Each upgrade is done under its own
// transaction, which is managed by each package itself, so the entire
// DB is passed instead of passing already opened write transaction.
//
// This will need to change later when upgrades in one package depend on
// data in another (such as removing chain synchronization from address
// manager).
err = waddrmgr.DoUpgrades(db, waddrmgrNamespaceKey, pubPass, params, cbs)
if err != nil {
return nil, err
}
err = wtxmgr.DoUpgrades(db, wtxmgrNamespaceKey)
if err != nil {
return nil, err
}
// Open database abstraction instances
var (
addrMgr *waddrmgr.Manager
txMgr *wtxmgr.Store
)
err = walletdb.View(db, func(tx walletdb.ReadTx) error {
addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey)
txmgrNs := tx.ReadBucket(wtxmgrNamespaceKey)
var err error
addrMgr, err = waddrmgr.Open(addrmgrNs, pubPass, params)
if err != nil {
return err
}
txMgr, err = wtxmgr.Open(txmgrNs, params)
return err
})
if err != nil {
return nil, err
}
log.Infof("Opened wallet") // TODO: log balance? last sync height? log.Infof("Opened wallet") // TODO: log balance? last sync height?
w := &Wallet{ w := &Wallet{
publicPassphrase: pubPass, publicPassphrase: pubPass,
db: db, db: db,
@ -3449,9 +3440,11 @@ func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
chainParams: params, chainParams: params,
quit: make(chan struct{}), quit: make(chan struct{}),
} }
w.NtfnServer = newNotificationServer(w) w.NtfnServer = newNotificationServer(w)
w.TxStore.NotifyUnspent = func(hash *chainhash.Hash, index uint32) { w.TxStore.NotifyUnspent = func(hash *chainhash.Hash, index uint32) {
w.NtfnServer.notifyUnspentOutput(0, hash, index) w.NtfnServer.notifyUnspentOutput(0, hash, index)
} }
return w, nil return w, nil
} }