// setupManager creates a new address manager and returns a teardown function // that should be invoked to ensure it is closed and removed upon completion. func setupManager(t *testing.T) (tearDownFunc func(), mgr *waddrmgr.Manager) { t.Parallel() // Create a new manager in a temp directory. dirName, err := ioutil.TempDir("", "mgrtest") if err != nil { t.Fatalf("Failed to create db temp dir: %v", err) } dbPath := filepath.Join(dirName, "mgrtest.db") db, namespace, err := createDbNamespace(dbPath) if err != nil { _ = os.RemoveAll(dirName) t.Fatalf("createDbNamespace: unexpected error: %v", err) } err = waddrmgr.Create(namespace, seed, pubPassphrase, privPassphrase, &chaincfg.MainNetParams, fastScrypt) if err == nil { mgr, err = waddrmgr.Open(namespace, pubPassphrase, &chaincfg.MainNetParams, nil) } if err != nil { db.Close() _ = os.RemoveAll(dirName) t.Fatalf("Failed to create Manager: %v", err) } tearDownFunc = func() { mgr.Close() db.Close() _ = os.RemoveAll(dirName) } return tearDownFunc, mgr }
func createWaddrmgr(ns walletdb.Namespace, params *chaincfg.Params) (*waddrmgr.Manager, error) { err := waddrmgr.Create(ns, seed, pubPassphrase, privPassphrase, params, fastScrypt) if err != nil { return nil, err } return waddrmgr.Open(ns, pubPassphrase, params, nil) }
// ExportWatchingWallet returns a watching-only version of the wallet serialized // database as a base64-encoded string. func (w *Wallet) ExportWatchingWallet(pubPass string) (string, error) { tmpDir, err := ioutil.TempDir("", "btcwallet") if err != nil { return "", err } defer os.RemoveAll(tmpDir) // Create a new file and write a copy of the current database into it. woDbPath := filepath.Join(tmpDir, walletDbWatchingOnlyName) fi, err := os.OpenFile(woDbPath, os.O_CREATE|os.O_RDWR, 0600) if err != nil { return "", err } if err := w.db.Copy(fi); err != nil { fi.Close() return "", err } fi.Close() defer os.Remove(woDbPath) // Open the new database, get the address manager namespace, and open // it. woDb, err := walletdb.Open("bdb", woDbPath) if err != nil { _ = os.Remove(woDbPath) return "", err } defer woDb.Close() namespace, err := woDb.Namespace(waddrmgrNamespaceKey) if err != nil { return "", err } woMgr, err := waddrmgr.Open(namespace, []byte(pubPass), w.chainParams, nil) if err != nil { return "", err } defer woMgr.Close() // Convert the namespace to watching only if needed. if err := woMgr.ConvertToWatchingOnly(); err != nil { // Only return the error is it's not because it's already // watching-only. When it is already watching-only, the code // just falls through to the export below. if !waddrmgr.IsError(err, waddrmgr.ErrWatchingOnly) { return "", err } } // Export the watching only wallet's serialized data. woWallet := *w woWallet.db = woDb woWallet.Manager = woMgr return woWallet.exportBase64() }
// TstCreatePool creates a Pool on a fresh walletdb and returns it. It also // returns the pool's waddrmgr.Manager (which uses the same walletdb, but with a // different namespace) as a convenience, and a teardown function that closes // the Manager and removes the directory used to store the database. func TstCreatePool(t *testing.T) (tearDownFunc func(), mgr *waddrmgr.Manager, pool *Pool) { // This should be moved somewhere else eventually as not all of our tests // call this function, but right now the only option would be to have the // t.Parallel() call in each of our tests. t.Parallel() // Create a new wallet DB and addr manager. dir, err := ioutil.TempDir("", "pool_test") if err != nil { t.Fatalf("Failed to create db dir: %v", err) } db, err := walletdb.Create("bdb", filepath.Join(dir, "wallet.db")) if err != nil { t.Fatalf("Failed to create wallet DB: %v", err) } mgrNamespace, err := db.Namespace([]byte("waddrmgr")) if err != nil { t.Fatalf("Failed to create addr manager DB namespace: %v", err) } var fastScrypt = &waddrmgr.ScryptOptions{N: 16, R: 8, P: 1} err = waddrmgr.Create(mgrNamespace, seed, pubPassphrase, privPassphrase, &chaincfg.MainNetParams, fastScrypt) if err == nil { mgr, err = waddrmgr.Open(mgrNamespace, pubPassphrase, &chaincfg.MainNetParams, nil) } if err != nil { t.Fatalf("Failed to create addr manager: %v", err) } // Create a walletdb for votingpools. vpNamespace, err := db.Namespace([]byte("votingpool")) if err != nil { t.Fatalf("Failed to create VotingPool DB namespace: %v", err) } pool, err = Create(vpNamespace, mgr, []byte{0x00}) if err != nil { t.Fatalf("Voting Pool creation failed: %v", err) } tearDownFunc = func() { db.Close() mgr.Close() os.RemoveAll(dir) } return tearDownFunc, mgr, pool }
// Open loads an already-created wallet from the passed database and namespaces. func Open(pubPass []byte, params *chaincfg.Params, db walletdb.DB, waddrmgrNS, wtxmgrNS walletdb.Namespace, cbs *waddrmgr.OpenCallbacks) (*Wallet, error) { addrMgr, err := waddrmgr.Open(waddrmgrNS, pubPass, params, cbs) if err != nil { return nil, err } txMgr, err := wtxmgr.Open(wtxmgrNS) if err != nil { if !wtxmgr.IsNoExists(err) { return nil, err } log.Info("No recorded transaction history -- needs full rescan") err = addrMgr.SetSyncedTo(nil) if err != nil { return nil, err } txMgr, err = wtxmgr.Create(wtxmgrNS) if err != nil { return nil, err } } log.Infof("Opened wallet") // TODO: log balance? last sync height? w := &Wallet{ db: db, Manager: addrMgr, TxStore: txMgr, lockedOutpoints: map[wire.OutPoint]struct{}{}, FeeIncrement: defaultFeeIncrement, rescanAddJob: make(chan *RescanJob), rescanBatch: make(chan *rescanBatch), rescanNotifications: make(chan interface{}), rescanProgress: make(chan *RescanProgressMsg), rescanFinished: make(chan *RescanFinishedMsg), createTxRequests: make(chan createTxRequest), unlockRequests: make(chan unlockRequest), lockRequests: make(chan struct{}), holdUnlockRequests: make(chan chan HeldUnlock), lockState: make(chan bool), changePassphrase: make(chan changePassphraseRequest), chainParams: params, quit: make(chan struct{}), } return w, nil }