Open all account files at startup.
This change checks for all wallet files in the account directory, and then attempts to open each of the available accounts for those wallets. Before, only the default account would ever be opened.
This commit is contained in:
parent
830829a79f
commit
b4373dc070
2 changed files with 77 additions and 9 deletions
|
@ -325,6 +325,17 @@ func (store *AccountStore) Track() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WalletOpenError is a special error type so problems opening wallet
|
||||||
|
// files can be differentiated (by a type assertion) from other errors.
|
||||||
|
type WalletOpenError struct {
|
||||||
|
Err string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error satisifies the builtin error interface.
|
||||||
|
func (e *WalletOpenError) Error() string {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
// OpenAccount opens an account described by account in the data
|
// OpenAccount opens an account described by account in the data
|
||||||
// directory specified by cfg. If the wallet does not exist, ErrNoWallet
|
// directory specified by cfg. If the wallet does not exist, ErrNoWallet
|
||||||
// is returned as an error.
|
// is returned as an error.
|
||||||
|
@ -356,12 +367,14 @@ func (store *AccountStore) OpenAccount(name string, cfg *config) error {
|
||||||
// Must create and save wallet first.
|
// Must create and save wallet first.
|
||||||
return ErrNoWallet
|
return ErrNoWallet
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot open wallet file: %s", err)
|
msg := fmt.Sprintf("cannot open wallet file: %s", err)
|
||||||
|
return &WalletOpenError{msg}
|
||||||
}
|
}
|
||||||
defer wfile.Close()
|
defer wfile.Close()
|
||||||
|
|
||||||
if _, err = wlt.ReadFrom(wfile); err != nil {
|
if _, err = wlt.ReadFrom(wfile); err != nil {
|
||||||
return fmt.Errorf("cannot read wallet: %s", err)
|
msg := fmt.Sprintf("cannot read wallet: %s", err)
|
||||||
|
return &WalletOpenError{msg}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read tx file. If this fails, return a ErrNoTxs error and let
|
// Read tx file. If this fails, return a ErrNoTxs error and let
|
||||||
|
|
69
cmd.go
69
cmd.go
|
@ -27,6 +27,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -34,7 +35,9 @@ import (
|
||||||
var (
|
var (
|
||||||
// ErrNoWallet describes an error where a wallet does not exist and
|
// ErrNoWallet describes an error where a wallet does not exist and
|
||||||
// must be created first.
|
// must be created first.
|
||||||
ErrNoWallet = errors.New("wallet file does not exist")
|
ErrNoWallet = &WalletOpenError{
|
||||||
|
Err: "wallet file does not exist",
|
||||||
|
}
|
||||||
|
|
||||||
// ErrNoUtxos describes an error where the wallet file was successfully
|
// ErrNoUtxos describes an error where the wallet file was successfully
|
||||||
// read, but the UTXO file was not. To properly handle this error,
|
// read, but the UTXO file was not. To properly handle this error,
|
||||||
|
@ -146,12 +149,8 @@ func main() {
|
||||||
// Check and update any old file locations.
|
// Check and update any old file locations.
|
||||||
updateOldFileLocations()
|
updateOldFileLocations()
|
||||||
|
|
||||||
// Open default account.
|
// Open all account saved to disk.
|
||||||
// TODO(jrick): open all available accounts.
|
OpenAccounts()
|
||||||
err = accountstore.OpenAccount("", cfg)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("cannot open default account: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read CA file to verify a btcd TLS connection.
|
// Read CA file to verify a btcd TLS connection.
|
||||||
cafile, err := ioutil.ReadFile(cfg.CAFile)
|
cafile, err := ioutil.ReadFile(cfg.CAFile)
|
||||||
|
@ -247,6 +246,62 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OpenAccounts attempts to open all saved accounts.
|
||||||
|
func OpenAccounts() {
|
||||||
|
// The default account must exist, or btcwallet acts as if no
|
||||||
|
// wallets/accounts have been created yet.
|
||||||
|
if err := accountstore.OpenAccount("", cfg); err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case *WalletOpenError:
|
||||||
|
log.Errorf("Default account wallet file unreadable: %v", err)
|
||||||
|
return
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.Warnf("Non-critical problem opening an account file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all filenames in the account directory, and look for any
|
||||||
|
// filenames matching '*-wallet.bin'. These are wallets for
|
||||||
|
// additional saved accounts.
|
||||||
|
accountDir, err := os.Open(networkDir(cfg.Net()))
|
||||||
|
if err != nil {
|
||||||
|
// Can't continue.
|
||||||
|
log.Errorf("Unable to open account directory: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer accountDir.Close()
|
||||||
|
fileNames, err := accountDir.Readdirnames(0)
|
||||||
|
if err != nil {
|
||||||
|
// fileNames might be partially set, so log an error and
|
||||||
|
// at least try to open some accounts.
|
||||||
|
log.Errorf("Unable to read all account files: %v", err)
|
||||||
|
}
|
||||||
|
var accounts []string
|
||||||
|
for _, file := range fileNames {
|
||||||
|
if strings.HasSuffix(file, "-wallet.bin") {
|
||||||
|
name := strings.TrimSuffix(file, "-wallet.bin")
|
||||||
|
accounts = append(accounts, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open all additional accounts.
|
||||||
|
for _, a := range accounts {
|
||||||
|
// Log txstore/utxostore errors as these will be recovered
|
||||||
|
// from with a rescan, but wallet errors must be returned
|
||||||
|
// to the caller.
|
||||||
|
if err := accountstore.OpenAccount(a, cfg); err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case *WalletOpenError:
|
||||||
|
log.Errorf("Error opening account's wallet: %v", err)
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.Warnf("Non-critical error opening an account file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var accessRPC = make(chan *AccessCurrentRPCConn)
|
var accessRPC = make(chan *AccessCurrentRPCConn)
|
||||||
|
|
||||||
// AccessCurrentRPCConn is used to access the current RPC connection
|
// AccessCurrentRPCConn is used to access the current RPC connection
|
||||||
|
|
Loading…
Reference in a new issue