// OpenSavedAccount opens a named account from disk. If the wallet does not // exist, ErrNoWallet is returned as an error. func OpenSavedAccount(name string, cfg *config) (*Account, error) { netdir := networkDir(cfg.Net()) if err := checkCreateDir(netdir); err != nil { return nil, err } wlt := new(wallet.Wallet) a := &Account{ Wallet: wlt, name: name, } wfilepath := accountFilename("wallet.bin", name, netdir) utxofilepath := accountFilename("utxo.bin", name, netdir) txfilepath := accountFilename("tx.bin", name, netdir) var wfile, utxofile, txfile *os.File // Read wallet file. wfile, err := os.Open(wfilepath) if err != nil { if os.IsNotExist(err) { // Must create and save wallet first. return nil, ErrNoWallet } msg := fmt.Sprintf("cannot open wallet file: %s", err) return nil, &WalletOpenError{msg} } defer wfile.Close() if _, err = wlt.ReadFrom(wfile); err != nil { msg := fmt.Sprintf("cannot read wallet: %s", err) return nil, &WalletOpenError{msg} } // Read tx file. If this fails, return a ErrNoTxs error and let // the caller decide if a rescan is necessary. var finalErr error if txfile, err = os.Open(txfilepath); err != nil { log.Errorf("cannot open tx file: %s", err) // This is not a error we should immediately return with, // but other errors can be more important, so only return // this if none of the others are hit. finalErr = ErrNoTxs } else { defer txfile.Close() var txs tx.TxStore if _, err = txs.ReadFrom(txfile); err != nil { log.Errorf("cannot read tx file: %s", err) finalErr = ErrNoTxs } else { a.TxStore = txs } } // Read utxo file. If this fails, return a ErrNoUtxos error so a // rescan can be done since the wallet creation block. var utxos tx.UtxoStore utxofile, err = os.Open(utxofilepath) if err != nil { log.Errorf("cannot open utxo file: %s", err) finalErr = ErrNoUtxos a.fullRescan = true } else { defer utxofile.Close() if _, err = utxos.ReadFrom(utxofile); err != nil { log.Errorf("cannot read utxo file: %s", err) finalErr = ErrNoUtxos } else { a.UtxoStore = utxos } } // Mark all active payment addresses as belonging to this account. for addr := range a.ActivePaymentAddresses() { MarkAddressForAccount(addr, name) } return a, finalErr }
// OpenAccount opens an account described by account in the data // directory specified by cfg. If the wallet does not exist, ErrNoWallet // is returned as an error. // // Wallets opened from this function are not set to track against a // btcd connection. func (store *AccountStore) OpenAccount(name string, cfg *config) error { wlt := new(wallet.Wallet) a := &Account{ Wallet: wlt, name: name, } netdir := networkDir(cfg.Net()) if err := checkCreateDir(netdir); err != nil { return err } wfilepath := accountFilename("wallet.bin", name, netdir) utxofilepath := accountFilename("utxo.bin", name, netdir) txfilepath := accountFilename("tx.bin", name, netdir) var wfile, utxofile, txfile *os.File // Read wallet file. wfile, err := os.Open(wfilepath) if err != nil { if os.IsNotExist(err) { // Must create and save wallet first. return ErrNoWallet } msg := fmt.Sprintf("cannot open wallet file: %s", err) return &WalletOpenError{msg} } defer wfile.Close() if _, err = wlt.ReadFrom(wfile); err != nil { msg := fmt.Sprintf("cannot read wallet: %s", err) return &WalletOpenError{msg} } // Read tx file. If this fails, return a ErrNoTxs error and let // the caller decide if a rescan is necessary. var finalErr error if txfile, err = os.Open(txfilepath); err != nil { log.Errorf("cannot open tx file: %s", err) // This is not a error we should immediately return with, // but other errors can be more important, so only return // this if none of the others are hit. finalErr = ErrNoTxs } else { defer txfile.Close() var txs tx.TxStore if _, err = txs.ReadFrom(txfile); err != nil { log.Errorf("cannot read tx file: %s", err) finalErr = ErrNoTxs } else { a.TxStore.s = txs } } // Read utxo file. If this fails, return a ErrNoUtxos error so a // rescan can be done since the wallet creation block. var utxos tx.UtxoStore utxofile, err = os.Open(utxofilepath) if err != nil { log.Errorf("cannot open utxo file: %s", err) finalErr = ErrNoUtxos } else { defer utxofile.Close() if _, err = utxos.ReadFrom(utxofile); err != nil { log.Errorf("cannot read utxo file: %s", err) finalErr = ErrNoUtxos } else { a.UtxoStore.s = utxos } } store.Lock() switch finalErr { case ErrNoTxs: // Do nothing special for now. This will be implemented when // the tx history file is properly written. store.accounts[name] = a case ErrNoUtxos: // Add wallet, but mark wallet as needing a full rescan since // the wallet creation block. This will take place when btcd // connects. a.fullRescan = true store.accounts[name] = a case nil: store.accounts[name] = a default: log.Warnf("cannot open wallet: %v", err) } store.Unlock() // Mark all active payment addresses as belonging to this account. for addr := range a.ActivePaymentAddresses() { MarkAddressForAccount(addr, name) } return nil }