Ejemplo n.º 1
0
// CreateEncryptedWallet creates a new default account with a wallet file
// encrypted with passphrase.
func (am *AccountManager) CreateEncryptedWallet(passphrase []byte) error {
	if len(am.AllAccounts()) != 0 {
		return ErrWalletExists
	}

	// Get current block's height and hash.
	bs, err := GetCurBlock()
	if err != nil {
		return err
	}

	// Create new wallet in memory.
	wlt, err := wallet.NewWallet("", "Default acccount", passphrase,
		activeNet.Params, &bs, cfg.KeypoolSize)
	if err != nil {
		return err
	}

	// Create new account and begin managing with the global account
	// manager.  Registering will fail if the new account can not be
	// written immediately to disk.
	a := &Account{
		Wallet:          wlt,
		TxStore:         txstore.New(),
		lockedOutpoints: map[btcwire.OutPoint]struct{}{},
	}
	if err := am.RegisterNewAccount(a); err != nil {
		return err
	}

	// Begin tracking account against a connected btcd.
	a.Track()

	return nil
}
Ejemplo n.º 2
0
// 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, &walletOpenError{
			Err: err.Error(),
		}
	}

	wlt := new(wallet.Wallet)
	txs := txstore.New()
	a := &Account{
		name:    name,
		Wallet:  wlt,
		TxStore: txs,
	}

	wfilepath := accountFilename("wallet.bin", name, netdir)
	txfilepath := accountFilename("tx.bin", name, netdir)
	var wfile, 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
		a.fullRescan = true
	} else {
		defer txfile.Close()
		if _, err = txs.ReadFrom(txfile); err != nil {
			log.Errorf("cannot read tx file: %s", err)
			a.fullRescan = true
			finalErr = errNoTxs
		}
	}

	return a, finalErr
}
Ejemplo n.º 3
0
// 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(activeNet.Params)
	if err := checkCreateDir(netdir); err != nil {
		return nil, &walletOpenError{
			Err: err.Error(),
		}
	}

	wlt := new(wallet.Wallet)
	txs := txstore.New()
	a := &Account{
		name:            name,
		Wallet:          wlt,
		TxStore:         txs,
		lockedOutpoints: map[btcwire.OutPoint]struct{}{},
	}

	walletPath := accountFilename("wallet.bin", name, netdir)
	txstorePath := accountFilename("tx.bin", name, netdir)

	// Read wallet file.
	walletFi, err := os.Open(walletPath)
	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}
	}
	if _, err = wlt.ReadFrom(walletFi); err != nil {
		if err := walletFi.Close(); err != nil {
			log.Warnf("Cannot close wallet file: %v", err)
		}
		msg := fmt.Sprintf("Cannot read wallet: %s", err)
		return nil, &walletOpenError{msg}
	}

	// Read txstore file.  If this fails, write a new empty transaction
	// store to disk, mark the wallet as unsynced, and write the unsynced
	// wallet to disk.
	//
	// This file is opened read/write so it may be truncated if a new empty
	// transaction store must be written.
	txstoreFi, err := os.OpenFile(txstorePath, os.O_RDWR, 0)
	if err != nil {
		if err := walletFi.Close(); err != nil {
			log.Warnf("Cannot close wallet file: %v", err)
		}
		if err := writeUnsyncedWallet(a, walletPath); err != nil {
			return nil, err
		}

		// Create and write empty txstore, if it doesn't exist.
		if !fileExists(txstorePath) {
			log.Warn("Transaction store file missing")
			if txstoreFi, err = os.Create(txstorePath); err != nil {
				return nil, fmt.Errorf("cannot create new "+
					"txstore file: %v", err)
			}
			defer func() {
				if err := txstoreFi.Close(); err != nil {
					log.Warnf("Cannot close transaction "+
						"store file: %v", err)
				}
			}()
		} else {
			return nil, fmt.Errorf("transaction store file "+
				"exists but cannot be opened: %v", err)
		}

		if _, err := txs.WriteTo(txstoreFi); err != nil {
			log.Warn(err)
		}
		return a, nil
	}
	if _, err = txs.ReadFrom(txstoreFi); err != nil {
		if err := walletFi.Close(); err != nil {
			log.Warnf("Cannot close wallet file: %v", err)
		}
		if err := writeUnsyncedWallet(a, walletPath); err != nil {
			return nil, err
		}

		defer func() {
			if err := txstoreFi.Close(); err != nil {
				log.Warnf("Cannot close transaction store "+
					"file: %v", err)
			}
		}()
		log.Warnf("Cannot read transaction store: %s", err)
		if _, err := txstoreFi.Seek(0, os.SEEK_SET); err != nil {
			return nil, err
		}
		if err := txstoreFi.Truncate(0); err != nil {
			return nil, err
		}
		if _, err := txs.WriteTo(txstoreFi); err != nil {
			log.Warn("Cannot write new transaction store: %v", err)
		}
		log.Infof("Wrote empty transaction store file")
		return a, nil
	}

	if err := walletFi.Close(); err != nil {
		log.Warnf("Cannot close wallet file: %v", err)
	}
	if err := txstoreFi.Close(); err != nil {
		log.Warnf("Cannot close transaction store file: %v", err)
	}
	return a, nil
}