[#issue-403] Account package cleanup

This commit is contained in:
Adrià Cidre 2018-03-22 13:31:12 +01:00
parent 01769e9ee8
commit 18fbebc942
No known key found for this signature in database
GPG Key ID: D246A27D58A92CAB
20 changed files with 413 additions and 544 deletions

View File

@ -1,7 +1,6 @@
package account
import (
"context"
"encoding/json"
"errors"
"fmt"
@ -14,30 +13,32 @@ import (
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/status-im/status-go/extkeys"
"github.com/status-im/status-go/geth/common"
"github.com/status-im/status-go/geth/rpc"
)
// errors
var (
ErrAddressToAccountMappingFailure = errors.New("cannot retrieve a valid account for a given address")
ErrAccountToKeyMappingFailure = errors.New("cannot retrieve a valid key for a given account")
ErrWhisperIdentityInjectionFailure = errors.New("failed to inject identity into Whisper")
ErrWhisperClearIdentitiesFailure = errors.New("failed to clear whisper identities")
ErrNoAccountSelected = errors.New("no account has been selected, please login")
ErrInvalidMasterKeyCreated = errors.New("can not create master extended key")
ErrAddressToAccountMappingFailure = errors.New("cannot retrieve a valid account for a given address")
ErrAccountToKeyMappingFailure = errors.New("cannot retrieve a valid key for a given account")
ErrNoAccountSelected = errors.New("no account has been selected, please login")
ErrInvalidMasterKeyCreated = errors.New("can not create master extended key")
)
// Manager represents account manager interface
type Manager struct {
nodeManager common.NodeManager
selectedAccount *common.SelectedExtKey // account that was processed during the last call to SelectAccount()
// GethServiceProvider provides required geth services.
type GethServiceProvider interface {
AccountManager() (*accounts.Manager, error)
AccountKeyStore() (*keystore.KeyStore, error)
}
// NewManager returns new node account manager
func NewManager(nodeManager common.NodeManager) *Manager {
// Manager represents account manager interface.
type Manager struct {
geth GethServiceProvider
selectedAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
}
// NewManager returns new node account manager.
func NewManager(geth GethServiceProvider) *Manager {
return &Manager{
nodeManager: nodeManager,
geth: geth,
}
}
@ -72,7 +73,7 @@ func (m *Manager) CreateAccount(password string) (address, pubKey, mnemonic stri
// CKD#2 is used as root for master accounts (when parentAddress is "").
// Otherwise (when parentAddress != ""), child is derived directly from parent.
func (m *Manager) CreateChildAccount(parentAddress, password string) (address, pubKey string, err error) {
keyStore, err := m.nodeManager.AccountKeyStore()
keyStore, err := m.geth.AccountKeyStore()
if err != nil {
return "", "", err
}
@ -85,7 +86,7 @@ func (m *Manager) CreateChildAccount(parentAddress, password string) (address, p
return "", "", ErrNoAccountSelected
}
account, err := common.ParseAccountString(parentAddress)
account, err := ParseAccountString(parentAddress)
if err != nil {
return "", "", ErrAddressToAccountMappingFailure
}
@ -203,15 +204,14 @@ func (m *Manager) VerifyAccountPassword(keyStoreDir, address, password string) (
}
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
// using provided password. Once verification is done, decrypted key is injected into Whisper (as a single identity,
// all previous identities are removed).
// using provided password. Once verification is done, all previous identities are removed).
func (m *Manager) SelectAccount(address, password string) error {
keyStore, err := m.nodeManager.AccountKeyStore()
keyStore, err := m.geth.AccountKeyStore()
if err != nil {
return err
}
account, err := common.ParseAccountString(address)
account, err := ParseAccountString(address)
if err != nil {
return ErrAddressToAccountMappingFailure
}
@ -221,22 +221,12 @@ func (m *Manager) SelectAccount(address, password string) error {
return fmt.Errorf("%s: %v", ErrAccountToKeyMappingFailure.Error(), err)
}
whisperService, err := m.nodeManager.WhisperService()
if err != nil {
return err
}
err = whisperService.SelectKeyPair(accountKey.PrivateKey)
if err != nil {
return ErrWhisperIdentityInjectionFailure
}
// persist account key for easier recovery of currently selected key
subAccounts, err := m.findSubAccounts(accountKey.ExtendedKey, accountKey.SubAccountIndex)
if err != nil {
return err
}
m.selectedAccount = &common.SelectedExtKey{
m.selectedAccount = &SelectedExtKey{
Address: account.Address,
AccountKey: accountKey,
SubAccounts: subAccounts,
@ -246,44 +236,15 @@ func (m *Manager) SelectAccount(address, password string) error {
}
// SelectedAccount returns currently selected account
func (m *Manager) SelectedAccount() (*common.SelectedExtKey, error) {
func (m *Manager) SelectedAccount() (*SelectedExtKey, error) {
if m.selectedAccount == nil {
return nil, ErrNoAccountSelected
}
return m.selectedAccount, nil
}
// ReSelectAccount selects previously selected account, often, after node restart.
func (m *Manager) ReSelectAccount() error {
selectedAccount := m.selectedAccount
if selectedAccount == nil {
return nil
}
whisperService, err := m.nodeManager.WhisperService()
if err != nil {
return err
}
if err := whisperService.SelectKeyPair(selectedAccount.AccountKey.PrivateKey); err != nil {
return ErrWhisperIdentityInjectionFailure
}
return nil
}
// Logout clears whisper identities
// Logout clears selectedAccount.
func (m *Manager) Logout() error {
whisperService, err := m.nodeManager.WhisperService()
if err != nil {
return err
}
err = whisperService.DeleteKeyPairs()
if err != nil {
return fmt.Errorf("%s: %v", ErrWhisperClearIdentitiesFailure, err)
}
m.selectedAccount = nil
return nil
@ -292,7 +253,7 @@ func (m *Manager) Logout() error {
// importExtendedKey processes incoming extended key, extracts required info and creates corresponding account key.
// Once account key is formed, that key is put (if not already) into keystore i.e. key is *encoded* into key file.
func (m *Manager) importExtendedKey(extKey *extkeys.ExtendedKey, password string) (address, pubKey string, err error) {
keyStore, err := m.nodeManager.AccountKeyStore()
keyStore, err := m.geth.AccountKeyStore()
if err != nil {
return "", "", err
}
@ -317,7 +278,7 @@ func (m *Manager) importExtendedKey(extKey *extkeys.ExtendedKey, password string
// Accounts returns list of addresses for selected account, including
// subaccounts.
func (m *Manager) Accounts() ([]gethcommon.Address, error) {
am, err := m.nodeManager.AccountManager()
am, err := m.geth.AccountManager()
if err != nil {
return nil, err
}
@ -353,13 +314,6 @@ func (m *Manager) Accounts() ([]gethcommon.Address, error) {
return filtered, nil
}
// AccountsRPCHandler returns RPC Handler for the Accounts() method.
func (m *Manager) AccountsRPCHandler() rpc.Handler {
return func(context.Context, ...interface{}) (interface{}, error) {
return m.Accounts()
}
}
// refreshSelectedAccount re-populates list of sub-accounts of the currently selected account (if any)
func (m *Manager) refreshSelectedAccount() {
if m.selectedAccount == nil {
@ -376,7 +330,7 @@ func (m *Manager) refreshSelectedAccount() {
if err != nil {
return
}
m.selectedAccount = &common.SelectedExtKey{
m.selectedAccount = &SelectedExtKey{
Address: m.selectedAccount.Address,
AccountKey: m.selectedAccount.AccountKey,
SubAccounts: subAccounts,
@ -387,7 +341,7 @@ func (m *Manager) refreshSelectedAccount() {
// that belong to the currently selected account.
// The extKey is CKD#2 := root of sub-accounts of the main account
func (m *Manager) findSubAccounts(extKey *extkeys.ExtendedKey, subAccountIndex uint32) ([]accounts.Account, error) {
keyStore, err := m.nodeManager.AccountKeyStore()
keyStore, err := m.geth.AccountKeyStore()
if err != nil {
return []accounts.Account{}, err
}
@ -421,12 +375,12 @@ func (m *Manager) findSubAccounts(extKey *extkeys.ExtendedKey, subAccountIndex u
// The running node, has a keystore directory which is loaded on start. Key file
// for a given address is expected to be in that directory prior to node start.
func (m *Manager) AddressToDecryptedAccount(address, password string) (accounts.Account, *keystore.Key, error) {
keyStore, err := m.nodeManager.AccountKeyStore()
keyStore, err := m.geth.AccountKeyStore()
if err != nil {
return accounts.Account{}, nil, err
}
account, err := common.ParseAccountString(address)
account, err := ParseAccountString(address)
if err != nil {
return accounts.Account{}, nil, ErrAddressToAccountMappingFailure
}

View File

@ -12,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
gethcommon "github.com/ethereum/go-ethereum/common"
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
"github.com/golang/mock/gomock"
"github.com/status-im/status-go/geth/common"
. "github.com/status-im/status-go/t/utils"
@ -115,7 +114,6 @@ func TestVerifyAccountPasswordWithAccountBeforeEIP55(t *testing.T) {
}
var (
errWhisper = errors.New("Can't return a whisper service")
errKeyStore = errors.New("Can't return a key store")
errAccManager = errors.New("Can't return an account manager")
)
@ -149,7 +147,6 @@ func TestManagerTestSuite(t *testing.T) {
nodeManager: nodeManager,
accManager: accManager,
keyStore: keyStore,
shh: whisper.New(nil),
gethAccManager: accounts.NewManager(),
}
@ -167,7 +164,6 @@ type ManagerTestSuite struct {
nodeManager *common.MockNodeManager
accManager *Manager
keyStore *keystore.KeyStore
shh *whisper.Whisper
gethAccManager *accounts.Manager
}
@ -183,7 +179,7 @@ type testAccount struct {
// development so this is a good workaround to use with EXPECT().Func().AnyTimes()
func (s *ManagerTestSuite) reinitMock() {
s.nodeManager = newMockNodeManager(s.T())
s.accManager.nodeManager = s.nodeManager
s.accManager.geth = s.nodeManager
}
// SetupTest is used here for reinitializing the mock before every
@ -219,7 +215,6 @@ func (s *ManagerTestSuite) TestSelectAccount() {
testCases := []struct {
name string
accountKeyStoreReturn []interface{}
whisperServiceReturn []interface{}
address string
password string
expectedError error
@ -227,7 +222,6 @@ func (s *ManagerTestSuite) TestSelectAccount() {
{
"success",
[]interface{}{s.keyStore, nil},
[]interface{}{s.shh, nil},
s.address,
s.password,
nil,
@ -235,23 +229,13 @@ func (s *ManagerTestSuite) TestSelectAccount() {
{
"fail_keyStore",
[]interface{}{nil, errKeyStore},
[]interface{}{s.shh, nil},
s.address,
s.password,
errKeyStore,
},
{
"fail_whisperService",
[]interface{}{s.keyStore, nil},
[]interface{}{nil, errWhisper},
s.address,
s.password,
errWhisper,
},
{
"fail_wrongAddress",
[]interface{}{s.keyStore, nil},
[]interface{}{s.shh, nil},
"wrong-address",
s.password,
ErrAddressToAccountMappingFailure,
@ -259,7 +243,6 @@ func (s *ManagerTestSuite) TestSelectAccount() {
{
"fail_wrongPassword",
[]interface{}{s.keyStore, nil},
[]interface{}{s.shh, nil},
s.address,
"wrong-password",
errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase"),
@ -270,7 +253,6 @@ func (s *ManagerTestSuite) TestSelectAccount() {
s.T().Run(testCase.name, func(t *testing.T) {
s.reinitMock()
s.nodeManager.EXPECT().AccountKeyStore().Return(testCase.accountKeyStoreReturn...).AnyTimes()
s.nodeManager.EXPECT().WhisperService().Return(testCase.whisperServiceReturn...).AnyTimes()
err := s.accManager.SelectAccount(testCase.address, testCase.password)
s.Equal(testCase.expectedError, err)
})
@ -290,7 +272,6 @@ func (s *ManagerTestSuite) TestCreateChildAccount() {
// Now, select the test account for rest of the test cases.
s.reinitMock()
s.nodeManager.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
s.nodeManager.EXPECT().WhisperService().Return(s.shh, nil).AnyTimes()
err := s.accManager.SelectAccount(s.address, s.password)
s.NoError(err)
@ -347,60 +328,16 @@ func (s *ManagerTestSuite) TestCreateChildAccount() {
}
}
func (s *ManagerTestSuite) TestSelectedAndReSelectAccount() {
// Select the test account
s.nodeManager.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
s.nodeManager.EXPECT().WhisperService().Return(s.shh, nil).AnyTimes()
err := s.accManager.SelectAccount(s.address, s.password)
s.NoError(err)
s.T().Run("success", func(t *testing.T) {
acc, err := s.accManager.SelectedAccount()
s.NoError(err)
s.NotNil(acc)
err = s.accManager.ReSelectAccount()
s.NoError(err)
})
s.T().Run("ReSelect_fail_whisper", func(t *testing.T) {
s.reinitMock()
s.nodeManager.EXPECT().WhisperService().Return(nil, errWhisper).AnyTimes()
err = s.accManager.ReSelectAccount()
s.Equal(errWhisper, err)
})
s.accManager.selectedAccount = nil
s.reinitMock()
s.nodeManager.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
s.nodeManager.EXPECT().WhisperService().Return(s.shh, nil).AnyTimes()
s.T().Run("Selected_fail_noAccount", func(t *testing.T) {
_, err := s.accManager.SelectedAccount()
s.Equal(ErrNoAccountSelected, err)
})
s.T().Run("ReSelect_success_noAccount", func(t *testing.T) {
err = s.accManager.ReSelectAccount()
s.NoError(err)
})
}
func (s *ManagerTestSuite) TestLogout() {
s.nodeManager.EXPECT().WhisperService().Return(s.shh, nil)
err := s.accManager.Logout()
s.NoError(err)
s.nodeManager.EXPECT().WhisperService().Return(nil, errWhisper)
err = s.accManager.Logout()
s.Equal(errWhisper, err)
s.Nil(err)
s.Nil(s.accManager.selectedAccount)
}
// TestAccounts tests cases for (*Manager).Accounts.
func (s *ManagerTestSuite) TestAccounts() {
// Select the test account
s.nodeManager.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
s.nodeManager.EXPECT().WhisperService().Return(s.shh, nil).AnyTimes()
err := s.accManager.SelectAccount(s.address, s.password)
s.NoError(err)

62
geth/account/utils.go Normal file
View File

@ -0,0 +1,62 @@
package account
import (
"errors"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
)
// errors
var (
ErrInvalidAccountAddressOrKey = errors.New("cannot parse address or key to valid account address")
)
// SelectedExtKey is a container for the selected (logged in) external account.
type SelectedExtKey struct {
Address common.Address
AccountKey *keystore.Key
SubAccounts []accounts.Account
}
// Hex dumps address of a given extended key as hex string.
func (k *SelectedExtKey) Hex() string {
if k == nil {
return "0x0"
}
return k.Address.Hex()
}
// ParseAccountString parses hex encoded string and returns is as accounts.Account.
func ParseAccountString(account string) (accounts.Account, error) {
// valid address, convert to account
if common.IsHexAddress(account) {
return accounts.Account{Address: common.HexToAddress(account)}, nil
}
return accounts.Account{}, ErrInvalidAccountAddressOrKey
}
// FromAddress converts account address from string to common.Address.
// The function is useful to format "From" field of send transaction struct.
func FromAddress(accountAddress string) common.Address {
from, err := ParseAccountString(accountAddress)
if err != nil {
return common.Address{}
}
return from.Address
}
// ToAddress converts account address from string to *common.Address.
// The function is useful to format "To" field of send transaction struct.
func ToAddress(accountAddress string) *common.Address {
to, err := ParseAccountString(accountAddress)
if err != nil {
return nil
}
return &to.Address
}

View File

@ -0,0 +1,67 @@
package account
// Basic imports
import (
"testing"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/suite"
)
type AccountUtilsTestSuite struct {
suite.Suite
validKey string
}
func (suite *AccountUtilsTestSuite) SetupTest() {
suite.validKey = "0xF35E0325dad87e2661c4eF951d58727e6d583d5c"
}
func (suite *AccountUtilsTestSuite) TestToAddress() {
addr := ToAddress(suite.validKey)
suite.Equal(suite.validKey, addr.String())
}
func (suite *AccountUtilsTestSuite) TestToAddressInvalidAddress() {
addr := ToAddress("foobar")
suite.Nil(addr)
}
func (suite *AccountUtilsTestSuite) TestFromAddress() {
var flagtests = []struct {
in string
out string
}{
{suite.validKey, suite.validKey},
{"foobar", "0x0000000000000000000000000000000000000000"},
}
for _, tt := range flagtests {
addr := FromAddress(tt.in)
suite.Equal(tt.out, addr.String())
}
}
func (suite *AccountUtilsTestSuite) TestHex() {
var addr *SelectedExtKey
cr, _ := crypto.GenerateKey()
var flagtests = []struct {
in *SelectedExtKey
out string
}{
{&SelectedExtKey{
Address: FromAddress(suite.validKey),
AccountKey: &keystore.Key{PrivateKey: cr},
}, suite.validKey},
{addr, "0x0"},
}
for _, tt := range flagtests {
suite.Equal(tt.in.Hex(), tt.out)
}
}
func TestAccountUtilsTestSuite(t *testing.T) {
suite.Run(t, new(AccountUtilsTestSuite))
}

View File

@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/geth/account"
"github.com/status-im/status-go/geth/common"
"github.com/status-im/status-go/geth/jail"
"github.com/status-im/status-go/geth/params"
@ -39,7 +40,7 @@ func (api *StatusAPI) NodeManager() common.NodeManager {
}
// AccountManager returns reference to account manager
func (api *StatusAPI) AccountManager() common.AccountManager {
func (api *StatusAPI) AccountManager() *account.Manager {
return api.b.AccountManager()
}
@ -135,13 +136,13 @@ func (api *StatusAPI) SelectAccount(address, password string) error {
// FIXME(oleg-raev): This method doesn't make stop, it rather resets its cells to an initial state
// and should be properly renamed, for example: ResetCells
api.b.jailManager.Stop()
return api.b.AccountManager().SelectAccount(address, password)
return api.b.SelectAccount(address, password)
}
// Logout clears whisper identities
func (api *StatusAPI) Logout() error {
api.b.jailManager.Stop()
return api.b.AccountManager().Logout()
return api.b.Logout()
}
// SendTransaction creates a new transaction and waits until it's complete.

View File

@ -2,6 +2,7 @@ package api
import (
"context"
"errors"
"fmt"
"sync"
@ -23,11 +24,18 @@ const (
fcmServerKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx"
)
var (
// ErrWhisperClearIdentitiesFailure clearing whisper identities has failed.
ErrWhisperClearIdentitiesFailure = errors.New("failed to clear whisper identities")
// ErrWhisperIdentityInjectionFailure injecting whisper identities has failed.
ErrWhisperIdentityInjectionFailure = errors.New("failed to inject identity into Whisper")
)
// StatusBackend implements Status.im service
type StatusBackend struct {
mu sync.Mutex
nodeManager *node.NodeManager
accountManager common.AccountManager
accountManager *account.Manager
txQueueManager *transactions.Manager
jailManager jail.Manager
newNotification common.NotificationConstructor
@ -61,7 +69,7 @@ func (b *StatusBackend) NodeManager() *node.NodeManager {
}
// AccountManager returns reference to account manager
func (b *StatusBackend) AccountManager() common.AccountManager {
func (b *StatusBackend) AccountManager() *account.Manager {
return b.accountManager
}
@ -116,7 +124,7 @@ func (b *StatusBackend) startNode(config *params.NodeConfig) (err error) {
if err := b.registerHandlers(); err != nil {
b.log.Error("Handler registration failed", "err", err)
}
if err := b.accountManager.ReSelectAccount(); err != nil {
if err := b.ReSelectAccount(); err != nil {
b.log.Error("Reselect account failed", "err", err)
}
b.log.Info("Account reselected")
@ -226,7 +234,9 @@ func (b *StatusBackend) registerHandlers() error {
if rpcClient == nil {
return node.ErrRPCClient
}
rpcClient.RegisterHandler("eth_accounts", b.accountManager.AccountsRPCHandler())
rpcClient.RegisterHandler("eth_accounts", func(context.Context, ...interface{}) (interface{}, error) {
return b.AccountManager().Accounts()
})
rpcClient.RegisterHandler("eth_sendTransaction", b.txQueueManager.SendTransactionRPCHandler)
return nil
}
@ -247,3 +257,60 @@ func (b *StatusBackend) AppStateChange(state AppState) {
// TODO: put node in low-power mode if the app is in background (or inactive)
// and normal mode if the app is in foreground.
}
// Logout clears whisper identities.
func (b *StatusBackend) Logout() error {
whisperService, err := b.nodeManager.WhisperService()
if err != nil {
return err
}
err = whisperService.DeleteKeyPairs()
if err != nil {
return fmt.Errorf("%s: %v", ErrWhisperClearIdentitiesFailure, err)
}
return b.AccountManager().Logout()
}
// ReSelectAccount selects previously selected account, often, after node restart.
func (b *StatusBackend) ReSelectAccount() error {
selectedAccount, err := b.AccountManager().SelectedAccount()
if selectedAccount == nil || err == account.ErrNoAccountSelected {
return nil
}
whisperService, err := b.nodeManager.WhisperService()
if err != nil {
return err
}
if err := whisperService.SelectKeyPair(selectedAccount.AccountKey.PrivateKey); err != nil {
return ErrWhisperIdentityInjectionFailure
}
return nil
}
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
// using provided password. Once verification is done, decrypted key is injected into Whisper (as a single identity,
// all previous identities are removed).
func (b *StatusBackend) SelectAccount(address, password string) error {
err := b.accountManager.SelectAccount(address, password)
if err != nil {
return err
}
acc, err := b.accountManager.SelectedAccount()
if err != nil {
return err
}
whisperService, err := b.nodeManager.WhisperService()
if err != nil {
return err
}
err = whisperService.SelectKeyPair(acc.AccountKey.PrivateKey)
if err != nil {
return ErrWhisperIdentityInjectionFailure
}
return nil
}

View File

@ -27,22 +27,6 @@ var (
ErrDeprecatedMethod = errors.New("Method is depricated and will be removed in future release")
)
// SelectedExtKey is a container for currently selected (logged in) account
type SelectedExtKey struct {
Address common.Address
AccountKey *keystore.Key
SubAccounts []accounts.Account
}
// Hex dumps address of a given extended key as hex string
func (k *SelectedExtKey) Hex() string {
if k == nil {
return "0x0"
}
return k.Address.Hex()
}
// NodeManager defines expected methods for managing Status node
type NodeManager interface {
// StartNode start Status node, fails if node is already started
@ -89,53 +73,6 @@ type NodeManager interface {
RPCClient() *rpc.Client
}
// AccountManager defines expected methods for managing Status accounts
type AccountManager interface {
// CreateAccount creates an internal geth account
// BIP44-compatible keys are generated: CKD#1 is stored as account key, CKD#2 stored as sub-account root
// Public key of CKD#1 is returned, with CKD#2 securely encoded into account key file (to be used for
// sub-account derivations)
CreateAccount(password string) (address, pubKey, mnemonic string, err error)
// CreateChildAccount creates sub-account for an account identified by parent address.
// CKD#2 is used as root for master accounts (when parentAddress is "").
// Otherwise (when parentAddress != ""), child is derived directly from parent.
CreateChildAccount(parentAddress, password string) (address, pubKey string, err error)
// RecoverAccount re-creates master key using given details.
// Once master key is re-generated, it is inserted into keystore (if not already there).
RecoverAccount(password, mnemonic string) (address, pubKey string, err error)
// VerifyAccountPassword tries to decrypt a given account key file, with a provided password.
// If no error is returned, then account is considered verified.
VerifyAccountPassword(keyStoreDir, address, password string) (*keystore.Key, error)
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
// using provided password. Once verification is done, decrypted key is injected into Whisper (as a single identity,
// all previous identities are removed).
SelectAccount(address, password string) error
// ReSelectAccount selects previously selected account, often, after node restart.
ReSelectAccount() error
// SelectedAccount returns currently selected account
SelectedAccount() (*SelectedExtKey, error)
// Logout clears whisper identities
Logout() error
// Accounts returns handler to process account list request
Accounts() ([]common.Address, error)
// AccountsRPCHandler returns RPC wrapper for Accounts()
AccountsRPCHandler() rpc.Handler
// AddressToDecryptedAccount tries to load decrypted key for a given account.
// The running node, has a keystore directory which is loaded on start. Key file
// for a given address is expected to be in that directory prior to node start.
AddressToDecryptedAccount(address, password string) (accounts.Account, *keystore.Key, error)
}
// TransactionResult is a JSON returned from transaction complete function (used internally)
type TransactionResult struct {
Hash common.Hash

View File

@ -10,7 +10,6 @@ import (
accounts "github.com/ethereum/go-ethereum/accounts"
keystore "github.com/ethereum/go-ethereum/accounts/keystore"
common "github.com/ethereum/go-ethereum/common"
les "github.com/ethereum/go-ethereum/les"
node "github.com/ethereum/go-ethereum/node"
whisperv6 "github.com/ethereum/go-ethereum/whisper/whisperv6"
@ -215,170 +214,3 @@ func (m *MockNodeManager) RPCClient() *rpc.Client {
func (mr *MockNodeManagerMockRecorder) RPCClient() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RPCClient", reflect.TypeOf((*MockNodeManager)(nil).RPCClient))
}
// MockAccountManager is a mock of AccountManager interface
type MockAccountManager struct {
ctrl *gomock.Controller
recorder *MockAccountManagerMockRecorder
}
// MockAccountManagerMockRecorder is the mock recorder for MockAccountManager
type MockAccountManagerMockRecorder struct {
mock *MockAccountManager
}
// NewMockAccountManager creates a new mock instance
func NewMockAccountManager(ctrl *gomock.Controller) *MockAccountManager {
mock := &MockAccountManager{ctrl: ctrl}
mock.recorder = &MockAccountManagerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockAccountManager) EXPECT() *MockAccountManagerMockRecorder {
return m.recorder
}
// CreateAccount mocks base method
func (m *MockAccountManager) CreateAccount(password string) (string, string, string, error) {
ret := m.ctrl.Call(m, "CreateAccount", password)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(string)
ret2, _ := ret[2].(string)
ret3, _ := ret[3].(error)
return ret0, ret1, ret2, ret3
}
// CreateAccount indicates an expected call of CreateAccount
func (mr *MockAccountManagerMockRecorder) CreateAccount(password interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAccount", reflect.TypeOf((*MockAccountManager)(nil).CreateAccount), password)
}
// CreateChildAccount mocks base method
func (m *MockAccountManager) CreateChildAccount(parentAddress, password string) (string, string, error) {
ret := m.ctrl.Call(m, "CreateChildAccount", parentAddress, password)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(string)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// CreateChildAccount indicates an expected call of CreateChildAccount
func (mr *MockAccountManagerMockRecorder) CreateChildAccount(parentAddress, password interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateChildAccount", reflect.TypeOf((*MockAccountManager)(nil).CreateChildAccount), parentAddress, password)
}
// RecoverAccount mocks base method
func (m *MockAccountManager) RecoverAccount(password, mnemonic string) (string, string, error) {
ret := m.ctrl.Call(m, "RecoverAccount", password, mnemonic)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(string)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// RecoverAccount indicates an expected call of RecoverAccount
func (mr *MockAccountManagerMockRecorder) RecoverAccount(password, mnemonic interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecoverAccount", reflect.TypeOf((*MockAccountManager)(nil).RecoverAccount), password, mnemonic)
}
// VerifyAccountPassword mocks base method
func (m *MockAccountManager) VerifyAccountPassword(keyStoreDir, address, password string) (*keystore.Key, error) {
ret := m.ctrl.Call(m, "VerifyAccountPassword", keyStoreDir, address, password)
ret0, _ := ret[0].(*keystore.Key)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// VerifyAccountPassword indicates an expected call of VerifyAccountPassword
func (mr *MockAccountManagerMockRecorder) VerifyAccountPassword(keyStoreDir, address, password interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyAccountPassword", reflect.TypeOf((*MockAccountManager)(nil).VerifyAccountPassword), keyStoreDir, address, password)
}
// SelectAccount mocks base method
func (m *MockAccountManager) SelectAccount(address, password string) error {
ret := m.ctrl.Call(m, "SelectAccount", address, password)
ret0, _ := ret[0].(error)
return ret0
}
// SelectAccount indicates an expected call of SelectAccount
func (mr *MockAccountManagerMockRecorder) SelectAccount(address, password interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectAccount", reflect.TypeOf((*MockAccountManager)(nil).SelectAccount), address, password)
}
// ReSelectAccount mocks base method
func (m *MockAccountManager) ReSelectAccount() error {
ret := m.ctrl.Call(m, "ReSelectAccount")
ret0, _ := ret[0].(error)
return ret0
}
// ReSelectAccount indicates an expected call of ReSelectAccount
func (mr *MockAccountManagerMockRecorder) ReSelectAccount() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReSelectAccount", reflect.TypeOf((*MockAccountManager)(nil).ReSelectAccount))
}
// SelectedAccount mocks base method
func (m *MockAccountManager) SelectedAccount() (*SelectedExtKey, error) {
ret := m.ctrl.Call(m, "SelectedAccount")
ret0, _ := ret[0].(*SelectedExtKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SelectedAccount indicates an expected call of SelectedAccount
func (mr *MockAccountManagerMockRecorder) SelectedAccount() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectedAccount", reflect.TypeOf((*MockAccountManager)(nil).SelectedAccount))
}
// Logout mocks base method
func (m *MockAccountManager) Logout() error {
ret := m.ctrl.Call(m, "Logout")
ret0, _ := ret[0].(error)
return ret0
}
// Logout indicates an expected call of Logout
func (mr *MockAccountManagerMockRecorder) Logout() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logout", reflect.TypeOf((*MockAccountManager)(nil).Logout))
}
// Accounts mocks base method
func (m *MockAccountManager) Accounts() ([]common.Address, error) {
ret := m.ctrl.Call(m, "Accounts")
ret0, _ := ret[0].([]common.Address)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Accounts indicates an expected call of Accounts
func (mr *MockAccountManagerMockRecorder) Accounts() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accounts", reflect.TypeOf((*MockAccountManager)(nil).Accounts))
}
// AccountsRPCHandler mocks base method
func (m *MockAccountManager) AccountsRPCHandler() rpc.Handler {
ret := m.ctrl.Call(m, "AccountsRPCHandler")
ret0, _ := ret[0].(rpc.Handler)
return ret0
}
// AccountsRPCHandler indicates an expected call of AccountsRPCHandler
func (mr *MockAccountManagerMockRecorder) AccountsRPCHandler() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountsRPCHandler", reflect.TypeOf((*MockAccountManager)(nil).AccountsRPCHandler))
}
// AddressToDecryptedAccount mocks base method
func (m *MockAccountManager) AddressToDecryptedAccount(address, password string) (accounts.Account, *keystore.Key, error) {
ret := m.ctrl.Call(m, "AddressToDecryptedAccount", address, password)
ret0, _ := ret[0].(accounts.Account)
ret1, _ := ret[1].(*keystore.Key)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// AddressToDecryptedAccount indicates an expected call of AddressToDecryptedAccount
func (mr *MockAccountManagerMockRecorder) AddressToDecryptedAccount(address, password interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddressToDecryptedAccount", reflect.TypeOf((*MockAccountManager)(nil).AddressToDecryptedAccount), address, password)
}

View File

@ -3,7 +3,6 @@ package common
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -13,8 +12,6 @@ import (
"runtime/debug"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/pborman/uuid"
"github.com/status-im/status-go/static"
@ -28,46 +25,9 @@ const (
type contextKey string // in order to make sure that our context key does not collide with keys from other packages
// errors
var (
ErrInvalidAccountAddressOrKey = errors.New("cannot parse address or key to valid account address")
)
// All general log messages in this package should be routed through this logger.
var logger = log.New("package", "status-go/geth/common")
// ParseAccountString parses hex encoded string and returns is as accounts.Account.
func ParseAccountString(account string) (accounts.Account, error) {
// valid address, convert to account
if common.IsHexAddress(account) {
return accounts.Account{Address: common.HexToAddress(account)}, nil
}
return accounts.Account{}, ErrInvalidAccountAddressOrKey
}
// FromAddress converts account address from string to common.Address.
// The function is useful to format "From" field of send transaction struct.
func FromAddress(accountAddress string) common.Address {
from, err := ParseAccountString(accountAddress)
if err != nil {
return common.Address{}
}
return from.Address
}
// ToAddress converts account address from string to *common.Address.
// The function is useful to format "To" field of send transaction struct.
func ToAddress(accountAddress string) *common.Address {
to, err := ParseAccountString(accountAddress)
if err != nil {
return nil
}
return &to.Address
}
// ImportTestAccount imports keystore from static resources, see "static/keys" folder
func ImportTestAccount(keystoreDir, accountFile string) error {
// make sure that keystore folder exists

View File

@ -0,0 +1,58 @@
package transactions
import (
"reflect"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/golang/mock/gomock"
"github.com/status-im/status-go/geth/account"
)
// MockAccountManager is a mock of AccountManager interface
type MockAccountManager struct {
ctrl *gomock.Controller
recorder *MockAccountManagerMockRecorder
}
// MockAccountManagerMockRecorder is the mock recorder for MockAccountManager
type MockAccountManagerMockRecorder struct {
mock *MockAccountManager
}
// NewMockAccountManager creates a new mock instance
func NewMockAccountManager(ctrl *gomock.Controller) *MockAccountManager {
mock := &MockAccountManager{ctrl: ctrl}
mock.recorder = &MockAccountManagerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockAccountManager) EXPECT() *MockAccountManagerMockRecorder {
return m.recorder
}
// VerifyAccountPassword mocks base method
func (m *MockAccountManager) VerifyAccountPassword(keyStoreDir, address, password string) (*keystore.Key, error) {
ret := m.ctrl.Call(m, "VerifyAccountPassword", keyStoreDir, address, password)
ret0, _ := ret[0].(*keystore.Key)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// VerifyAccountPassword indicates an expected call of VerifyAccountPassword
func (mr *MockAccountManagerMockRecorder) VerifyAccountPassword(keyStoreDir, address, password interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyAccountPassword", reflect.TypeOf((*MockAccountManager)(nil).VerifyAccountPassword), keyStoreDir, address, password)
}
// SelectedAccount mocks base method
func (m *MockAccountManager) SelectedAccount() (*account.SelectedExtKey, error) {
ret := m.ctrl.Call(m, "SelectedAccount")
ret0, _ := ret[0].(*account.SelectedExtKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SelectedAccount indicates an expected call of SelectedAccount
func (mr *MockAccountManagerMockRecorder) SelectedAccount() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectedAccount", reflect.TypeOf((*MockAccountManager)(nil).SelectedAccount))
}

View File

@ -0,0 +1,16 @@
package transactions
import (
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/status-im/status-go/geth/account"
)
// Accounter defines expected methods for managing Status accounts.
type Accounter interface {
// SelectedAccount returns currently selected account
SelectedAccount() (*account.SelectedExtKey, error)
// VerifyAccountPassword tries to decrypt a given account key file, with a provided password.
// If no error is returned, then account is considered verified.
VerifyAccountPassword(keyStoreDir, address, password string) (*keystore.Key, error)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/geth/account"
"github.com/status-im/status-go/geth/common"
"github.com/status-im/status-go/geth/params"
"github.com/status-im/status-go/geth/transactions/queue"
@ -29,7 +30,7 @@ const (
// Manager provides means to manage internal Status Backend (injected into LES)
type Manager struct {
nodeManager common.NodeManager
accountManager common.AccountManager
accountManager Accounter
txQueue *queue.TxQueue
ethTxClient EthTransactor
notify bool
@ -42,7 +43,7 @@ type Manager struct {
}
// NewManager returns a new Manager.
func NewManager(nodeManager common.NodeManager, accountManager common.AccountManager) *Manager {
func NewManager(nodeManager common.NodeManager, accountManager Accounter) *Manager {
return &Manager{
nodeManager: nodeManager,
accountManager: accountManager,
@ -151,7 +152,7 @@ func (m *Manager) CompleteTransaction(id common.QueuedTxID, password string) (ha
return hash, err
}
func (m *Manager) validateAccount(config *params.NodeConfig, tx *common.QueuedTx, password string) (*common.SelectedExtKey, error) {
func (m *Manager) validateAccount(config *params.NodeConfig, tx *common.QueuedTx, password string) (*account.SelectedExtKey, error) {
selectedAccount, err := m.accountManager.SelectedAccount()
if err != nil {
m.log.Warn("failed to get a selected account", "err", err)
@ -170,7 +171,7 @@ func (m *Manager) validateAccount(config *params.NodeConfig, tx *common.QueuedTx
return selectedAccount, nil
}
func (m *Manager) completeTransaction(config *params.NodeConfig, selectedAccount *common.SelectedExtKey, queuedTx *common.QueuedTx) (hash gethcommon.Hash, err error) {
func (m *Manager) completeTransaction(config *params.NodeConfig, selectedAccount *account.SelectedExtKey, queuedTx *common.QueuedTx) (hash gethcommon.Hash, err error) {
m.log.Info("complete transaction", "id", queuedTx.ID)
m.addrLock.LockAddr(queuedTx.Args.From)
var localNonce uint64

View File

@ -18,6 +18,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"
"github.com/status-im/status-go/geth/account"
"github.com/status-im/status-go/geth/common"
"github.com/status-im/status-go/geth/params"
"github.com/status-im/status-go/geth/rpc"
@ -35,7 +36,7 @@ type TxQueueTestSuite struct {
nodeManagerMockCtrl *gomock.Controller
nodeManagerMock *common.MockNodeManager
accountManagerMockCtrl *gomock.Controller
accountManagerMock *common.MockAccountManager
accountManagerMock *MockAccountManager
server *gethrpc.Server
client *gethrpc.Client
txServiceMockCtrl *gomock.Controller
@ -51,7 +52,7 @@ func (s *TxQueueTestSuite) SetupTest() {
s.txServiceMockCtrl = gomock.NewController(s.T())
s.nodeManagerMock = common.NewMockNodeManager(s.nodeManagerMockCtrl)
s.accountManagerMock = common.NewMockAccountManager(s.accountManagerMockCtrl)
s.accountManagerMock = NewMockAccountManager(s.accountManagerMockCtrl)
s.server, s.txServiceMock = fake.NewTestServer(s.txServiceMockCtrl)
s.client = gethrpc.DialInProc(s.server)
@ -83,7 +84,7 @@ var (
testNonce = hexutil.Uint64(10)
)
func (s *TxQueueTestSuite) setupTransactionPoolAPI(tx *common.QueuedTx, returnNonce, resultNonce hexutil.Uint64, account *common.SelectedExtKey, txErr error) {
func (s *TxQueueTestSuite) setupTransactionPoolAPI(tx *common.QueuedTx, returnNonce, resultNonce hexutil.Uint64, account *account.SelectedExtKey, txErr error) {
// Expect calls to gas functions only if there are no user defined values.
// And also set the expected gas and gas price for RLP encoding the expected tx.
var usedGas hexutil.Uint64
@ -107,7 +108,7 @@ func (s *TxQueueTestSuite) setupTransactionPoolAPI(tx *common.QueuedTx, returnNo
s.txServiceMock.EXPECT().SendRawTransaction(gomock.Any(), data).Return(gethcommon.Hash{}, txErr)
}
func (s *TxQueueTestSuite) rlpEncodeTx(tx *common.QueuedTx, config *params.NodeConfig, account *common.SelectedExtKey, nonce *hexutil.Uint64, gas hexutil.Uint64, gasPrice *big.Int) hexutil.Bytes {
func (s *TxQueueTestSuite) rlpEncodeTx(tx *common.QueuedTx, config *params.NodeConfig, account *account.SelectedExtKey, nonce *hexutil.Uint64, gas hexutil.Uint64, gasPrice *big.Int) hexutil.Bytes {
newTx := types.NewTransaction(
uint64(*nonce),
gethcommon.Address(*tx.Args.To),
@ -124,7 +125,7 @@ func (s *TxQueueTestSuite) rlpEncodeTx(tx *common.QueuedTx, config *params.NodeC
return hexutil.Bytes(data)
}
func (s *TxQueueTestSuite) setupStatusBackend(account *common.SelectedExtKey, password string, passwordErr error) {
func (s *TxQueueTestSuite) setupStatusBackend(account *account.SelectedExtKey, password string, passwordErr error) {
s.nodeManagerMock.EXPECT().NodeConfig().Return(s.nodeConfig, nil)
s.accountManagerMock.EXPECT().SelectedAccount().Return(account, nil)
s.accountManagerMock.EXPECT().VerifyAccountPassword(s.nodeConfig.KeyStoreDir, account.Address.String(), password).Return(
@ -134,8 +135,8 @@ func (s *TxQueueTestSuite) setupStatusBackend(account *common.SelectedExtKey, pa
func (s *TxQueueTestSuite) TestCompleteTransaction() {
password := TestConfig.Account1.Password
key, _ := crypto.GenerateKey()
account := &common.SelectedExtKey{
Address: common.FromAddress(TestConfig.Account1.Address),
selectedAccount := &account.SelectedExtKey{
Address: account.FromAddress(TestConfig.Account1.Address),
AccountKey: &keystore.Key{PrivateKey: key},
}
testCases := []struct {
@ -168,14 +169,14 @@ func (s *TxQueueTestSuite) TestCompleteTransaction() {
for _, testCase := range testCases {
s.T().Run(testCase.name, func(t *testing.T) {
s.SetupTest()
s.setupStatusBackend(account, password, nil)
s.setupStatusBackend(selectedAccount, password, nil)
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Gas: testCase.gas,
GasPrice: testCase.gasPrice,
})
s.setupTransactionPoolAPI(tx, testNonce, testNonce, account, nil)
s.setupTransactionPoolAPI(tx, testNonce, testNonce, selectedAccount, nil)
s.NoError(s.manager.QueueTransaction(tx))
w := make(chan struct{})
@ -203,18 +204,18 @@ func (s *TxQueueTestSuite) TestCompleteTransaction() {
func (s *TxQueueTestSuite) TestCompleteTransactionMultipleTimes() {
password := TestConfig.Account1.Password
key, _ := crypto.GenerateKey()
account := &common.SelectedExtKey{
Address: common.FromAddress(TestConfig.Account1.Address),
selectedAccount := &account.SelectedExtKey{
Address: account.FromAddress(TestConfig.Account1.Address),
AccountKey: &keystore.Key{PrivateKey: key},
}
s.setupStatusBackend(account, password, nil)
s.setupStatusBackend(selectedAccount, password, nil)
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.setupTransactionPoolAPI(tx, testNonce, testNonce, account, nil)
s.setupTransactionPoolAPI(tx, testNonce, testNonce, selectedAccount, nil)
err := s.manager.QueueTransaction(tx)
s.NoError(err)
@ -257,13 +258,13 @@ func (s *TxQueueTestSuite) TestCompleteTransactionMultipleTimes() {
func (s *TxQueueTestSuite) TestAccountMismatch() {
s.nodeManagerMock.EXPECT().NodeConfig().Return(s.nodeConfig, nil)
s.accountManagerMock.EXPECT().SelectedAccount().Return(&common.SelectedExtKey{
Address: common.FromAddress(TestConfig.Account2.Address),
s.accountManagerMock.EXPECT().SelectedAccount().Return(&account.SelectedExtKey{
Address: account.FromAddress(TestConfig.Account2.Address),
}, nil)
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.NoError(s.manager.QueueTransaction(tx))
@ -279,14 +280,14 @@ func (s *TxQueueTestSuite) TestAccountMismatch() {
func (s *TxQueueTestSuite) TestInvalidPassword() {
password := "invalid-password"
key, _ := crypto.GenerateKey()
account := &common.SelectedExtKey{
Address: common.FromAddress(TestConfig.Account1.Address),
selectedAccount := &account.SelectedExtKey{
Address: account.FromAddress(TestConfig.Account1.Address),
AccountKey: &keystore.Key{PrivateKey: key},
}
s.setupStatusBackend(account, password, keystore.ErrDecrypt)
s.setupStatusBackend(selectedAccount, password, keystore.ErrDecrypt)
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.NoError(s.manager.QueueTransaction(tx))
@ -300,8 +301,8 @@ func (s *TxQueueTestSuite) TestInvalidPassword() {
func (s *TxQueueTestSuite) TestDiscardTransaction() {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.NoError(s.manager.QueueTransaction(tx))
@ -320,8 +321,8 @@ func (s *TxQueueTestSuite) TestDiscardTransaction() {
func (s *TxQueueTestSuite) TestCompletionTimedOut() {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.NoError(s.manager.QueueTransaction(tx))
@ -340,21 +341,21 @@ func (s *TxQueueTestSuite) TestLocalNonce() {
txCount := 3
password := TestConfig.Account1.Password
key, _ := crypto.GenerateKey()
account := &common.SelectedExtKey{
Address: common.FromAddress(TestConfig.Account1.Address),
selectedAccount := &account.SelectedExtKey{
Address: account.FromAddress(TestConfig.Account1.Address),
AccountKey: &keystore.Key{PrivateKey: key},
}
// setup call expectations for 5 transactions in total
for i := 0; i < txCount+2; i++ {
s.setupStatusBackend(account, password, nil)
s.setupStatusBackend(selectedAccount, password, nil)
}
nonce := hexutil.Uint64(0)
for i := 0; i < txCount; i++ {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.setupTransactionPoolAPI(tx, nonce, hexutil.Uint64(i), account, nil)
s.setupTransactionPoolAPI(tx, nonce, hexutil.Uint64(i), selectedAccount, nil)
s.NoError(s.manager.QueueTransaction(tx))
hash, err := s.manager.CompleteTransaction(tx.ID, password)
rst := s.manager.WaitForTransaction(tx)
@ -367,10 +368,10 @@ func (s *TxQueueTestSuite) TestLocalNonce() {
}
nonce = hexutil.Uint64(5)
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.setupTransactionPoolAPI(tx, nonce, nonce, account, nil)
s.setupTransactionPoolAPI(tx, nonce, nonce, selectedAccount, nil)
s.NoError(s.manager.QueueTransaction(tx))
hash, err := s.manager.CompleteTransaction(tx.ID, password)
rst := s.manager.WaitForTransaction(tx)
@ -381,10 +382,10 @@ func (s *TxQueueTestSuite) TestLocalNonce() {
s.Equal(uint64(nonce)+1, resultNonce.(uint64))
testErr := errors.New("test")
s.txServiceMock.EXPECT().GetTransactionCount(gomock.Any(), account.Address, gethrpc.PendingBlockNumber).Return(nil, testErr)
s.txServiceMock.EXPECT().GetTransactionCount(gomock.Any(), selectedAccount.Address, gethrpc.PendingBlockNumber).Return(nil, testErr)
tx = common.CreateTransaction(context.Background(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
})
s.NoError(s.manager.QueueTransaction(tx))
_, err = s.manager.CompleteTransaction(tx.ID, password)

View File

@ -410,7 +410,7 @@ func testCreateChildAccount(t *testing.T) bool { //nolint: gocyclo
address, pubKey, mnemonic := createAccountResponse.Address, createAccountResponse.PubKey, createAccountResponse.Mnemonic
t.Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
acct, err := common.ParseAccountString(address)
acct, err := account.ParseAccountString(address)
if err != nil {
t.Errorf("can not get account from address: %v", err)
return false
@ -548,7 +548,7 @@ func testRecoverAccount(t *testing.T) bool { //nolint: gocyclo
}
// now test recovering, but make sure that account/key file is removed i.e. simulate recovering on a new device
account, err := common.ParseAccountString(address)
account, err := account.ParseAccountString(address)
if err != nil {
t.Errorf("can not get account from address: %v", err)
}
@ -819,8 +819,8 @@ func testCompleteTransaction(t *testing.T) bool {
// this call blocks, up until Complete Transaction is called
txCheckHash, err := statusAPI.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
if err != nil {
@ -884,8 +884,8 @@ func testCompleteMultipleQueuedTransactions(t *testing.T) bool { //nolint: gocyc
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
sendTx := func() {
txHashCheck, err := statusAPI.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
if err != nil {
@ -1067,8 +1067,8 @@ func testDiscardTransaction(t *testing.T) bool { //nolint: gocyclo
// this call blocks, and should return when DiscardQueuedTransaction() is called
txHashCheck, err := statusAPI.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
if err != transactions.ErrQueuedTxDiscarded {
@ -1158,8 +1158,8 @@ func testDiscardMultipleQueuedTransactions(t *testing.T) bool { //nolint: gocycl
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
sendTx := func() {
txHashCheck, err := statusAPI.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
if err != transactions.ErrQueuedTxDiscarded {

View File

@ -23,7 +23,7 @@ func (s *AccountsTestSuite) TestRPCEthAccounts() {
defer s.StopTestBackend()
// log into test account
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
rpcClient := s.Backend.NodeManager().RPCClient()
@ -50,7 +50,7 @@ func (s *AccountsTestSuite) TestRPCEthAccountsWithUpstream() {
defer s.StopTestBackend()
// log into test account
err = s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
rpcClient := s.Backend.NodeManager().RPCClient()

View File

@ -6,7 +6,6 @@ import (
"testing"
"github.com/status-im/status-go/geth/account"
"github.com/status-im/status-go/geth/common"
e2e "github.com/status-im/status-go/t/e2e"
. "github.com/status-im/status-go/t/utils"
"github.com/stretchr/testify/suite"
@ -40,7 +39,7 @@ func (s *AccountsTestSuite) TestAccountsList() {
s.Zero(len(accounts), "accounts returned, while there should be none (we haven't logged in yet)")
// select account (sub-accounts will be created for this key)
err = s.Backend.AccountManager().SelectAccount(address, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(address, TestConfig.Account1.Password)
s.NoError(err, "account selection failed")
// at this point main account should show up
@ -94,7 +93,7 @@ func (s *AccountsTestSuite) TestCreateChildAccount() {
s.NoError(err)
s.T().Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
acct, err := common.ParseAccountString(address)
acct, err := account.ParseAccountString(address)
s.NoError(err, "can not get account from address")
// obtain decrypted key, and make sure that extended key (which will be used as root for sub-accounts) is present
@ -106,7 +105,7 @@ func (s *AccountsTestSuite) TestCreateChildAccount() {
_, _, err = s.Backend.AccountManager().CreateChildAccount("", TestConfig.Account1.Password)
s.EqualError(account.ErrNoAccountSelected, err.Error(), "expected error is not returned (tried to create sub-account w/o login)")
err = s.Backend.AccountManager().SelectAccount(address, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(address, TestConfig.Account1.Password)
s.NoError(err, "cannot select account")
// try to create sub-account with wrong password
@ -147,7 +146,7 @@ func (s *AccountsTestSuite) TestRecoverAccount() {
s.False(address != addressCheck || pubKey != pubKeyCheck, "incorrect accound details recovered")
// now test recovering, but make sure that acc/key file is removed i.e. simulate recovering on a new device
acc, err := common.ParseAccountString(address)
acc, err := account.ParseAccountString(address)
s.NoError(err, "can not get acc from address")
acc, key, err := keyStore.AccountDecryptedKey(acc, TestConfig.Account1.Password)
@ -177,7 +176,7 @@ func (s *AccountsTestSuite) TestRecoverAccount() {
// make sure that identity is not (yet injected)
s.False(whisperService.HasKeyPair(pubKeyCheck), "identity already present in whisper")
s.NoError(s.Backend.AccountManager().SelectAccount(addressCheck, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(addressCheck, TestConfig.Account1.Password))
s.True(whisperService.HasKeyPair(pubKeyCheck), "identity not injected into whisper")
}
@ -201,17 +200,17 @@ func (s *AccountsTestSuite) TestSelectAccount() {
s.False(whisperService.HasKeyPair(pubKey1), "identity already present in whisper")
// try selecting with wrong password
err = s.Backend.AccountManager().SelectAccount(address1, "wrongPassword")
err = s.Backend.SelectAccount(address1, "wrongPassword")
expectedErr := errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase")
s.EqualError(expectedErr, err.Error(), "select account is expected to throw error: wrong password used")
err = s.Backend.AccountManager().SelectAccount(address1, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(address1, TestConfig.Account1.Password)
s.NoError(err)
s.True(whisperService.HasKeyPair(pubKey1), "identity not injected into whisper")
// select another account, make sure that previous account is wiped out from Whisper cache
s.False(whisperService.HasKeyPair(pubKey2), "identity already present in whisper")
s.NoError(s.Backend.AccountManager().SelectAccount(address2, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(address2, TestConfig.Account1.Password))
s.True(whisperService.HasKeyPair(pubKey2), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(pubKey1), "identity should be removed, but it is still present in whisper")
}
@ -237,16 +236,16 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
s.Nil(selectedAccount)
// select account
err = s.Backend.AccountManager().SelectAccount(address1, "wrongPassword")
err = s.Backend.SelectAccount(address1, "wrongPassword")
expectedErr := errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase")
s.EqualError(expectedErr, err.Error())
s.NoError(s.Backend.AccountManager().SelectAccount(address1, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(address1, TestConfig.Account1.Password))
s.True(whisperService.HasKeyPair(pubKey1), "identity not injected into whisper")
// select another account, make sure that previous account is wiped out from Whisper cache
s.False(whisperService.HasKeyPair(pubKey2), "identity already present in whisper")
s.NoError(s.Backend.AccountManager().SelectAccount(address2, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(address2, TestConfig.Account1.Password))
s.True(whisperService.HasKeyPair(pubKey2), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(pubKey1), "identity should be removed, but it is still present in whisper")

View File

@ -104,7 +104,7 @@ func (s *APIBackendTestSuite) TestRaceConditions() {
// SelectAccount
log.Info("CreateAccount()")
err = s.Backend.AccountManager().SelectAccount(address, "password")
err = s.Backend.SelectAccount(address, "password")
s.T().Logf("SelectAccount(%v, %v), error: %v", address, "password", err)
// CreateChildAccount

View File

@ -131,7 +131,7 @@ func (s *JailRPCTestSuite) TestContractDeployment() {
event := envelope.Event.(map[string]interface{})
s.T().Logf("transaction queued and will be completed shortly, id: %v", event["id"])
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
txID := event["id"].(string)
var txErr error
@ -197,7 +197,7 @@ func (s *JailRPCTestSuite) TestJailVMPersistence() {
EnsureNodeSync(s.Backend.NodeManager())
// log into account from which transactions will be sent
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err, "cannot select account: %v", TestConfig.Account1.Address)
type testCase struct {

View File

@ -39,7 +39,7 @@ func (s *TransactionsTestSuite) TestCallRPCSendTransaction() {
EnsureNodeSync(s.Backend.NodeManager())
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
transactionCompleted := make(chan struct{})
@ -91,7 +91,7 @@ func (s *TransactionsTestSuite) TestCallRPCSendTransactionUpstream() {
s.StartTestBackend(e2e.WithUpstream(addr))
defer s.StopTestBackend()
err = s.Backend.AccountManager().SelectAccount(TestConfig.Account2.Address, TestConfig.Account2.Password)
err = s.Backend.SelectAccount(TestConfig.Account2.Address, TestConfig.Account2.Password)
s.NoError(err)
transactionCompleted := make(chan struct{})
@ -176,7 +176,7 @@ func (s *TransactionsTestSuite) TestSendContractTx() {
// the second call will also fail (we are logged in as different user)
log.Info("trying to complete with invalid user")
err = s.Backend.AccountManager().SelectAccount(sampleAddress, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(sampleAddress, TestConfig.Account1.Password)
s.NoError(err)
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)),
@ -190,7 +190,7 @@ func (s *TransactionsTestSuite) TestSendContractTx() {
// the third call will work as expected (as we are logged in with correct credentials)
log.Info("trying to complete with correct user, this should succeed")
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)),
TestConfig.Account1.Password,
@ -209,7 +209,7 @@ func (s *TransactionsTestSuite) TestSendContractTx() {
gas := uint64(params.DefaultGas)
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: nil, // marker, contract creation is expected
//Value: (*hexutil.Big)(new(big.Int).Mul(big.NewInt(1), gethcommon.Ether)),
Gas: (*hexutil.Uint64)(&gas),
@ -265,7 +265,7 @@ func (s *TransactionsTestSuite) TestSendEther() {
// the second call will also fail (we are logged in as different user)
log.Info("trying to complete with invalid user")
err = s.Backend.AccountManager().SelectAccount(sampleAddress, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(sampleAddress, TestConfig.Account1.Password)
s.NoError(err)
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)), TestConfig.Account1.Password)
@ -277,7 +277,7 @@ func (s *TransactionsTestSuite) TestSendEther() {
// the third call will work as expected (as we are logged in with correct credentials)
log.Info("trying to complete with correct user, this should succeed")
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)),
TestConfig.Account1.Password,
@ -291,8 +291,8 @@ func (s *TransactionsTestSuite) TestSendEther() {
// this call blocks, up until Complete Transaction is called
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
s.NoError(err, "cannot send transaction")
@ -318,7 +318,7 @@ func (s *TransactionsTestSuite) TestSendEtherTxUpstream() {
s.StartTestBackend(e2e.WithUpstream(addr))
defer s.StopTestBackend()
err = s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err = s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
completeQueuedTransaction := make(chan struct{})
@ -348,8 +348,8 @@ func (s *TransactionsTestSuite) TestSendEtherTxUpstream() {
// This call blocks, up until Complete Transaction is called.
// Explicitly not setting Gas to get it estimated.
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
GasPrice: (*hexutil.Big)(big.NewInt(28000000000)),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
@ -372,7 +372,7 @@ func (s *TransactionsTestSuite) TestDoubleCompleteQueuedTransactions() {
EnsureNodeSync(s.Backend.NodeManager())
// log into account from which transactions will be sent
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
completeQueuedTransaction := make(chan struct{})
@ -421,8 +421,8 @@ func (s *TransactionsTestSuite) TestDoubleCompleteQueuedTransactions() {
// this call blocks, and should return on *second* attempt to CompleteTransaction (w/ the correct password)
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
s.NoError(err, "cannot send transaction")
@ -449,7 +449,7 @@ func (s *TransactionsTestSuite) TestDiscardQueuedTransaction() {
s.Backend.TxQueueManager().TransactionQueue().Reset()
// log into account from which transactions will be sent
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
completeQueuedTransaction := make(chan struct{})
@ -499,8 +499,8 @@ func (s *TransactionsTestSuite) TestDiscardQueuedTransaction() {
// this call blocks, and should return when DiscardQueuedTransaction() is called
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
s.EqualError(err, transactions.ErrQueuedTxDiscarded.Error(), "transaction is expected to be discarded")
@ -523,7 +523,7 @@ func (s *TransactionsTestSuite) TestCompleteMultipleQueuedTransactions() {
s.TxQueueManager().TransactionQueue().Reset()
// log into account from which transactions will be sent
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
s.sendConcurrentTransactions(3)
@ -539,7 +539,7 @@ func (s *TransactionsTestSuite) TestDiscardMultipleQueuedTransactions() {
s.Backend.TxQueueManager().TransactionQueue().Reset()
// log into account from which transactions will be sent
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
testTxCount := 3
txIDs := make(chan common.QueuedTxID, testTxCount)
@ -584,8 +584,8 @@ func (s *TransactionsTestSuite) TestDiscardMultipleQueuedTransactions() {
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
sendTx := func() {
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
require.EqualError(err, transactions.ErrQueuedTxDiscarded.Error())
@ -650,7 +650,7 @@ func (s *TransactionsTestSuite) TestNonExistentQueuedTransactions() {
defer s.StopTestBackend()
// log into account from which transactions will be sent
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
// replace transaction notification handler
signal.SetDefaultNodeNotificationHandler(func(string) {})
@ -688,7 +688,7 @@ func (s *TransactionsTestSuite) TestEvictionOfQueuedTransactions() {
s.Backend.TxQueueManager().TransactionQueue().Reset()
// log into account from which transactions will be sent
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
txQueue := s.Backend.TxQueueManager().TransactionQueue()
s.Zero(txQueue.Count(), "transaction count should be zero")
@ -721,7 +721,7 @@ func (s *TransactionsTestSuite) TestCompleteMultipleQueuedTransactionsUpstream()
s.TxQueueManager().TransactionQueue().Reset()
// log into account from which transactions will be sent
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
s.sendConcurrentTransactions(30)
@ -767,8 +767,8 @@ func (s *TransactionsTestSuite) sendConcurrentTransactions(testTxCount int) {
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
sendTx := func() {
txHashCheck, err := s.Backend.SendTransaction(context.TODO(), common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
From: account.FromAddress(TestConfig.Account1.Address),
To: account.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
require.NoError(err, "cannot send transaction")

View File

@ -92,26 +92,3 @@ func (s *WhisperTestSuite) TestWhisperFilterRace() {
<-allFiltersAdded
}
func (s *WhisperTestSuite) TestLogout() {
s.StartTestNode()
defer s.StopTestNode()
whisperService, err := s.NodeManager.WhisperService()
s.NoError(err)
accountManager := account.NewManager(s.NodeManager)
s.NotNil(accountManager)
// create an account
address, pubKey, _, err := accountManager.CreateAccount(TestConfig.Account1.Password)
s.NoError(err)
// make sure that identity doesn't exist (yet) in Whisper
s.False(whisperService.HasKeyPair(pubKey), "identity already present in whisper")
s.NoError(accountManager.SelectAccount(address, TestConfig.Account1.Password))
s.True(whisperService.HasKeyPair(pubKey), "identity not injected into whisper")
s.NoError(accountManager.Logout())
s.False(whisperService.HasKeyPair(pubKey), "identity not cleared from whisper")
}