github.com/codingfuture/orig-energi3@v0.8.4/accounts/keystore/wallet.go (about)

     1  // Copyright 2018 The Energi Core Authors
     2  // Copyright 2017 The go-ethereum Authors
     3  // This file is part of the Energi Core library.
     4  //
     5  // The Energi Core library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The Energi Core library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package keystore
    19  
    20  import (
    21  	"math/big"
    22  
    23  	ethereum "github.com/ethereum/go-ethereum"
    24  	"github.com/ethereum/go-ethereum/accounts"
    25  	"github.com/ethereum/go-ethereum/core/types"
    26  )
    27  
    28  // keystoreWallet implements the accounts.Wallet interface for the original
    29  // keystore.
    30  type keystoreWallet struct {
    31  	account  accounts.Account // Single account contained in this wallet
    32  	keystore *KeyStore        // Keystore where the account originates from
    33  }
    34  
    35  // URL implements accounts.Wallet, returning the URL of the account within.
    36  func (w *keystoreWallet) URL() accounts.URL {
    37  	return w.account.URL
    38  }
    39  
    40  // Status implements accounts.Wallet, returning whether the account held by the
    41  // keystore wallet is unlocked or not.
    42  func (w *keystoreWallet) Status() (string, error) {
    43  	w.keystore.mu.RLock()
    44  	defer w.keystore.mu.RUnlock()
    45  
    46  	if ke, ok := w.keystore.unlocked[w.account.Address]; ok {
    47  		if ke.stakingOnly {
    48  			return "Staking", nil
    49  		}
    50  
    51  		return "Unlocked", nil
    52  	}
    53  	return "Locked", nil
    54  }
    55  
    56  // Open implements accounts.Wallet, but is a noop for plain wallets since there
    57  // is no connection or decryption step necessary to access the list of accounts.
    58  func (w *keystoreWallet) Open(passphrase string) error { return nil }
    59  
    60  // Close implements accounts.Wallet, but is a noop for plain wallets since there
    61  // is no meaningful open operation.
    62  func (w *keystoreWallet) Close() error { return nil }
    63  
    64  // Accounts implements accounts.Wallet, returning an account list consisting of
    65  // a single account that the plain kestore wallet contains.
    66  func (w *keystoreWallet) Accounts() []accounts.Account {
    67  	return []accounts.Account{w.account}
    68  }
    69  
    70  // Contains implements accounts.Wallet, returning whether a particular account is
    71  // or is not wrapped by this wallet instance.
    72  func (w *keystoreWallet) Contains(account accounts.Account) bool {
    73  	return account.Address == w.account.Address && (account.URL == (accounts.URL{}) || account.URL == w.account.URL)
    74  }
    75  
    76  // Derive implements accounts.Wallet, but is a noop for plain wallets since there
    77  // is no notion of hierarchical account derivation for plain keystore accounts.
    78  func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) {
    79  	return accounts.Account{}, accounts.ErrNotSupported
    80  }
    81  
    82  // SelfDerive implements accounts.Wallet, but is a noop for plain wallets since
    83  // there is no notion of hierarchical account derivation for plain keystore accounts.
    84  func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) {}
    85  
    86  // SignHash implements accounts.Wallet, attempting to sign the given hash with
    87  // the given account. If the wallet does not wrap this particular account, an
    88  // error is returned to avoid account leakage (even though in theory we may be
    89  // able to sign via our shared keystore backend).
    90  func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) {
    91  	// Make sure the requested account is contained within
    92  	if !w.Contains(account) {
    93  		return nil, accounts.ErrUnknownAccount
    94  	}
    95  	// Account seems valid, request the keystore to sign
    96  	return w.keystore.SignHash(account, hash)
    97  }
    98  
    99  // SignTx implements accounts.Wallet, attempting to sign the given transaction
   100  // with the given account. If the wallet does not wrap this particular account,
   101  // an error is returned to avoid account leakage (even though in theory we may
   102  // be able to sign via our shared keystore backend).
   103  func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
   104  	// Make sure the requested account is contained within
   105  	if !w.Contains(account) {
   106  		return nil, accounts.ErrUnknownAccount
   107  	}
   108  	// Account seems valid, request the keystore to sign
   109  	return w.keystore.SignTx(account, tx, chainID)
   110  }
   111  
   112  // SignHashWithPassphrase implements accounts.Wallet, attempting to sign the
   113  // given hash with the given account using passphrase as extra authentication.
   114  func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) {
   115  	// Make sure the requested account is contained within
   116  	if !w.Contains(account) {
   117  		return nil, accounts.ErrUnknownAccount
   118  	}
   119  	// Account seems valid, request the keystore to sign
   120  	return w.keystore.SignHashWithPassphrase(account, passphrase, hash)
   121  }
   122  
   123  // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given
   124  // transaction with the given account using passphrase as extra authentication.
   125  func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
   126  	// Make sure the requested account is contained within
   127  	if !w.Contains(account) {
   128  		return nil, accounts.ErrUnknownAccount
   129  	}
   130  	// Account seems valid, request the keystore to sign
   131  	return w.keystore.SignTxWithPassphrase(account, passphrase, tx, chainID)
   132  }
   133  
   134  // Check if account is available for immediate signing of PoS blocks
   135  func (w *keystoreWallet) IsUnlockedForStaking(account accounts.Account) bool {
   136  	// TODO: support special PoS unlock mode
   137  	s, _ := w.Status()
   138  	return s == "Unlocked" || s == "Staking"
   139  }