Skip to content

Commit

Permalink
Integrate walletdb and updated waddrmgr.
Browse files Browse the repository at this point in the history
This commit converts the wallet to use the new walletdb package as well as
the updated version of the secure hierarchical deterministic wallet
address manager which uses the new namespace feature provided by waleltdb.
  • Loading branch information
davecgh committed Nov 10, 2014
1 parent 8f1cd24 commit 77fd5f1
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 84 deletions.
46 changes: 11 additions & 35 deletions btcwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ func walletMain() error {
}()
}

// Load the wallet database. It must have been created with the
// --create option already or this will return an appropriate error.
wallet, err := openWallet()
if err != nil {
log.Errorf("%v", err)
return err
}
defer wallet.db.Close()

// Create and start HTTP server to serve wallet client connections.
// This will be updated with the wallet and chain server RPC client
// created below after each is created.
Expand All @@ -78,6 +87,7 @@ func walletMain() error {
return err
}
server.Start()
server.SetWallet(wallet)

// Shutdown the server if an interrupt signal is received.
addInterruptHandler(server.Stop)
Expand Down Expand Up @@ -116,50 +126,16 @@ func walletMain() error {
chainSvrChan <- rpcc
}()

// Create a channel to report unrecoverable errors during the loading of
// the wallet files. These may include OS file handling errors or
// issues deserializing the wallet files, but does not include missing
// wallet files (as that must be handled by creating a new wallet).
walletOpenErrors := make(chan error)

go func() {
defer close(walletOpenErrors)

// Open wallet structures from disk.
w, err := openWallet()
if err != nil {
if os.IsNotExist(err) {
// If the manager file is missing, notify the
// server that generating new wallets is ok.
server.SetWallet(nil)
return
} else {
// If the manager file exists but another error
// was encountered, we cannot continue.
log.Errorf("Cannot load wallet files: %v", err)
walletOpenErrors <- err
return
}
}

server.SetWallet(w)

// Start wallet goroutines and handle RPC client notifications
// if the chain server connection was opened.
select {
case chainSvr := <-chainSvrChan:
w.Start(chainSvr)
wallet.Start(chainSvr)
case <-server.quit:
}
}()

// Check for unrecoverable errors during the wallet startup, and return
// the error, if any.
err, ok := <-walletOpenErrors
if ok {
return err
}

// Wait for the server to shutdown either due to a stop RPC request
// or an interrupt.
server.WaitForShutdown()
Expand Down
28 changes: 14 additions & 14 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ import (
)

const (
defaultCAFilename = "btcd.cert"
defaultConfigFilename = "btcwallet.conf"
defaultBtcNet = btcwire.TestNet3
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "btcwallet.log"
defaultDisallowFree = false
defaultRPCMaxClients = 10
defaultRPCMaxWebsockets = 25
addrMgrName = "addrmgr.bin"
addrMgrWatchingOnlyName = "addrmgrwo.bin"
defaultCAFilename = "btcd.cert"
defaultConfigFilename = "btcwallet.conf"
defaultBtcNet = btcwire.TestNet3
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "btcwallet.log"
defaultDisallowFree = false
defaultRPCMaxClients = 10
defaultRPCMaxWebsockets = 25
walletDbName = "wallet.db"
walletDbWatchingOnlyName = "wowallet.db"
)

var (
Expand Down Expand Up @@ -364,11 +364,11 @@ func loadConfig() (*config, []string, error) {

// Ensure the wallet exists or create it when the create flag is set.
netDir := networkDir(cfg.DataDir, activeNet.Params)
mgrPath := filepath.Join(netDir, addrMgrName)
dbPath := filepath.Join(netDir, walletDbName)
if cfg.Create {
// Error if the create flag is set and the wallet already
// exists.
if fileExists(mgrPath) {
if fileExists(dbPath) {
err := fmt.Errorf("cannot create wallet: file already exists")
fmt.Fprintln(os.Stderr, err)
return nil, nil, err
Expand All @@ -389,7 +389,7 @@ func loadConfig() (*config, []string, error) {
// Created successfully, so exit now with success.
os.Exit(0)

} else if !fileExists(mgrPath) {
} else if !fileExists(dbPath) {
var err error
keystorePath := filepath.Join(netDir, keystore.Filename)
if !fileExists(keystorePath) {
Expand Down
17 changes: 14 additions & 3 deletions createtx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/conformal/btcutil/hdkeychain"
"github.com/conformal/btcwallet/txstore"
"github.com/conformal/btcwallet/waddrmgr"
"github.com/conformal/btcwallet/walletdb"
_ "github.com/conformal/btcwallet/walletdb/bdb"
"github.com/conformal/btcwire"
)

Expand Down Expand Up @@ -163,8 +165,17 @@ func checkOutputsMatch(t *testing.T, msgtx *btcwire.MsgTx, expected map[string]b

// newManager creates a new waddrmgr and imports the given privKey into it.
func newManager(t *testing.T, privKeys []string, bs *waddrmgr.BlockStamp) *waddrmgr.Manager {
dbPath := filepath.Join(os.TempDir(), "waddrmgr.bin")
dbPath := filepath.Join(os.TempDir(), "wallet.bin")
os.Remove(dbPath)
db, err := walletdb.Create("bdb", dbPath)
if err != nil {
t.Fatal(err)
}

namespace, err := db.Namespace(waddrmgrNamespaceKey)
if err != nil {
t.Fatal(err)
}

seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen)
if err != nil {
Expand All @@ -173,8 +184,8 @@ func newManager(t *testing.T, privKeys []string, bs *waddrmgr.BlockStamp) *waddr

pubPassphrase := []byte("pub")
privPassphrase := []byte("priv")
mgr, err := waddrmgr.Create(dbPath, seed, pubPassphrase, privPassphrase,
activeNet.Params, fastScrypt)
mgr, err := waddrmgr.Create(namespace, seed, pubPassphrase,
privPassphrase, activeNet.Params, fastScrypt)
if err != nil {
t.Fatal(err)
}
Expand Down
11 changes: 4 additions & 7 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1661,12 +1661,7 @@ func ExportWatchingWallet(w *Wallet, chainSvr *chain.Client, icmd btcjson.Cmd) (
return nil, err
}

wa, err := w.ExportWatchingWallet()
if err != nil {
return nil, err
}

return wa.exportBase64()
return w.ExportWatchingWallet()
}

// GetAddressesByAccount handles a getaddressesbyaccount request by returning
Expand Down Expand Up @@ -1718,7 +1713,9 @@ func GetInfo(w *Wallet, chainSvr *chain.Client, icmd btcjson.Cmd) (interface{},
return nil, err
}

info.WalletVersion = int32(waddrmgr.LatestDbVersion)
// TODO(davec): This should probably have a database version as opposed
// to using the manager version.
info.WalletVersion = int32(waddrmgr.LatestMgrVersion)
info.Balance = bal.ToUnit(btcutil.AmountBTC)
// Keypool times are not tracked. set to current time.
info.KeypoolOldest = time.Now().Unix()
Expand Down
7 changes: 5 additions & 2 deletions waddrmgr/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ var (
privPassphrase = []byte("81lUHXnOMZ@?XXd7O9xyDIWIbXX-lj")
pubPassphrase2 = []byte("-0NV4P~VSJBWbunw}%<Z]fuGpbN[ZI")
privPassphrase2 = []byte("~{<]08%6!-?2s<$(8$8:f(5[4/!/{Y")

// waddrmgrNamespaceKey is the namespace key for the waddrmgr package.
waddrmgrNamespaceKey = []byte("waddrmgrNamespace")
)

// checkManagerError ensures the passed error is a ManagerError with an error
Expand Down Expand Up @@ -76,7 +79,7 @@ func createDbNamespace(dbPath string) (walletdb.Db, walletdb.Namespace, error) {
return nil, nil, err
}

namespace, err := db.Namespace([]byte("waddrmgr"))
namespace, err := db.Namespace(waddrmgrNamespaceKey)
if err != nil {
db.Close()
return nil, nil, err
Expand All @@ -93,7 +96,7 @@ func openDbNamespace(dbPath string) (walletdb.Db, walletdb.Namespace, error) {
return nil, nil, err
}

namespace, err := db.Namespace([]byte("waddrmgr"))
namespace, err := db.Namespace(waddrmgrNamespaceKey)
if err != nil {
db.Close()
return nil, nil, err
Expand Down
2 changes: 1 addition & 1 deletion waddrmgr/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ func (m *Manager) ChangePassphrase(oldPassphrase, newPassphrase []byte, private
//
// Executing this function on a manager that is already watching-only will have
// no effect.
func (m *Manager) ConvertToWatchingOnly(pubPassphrase []byte) error {
func (m *Manager) ConvertToWatchingOnly() error {
m.mtx.Lock()
defer m.mtx.Unlock()

Expand Down
Loading

0 comments on commit 77fd5f1

Please sign in to comment.