add selected wallet and selected chat accounts (#1326)
* use keyStore.ImportExtendedKeyForPurpose when creating keys * rename selectecAccount to selectedWalletAccount * add selectedChatAccount * update e2e test to check that injected whisper key is the chat public key * update TestSelectedAccountOnRestart to check that chat key is used in whisper * use chat account in api/backend * update mocks * temporarily update VERSION to build a release * check that chat/wallet keys are the same in a different test * add account test to check that wallet and chat keys are the same * test only that the chat key is injected in whisper * put back the right VERSION
This commit is contained in:
parent
54022561f5
commit
06d4a99c09
|
@ -36,7 +36,8 @@ type Manager struct {
|
|||
geth GethServiceProvider
|
||||
|
||||
mu sync.RWMutex
|
||||
selectedAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
|
||||
selectedWalletAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
|
||||
selectedChatAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
|
||||
}
|
||||
|
||||
// NewManager returns new node account manager.
|
||||
|
@ -69,7 +70,7 @@ func (m *Manager) CreateAccount(password string) (address, pubKey, mnemonic stri
|
|||
}
|
||||
|
||||
// import created key into account keystore
|
||||
address, pubKey, err = m.importExtendedKey(extKey, password)
|
||||
address, pubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
@ -89,8 +90,8 @@ func (m *Manager) CreateChildAccount(parentAddress, password string) (address, p
|
|||
return "", "", err
|
||||
}
|
||||
|
||||
if parentAddress == "" && m.selectedAccount != nil { // derive from selected account by default
|
||||
parentAddress = m.selectedAccount.Address.Hex()
|
||||
if parentAddress == "" && m.selectedWalletAccount != nil { // derive from selected account by default
|
||||
parentAddress = m.selectedWalletAccount.Address.Hex()
|
||||
}
|
||||
|
||||
if parentAddress == "" {
|
||||
|
@ -124,14 +125,14 @@ func (m *Manager) CreateChildAccount(parentAddress, password string) (address, p
|
|||
accountKey.SubAccountIndex++
|
||||
|
||||
// import derived key into account keystore
|
||||
address, pubKey, err = m.importExtendedKey(childKey, password)
|
||||
address, pubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, childKey, password)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// update in-memory selected account
|
||||
if m.selectedAccount != nil {
|
||||
m.selectedAccount.AccountKey = accountKey
|
||||
if m.selectedWalletAccount != nil {
|
||||
m.selectedWalletAccount.AccountKey = accountKey
|
||||
}
|
||||
|
||||
return address, pubKey, nil
|
||||
|
@ -148,7 +149,7 @@ func (m *Manager) RecoverAccount(password, mnemonic string) (address, pubKey str
|
|||
}
|
||||
|
||||
// import re-created key into account keystore
|
||||
address, pubKey, err = m.importExtendedKey(extKey, password)
|
||||
address, pubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -240,7 +241,16 @@ func (m *Manager) SelectAccount(address, password string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.selectedAccount = &SelectedExtKey{
|
||||
|
||||
m.selectedWalletAccount = &SelectedExtKey{
|
||||
Address: account.Address,
|
||||
AccountKey: accountKey,
|
||||
SubAccounts: subAccounts,
|
||||
}
|
||||
|
||||
// Before completely decoupling the wallet and chat keys,
|
||||
// we have a selectedChatAccount with the same key used for the wallet.
|
||||
m.selectedChatAccount = &SelectedExtKey{
|
||||
Address: account.Address,
|
||||
AccountKey: accountKey,
|
||||
SubAccounts: subAccounts,
|
||||
|
@ -249,35 +259,47 @@ func (m *Manager) SelectAccount(address, password string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SelectedAccount returns currently selected account
|
||||
func (m *Manager) SelectedAccount() (*SelectedExtKey, error) {
|
||||
// SelectedWalletAccount returns currently selected wallet account
|
||||
func (m *Manager) SelectedWalletAccount() (*SelectedExtKey, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
if m.selectedAccount == nil {
|
||||
if m.selectedWalletAccount == nil {
|
||||
return nil, ErrNoAccountSelected
|
||||
}
|
||||
return m.selectedAccount, nil
|
||||
return m.selectedWalletAccount, nil
|
||||
}
|
||||
|
||||
// Logout clears selectedAccount.
|
||||
// SelectedChatAccount returns currently selected chat account
|
||||
func (m *Manager) SelectedChatAccount() (*SelectedExtKey, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
if m.selectedChatAccount == nil {
|
||||
return nil, ErrNoAccountSelected
|
||||
}
|
||||
return m.selectedChatAccount, nil
|
||||
}
|
||||
|
||||
// Logout clears selectedWalletAccount.
|
||||
func (m *Manager) Logout() {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.selectedAccount = nil
|
||||
m.selectedWalletAccount = nil
|
||||
m.selectedChatAccount = nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
func (m *Manager) importExtendedKey(keyPurpose extkeys.KeyPurpose, extKey *extkeys.ExtendedKey, password string) (address, pubKey string, err error) {
|
||||
keyStore, err := m.geth.AccountKeyStore()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// imports extended key, create key file (if necessary)
|
||||
account, err := keyStore.ImportExtendedKey(extKey, password)
|
||||
account, err := keyStore.ImportExtendedKeyForPurpose(keyPurpose, extKey, password)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
@ -311,20 +333,20 @@ func (m *Manager) Accounts() ([]gethcommon.Address, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if m.selectedAccount == nil {
|
||||
if m.selectedWalletAccount == nil {
|
||||
return []gethcommon.Address{}, nil
|
||||
}
|
||||
|
||||
m.refreshSelectedAccount()
|
||||
m.refreshSelectedWalletAccount()
|
||||
|
||||
filtered := make([]gethcommon.Address, 0)
|
||||
for _, account := range addresses {
|
||||
// main account
|
||||
if m.selectedAccount.Address.Hex() == account.Hex() {
|
||||
if m.selectedWalletAccount.Address.Hex() == account.Hex() {
|
||||
filtered = append(filtered, account)
|
||||
} else {
|
||||
// sub accounts
|
||||
for _, subAccount := range m.selectedAccount.SubAccounts {
|
||||
for _, subAccount := range m.selectedWalletAccount.SubAccounts {
|
||||
if subAccount.Address.Hex() == account.Hex() {
|
||||
filtered = append(filtered, account)
|
||||
}
|
||||
|
@ -335,13 +357,13 @@ func (m *Manager) Accounts() ([]gethcommon.Address, error) {
|
|||
return filtered, nil
|
||||
}
|
||||
|
||||
// refreshSelectedAccount re-populates list of sub-accounts of the currently selected account (if any)
|
||||
func (m *Manager) refreshSelectedAccount() {
|
||||
if m.selectedAccount == nil {
|
||||
// refreshSelectedWalletAccount re-populates list of sub-accounts of the currently selected account (if any)
|
||||
func (m *Manager) refreshSelectedWalletAccount() {
|
||||
if m.selectedWalletAccount == nil {
|
||||
return
|
||||
}
|
||||
|
||||
accountKey := m.selectedAccount.AccountKey
|
||||
accountKey := m.selectedWalletAccount.AccountKey
|
||||
if accountKey == nil {
|
||||
return
|
||||
}
|
||||
|
@ -351,9 +373,9 @@ func (m *Manager) refreshSelectedAccount() {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
m.selectedAccount = &SelectedExtKey{
|
||||
Address: m.selectedAccount.Address,
|
||||
AccountKey: m.selectedAccount.AccountKey,
|
||||
m.selectedWalletAccount = &SelectedExtKey{
|
||||
Address: m.selectedWalletAccount.Address,
|
||||
AccountKey: m.selectedWalletAccount.AccountKey,
|
||||
SubAccounts: subAccounts,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,6 +254,13 @@ func (s *ManagerTestSuite) TestSelectAccount() {
|
|||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(testCase.accountKeyStoreReturn...).AnyTimes()
|
||||
err := s.accManager.SelectAccount(testCase.address, testCase.password)
|
||||
s.Equal(testCase.expectedError, err)
|
||||
|
||||
selectedWalletAccount, err := s.accManager.SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
selectedChatAccount, err := s.accManager.SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
|
||||
s.Equal(selectedWalletAccount.AccountKey, selectedChatAccount.AccountKey)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +268,7 @@ func (s *ManagerTestSuite) TestSelectAccount() {
|
|||
func (s *ManagerTestSuite) TestCreateChildAccount() {
|
||||
// First, test the negative case where an account is not selected
|
||||
// and an address is not provided.
|
||||
s.accManager.selectedAccount = nil
|
||||
s.accManager.selectedWalletAccount = nil
|
||||
s.T().Run("fail_noAccount", func(t *testing.T) {
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
|
||||
_, _, err := s.accManager.CreateChildAccount("", s.password)
|
||||
|
@ -329,7 +336,7 @@ func (s *ManagerTestSuite) TestCreateChildAccount() {
|
|||
|
||||
func (s *ManagerTestSuite) TestLogout() {
|
||||
s.accManager.Logout()
|
||||
s.Nil(s.accManager.selectedAccount)
|
||||
s.Nil(s.accManager.selectedWalletAccount)
|
||||
}
|
||||
|
||||
// TestAccounts tests cases for (*Manager).Accounts.
|
||||
|
@ -351,7 +358,7 @@ func (s *ManagerTestSuite) TestAccounts() {
|
|||
s.Equal(errAccManager, err)
|
||||
|
||||
// Selected account is nil but doesn't fail
|
||||
s.accManager.selectedAccount = nil
|
||||
s.accManager.selectedWalletAccount = nil
|
||||
s.gethServiceProvider.EXPECT().AccountManager().Return(s.gethAccManager, nil)
|
||||
accs, err = s.accManager.Accounts()
|
||||
s.NoError(err)
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/log"
|
||||
gethnode "github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/node"
|
||||
"github.com/status-im/status-go/notifications/push/fcm"
|
||||
|
@ -247,7 +246,7 @@ func (b *StatusBackend) CallPrivateRPC(inputJSON string) (string, error) {
|
|||
|
||||
// SendTransaction creates a new transaction and waits until it's complete.
|
||||
func (b *StatusBackend) SendTransaction(sendArgs transactions.SendTxArgs, password string) (hash gethcommon.Hash, err error) {
|
||||
verifiedAccount, err := b.getVerifiedAccount(password)
|
||||
verifiedAccount, err := b.getVerifiedWalletAccount(password)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
}
|
||||
|
@ -265,7 +264,7 @@ func (b *StatusBackend) SendTransaction(sendArgs transactions.SendTxArgs, passwo
|
|||
// SignMessage checks the pwd vs the selected account and passes on the signParams
|
||||
// to personalAPI for message signature
|
||||
func (b *StatusBackend) SignMessage(rpcParams personal.SignParams) (hexutil.Bytes, error) {
|
||||
verifiedAccount, err := b.getVerifiedAccount(rpcParams.Password)
|
||||
verifiedAccount, err := b.getVerifiedWalletAccount(rpcParams.Password)
|
||||
if err != nil {
|
||||
return hexutil.Bytes{}, err
|
||||
}
|
||||
|
@ -280,7 +279,7 @@ func (b *StatusBackend) Recover(rpcParams personal.RecoverParams) (gethcommon.Ad
|
|||
|
||||
// SignTypedData accepts data and password. Gets verified account and signs typed data.
|
||||
func (b *StatusBackend) SignTypedData(typed typeddata.TypedData, password string) (hexutil.Bytes, error) {
|
||||
account, err := b.getVerifiedAccount(password)
|
||||
account, err := b.getVerifiedWalletAccount(password)
|
||||
if err != nil {
|
||||
return hexutil.Bytes{}, err
|
||||
}
|
||||
|
@ -292,19 +291,19 @@ func (b *StatusBackend) SignTypedData(typed typeddata.TypedData, password string
|
|||
return hexutil.Bytes(sig), err
|
||||
}
|
||||
|
||||
func (b *StatusBackend) getVerifiedAccount(password string) (*account.SelectedExtKey, error) {
|
||||
selectedAccount, err := b.accountManager.SelectedAccount()
|
||||
func (b *StatusBackend) getVerifiedWalletAccount(password string) (*account.SelectedExtKey, error) {
|
||||
selectedWalletAccount, err := b.accountManager.SelectedWalletAccount()
|
||||
if err != nil {
|
||||
b.log.Error("failed to get a selected account", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
config := b.StatusNode().Config()
|
||||
_, err = b.accountManager.VerifyAccountPassword(config.KeyStoreDir, selectedAccount.Address.String(), password)
|
||||
_, err = b.accountManager.VerifyAccountPassword(config.KeyStoreDir, selectedWalletAccount.Address.String(), password)
|
||||
if err != nil {
|
||||
b.log.Error("failed to verify account", "account", selectedAccount.Address.String(), "error", err)
|
||||
b.log.Error("failed to verify account", "account", selectedWalletAccount.Address.String(), "error", err)
|
||||
return nil, err
|
||||
}
|
||||
return selectedAccount, nil
|
||||
return selectedWalletAccount, nil
|
||||
}
|
||||
|
||||
// registerHandlers attaches Status callback handlers to running node
|
||||
|
@ -403,15 +402,16 @@ func (b *StatusBackend) Logout() error {
|
|||
|
||||
// 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 {
|
||||
selectedChatAccount, err := b.AccountManager().SelectedChatAccount()
|
||||
if selectedChatAccount == nil || err == account.ErrNoAccountSelected {
|
||||
return nil
|
||||
}
|
||||
|
||||
whisperService, err := b.statusNode.WhisperService()
|
||||
switch err {
|
||||
case node.ErrServiceUnknown: // Whisper was never registered
|
||||
case nil:
|
||||
if err := whisperService.SelectKeyPair(selectedAccount.AccountKey.PrivateKey); err != nil {
|
||||
if err := whisperService.SelectKeyPair(selectedChatAccount.AccountKey.PrivateKey); err != nil {
|
||||
return ErrWhisperIdentityInjectionFailure
|
||||
}
|
||||
default:
|
||||
|
@ -432,7 +432,7 @@ func (b *StatusBackend) SelectAccount(address, password string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acc, err := b.accountManager.SelectedAccount()
|
||||
chatAccount, err := b.accountManager.SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ func (b *StatusBackend) SelectAccount(address, password string) error {
|
|||
switch err {
|
||||
case node.ErrServiceUnknown: // Whisper was never registered
|
||||
case nil:
|
||||
if err := whisperService.SelectKeyPair(acc.AccountKey.PrivateKey); err != nil {
|
||||
if err := whisperService.SelectKeyPair(chatAccount.AccountKey.PrivateKey); err != nil {
|
||||
return ErrWhisperIdentityInjectionFailure
|
||||
}
|
||||
default:
|
||||
|
@ -483,7 +483,7 @@ func appendIf(condition bool, services []gethnode.ServiceConstructor, service ge
|
|||
|
||||
// CreateContactCode create or return the latest contact code
|
||||
func (b *StatusBackend) CreateContactCode() (string, error) {
|
||||
selectedAccount, err := b.AccountManager().SelectedAccount()
|
||||
selectedChatAccount, err := b.AccountManager().SelectedChatAccount()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -493,7 +493,7 @@ func (b *StatusBackend) CreateContactCode() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
bundle, err := st.GetBundle(selectedAccount.AccountKey.PrivateKey)
|
||||
bundle, err := st.GetBundle(selectedChatAccount.AccountKey.PrivateKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ func (b *StatusBackend) CreateContactCode() (string, error) {
|
|||
|
||||
// ProcessContactCode process and adds the someone else's bundle
|
||||
func (b *StatusBackend) ProcessContactCode(contactCode string) error {
|
||||
selectedAccount, err := b.AccountManager().SelectedAccount()
|
||||
selectedChatAccount, err := b.AccountManager().SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ func (b *StatusBackend) ProcessContactCode(contactCode string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if _, err := st.ProcessPublicBundle(selectedAccount.AccountKey.PrivateKey, bundle); err != nil {
|
||||
if _, err := st.ProcessPublicBundle(selectedChatAccount.AccountKey.PrivateKey, bundle); err != nil {
|
||||
b.log.Error("error adding bundle", "err", err)
|
||||
return err
|
||||
}
|
||||
|
@ -544,17 +544,17 @@ func (b *StatusBackend) ExtractGroupMembershipSignatures(signaturePairs [][2]str
|
|||
|
||||
// SignGroupMembership signs a piece of data containing membership information
|
||||
func (b *StatusBackend) SignGroupMembership(content string) (string, error) {
|
||||
selectedAccount, err := b.AccountManager().SelectedAccount()
|
||||
selectedChatAccount, err := b.AccountManager().SelectedChatAccount()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return crypto.Sign(content, selectedAccount.AccountKey.PrivateKey)
|
||||
return crypto.Sign(content, selectedChatAccount.AccountKey.PrivateKey)
|
||||
}
|
||||
|
||||
// EnableInstallation enables an installation for multi-device sync.
|
||||
func (b *StatusBackend) EnableInstallation(installationID string) error {
|
||||
selectedAccount, err := b.AccountManager().SelectedAccount()
|
||||
selectedChatAccount, err := b.AccountManager().SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ func (b *StatusBackend) EnableInstallation(installationID string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := st.EnableInstallation(&selectedAccount.AccountKey.PrivateKey.PublicKey, installationID); err != nil {
|
||||
if err := st.EnableInstallation(&selectedChatAccount.AccountKey.PrivateKey.PublicKey, installationID); err != nil {
|
||||
b.log.Error("error enabling installation", "err", err)
|
||||
return err
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ func (b *StatusBackend) EnableInstallation(installationID string) error {
|
|||
|
||||
// DisableInstallation disables an installation for multi-device sync.
|
||||
func (b *StatusBackend) DisableInstallation(installationID string) error {
|
||||
selectedAccount, err := b.AccountManager().SelectedAccount()
|
||||
selectedChatAccount, err := b.AccountManager().SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ func (b *StatusBackend) DisableInstallation(installationID string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := st.DisableInstallation(&selectedAccount.AccountKey.PrivateKey.PublicKey, installationID); err != nil {
|
||||
if err := st.DisableInstallation(&selectedChatAccount.AccountKey.PrivateKey.PublicKey, installationID); err != nil {
|
||||
b.log.Error("error disabling installation", "err", err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.NoError(err)
|
||||
|
||||
// make sure that no account is selected by default
|
||||
selectedAccount, err := s.Backend.AccountManager().SelectedAccount()
|
||||
selectedAccount, err := s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "account selected, but should not be")
|
||||
s.Nil(selectedAccount)
|
||||
|
||||
|
@ -225,7 +225,7 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.NoError(s.Backend.StopNode())
|
||||
|
||||
// make sure that account is still selected
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedAccount()
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedAccount)
|
||||
s.Equal(selectedAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
|
@ -234,7 +234,7 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.Require().NoError(s.Backend.StartNode(&preservedNodeConfig))
|
||||
|
||||
// re-check selected account (account2 MUST be selected)
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedAccount()
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedAccount)
|
||||
s.Equal(selectedAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
|
@ -247,7 +247,7 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.NoError(s.Backend.Logout())
|
||||
s.RestartTestNode()
|
||||
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedAccount()
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error())
|
||||
s.Nil(selectedAccount)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/status-im/status-go/account"
|
||||
e2e "github.com/status-im/status-go/t/e2e"
|
||||
|
@ -141,30 +142,44 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
|
|||
// create test accounts
|
||||
address1, pubKey1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
address2, pubKey2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
address2, pubKey2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
s.False(whisperService.HasKeyPair(pubKey1), "identity already present in whisper")
|
||||
|
||||
// make sure that no account is selected by default
|
||||
selectedAccount, err := s.Backend.AccountManager().SelectedAccount()
|
||||
selectedWalletAccount, err := s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "account selected, but should not be")
|
||||
s.Nil(selectedAccount)
|
||||
s.Nil(selectedWalletAccount)
|
||||
|
||||
// select account
|
||||
// make sure that no chat account is selected by default
|
||||
selectedChatAccount, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "account selected, but should not be")
|
||||
s.Nil(selectedChatAccount)
|
||||
|
||||
// select account with wrong password
|
||||
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 with right password
|
||||
s.NoError(s.Backend.SelectAccount(address1, TestConfig.Account1.Password))
|
||||
s.True(whisperService.HasKeyPair(pubKey1), "identity not injected into whisper")
|
||||
selectedChatAccount1, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
selectedChatPubKey1 := hexutil.Encode(crypto.FromECDSAPub(&selectedChatAccount1.AccountKey.PrivateKey.PublicKey))
|
||||
s.Equal(selectedChatPubKey1, pubKey1)
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey1), "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.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")
|
||||
s.NoError(s.Backend.SelectAccount(address2, TestConfig.Account2.Password))
|
||||
selectedChatAccount2, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
selectedChatPubKey2 := hexutil.Encode(crypto.FromECDSAPub(&selectedChatAccount2.AccountKey.PrivateKey.PublicKey))
|
||||
s.Equal(selectedChatPubKey2, pubKey2)
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(selectedChatPubKey1), "identity should be removed, but it is still present in whisper")
|
||||
|
||||
// stop node (and all of its sub-protocols)
|
||||
nodeConfig := s.Backend.StatusNode().Config()
|
||||
|
@ -176,32 +191,59 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.Require().NoError(s.Backend.StartNode(&preservedNodeConfig))
|
||||
|
||||
// re-check selected account (account2 MUST be selected)
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedAccount()
|
||||
selectedWalletAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedAccount)
|
||||
s.Equal(selectedAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
s.NotNil(selectedWalletAccount)
|
||||
s.Equal(selectedWalletAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
|
||||
// make sure that Whisper gets identity re-injected
|
||||
whisperService = s.WhisperService()
|
||||
s.True(whisperService.HasKeyPair(pubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(pubKey1), "identity should not be present, but it is still present in whisper")
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(selectedChatPubKey1), "identity should not be present, but it is still present in whisper")
|
||||
|
||||
// now restart node using RestartNode() method, and make sure that account is still available
|
||||
s.RestartTestNode()
|
||||
defer s.StopTestBackend()
|
||||
|
||||
whisperService = s.WhisperService()
|
||||
s.True(whisperService.HasKeyPair(pubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(pubKey1), "identity should not be present, but it is still present in whisper")
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(selectedChatPubKey1), "identity should not be present, but it is still present in whisper")
|
||||
|
||||
// now logout, and make sure that on restart no account is selected (i.e. logout works properly)
|
||||
s.NoError(s.Backend.Logout())
|
||||
s.RestartTestNode()
|
||||
whisperService = s.WhisperService()
|
||||
s.False(whisperService.HasKeyPair(pubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(pubKey1), "identity should not be present, but it is still present in whisper")
|
||||
s.False(whisperService.HasKeyPair(selectedChatPubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(selectedChatPubKey1), "identity should not be present, but it is still present in whisper")
|
||||
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedAccount()
|
||||
selectedWalletAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error())
|
||||
s.Nil(selectedAccount)
|
||||
s.Nil(selectedWalletAccount)
|
||||
|
||||
selectedChatAccount, err = s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error())
|
||||
s.Nil(selectedChatAccount)
|
||||
}
|
||||
|
||||
func (s *WhisperTestSuite) TestSelectedChatKeyIsUsedInWhisper() {
|
||||
s.StartTestBackend()
|
||||
defer s.StopTestBackend()
|
||||
|
||||
whisperService, err := s.Backend.StatusNode().WhisperService()
|
||||
s.NoError(err)
|
||||
|
||||
// create an account
|
||||
address, _, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// select account
|
||||
s.NoError(s.Backend.SelectAccount(address, TestConfig.Account1.Password))
|
||||
|
||||
// Get the chat account
|
||||
selectedChatAccount, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
|
||||
// chat key should be injected in whisper
|
||||
selectedChatPubKey := hexutil.Encode(crypto.FromECDSAPub(&selectedChatAccount.AccountKey.PrivateKey.PublicKey))
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey), "identity not injected in whisper")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue