Passing Master info to Messenger

This commit is contained in:
Samuel Hawksby-Robinson 2020-12-09 14:03:43 +00:00 committed by Andrea Maria Piana
parent 0b6061b444
commit 16fecf5520
11 changed files with 72 additions and 33 deletions

View File

@ -61,13 +61,15 @@ func (m *Manager) AccountsGenerator() *generator.Generator {
// 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)
func (m *Manager) CreateAccount(password string) (Info, string, error) {
func (m *Manager) CreateAccount(password string) (generator.IdentifiedAccountInfo, Info, string, error) {
var mkInfo generator.IdentifiedAccountInfo
info := Info{}
// generate mnemonic phrase
mn := extkeys.NewMnemonic()
mnemonic, err := mn.MnemonicPhrase(extkeys.EntropyStrength128, extkeys.EnglishLanguage)
if err != nil {
return info, "", fmt.Errorf("can not create mnemonic seed: %v", err)
return mkInfo, info, "", fmt.Errorf("can not create mnemonic seed: %v", err)
}
// Generate extended master key (see BIP32)
@ -77,19 +79,21 @@ func (m *Manager) CreateAccount(password string) (Info, string, error) {
// for expert users, to be able to add a passphrase to the generation of the seed.
extKey, err := extkeys.NewMaster(mn.MnemonicSeed(mnemonic, ""))
if err != nil {
return info, "", fmt.Errorf("can not create master extended key: %v", err)
return mkInfo, info, "", fmt.Errorf("can not create master extended key: %v", err)
}
mkInfo = generator.IdentifiedAccountInfoFromExtKey(extKey)
// import created key into account keystore
info.WalletAddress, info.WalletPubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
if err != nil {
return info, "", err
return mkInfo, info, "", err
}
info.ChatAddress = info.WalletAddress
info.ChatPubKey = info.WalletPubKey
return info, mnemonic, nil
return mkInfo, info, mnemonic, nil
}
// RecoverAccount re-creates master key using given details.

View File

@ -146,7 +146,7 @@ func (s *ManagerTestSuite) SetupTest() {
testPassword := "test-password"
// Initial test - create test account
accountInfo, mnemonic, err := s.accManager.CreateAccount(testPassword)
_, accountInfo, mnemonic, err := s.accManager.CreateAccount(testPassword)
s.Require().NoError(err)
s.Require().NotEmpty(accountInfo.WalletAddress)
s.Require().NotEmpty(accountInfo.WalletPubKey)

View File

@ -79,3 +79,12 @@ type GeneratedAndDerivedAccountInfo struct {
GeneratedAccountInfo
Derived map[string]AccountInfo `json:"derived"`
}
func IdentifiedAccountInfoFromExtKey(extKey *extkeys.ExtendedKey) IdentifiedAccountInfo {
acc := account{
privateKey: extKey.ToECDSA(),
extendedKey: extKey,
}
return acc.toIdentifiedAccountInfo("")
}

View File

@ -242,7 +242,7 @@ func initNodeAndLogin(t *testing.T, backend *GethStatusBackend) (string, string)
require.NoError(t, backend.AccountManager().InitKeystore(config.KeyStoreDir))
err = backend.StartNode(config)
require.NoError(t, err)
info, _, err := backend.AccountManager().CreateAccount(password)
_, info, _, err := backend.AccountManager().CreateAccount(password)
require.NoError(t, err)
loginParams := account.LoginParams{

View File

@ -187,7 +187,7 @@ func TestBackendAccountsConcurrently(t *testing.T) {
for i := 0; i < count; i++ {
wgCreateAccounts.Add(1)
go func(pass string) {
accountInfo, _, err := backend.AccountManager().CreateAccount(pass)
_, accountInfo, _, err := backend.AccountManager().CreateAccount(pass)
assert.NoError(t, err)
addressCh <- [...]string{accountInfo.WalletAddress, accountInfo.ChatAddress, pass}
wgCreateAccounts.Done()

View File

@ -78,6 +78,7 @@ type GethStatusBackend struct {
personalAPI *personal.PublicAPI
rpcFilters *rpcfilters.Service
multiaccountsDB *multiaccounts.Database
account *multiaccounts.Account
accountManager *account.GethManager
transactor *transactions.Transactor
connectionState connectionState
@ -266,6 +267,8 @@ func (b *GethStatusBackend) startNodeWithKey(acc multiaccounts.Account, password
if err := logutils.OverrideRootLogWithConfig(conf, false); err != nil {
return err
}
b.account = &acc
accountsDB := accounts.NewDB(b.appDB)
walletAddr, err := accountsDB.GetWalletAddress()
if err != nil {
@ -322,6 +325,7 @@ func (b *GethStatusBackend) startNodeWithAccount(acc multiaccounts.Account, pass
if err := logutils.OverrideRootLogWithConfig(conf, false); err != nil {
return err
}
b.account = &acc
accountsDB := accounts.NewDB(b.appDB)
chatAddr, err := accountsDB.GetChatAddress()
if err != nil {
@ -1104,6 +1108,14 @@ func (b *GethStatusBackend) SelectAccount(loginParams account.LoginParams) error
return nil
}
func (b *GethStatusBackend) GetActiveAccount() (*multiaccounts.Account, error) {
if b.account == nil {
return nil, errors.New("master key account is nil in the GetStatusBackend")
}
return b.account, nil
}
func (b *GethStatusBackend) injectAccountsIntoServices() error {
chatAccount, err := b.accountManager.SelectedChatAccount()
if err != nil {
@ -1127,13 +1139,18 @@ func (b *GethStatusBackend) injectAccountsIntoServices() error {
return err
}
acc, err := b.GetActiveAccount()
if err != nil {
return err
}
if whisperService != nil {
st, err := b.statusNode.ShhExtService()
if err != nil {
return err
}
if err := st.InitProtocol(identity, b.appDB, b.multiaccountsDB, logutils.ZapLogger()); err != nil {
if err := st.InitProtocol(identity, b.appDB, b.multiaccountsDB, acc, logutils.ZapLogger()); err != nil {
return err
}
return nil
@ -1161,7 +1178,7 @@ func (b *GethStatusBackend) injectAccountsIntoServices() error {
return err
}
if err := st.InitProtocol(identity, b.appDB, b.multiaccountsDB, logutils.ZapLogger()); err != nil {
if err := st.InitProtocol(identity, b.appDB, b.multiaccountsDB, acc, logutils.ZapLogger()); err != nil {
return err
}
}

View File

@ -3,7 +3,6 @@ package protocol
import (
"context"
"crypto/ecdsa"
"crypto/sha256"
"database/sql"
"encoding/hex"
"encoding/json"
@ -22,7 +21,6 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/golang/protobuf/proto"
gethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
enstypes "github.com/status-im/status-go/eth-node/types/ens"
@ -85,6 +83,7 @@ type Messenger struct {
mailserver []byte
database *sql.DB
multiAccounts *multiaccounts.Database
account *multiaccounts.Account
quit chan struct{}
mutex sync.Mutex
@ -285,6 +284,7 @@ func NewMessenger(
verifyTransactionClient: c.verifyTransactionClient,
database: database,
multiAccounts: c.multiAccount,
account: c.account,
quit: make(chan struct{}),
shutdownTasks: []func() error{
database.Close,
@ -573,10 +573,7 @@ func (m *Messenger) shouldPublishChatIdentity(chatID string) (bool, error) {
// context 'public-chat' will attach only the 'thumbnail' IdentityImage
// context 'private-chat' will attach all IdentityImage
func (m *Messenger) createChatIdentity(context string) (*protobuf.ChatIdentity, error) {
keyUIDBytes := sha256.Sum256(gethcrypto.FromECDSAPub(&m.identity.PublicKey))
keyUID := types.EncodeHex(keyUIDBytes[:])
m.logger.Info(fmt.Sprintf("generated keyUID '%s' from PublicKey", keyUID))
m.logger.Info(fmt.Sprintf("account keyUID '%s'", m.account.KeyUID))
m.logger.Info(fmt.Sprintf("context '%s'", context))
ci := &protobuf.ChatIdentity{
@ -590,7 +587,7 @@ func (m *Messenger) createChatIdentity(context string) (*protobuf.ChatIdentity,
case "public-chat":
m.logger.Info(fmt.Sprintf("handling public-chat ChatIdentity"))
img, err := m.multiAccounts.GetIdentityImage(keyUID, userimage.SmallDimName)
img, err := m.multiAccounts.GetIdentityImage(m.account.KeyUID, userimage.SmallDimName)
if err != nil {
return nil, err
}
@ -599,12 +596,12 @@ func (m *Messenger) createChatIdentity(context string) (*protobuf.ChatIdentity,
m.logger.Info(fmt.Sprintf("public-chat images.IdentityImage '%s' '%s'", string(imgJson), spew.Sdump(img)))
ciis[userimage.SmallDimName] = m.adaptIdentityImageToProtobuf(img)
m.logger.Info(fmt.Sprintf("public-chat protobuf.IdentityImage '%s'", spew.Sdump(ciis)))
//m.logger.Info(fmt.Sprintf("public-chat protobuf.IdentityImage '%s'", spew.Sdump(ciis)))
ci.Images = ciis
case "private-chat":
m.logger.Info(fmt.Sprintf("handling private-chat ChatIdentity"))
imgs, err := m.multiAccounts.GetIdentityImages(keyUID)
imgs, err := m.multiAccounts.GetIdentityImages(m.account.KeyUID)
if err != nil {
return nil, err
}

View File

@ -32,6 +32,7 @@ type config struct {
dbConfig dbConfig
db *sql.DB
multiAccount *multiaccounts.Database
account *multiaccounts.Account
verifyTransactionClient EthClient
@ -101,6 +102,13 @@ func WithMultiAccounts(ma *multiaccounts.Database) Option {
}
}
func WithAccount(acc *multiaccounts.Account) Option {
return func(c *config) error {
c.account = acc
return nil
}
}
func WithPushNotificationServerConfig(pushNotificationServerConfig *pushnotificationserver.Config) Option {
return func(c *config) error {
c.pushNotificationServerConfig = pushNotificationServerConfig

View File

@ -70,6 +70,7 @@ type Service struct {
lastUsedMonitor *mailservers.LastUsedConnectionMonitor
accountsDB *accounts.Database
multiAccountsDB *multiaccounts.Database
account *multiaccounts.Account
}
// Make sure that Service implements node.Service interface.
@ -115,7 +116,7 @@ func (s *Service) GetPeer(rawURL string) (*enode.Node, error) {
return enode.ParseV4(rawURL)
}
func (s *Service) InitProtocol(identity *ecdsa.PrivateKey, db *sql.DB, multiAccountDb *multiaccounts.Database, logger *zap.Logger) error {
func (s *Service) InitProtocol(identity *ecdsa.PrivateKey, db *sql.DB, multiAccountDb *multiaccounts.Database, acc *multiaccounts.Account, logger *zap.Logger) error {
if !s.config.PFSEnabled {
return nil
}
@ -148,8 +149,9 @@ func (s *Service) InitProtocol(identity *ecdsa.PrivateKey, db *sql.DB, multiAcco
}
s.accountsDB = accounts.NewDB(db)
s.multiAccountsDB = multiAccountDb
s.account = acc
options, err := buildMessengerOptions(s.config, identity, db, s.multiAccountsDB, envelopesMonitorConfig, s.accountsDB, logger)
options, err := buildMessengerOptions(s.config, identity, db, s.multiAccountsDB, acc, envelopesMonitorConfig, s.accountsDB, logger)
if err != nil {
return err
}
@ -456,6 +458,7 @@ func buildMessengerOptions(
identity *ecdsa.PrivateKey,
db *sql.DB,
multiAccounts *multiaccounts.Database,
account *multiaccounts.Account,
envelopesMonitorConfig *transport.EnvelopesMonitorConfig,
accountsDB *accounts.Database,
logger *zap.Logger,
@ -465,6 +468,7 @@ func buildMessengerOptions(
protocol.WithPushNotifications(),
protocol.WithDatabase(db),
protocol.WithMultiAccounts(multiAccounts),
protocol.WithAccount(account),
protocol.WithEnvelopesMonitorConfig(envelopesMonitorConfig),
protocol.WithOnNegotiatedFilters(onNegotiatedFilters),
}

View File

@ -46,7 +46,7 @@ func (s *AccountsTestSuite) TestAccountsList() {
s.Zero(len(accounts), "accounts returned, while there should be none (we haven't logged in yet)")
// create an account
accountInfo, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
_, accountInfo, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
s.NoError(err)
// ensure that there is still no accounts returned
@ -131,7 +131,7 @@ func (s *AccountsTestSuite) TestRecoverAccount() {
s.NotNil(keyStore)
// create an acc
accountInfo, mnemonic, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
_, accountInfo, mnemonic, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
s.NoError(err)
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s, mnemonic:%s}",
accountInfo.WalletAddress, accountInfo.WalletPubKey, accountInfo.ChatAddress, accountInfo.ChatPubKey, mnemonic)
@ -172,12 +172,12 @@ func (s *AccountsTestSuite) TestSelectAccount() {
defer s.StopTestBackend()
// create an account
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
_, accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
s.NoError(err)
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s}",
accountInfo1.WalletAddress, accountInfo1.WalletPubKey, accountInfo1.ChatAddress, accountInfo1.ChatPubKey)
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
_, accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
s.NoError(err)
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s}",
accountInfo2.WalletAddress, accountInfo2.WalletPubKey, accountInfo2.ChatAddress, accountInfo2.ChatPubKey)
@ -218,9 +218,9 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
s.StartTestBackend()
// create test accounts
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
_, accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
s.NoError(err)
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
_, accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(utils.TestConfig.Account1.Password)
s.NoError(err)
// make sure that no account is selected by default

View File

@ -108,11 +108,11 @@ func (s *WhisperTestSuite) TestSelectAccount() {
s.NoError(err)
// create account 1
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
_, accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
s.NoError(err)
// create account 2
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
_, accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
s.NoError(err)
// make sure that identities are not injected yet
@ -142,7 +142,7 @@ func (s *WhisperTestSuite) TestLogout() {
s.NoError(err)
// create an account
accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
_, accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
s.NoError(err)
// make sure that identity doesn't exist (yet) in Whisper
@ -162,9 +162,9 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
whisperService := s.WhisperService()
// create test accounts
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
_, accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
s.NoError(err)
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
_, accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
s.NoError(err)
// make sure that identity is not (yet injected)
@ -259,7 +259,7 @@ func (s *WhisperTestSuite) TestSelectedChatKeyIsUsedInWhisper() {
s.NoError(err)
// create an account
accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
_, accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
s.NoError(err)
// select account