From 28c804ccc804f8b35b3ce111d43d19b0b72d4850 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Tue, 11 Aug 2020 20:15:46 +0800 Subject: [PATCH 1/7] bdb: add timeout option in bbolt --- walletdb/bdb/README.md | 11 ++-- walletdb/bdb/db.go | 6 ++- walletdb/bdb/doc.go | 11 ++-- walletdb/bdb/driver.go | 33 ++++++++---- walletdb/bdb/driver_test.go | 99 +++++++++++++++++++++++++++++----- walletdb/bdb/interface_test.go | 2 +- 6 files changed, 126 insertions(+), 36 deletions(-) diff --git a/walletdb/bdb/README.md b/walletdb/bdb/README.md index 67ae35f..0d7db3f 100644 --- a/walletdb/bdb/README.md +++ b/walletdb/bdb/README.md @@ -10,19 +10,20 @@ datastore. Package bdb is licensed under the copyfree ISC license. ## Usage This package is only a driver to the walletdb package and provides the database -type of "bdb". The only parameters the Open and Create functions take is the -database path as a string, and an option for the database to not sync its -freelist to disk as a bool: +type of "bdb". The only parameters the Open and Create functions take are the +database path as a string, an option for the database to not sync its freelist +to disk as a bool, and a timeout value for opening the database as a +time.Duration: ```Go -db, err := walletdb.Open("bdb", "path/to/database.db", true) +db, err := walletdb.Open("bdb", "path/to/database.db", true, 60*time.Second) if err != nil { // Handle error } ``` ```Go -db, err := walletdb.Create("bdb", "path/to/database.db", true) +db, err := walletdb.Create("bdb", "path/to/database.db", true, 60*time.Second) if err != nil { // Handle error } diff --git a/walletdb/bdb/db.go b/walletdb/bdb/db.go index 2408fad..e6a782f 100644 --- a/walletdb/bdb/db.go +++ b/walletdb/bdb/db.go @@ -7,6 +7,7 @@ package bdb import ( "io" "os" + "time" "github.com/btcsuite/btcwallet/walletdb" "go.etcd.io/bbolt" @@ -367,7 +368,9 @@ func fileExists(name string) bool { // openDB opens the database at the provided path. walletdb.ErrDbDoesNotExist // is returned if the database doesn't exist and the create flag is not set. -func openDB(dbPath string, noFreelistSync bool, create bool) (walletdb.DB, error) { +func openDB(dbPath string, noFreelistSync bool, + create bool, timeout time.Duration) (walletdb.DB, error) { + if !create && !fileExists(dbPath) { return nil, walletdb.ErrDbDoesNotExist } @@ -377,6 +380,7 @@ func openDB(dbPath string, noFreelistSync bool, create bool) (walletdb.DB, error options := &bbolt.Options{ NoFreelistSync: noFreelistSync, FreelistType: bbolt.FreelistMapType, + Timeout: timeout, } boltDB, err := bbolt.Open(dbPath, 0600, options) diff --git a/walletdb/bdb/doc.go b/walletdb/bdb/doc.go index 6e5087a..af8ffd4 100644 --- a/walletdb/bdb/doc.go +++ b/walletdb/bdb/doc.go @@ -9,16 +9,17 @@ datastore. Usage This package is only a driver to the walletdb package and provides the database -type of "bdb". The only parameters the Open and Create functions take is the -database path as a string, and an option for the database to not sync its -freelist to disk as a bool: +type of "bdb". The only parameters the Open and Create functions take are the +database path as a string, an option for the database to not sync its freelist +to disk as a bool, and a timeout value for opening the database as a +time.Duration: - db, err := walletdb.Open("bdb", "path/to/database.db", true) + db, err := walletdb.Open("bdb", "path/to/database.db", true, 60*time.Second) if err != nil { // Handle error } - db, err := walletdb.Create("bdb", "path/to/database.db", true) + db, err := walletdb.Create("bdb", "path/to/database.db", true, 60*time.Second) if err != nil { // Handle error } diff --git a/walletdb/bdb/driver.go b/walletdb/bdb/driver.go index 78442fd..da4ad26 100644 --- a/walletdb/bdb/driver.go +++ b/walletdb/bdb/driver.go @@ -6,6 +6,7 @@ package bdb import ( "fmt" + "time" "github.com/btcsuite/btcwallet/walletdb" ) @@ -15,50 +16,60 @@ const ( ) // parseArgs parses the arguments from the walletdb Open/Create methods. -func parseArgs(funcName string, args ...interface{}) (string, bool, error) { - if len(args) != 2 { - return "", false, fmt.Errorf("invalid arguments to %s.%s -- "+ - "expected database path and no-freelist-sync option", +func parseArgs(funcName string, + args ...interface{}) (string, bool, time.Duration, error) { + + if len(args) != 3 { + return "", false, 0, fmt.Errorf("invalid arguments to %s.%s "+ + "-- expected database path, no-freelist-sync and "+ + "timeout option", dbType, funcName) } dbPath, ok := args[0].(string) if !ok { - return "", false, fmt.Errorf("first argument to %s.%s is "+ + return "", false, 0, fmt.Errorf("first argument to %s.%s is "+ "invalid -- expected database path string", dbType, funcName) } noFreelistSync, ok := args[1].(bool) if !ok { - return "", false, fmt.Errorf("second argument to %s.%s is "+ + return "", false, 0, fmt.Errorf("second argument to %s.%s is "+ "invalid -- expected no-freelist-sync bool", dbType, funcName) } - return dbPath, noFreelistSync, nil + timeout, ok := args[2].(time.Duration) + if !ok { + return "", false, 0, fmt.Errorf("third argument to %s.%s is "+ + "invalid -- expected timeout time.Duration", dbType, + funcName) + } + + return dbPath, noFreelistSync, timeout, nil } // openDBDriver is the callback provided during driver registration that opens // an existing database for use. func openDBDriver(args ...interface{}) (walletdb.DB, error) { - dbPath, noFreelistSync, err := parseArgs("Open", args...) + dbPath, noFreelistSync, timeout, err := parseArgs("Open", args...) if err != nil { return nil, err } - return openDB(dbPath, noFreelistSync, false) + return openDB(dbPath, noFreelistSync, false, timeout) } // createDBDriver is the callback provided during driver registration that // creates, initializes, and opens a database for use. func createDBDriver(args ...interface{}) (walletdb.DB, error) { - dbPath, noFreelistSync, err := parseArgs("Create", args...) + dbPath, noFreelistSync, timeout, err := parseArgs("Create", args...) if err != nil { return nil, err } - return openDB(dbPath, noFreelistSync, true) + return openDB(dbPath, noFreelistSync, true, timeout) } func init() { diff --git a/walletdb/bdb/driver_test.go b/walletdb/bdb/driver_test.go index aa4d872..df88d49 100644 --- a/walletdb/bdb/driver_test.go +++ b/walletdb/bdb/driver_test.go @@ -11,13 +11,19 @@ import ( "path/filepath" "reflect" "testing" + "time" "github.com/btcsuite/btcwallet/walletdb" _ "github.com/btcsuite/btcwallet/walletdb/bdb" ) -// dbType is the database type name for this driver. -const dbType = "bdb" +const ( + // dbType is the database type name for this driver. + dbType = "bdb" + + // defaultDBTimeout is the value of db timeout for testing. + defaultDBTimeout = 10 * time.Second +) // TestCreateOpenFail ensures that errors related to creating and opening a // database are handled properly. @@ -25,7 +31,10 @@ func TestCreateOpenFail(t *testing.T) { // Ensure that attempting to open a database that doesn't exist returns // the expected error. wantErr := walletdb.ErrDbDoesNotExist - if _, err := walletdb.Open(dbType, "noexist.db", true); err != wantErr { + if _, err := walletdb.Open( + dbType, "noexist.db", true, defaultDBTimeout, + ); err != wantErr { + t.Errorf("Open: did not receive expected error - got %v, "+ "want %v", err, wantErr) return @@ -34,8 +43,11 @@ func TestCreateOpenFail(t *testing.T) { // Ensure that attempting to open a database with the wrong number of // parameters returns the expected error. wantErr = fmt.Errorf("invalid arguments to %s.Open -- expected "+ - "database path and no-freelist-sync option", dbType) - if _, err := walletdb.Open(dbType, 1, 2, 3); err.Error() != wantErr.Error() { + "database path, no-freelist-sync and timeout option", dbType) + if _, err := walletdb.Open( + dbType, 1, 2, 3, 4, + ); err.Error() != wantErr.Error() { + t.Errorf("Open: did not receive expected error - got %v, "+ "want %v", err, wantErr) return @@ -45,7 +57,36 @@ func TestCreateOpenFail(t *testing.T) { // the first parameter returns the expected error. wantErr = fmt.Errorf("first argument to %s.Open is invalid -- "+ "expected database path string", dbType) - if _, err := walletdb.Open(dbType, 1, true); err.Error() != wantErr.Error() { + if _, err := walletdb.Open( + dbType, 1, true, defaultDBTimeout, + ); err.Error() != wantErr.Error() { + + t.Errorf("Open: did not receive expected error - got %v, "+ + "want %v", err, wantErr) + return + } + + // Ensure that attempting to open a database with an invalid type for + // the second parameter returns the expected error. + wantErr = fmt.Errorf("second argument to %s.Open is invalid -- "+ + "expected no-freelist-sync bool", dbType) + if _, err := walletdb.Open( + dbType, "noexist.db", 1, defaultDBTimeout, + ); err.Error() != wantErr.Error() { + + t.Errorf("Open: did not receive expected error - got %v, "+ + "want %v", err, wantErr) + return + } + + // Ensure that attempting to open a database with an invalid type for + // the third parameter returns the expected error. + wantErr = fmt.Errorf("third argument to %s.Open is invalid -- "+ + "expected timeout time.Duration", dbType) + if _, err := walletdb.Open( + dbType, "noexist.db", true, 1, + ); err.Error() != wantErr.Error() { + t.Errorf("Open: did not receive expected error - got %v, "+ "want %v", err, wantErr) return @@ -54,18 +95,50 @@ func TestCreateOpenFail(t *testing.T) { // Ensure that attempting to create a database with the wrong number of // parameters returns the expected error. wantErr = fmt.Errorf("invalid arguments to %s.Create -- expected "+ - "database path and no-freelist-sync option", dbType) - if _, err := walletdb.Create(dbType, 1, 2, 3); err.Error() != wantErr.Error() { + "database path, no-freelist-sync and timeout option", dbType) + if _, err := walletdb.Create( + dbType, 1, 2, 3, 4, + ); err.Error() != wantErr.Error() { + t.Errorf("Create: did not receive expected error - got %v, "+ "want %v", err, wantErr) return } - // Ensure that attempting to open a database with an invalid type for + // Ensure that attempting to create a database with an invalid type for // the first parameter returns the expected error. wantErr = fmt.Errorf("first argument to %s.Create is invalid -- "+ "expected database path string", dbType) - if _, err := walletdb.Create(dbType, 1, true); err.Error() != wantErr.Error() { + if _, err := walletdb.Create( + dbType, 1, true, defaultDBTimeout, + ); err.Error() != wantErr.Error() { + + t.Errorf("Create: did not receive expected error - got %v, "+ + "want %v", err, wantErr) + return + } + + // Ensure that attempting to create a database with an invalid type for + // the second parameter returns the expected error. + wantErr = fmt.Errorf("second argument to %s.Create is invalid -- "+ + "expected no-freelist-sync bool", dbType) + if _, err := walletdb.Create( + dbType, "noexist.db", 1, defaultDBTimeout, + ); err.Error() != wantErr.Error() { + + t.Errorf("Create: did not receive expected error - got %v, "+ + "want %v", err, wantErr) + return + } + + // Ensure that attempting to create a database with an invalid type for + // the third parameter returns the expected error. + wantErr = fmt.Errorf("third argument to %s.Create is invalid -- "+ + "expected timeout time.Duration", dbType) + if _, err := walletdb.Create( + dbType, "noexist.db", true, 1, + ); err.Error() != wantErr.Error() { + t.Errorf("Create: did not receive expected error - got %v, "+ "want %v", err, wantErr) return @@ -81,7 +154,7 @@ func TestCreateOpenFail(t *testing.T) { defer os.Remove(tempDir) dbPath := filepath.Join(tempDir, "db") - db, err := walletdb.Create(dbType, dbPath, true) + db, err := walletdb.Create(dbType, dbPath, true, defaultDBTimeout) if err != nil { t.Errorf("Create: unexpected error: %v", err) return @@ -108,7 +181,7 @@ func TestPersistence(t *testing.T) { defer os.Remove(tempDir) dbPath := filepath.Join(tempDir, "db") - db, err := walletdb.Create(dbType, dbPath, true) + db, err := walletdb.Create(dbType, dbPath, true, defaultDBTimeout) if err != nil { t.Errorf("Failed to create test database (%s) %v", dbType, err) return @@ -144,7 +217,7 @@ func TestPersistence(t *testing.T) { // Close and reopen the database to ensure the values persist. db.Close() - db, err = walletdb.Open(dbType, dbPath, true) + db, err = walletdb.Open(dbType, dbPath, true, defaultDBTimeout) if err != nil { t.Errorf("Failed to open test database (%s) %v", dbType, err) return diff --git a/walletdb/bdb/interface_test.go b/walletdb/bdb/interface_test.go index 3755b1d..4bfddb0 100644 --- a/walletdb/bdb/interface_test.go +++ b/walletdb/bdb/interface_test.go @@ -32,5 +32,5 @@ func TestInterface(t *testing.T) { dbPath := filepath.Join(tempDir, "db") defer os.RemoveAll(dbPath) - walletdbtest.TestInterface(t, dbType, dbPath, true) + walletdbtest.TestInterface(t, dbType, dbPath, true, defaultDBTimeout) } From 08308c81eda04bdb4eeb833bc5b34101537db40d Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 12 Aug 2020 03:49:44 +0800 Subject: [PATCH 2/7] walletdb: update tests to use db timeout param --- walletdb/db_test.go | 7 ++++++- walletdb/example_test.go | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/walletdb/db_test.go b/walletdb/db_test.go index 30c4341..9e8760a 100644 --- a/walletdb/db_test.go +++ b/walletdb/db_test.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" "testing" + "time" "github.com/btcsuite/btcwallet/walletdb" _ "github.com/btcsuite/btcwallet/walletdb/bdb" @@ -21,6 +22,10 @@ var ( // bogus drivers for testing purposes while still allowing other tests // to easily iterate all supported drivers. ignoreDbTypes = map[string]bool{"createopenfail": true} + + // defaultDBTimeout specifies the timeout value when opening the wallet + // database. + defaultDBTimeout = 10 * time.Second ) // TestAddDuplicateDriver ensures that adding a duplicate driver does not @@ -64,7 +69,7 @@ func TestAddDuplicateDriver(t *testing.T) { defer os.Remove(tempDir) dbPath := filepath.Join(tempDir, "db") - db, err := walletdb.Create(dbType, dbPath, true) + db, err := walletdb.Create(dbType, dbPath, true, defaultDBTimeout) if err != nil { t.Errorf("failed to create database: %v", err) return diff --git a/walletdb/example_test.go b/walletdb/example_test.go index 4cb5134..c9640ab 100644 --- a/walletdb/example_test.go +++ b/walletdb/example_test.go @@ -28,7 +28,7 @@ func ExampleCreate() { // this, but it's done here in the example to ensure the example cleans // up after itself. dbPath := filepath.Join(os.TempDir(), "examplecreate.db") - db, err := walletdb.Create("bdb", dbPath, true) + db, err := walletdb.Create("bdb", dbPath, true, defaultDBTimeout) if err != nil { fmt.Println(err) return @@ -47,7 +47,7 @@ var exampleNum = 0 func exampleLoadDB() (walletdb.DB, func(), error) { dbName := fmt.Sprintf("exampleload%d.db", exampleNum) dbPath := filepath.Join(os.TempDir(), dbName) - db, err := walletdb.Create("bdb", dbPath, true) + db, err := walletdb.Create("bdb", dbPath, true, defaultDBTimeout) if err != nil { return nil, nil, err } @@ -111,7 +111,7 @@ func Example_basicUsage() { // this, but it's done here in the example to ensure the example cleans // up after itself. dbPath := filepath.Join(os.TempDir(), "exampleusage.db") - db, err := walletdb.Create("bdb", dbPath, true) + db, err := walletdb.Create("bdb", dbPath, true, defaultDBTimeout) if err != nil { fmt.Println(err) return From f6ea9d4d7b184845f7a8fe68c49f8dbc6270c409 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 12 Aug 2020 03:51:32 +0800 Subject: [PATCH 3/7] waddrmgr: update tests to use db timeout param --- waddrmgr/common_test.go | 8 ++++++-- waddrmgr/manager_test.go | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/waddrmgr/common_test.go b/waddrmgr/common_test.go index 20493fe..d14301e 100644 --- a/waddrmgr/common_test.go +++ b/waddrmgr/common_test.go @@ -200,6 +200,10 @@ var ( // expectedInternalAddrs is the list of expected internal addresses // generated from the seed expectedInternalAddrs = expectedAddrs[5:] + + // defaultDBTimeout specifies the timeout value when opening the wallet + // database. + defaultDBTimeout = 10 * time.Second ) // checkManagerError ensures the passed error is a ManagerError with an error @@ -238,7 +242,7 @@ func emptyDB(t *testing.T) (tearDownFunc func(), db walletdb.DB) { t.Fatalf("Failed to create db temp dir: %v", err) } dbPath := filepath.Join(dirName, "mgrtest.db") - db, err = walletdb.Create("bdb", dbPath, true) + db, err = walletdb.Create("bdb", dbPath, true, defaultDBTimeout) if err != nil { _ = os.RemoveAll(dirName) t.Fatalf("createDbNamespace: unexpected error: %v", err) @@ -259,7 +263,7 @@ func setupManager(t *testing.T) (tearDownFunc func(), db walletdb.DB, mgr *Manag t.Fatalf("Failed to create db temp dir: %v", err) } dbPath := filepath.Join(dirName, "mgrtest.db") - db, err = walletdb.Create("bdb", dbPath, true) + db, err = walletdb.Create("bdb", dbPath, true, defaultDBTimeout) if err != nil { _ = os.RemoveAll(dirName) t.Fatalf("createDbNamespace: unexpected error: %v", err) diff --git a/waddrmgr/manager_test.go b/waddrmgr/manager_test.go index 0db0a88..c4667ad 100644 --- a/waddrmgr/manager_test.go +++ b/waddrmgr/manager_test.go @@ -1683,7 +1683,7 @@ func testConvertWatchingOnly(tc *testContext) bool { defer os.Remove(woMgrName) // Open the new database copy and get the address manager namespace. - db, err := walletdb.Open("bdb", woMgrName, true) + db, err := walletdb.Open("bdb", woMgrName, true, defaultDBTimeout) if err != nil { tc.t.Errorf("openDbNamespace: unexpected error: %v", err) return false From 368301866e3ad1698f3dcec5dc0771272700dec3 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 12 Aug 2020 03:52:10 +0800 Subject: [PATCH 4/7] wtxmgr: update tests to use db timeout param --- wtxmgr/tx_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/wtxmgr/tx_test.go b/wtxmgr/tx_test.go index 8ef88a7..344b905 100644 --- a/wtxmgr/tx_test.go +++ b/wtxmgr/tx_test.go @@ -45,6 +45,10 @@ var ( Block: Block{Hash: *TstSignedTxBlockHash, Height: TstSpendingTxBlockHeight}, Time: time.Unix(1389114091, 0), } + + // defaultDBTimeout specifies the timeout value when opening the wallet + // database. + defaultDBTimeout = 10 * time.Second ) func testDB() (walletdb.DB, func(), error) { @@ -52,7 +56,9 @@ func testDB() (walletdb.DB, func(), error) { if err != nil { return nil, func() {}, err } - db, err := walletdb.Create("bdb", filepath.Join(tmpDir, "db"), true) + db, err := walletdb.Create( + "bdb", filepath.Join(tmpDir, "db"), true, defaultDBTimeout, + ) return db, func() { os.RemoveAll(tmpDir) }, err } @@ -64,7 +70,9 @@ func testStore() (*Store, walletdb.DB, func(), error) { return nil, nil, func() {}, err } - db, err := walletdb.Create("bdb", filepath.Join(tmpDir, "db"), true) + db, err := walletdb.Create( + "bdb", filepath.Join(tmpDir, "db"), true, defaultDBTimeout, + ) if err != nil { os.RemoveAll(tmpDir) return nil, nil, nil, err From 86bc349c6efd1306978ccf987c06c52e6a683646 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 12 Aug 2020 03:53:04 +0800 Subject: [PATCH 5/7] wallet: use db timeout in loader --- wallet/example_test.go | 8 +++++++- wallet/loader.go | 9 ++++++--- wallet/watchingonly_test.go | 4 +++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/wallet/example_test.go b/wallet/example_test.go index c6d1b82..5b29d2e 100644 --- a/wallet/example_test.go +++ b/wallet/example_test.go @@ -10,6 +10,10 @@ import ( "github.com/btcsuite/btcutil/hdkeychain" ) +// defaultDBTimeout specifies the timeout value when opening the wallet +// database. +var defaultDBTimeout = 10 * time.Second + // testWallet creates a test wallet and unlocks it. func testWallet(t *testing.T) (*Wallet, func()) { // Set up a wallet. @@ -32,7 +36,9 @@ func testWallet(t *testing.T) (*Wallet, func()) { pubPass := []byte("hello") privPass := []byte("world") - loader := NewLoader(&chaincfg.TestNet3Params, dir, true, 250) + loader := NewLoader( + &chaincfg.TestNet3Params, dir, true, defaultDBTimeout, 250, + ) w, err := loader.CreateNewWallet(pubPass, privPass, seed, time.Now()) if err != nil { t.Fatalf("unable to create wallet: %v", err) diff --git a/wallet/loader.go b/wallet/loader.go index 17f761f..c9d48ce 100644 --- a/wallet/loader.go +++ b/wallet/loader.go @@ -47,6 +47,7 @@ type Loader struct { chainParams *chaincfg.Params dbDirPath string noFreelistSync bool + timeout time.Duration recoveryWindow uint32 wallet *Wallet db walletdb.DB @@ -57,12 +58,14 @@ type Loader struct { // recovery window is non-zero, the wallet will attempt to recovery addresses // starting from the last SyncedTo height. func NewLoader(chainParams *chaincfg.Params, dbDirPath string, - noFreelistSync bool, recoveryWindow uint32) *Loader { + noFreelistSync bool, timeout time.Duration, + recoveryWindow uint32) *Loader { return &Loader{ chainParams: chainParams, dbDirPath: dbDirPath, noFreelistSync: noFreelistSync, + timeout: timeout, recoveryWindow: recoveryWindow, } } @@ -140,7 +143,7 @@ func (l *Loader) createNewWallet(pubPassphrase, privPassphrase, if err != nil { return nil, err } - db, err := walletdb.Create("bdb", dbPath, l.noFreelistSync) + db, err := walletdb.Create("bdb", dbPath, l.noFreelistSync, l.timeout) if err != nil { return nil, err } @@ -196,7 +199,7 @@ func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool) // Open the database using the boltdb backend. dbPath := filepath.Join(l.dbDirPath, walletDbName) - db, err := walletdb.Open("bdb", dbPath, l.noFreelistSync) + db, err := walletdb.Open("bdb", dbPath, l.noFreelistSync, l.timeout) if err != nil { log.Errorf("Failed to open database: %v", err) return nil, err diff --git a/wallet/watchingonly_test.go b/wallet/watchingonly_test.go index f7846b1..64a72b0 100644 --- a/wallet/watchingonly_test.go +++ b/wallet/watchingonly_test.go @@ -26,7 +26,9 @@ func TestCreateWatchingOnly(t *testing.T) { pubPass := []byte("hello") - loader := NewLoader(&chaincfg.TestNet3Params, dir, true, 250) + loader := NewLoader( + &chaincfg.TestNet3Params, dir, true, defaultDBTimeout, 250, + ) _, err = loader.CreateNewWatchingOnlyWallet(pubPass, time.Now()) if err != nil { t.Fatalf("unable to create wallet: %v", err) From 1cacaac9ea0d2e79880a419ccafc0da0a61509f9 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 12 Aug 2020 03:53:44 +0800 Subject: [PATCH 6/7] btcwallet: use db timeout param --- btcwallet.go | 10 +++++++--- cmd/dropwtxmgr/main.go | 23 ++++++++++++++++------- config.go | 5 ++++- walletsetup.go | 6 ++++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/btcwallet.go b/btcwallet.go index 4a96fef..72728fb 100644 --- a/btcwallet.go +++ b/btcwallet.go @@ -69,7 +69,9 @@ func walletMain() error { } dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) - loader := wallet.NewLoader(activeNet.Params, dbDir, true, 250) + loader := wallet.NewLoader( + activeNet.Params, dbDir, true, cfg.DBTimeout, 250, + ) // Create and start HTTP server to serve wallet client connections. // This will be updated with the wallet and chain server RPC client @@ -160,8 +162,10 @@ func rpcClientConnectLoop(legacyRPCServer *legacyrpc.Server, loader *wallet.Load spvdb walletdb.DB ) netDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) - spvdb, err = walletdb.Create("bdb", - filepath.Join(netDir, "neutrino.db"), true) + spvdb, err = walletdb.Create( + "bdb", filepath.Join(netDir, "neutrino.db"), + true, cfg.DBTimeout, + ) defer spvdb.Close() if err != nil { log.Errorf("Unable to create Neutrino DB: %s", err) diff --git a/cmd/dropwtxmgr/main.go b/cmd/dropwtxmgr/main.go index e1e3a1c..72552f3 100644 --- a/cmd/dropwtxmgr/main.go +++ b/cmd/dropwtxmgr/main.go @@ -9,6 +9,7 @@ import ( "fmt" "os" "path/filepath" + "time" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwallet/wallet" @@ -19,16 +20,24 @@ import ( const defaultNet = "mainnet" -var datadir = btcutil.AppDataDir("btcwallet", false) +var ( + datadir = btcutil.AppDataDir("btcwallet", false) + + // defaultTimeout is the default timeout value when opening the wallet + // database. + defaultTimeout = 60 * time.Second +) // Flags. var opts = struct { - Force bool `short:"f" description:"Force removal without prompt"` - DbPath string `long:"db" description:"Path to wallet database"` - DropLabels bool `long:"droplabels" description:"Drop transaction labels"` + Force bool `short:"f" description:"Force removal without prompt"` + DbPath string `long:"db" description:"Path to wallet database"` + DropLabels bool `long:"droplabels" description:"Drop transaction labels"` + Timeout time.Duration `long:"timeout" description:"Timeout value when opening the wallet database"` }{ - Force: false, - DbPath: filepath.Join(datadir, defaultNet, "wallet.db"), + Force: false, + DbPath: filepath.Join(datadir, defaultNet, "wallet.db"), + Timeout: defaultTimeout, } func init() { @@ -93,7 +102,7 @@ func mainInt() int { fmt.Println("Enter yes or no.") } - db, err := walletdb.Open("bdb", opts.DbPath, true) + db, err := walletdb.Open("bdb", opts.DbPath, true, opts.Timeout) if err != nil { fmt.Println("Failed to open database:", err) return 1 diff --git a/config.go b/config.go index 2b9e7ea..54575cb 100644 --- a/config.go +++ b/config.go @@ -33,7 +33,8 @@ const ( defaultRPCMaxClients = 10 defaultRPCMaxWebsockets = 25 - walletDbName = "wallet.db" + walletDbName = "wallet.db" + defaultDBTimeout = 60 * time.Second ) var ( @@ -58,6 +59,7 @@ type config struct { DebugLevel string `short:"d" long:"debuglevel" description:"Logging level {trace, debug, info, warn, error, critical}"` LogDir string `long:"logdir" description:"Directory to log output."` Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"` + DBTimeout time.Duration `long:"dbtimeout" description:"The timeout value to use when opening the wallet database."` // Wallet options WalletPass string `long:"walletpass" default-mask:"-" description:"The public wallet password -- Only required if the wallet was created with one"` @@ -273,6 +275,7 @@ func loadConfig() (*config, []string, error) { MaxPeers: neutrino.MaxPeers, BanDuration: neutrino.BanDuration, BanThreshold: neutrino.BanThreshold, + DBTimeout: defaultDBTimeout, } // Pre-parse the command line options to see if an alternative config diff --git a/walletsetup.go b/walletsetup.go index de63415..3723abe 100644 --- a/walletsetup.go +++ b/walletsetup.go @@ -102,7 +102,9 @@ func convertLegacyKeystore(legacyKeyStore *keystore.Store, w *wallet.Wallet) err // provided path. func createWallet(cfg *config) error { dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) - loader := wallet.NewLoader(activeNet.Params, dbDir, true, 250) + loader := wallet.NewLoader( + activeNet.Params, dbDir, true, cfg.DBTimeout, 250, + ) // When there is a legacy keystore, open it now to ensure any errors // don't end up exiting the process after the user has spent time @@ -219,7 +221,7 @@ func createSimulationWallet(cfg *config) error { fmt.Println("Creating the wallet...") // Create the wallet database backed by bolt db. - db, err := walletdb.Create("bdb", dbPath, true) + db, err := walletdb.Create("bdb", dbPath, true, cfg.DBTimeout) if err != nil { return err } From e34b43b938db51c092428b699a05deb258670cb8 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Sat, 7 Nov 2020 00:51:23 +0800 Subject: [PATCH 7/7] multi: unify WalletDBName and DefaultDBTimeout in loader --- cmd/dropwtxmgr/main.go | 8 ++------ config.go | 7 ++----- wallet/loader.go | 13 +++++++++---- walletsetup.go | 2 +- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/cmd/dropwtxmgr/main.go b/cmd/dropwtxmgr/main.go index 72552f3..b474db1 100644 --- a/cmd/dropwtxmgr/main.go +++ b/cmd/dropwtxmgr/main.go @@ -22,10 +22,6 @@ const defaultNet = "mainnet" var ( datadir = btcutil.AppDataDir("btcwallet", false) - - // defaultTimeout is the default timeout value when opening the wallet - // database. - defaultTimeout = 60 * time.Second ) // Flags. @@ -36,8 +32,8 @@ var opts = struct { Timeout time.Duration `long:"timeout" description:"Timeout value when opening the wallet database"` }{ Force: false, - DbPath: filepath.Join(datadir, defaultNet, "wallet.db"), - Timeout: defaultTimeout, + DbPath: filepath.Join(datadir, defaultNet, wallet.WalletDBName), + Timeout: wallet.DefaultDBTimeout, } func init() { diff --git a/config.go b/config.go index 54575cb..7c80280 100644 --- a/config.go +++ b/config.go @@ -32,9 +32,6 @@ const ( defaultLogFilename = "btcwallet.log" defaultRPCMaxClients = 10 defaultRPCMaxWebsockets = 25 - - walletDbName = "wallet.db" - defaultDBTimeout = 60 * time.Second ) var ( @@ -275,7 +272,7 @@ func loadConfig() (*config, []string, error) { MaxPeers: neutrino.MaxPeers, BanDuration: neutrino.BanDuration, BanThreshold: neutrino.BanThreshold, - DBTimeout: defaultDBTimeout, + DBTimeout: wallet.DefaultDBTimeout, } // Pre-parse the command line options to see if an alternative config @@ -418,7 +415,7 @@ func loadConfig() (*config, []string, error) { // Ensure the wallet exists or create it when the create flag is set. netDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) - dbPath := filepath.Join(netDir, walletDbName) + dbPath := filepath.Join(netDir, wallet.WalletDBName) if cfg.CreateTemp && cfg.Create { err := fmt.Errorf("The flags --create and --createtemp can not " + diff --git a/wallet/loader.go b/wallet/loader.go index c9d48ce..029114c 100644 --- a/wallet/loader.go +++ b/wallet/loader.go @@ -18,7 +18,12 @@ import ( ) const ( - walletDbName = "wallet.db" + // WalletDBName specified the database filename for the wallet. + WalletDBName = "wallet.db" + + // DefaultDBTimeout is the default timeout value when opening the wallet + // database. + DefaultDBTimeout = 60 * time.Second ) var ( @@ -129,7 +134,7 @@ func (l *Loader) createNewWallet(pubPassphrase, privPassphrase, return nil, ErrLoaded } - dbPath := filepath.Join(l.dbDirPath, walletDbName) + dbPath := filepath.Join(l.dbDirPath, WalletDBName) exists, err := fileExists(dbPath) if err != nil { return nil, err @@ -198,7 +203,7 @@ func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool) } // Open the database using the boltdb backend. - dbPath := filepath.Join(l.dbDirPath, walletDbName) + dbPath := filepath.Join(l.dbDirPath, WalletDBName) db, err := walletdb.Open("bdb", dbPath, l.noFreelistSync, l.timeout) if err != nil { log.Errorf("Failed to open database: %v", err) @@ -237,7 +242,7 @@ func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool) // WalletExists returns whether a file exists at the loader's database path. // This may return an error for unexpected I/O failures. func (l *Loader) WalletExists() (bool, error) { - dbPath := filepath.Join(l.dbDirPath, walletDbName) + dbPath := filepath.Join(l.dbDirPath, WalletDBName) return fileExists(dbPath) } diff --git a/walletsetup.go b/walletsetup.go index 3723abe..c70425e 100644 --- a/walletsetup.go +++ b/walletsetup.go @@ -217,7 +217,7 @@ func createSimulationWallet(cfg *config) error { netDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) // Create the wallet. - dbPath := filepath.Join(netDir, walletDbName) + dbPath := filepath.Join(netDir, wallet.WalletDBName) fmt.Println("Creating the wallet...") // Create the wallet database backed by bolt db.