示例#1
0
// 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
}
示例#2
0
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)
}
示例#3
0
// 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()
}
示例#4
0
// 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
}
示例#5
0
// 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
}