multi: extend walletdb bolt driver with NoFreelistSync option

This allows external callers to set the option instead. All tests
remained with the option enabled.
This commit is contained in:
Wilmer Paulino 2019-10-02 13:14:59 -04:00
parent 95d7aa0b49
commit 81797fe29d
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F
12 changed files with 45 additions and 32 deletions

View file

@ -69,7 +69,7 @@ func walletMain() error {
} }
dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params)
loader := wallet.NewLoader(activeNet.Params, dbDir, 250) loader := wallet.NewLoader(activeNet.Params, dbDir, true, 250)
// Create and start HTTP server to serve wallet client connections. // Create and start HTTP server to serve wallet client connections.
// This will be updated with the wallet and chain server RPC client // This will be updated with the wallet and chain server RPC client

View file

@ -99,7 +99,7 @@ func mainInt() int {
fmt.Println("Enter yes or no.") fmt.Println("Enter yes or no.")
} }
db, err := walletdb.Open("bdb", opts.DbPath) db, err := walletdb.Open("bdb", opts.DbPath, true)
if err != nil { if err != nil {
fmt.Println("Failed to open database:", err) fmt.Println("Failed to open database:", err)
return 1 return 1

View file

@ -242,7 +242,7 @@ func emptyDB(t *testing.T) (tearDownFunc func(), db walletdb.DB) {
t.Fatalf("Failed to create db temp dir: %v", err) t.Fatalf("Failed to create db temp dir: %v", err)
} }
dbPath := filepath.Join(dirName, "mgrtest.db") dbPath := filepath.Join(dirName, "mgrtest.db")
db, err = walletdb.Create("bdb", dbPath) db, err = walletdb.Create("bdb", dbPath, true)
if err != nil { if err != nil {
_ = os.RemoveAll(dirName) _ = os.RemoveAll(dirName)
t.Fatalf("createDbNamespace: unexpected error: %v", err) t.Fatalf("createDbNamespace: unexpected error: %v", err)
@ -263,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) t.Fatalf("Failed to create db temp dir: %v", err)
} }
dbPath := filepath.Join(dirName, "mgrtest.db") dbPath := filepath.Join(dirName, "mgrtest.db")
db, err = walletdb.Create("bdb", dbPath) db, err = walletdb.Create("bdb", dbPath, true)
if err != nil { if err != nil {
_ = os.RemoveAll(dirName) _ = os.RemoveAll(dirName)
t.Fatalf("createDbNamespace: unexpected error: %v", err) t.Fatalf("createDbNamespace: unexpected error: %v", err)

View file

@ -1651,7 +1651,7 @@ func testWatchingOnly(tc *testContext) bool {
defer os.Remove(woMgrName) defer os.Remove(woMgrName)
// Open the new database copy and get the address manager namespace. // Open the new database copy and get the address manager namespace.
db, err := walletdb.Open("bdb", woMgrName) db, err := walletdb.Open("bdb", woMgrName, true)
if err != nil { if err != nil {
tc.t.Errorf("openDbNamespace: unexpected error: %v", err) tc.t.Errorf("openDbNamespace: unexpected error: %v", err)
return false return false

View file

@ -41,7 +41,7 @@ func TestTxToOutputsDryRun(t *testing.T) {
pubPass := []byte("hello") pubPass := []byte("hello")
privPass := []byte("world") privPass := []byte("world")
loader := NewLoader(&chaincfg.TestNet3Params, dir, 250) loader := NewLoader(&chaincfg.TestNet3Params, dir, true, 250)
w, err := loader.CreateNewWallet(pubPass, privPass, seed, time.Now()) w, err := loader.CreateNewWallet(pubPass, privPass, seed, time.Now())
if err != nil { if err != nil {
t.Fatalf("unable to create wallet: %v", err) t.Fatalf("unable to create wallet: %v", err)

View file

@ -46,6 +46,7 @@ type Loader struct {
callbacks []func(*Wallet) callbacks []func(*Wallet)
chainParams *chaincfg.Params chainParams *chaincfg.Params
dbDirPath string dbDirPath string
noFreelistSync bool
recoveryWindow uint32 recoveryWindow uint32
wallet *Wallet wallet *Wallet
db walletdb.DB db walletdb.DB
@ -56,11 +57,12 @@ type Loader struct {
// recovery window is non-zero, the wallet will attempt to recovery addresses // recovery window is non-zero, the wallet will attempt to recovery addresses
// starting from the last SyncedTo height. // starting from the last SyncedTo height.
func NewLoader(chainParams *chaincfg.Params, dbDirPath string, func NewLoader(chainParams *chaincfg.Params, dbDirPath string,
recoveryWindow uint32) *Loader { noFreelistSync bool, recoveryWindow uint32) *Loader {
return &Loader{ return &Loader{
chainParams: chainParams, chainParams: chainParams,
dbDirPath: dbDirPath, dbDirPath: dbDirPath,
noFreelistSync: noFreelistSync,
recoveryWindow: recoveryWindow, recoveryWindow: recoveryWindow,
} }
} }
@ -119,7 +121,7 @@ func (l *Loader) CreateNewWallet(pubPassphrase, privPassphrase, seed []byte,
if err != nil { if err != nil {
return nil, err return nil, err
} }
db, err := walletdb.Create("bdb", dbPath) db, err := walletdb.Create("bdb", dbPath, l.noFreelistSync)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -168,7 +170,7 @@ func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool)
// Open the database using the boltdb backend. // 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) db, err := walletdb.Open("bdb", dbPath, l.noFreelistSync)
if err != nil { if err != nil {
log.Errorf("Failed to open database: %v", err) log.Errorf("Failed to open database: %v", err)
return nil, err return nil, err

View file

@ -10,18 +10,19 @@ datastore. Package bdb is licensed under the copyfree ISC license.
## Usage ## Usage
This package is only a driver to the walletdb package and provides the database This package is only a driver to the walletdb package and provides the database
type of "bdb". The only parameter the Open and Create functions take is the type of "bdb". The only parameters the Open and Create functions take is the
database path as a string: database path as a string, and an option for the database to not sync its
freelist to disk as a bool:
```Go ```Go
db, err := walletdb.Open("bdb", "path/to/database.db") db, err := walletdb.Open("bdb", "path/to/database.db", true)
if err != nil { if err != nil {
// Handle error // Handle error
} }
``` ```
```Go ```Go
db, err := walletdb.Create("bdb", "path/to/database.db") db, err := walletdb.Create("bdb", "path/to/database.db", true)
if err != nil { if err != nil {
// Handle error // Handle error
} }

View file

@ -339,7 +339,7 @@ func fileExists(name string) bool {
// openDB opens the database at the provided path. walletdb.ErrDbDoesNotExist // 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. // is returned if the database doesn't exist and the create flag is not set.
func openDB(dbPath string, create bool) (walletdb.DB, error) { func openDB(dbPath string, noFreelistSync bool, create bool) (walletdb.DB, error) {
if !create && !fileExists(dbPath) { if !create && !fileExists(dbPath) {
return nil, walletdb.ErrDbDoesNotExist return nil, walletdb.ErrDbDoesNotExist
} }
@ -347,7 +347,7 @@ func openDB(dbPath string, create bool) (walletdb.DB, error) {
// Specify bbolt freelist options to reduce heap pressure in case the // Specify bbolt freelist options to reduce heap pressure in case the
// freelist grows to be very large. // freelist grows to be very large.
options := &bbolt.Options{ options := &bbolt.Options{
NoFreelistSync: true, NoFreelistSync: noFreelistSync,
FreelistType: bbolt.FreelistMapType, FreelistType: bbolt.FreelistMapType,
} }

View file

@ -9,15 +9,16 @@ datastore.
Usage Usage
This package is only a driver to the walletdb package and provides the database This package is only a driver to the walletdb package and provides the database
type of "bdb". The only parameter the Open and Create functions take is the type of "bdb". The only parameters the Open and Create functions take is the
database path as a string: database path as a string, and an option for the database to not sync its
freelist to disk as a bool:
db, err := walletdb.Open("bdb", "path/to/database.db") db, err := walletdb.Open("bdb", "path/to/database.db", true)
if err != nil { if err != nil {
// Handle error // Handle error
} }
db, err := walletdb.Create("bdb", "path/to/database.db") db, err := walletdb.Create("bdb", "path/to/database.db", true)
if err != nil { if err != nil {
// Handle error // Handle error
} }

View file

@ -15,41 +15,50 @@ const (
) )
// parseArgs parses the arguments from the walletdb Open/Create methods. // parseArgs parses the arguments from the walletdb Open/Create methods.
func parseArgs(funcName string, args ...interface{}) (string, error) { func parseArgs(funcName string, args ...interface{}) (string, bool, error) {
if len(args) != 1 { if len(args) != 2 {
return "", fmt.Errorf("invalid arguments to %s.%s -- "+ return "", false, fmt.Errorf("invalid arguments to %s.%s -- "+
"expected database path", dbType, funcName) "expected database path and no-freelist-sync option",
dbType, funcName)
} }
dbPath, ok := args[0].(string) dbPath, ok := args[0].(string)
if !ok { if !ok {
return "", fmt.Errorf("first argument to %s.%s is invalid -- "+ return "", false, fmt.Errorf("first argument to %s.%s is "+
"expected database path string", dbType, funcName) "invalid -- expected database path string", dbType,
funcName)
} }
return dbPath, nil noFreelistSync, ok := args[1].(bool)
if !ok {
return "", false, fmt.Errorf("second argument to %s.%s is "+
"invalid -- expected no-freelist-sync bool", dbType,
funcName)
}
return dbPath, noFreelistSync, nil
} }
// openDBDriver is the callback provided during driver registration that opens // openDBDriver is the callback provided during driver registration that opens
// an existing database for use. // an existing database for use.
func openDBDriver(args ...interface{}) (walletdb.DB, error) { func openDBDriver(args ...interface{}) (walletdb.DB, error) {
dbPath, err := parseArgs("Open", args...) dbPath, noFreelistSync, err := parseArgs("Open", args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return openDB(dbPath, false) return openDB(dbPath, noFreelistSync, false)
} }
// createDBDriver is the callback provided during driver registration that // createDBDriver is the callback provided during driver registration that
// creates, initializes, and opens a database for use. // creates, initializes, and opens a database for use.
func createDBDriver(args ...interface{}) (walletdb.DB, error) { func createDBDriver(args ...interface{}) (walletdb.DB, error) {
dbPath, err := parseArgs("Create", args...) dbPath, noFreelistSync, err := parseArgs("Create", args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return openDB(dbPath, true) return openDB(dbPath, noFreelistSync, true)
} }
func init() { func init() {

View file

@ -130,7 +130,7 @@ func TestPersistence(t *testing.T) {
// Close and reopen the database to ensure the values persist. // Close and reopen the database to ensure the values persist.
db.Close() db.Close()
db, err = walletdb.Open(dbType, dbPath) db, err = walletdb.Open(dbType, dbPath, true)
if err != nil { if err != nil {
t.Errorf("Failed to open test database (%s) %v", dbType, err) t.Errorf("Failed to open test database (%s) %v", dbType, err)
return return

View file

@ -102,7 +102,7 @@ func convertLegacyKeystore(legacyKeyStore *keystore.Store, w *wallet.Wallet) err
// provided path. // provided path.
func createWallet(cfg *config) error { func createWallet(cfg *config) error {
dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params)
loader := wallet.NewLoader(activeNet.Params, dbDir, 250) loader := wallet.NewLoader(activeNet.Params, dbDir, true, 250)
// When there is a legacy keystore, open it now to ensure any errors // 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 // don't end up exiting the process after the user has spent time