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:
Andrea Franz 2019-01-09 09:47:06 +01:00 committed by GitHub
parent 54022561f5
commit 06d4a99c09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 150 additions and 79 deletions

View File

@ -35,8 +35,9 @@ type GethServiceProvider interface {
type Manager struct {
geth GethServiceProvider
mu sync.RWMutex
selectedAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
mu sync.RWMutex
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,
}
}

View File

@ -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)

View File

@ -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
}

View File

@ -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)
}

View File

@ -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")
}