chore!: simplify local pairing API (#5643)

* chore!: switch to use CreateAccount, fix tests

* chore_: move GenerateInstallationID to multidevice

* chore!: clean up ReceiverConfig

* chore_: use DefaultKeystoreRelativePath

* chore_: cleanup

* fix_: import api

* chore_: lint fix

* chore_: remove unused import
This commit is contained in:
Igor Sirotin 2024-08-14 21:10:19 +01:00 committed by GitHub
parent 771f26210a
commit f660be0daa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 258 additions and 479 deletions

View File

@ -1181,7 +1181,7 @@ func TestConvertAccount(t *testing.T) {
defaultSettings, err := defaultSettings(genAccInfo.KeyUID, genAccInfo.Address, derivedAccounts)
require.NoError(t, err)
nodeConfig, err := defaultNodeConfig(defaultSettings.InstallationID, &requests.CreateAccount{
nodeConfig, err := DefaultNodeConfig(defaultSettings.InstallationID, &requests.CreateAccount{
LogLevel: defaultSettings.LogLevel,
})
require.NoError(t, err)

View File

@ -6,44 +6,48 @@ import (
"math/big"
"path/filepath"
"github.com/google/uuid"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol"
"github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
)
const pathWalletRoot = "m/44'/60'/0'/0"
const pathEIP1581 = "m/43'/60'/1581'"
const pathDefaultChat = pathEIP1581 + "/0'/0"
const pathEncryption = pathEIP1581 + "/1'/0"
const pathDefaultWallet = pathWalletRoot + "/0"
const defaultMnemonicLength = 12
const shardsTestClusterID = 16
const walletAccountDefaultName = "Account 1"
const keystoreRelativePath = "keystore"
const DefaultKeycardPairingDataFile = "/ethereum/mainnet_rpc/keycard/pairings.json"
const (
pathWalletRoot = "m/44'/60'/0'/0"
pathEIP1581 = "m/43'/60'/1581'"
pathDefaultChat = pathEIP1581 + "/0'/0"
pathEncryption = pathEIP1581 + "/1'/0"
pathDefaultWallet = pathWalletRoot + "/0"
defaultMnemonicLength = 12
shardsTestClusterID = 16
walletAccountDefaultName = "Account 1"
const DefaultDataDir = "/ethereum/mainnet_rpc"
const DefaultNodeName = "StatusIM"
const DefaultLogFile = "geth.log"
const DefaultLogLevel = "ERROR"
const DefaultMaxPeers = 20
const DefaultMaxPendingPeers = 20
const DefaultListenAddr = ":0"
const DefaultMaxMessageDeliveryAttempts = 3
const DefaultVerifyTransactionChainID = 1
DefaultKeystoreRelativePath = "keystore"
DefaultKeycardPairingDataFile = "/ethereum/mainnet_rpc/keycard/pairings.json"
DefaultDataDir = "/ethereum/mainnet_rpc"
DefaultNodeName = "StatusIM"
DefaultLogFile = "geth.log"
DefaultLogLevel = "ERROR"
DefaultMaxPeers = 20
DefaultMaxPendingPeers = 20
DefaultListenAddr = ":0"
DefaultMaxMessageDeliveryAttempts = 3
DefaultVerifyTransactionChainID = 1
DefaultCurrentNetwork = "mainnet_rpc"
)
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet, pathEncryption}
var (
paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet, pathEncryption}
var DefaultFleet = params.FleetStatusProd
DefaultFleet = params.FleetStatusProd
var overrideApiConfig = overrideApiConfigProd
overrideApiConfig = overrideApiConfigProd
)
func defaultSettings(keyUID string, address string, derivedAddresses map[string]generator.AccountInfo) (*settings.Settings, error) {
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
@ -77,7 +81,7 @@ func defaultSettings(keyUID string, address string, derivedAddresses map[string]
s.SigningPhrase = signingPhrase
s.SendPushNotifications = true
s.InstallationID = uuid.New().String()
s.InstallationID = multidevice.GenerateInstallationID()
s.UseMailservers = true
s.PreviewPrivacy = true
@ -102,7 +106,7 @@ func defaultSettings(keyUID string, address string, derivedAddresses map[string]
}
networkRawMessage := json.RawMessage(networksJSON)
s.Networks = &networkRawMessage
s.CurrentNetwork = "mainnet_rpc"
s.CurrentNetwork = DefaultCurrentNetwork
s.TokenGroupByCommunity = false
s.ShowCommunityAssetWhenSendingTokens = true
@ -250,9 +254,10 @@ func overrideApiConfigProd(nodeConfig *params.NodeConfig, config *requests.APICo
nodeConfig.WSPort = config.WSPort
}
func defaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
func DefaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.RootDataDir = request.RootDataDir
nodeConfig.LogEnabled = request.LogEnabled
nodeConfig.LogFile = DefaultLogFile
nodeConfig.LogDir = request.LogFilePath
@ -399,6 +404,12 @@ func defaultNodeConfig(installationID string, request *requests.CreateAccount, o
return nodeConfig, nil
}
func DefaultKeystorePath(rootDataDir string, keyUID string) (string, string) {
relativePath := filepath.Join(DefaultKeystoreRelativePath, keyUID)
absolutePath := filepath.Join(rootDataDir, relativePath)
return relativePath, absolutePath
}
func buildSigningPhrase() (string, error) {
length := big.NewInt(int64(len(dictionary)))
a, err := rand.Int(rand.Reader, length)

View File

@ -74,8 +74,6 @@ var (
ErrRPCClientUnavailable = errors.New("JSON-RPC client is unavailable")
// ErrDBNotAvailable is returned if a method is called before the DB is available for usage
ErrDBNotAvailable = errors.New("DB is unavailable")
// ErrConfigNotAvailable is returned if a method is called before the nodeconfig is set
ErrConfigNotAvailable = errors.New("NodeConfig is not available")
)
var _ StatusBackend = (*GethStatusBackend)(nil)
@ -1340,7 +1338,7 @@ func (b *GethStatusBackend) RestoreKeycardAccountAndLogin(request *requests.Rest
return nil, err
}
keyStoreDir, err := b.initKeyStoreDirWithAccount(request.RootDataDir, request.Keycard.KeyUID)
keyStoreDir, err := b.InitKeyStoreDirWithAccount(request.RootDataDir, request.Keycard.KeyUID)
if err != nil {
return nil, err
}
@ -1438,7 +1436,7 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati
return nil, err
}
keyStoreDir, err := b.initKeyStoreDirWithAccount(request.RootDataDir, info.KeyUID)
keyStoreDir, err := b.InitKeyStoreDirWithAccount(request.RootDataDir, info.KeyUID)
if err != nil {
return nil, err
}
@ -1511,12 +1509,11 @@ func (b *GethStatusBackend) prepareNodeAccount(request *requests.CreateAccount,
return response, nil
}
func (b *GethStatusBackend) initKeyStoreDirWithAccount(rootDataDir, keyUID string) (string, error) {
func (b *GethStatusBackend) InitKeyStoreDirWithAccount(rootDataDir, keyUID string) (string, error) {
b.UpdateRootDataDir(rootDataDir)
keystoreDir := keystoreRelativePath
userKeyStoreDir := filepath.Join(keystoreDir, keyUID)
keyStoreRelativePath, keystoreAbsolutePath := DefaultKeystorePath(rootDataDir, keyUID)
// Initialize keystore dir with account
return userKeyStoreDir, b.accountManager.InitKeystore(filepath.Join(b.rootDataDir, userKeyStoreDir))
return keyStoreRelativePath, b.accountManager.InitKeystore(keystoreAbsolutePath)
}
func (b *GethStatusBackend) generateAccountInfo(mnemonic string) (*generator.GeneratedAccountInfo, error) {
@ -1629,7 +1626,7 @@ func (b *GethStatusBackend) prepareSettings(request *requests.CreateAccount, inp
}
func (b *GethStatusBackend) prepareConfig(request *requests.CreateAccount, input *prepareAccountInput, installationID string) (*params.NodeConfig, error) {
nodeConfig, err := defaultNodeConfig(installationID, request, input.opts...)
nodeConfig, err := DefaultNodeConfig(installationID, request, input.opts...)
if err != nil {
return nil, err
}

View File

@ -4,6 +4,8 @@ import (
"crypto/ecdsa"
"database/sql"
"github.com/google/uuid"
"github.com/status-im/status-go/eth-node/crypto"
)
@ -127,3 +129,7 @@ func (s *Multidevice) DisableInstallation(myIdentityKey *ecdsa.PublicKey, instal
myIdentityKeyC := crypto.CompressPubkey(myIdentityKey)
return s.persistence.DisableInstallation(myIdentityKeyC, installationID)
}
func GenerateInstallationID() string {
return uuid.New().String()
}

View File

@ -123,11 +123,11 @@ func (c *CreateAccount) Validate(validation *CreateAccountValidation) error {
return errors.Wrap(ErrCreateAccountInvalidDisplayName, err.Error())
}
if len(c.Password) == 0 {
if len(c.Password) == 0 && !validation.AllowEmptyPassword {
return ErrCreateAccountInvalidPassword
}
if len(c.CustomizationColor) == 0 {
if len(c.CustomizationColor) == 0 && !validation.AllowEmptyCustomizationColor {
return ErrCreateAccountInvalidCustomizationColor
}
@ -140,5 +140,7 @@ func (c *CreateAccount) Validate(validation *CreateAccountValidation) error {
// NOTE: Reasoning for this struct here: https://github.com/status-im/status-go/pull/4980#discussion_r1539219099
type CreateAccountValidation struct {
AllowEmptyDisplayName bool
AllowEmptyDisplayName bool
AllowEmptyPassword bool
AllowEmptyCustomizationColor bool
}

View File

@ -17,6 +17,7 @@ import (
"golang.org/x/exp/maps"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/connection"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"

View File

@ -12,6 +12,7 @@ import (
"net/http"
"net/http/cookiejar"
"net/url"
"runtime"
"go.uber.org/zap"
@ -523,11 +524,12 @@ func setupReceivingClient(backend *api.GethStatusBackend, cs, configJSON string)
if err != nil {
return nil, err
}
receiverConf := conf.ReceiverConfig
if err = setDefaultNodeConfig(receiverConf.NodeConfig); err != nil {
return nil, err
}
err = validateAndVerifyNodeConfig(conf, receiverConf)
// This is a temporal solution to allow clients not to pass DeviceType.
// Check DeviceType deprecation reason for more info.
conf.ReceiverConfig.DeviceType = runtime.GOOS
err = validateReceiverConfig(conf, conf.ReceiverConfig)
if err != nil {
return nil, err
}

View File

@ -10,9 +10,6 @@ import (
"regexp"
"strings"
"github.com/google/uuid"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/requests"
"gopkg.in/go-playground/validator.v9"
@ -43,12 +40,6 @@ func newValidate() (*validator.Validate, error) {
return nil, err
}
if err := validate.RegisterValidation("not_end_keyuid", func(fl validator.FieldLevel) bool {
keystorePath := fl.Field().String()
return len(keystorePath) <= 66 || !keyUIDPattern.MatchString(keystorePath[len(keystorePath)-66:])
}); err != nil {
return nil, err
}
return validate, nil
}
@ -120,21 +111,17 @@ func validateAndVerifyPassword(s interface{}, senderConfig *SenderConfig) error
return validateKeys(keys, senderConfig.Password)
}
func validateAndVerifyNodeConfig(s interface{}, receiverConfig *ReceiverConfig) error {
func validateReceiverConfig(s interface{}, receiverConfig *ReceiverConfig) error {
err := validate(s)
if err != nil {
return err
}
if receiverConfig.NodeConfig == nil {
return fmt.Errorf("node config is required for receiver config")
}
if receiverConfig.NodeConfig.RootDataDir == "" {
return fmt.Errorf("root data dir is required for node config")
}
return receiverConfig.NodeConfig.Validate()
return receiverConfig.CreateAccount.Validate(&requests.CreateAccountValidation{
AllowEmptyDisplayName: true,
AllowEmptyCustomizationColor: true,
AllowEmptyPassword: true,
})
}
func emptyDir(dir string) error {
@ -247,109 +234,3 @@ func validateKeystoreFilesConfig(backend *api.GethStatusBackend, conf interface{
return nil
}
// setDefaultNodeConfig sets default values for the node configuration.
// Config Values still needed from the mobile include
// VerifyTransactionURL/VerifyENSURL/VerifyENSContractAddress/VerifyTransactionChainID
// LogEnabled/LogDir/RootDataDir/LightClient/Nameserver
func setDefaultNodeConfig(c *params.NodeConfig) error {
if c == nil {
return nil
}
err := c.UpdateWithDefaults()
if err != nil {
return err
}
// following specifiedXXX variables are used to check if frontend has specified the value
// if not, the default value is set. NOTE: we also check 2 extra fields: WakuV2Config(LightClient|Nameserver)
// see api.SetFleet for more details
specifiedVerifyTransactionURL := c.ShhextConfig.VerifyTransactionURL
specifiedVerifyENSURL := c.ShhextConfig.VerifyENSURL
specifiedVerifyENSContractAddress := c.ShhextConfig.VerifyENSContractAddress
specifiedVerifyTransactionChainID := c.ShhextConfig.VerifyTransactionChainID
specifiedNetworkID := c.NetworkID
specifiedNetworks := c.Networks
specifiedUpstreamConfigURL := c.UpstreamConfig.URL
specifiedLogEnabled := c.LogEnabled
specifiedLogLevel := c.LogLevel
specifiedFleet := c.ClusterConfig.Fleet
specifiedInstallationID := c.ShhextConfig.InstallationID
specifiedTorrentConfigEnabled := c.TorrentConfig.Enabled
specifiedTorrentConfigPort := c.TorrentConfig.Port
if len(specifiedNetworks) == 0 {
c.Networks = api.BuildDefaultNetworks(&requests.WalletSecretsConfig{})
}
if specifiedNetworkID == 0 {
c.NetworkID = c.Networks[0].ChainID
}
c.UpstreamConfig.Enabled = true
if specifiedUpstreamConfigURL == "" {
c.UpstreamConfig.URL = c.Networks[0].RPCURL
}
if specifiedLogEnabled && specifiedLogLevel == "" {
c.LogLevel = api.DefaultLogLevel
}
c.LogFile = api.DefaultLogFile
c.Name = api.DefaultNodeName
c.DataDir = api.DefaultDataDir
c.KeycardPairingDataFile = api.DefaultKeycardPairingDataFile
c.Rendezvous = false
c.NoDiscovery = true
c.MaxPeers = api.DefaultMaxPeers
c.MaxPendingPeers = api.DefaultMaxPendingPeers
c.LocalNotificationsConfig = params.LocalNotificationsConfig{Enabled: true}
c.BrowsersConfig = params.BrowsersConfig{Enabled: true}
c.PermissionsConfig = params.PermissionsConfig{Enabled: true}
c.MailserversConfig = params.MailserversConfig{Enabled: true}
c.ListenAddr = api.DefaultListenAddr
if specifiedFleet == "" {
err = api.SetDefaultFleet(c)
if err != nil {
return err
}
}
if specifiedInstallationID == "" {
specifiedInstallationID = uuid.New().String()
}
c.ShhextConfig = params.ShhextConfig{
InstallationID: specifiedInstallationID,
MaxMessageDeliveryAttempts: api.DefaultMaxMessageDeliveryAttempts,
MailServerConfirmations: true,
DataSyncEnabled: true,
PFSEnabled: true,
VerifyTransactionURL: specifiedVerifyTransactionURL,
VerifyENSURL: specifiedVerifyENSURL,
VerifyENSContractAddress: specifiedVerifyENSContractAddress,
}
if specifiedVerifyTransactionChainID == 0 {
c.ShhextConfig.VerifyTransactionChainID = int64(c.Networks[0].ChainID)
}
if specifiedVerifyTransactionURL == "" {
c.ShhextConfig.VerifyTransactionURL = c.Networks[0].FallbackURL
}
if specifiedVerifyENSURL == "" {
c.ShhextConfig.VerifyENSURL = c.Networks[0].FallbackURL
}
c.TorrentConfig = params.TorrentConfig{
Enabled: specifiedTorrentConfigEnabled,
Port: specifiedTorrentConfigPort,
DataDir: filepath.Join(c.RootDataDir, params.ArchivesRelativePath),
TorrentDir: filepath.Join(c.RootDataDir, params.TorrentTorrentsRelativePath),
}
return nil
}

View File

@ -54,7 +54,10 @@ func (tpsc *TestPairingServerComponents) SetupPairingServerComponents(t *testing
tpsc.SS, err = NewSenderServer(nil, &SenderServerConfig{ServerConfig: sc, SenderConfig: &SenderConfig{}})
require.NoError(t, err)
tpsc.RS, err = NewReceiverServer(nil, &ReceiverServerConfig{ServerConfig: sc, ReceiverConfig: &ReceiverConfig{}})
tpsc.RS, err = NewReceiverServer(nil, &ReceiverServerConfig{
ServerConfig: sc,
ReceiverConfig: &ReceiverConfig{},
})
require.NoError(t, err)
}

View File

@ -5,8 +5,9 @@ import (
"crypto/tls"
"net"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/requests"
)
type SenderConfig struct {
@ -23,20 +24,13 @@ type SenderConfig struct {
}
type ReceiverConfig struct {
// nodeConfig is required, but we'll validate it separately
NodeConfig *params.NodeConfig `json:"nodeConfig"`
// ReceiverConfig.KeystorePath must not end with keyUID (because keyUID is not known yet)
KeystorePath string `json:"keystorePath" validate:"required,not_end_keyuid"`
CreateAccount *requests.CreateAccount `json:"createAccount" validate:"required"`
// DeviceType SendPairInstallation need this information
DeviceType string `json:"deviceType" validate:"required"`
KDFIterations int `json:"kdfIterations" validate:"gte=0"`
// Deprecated: This field will be automatically overridden with runtime.GOOS and can be omitted by client.
// The field will be removed in https://github.com/status-im/status-go/issues/3351 is fully implemented.
DeviceType string `json:"-"`
// SettingCurrentNetwork corresponding to field current_network from table settings, so that we can override current network from sender
SettingCurrentNetwork string `json:"settingCurrentNetwork" validate:"required"`
DeviceName string `json:"deviceName"`
DB *multiaccounts.Database `json:"-"`
LoggedInKeyUID string `json:"-"`
}
@ -146,3 +140,10 @@ func NewReceiverServerConfig() *ReceiverServerConfig {
ServerConfig: new(ServerConfig),
}
}
func (c *ReceiverConfig) AbsoluteKeystorePath() string {
// Follow the same path as in InitKeyStoreDirWithAccount
// Keep keyUID empty as it's unknown yet
_, path := api.DefaultKeystorePath(c.CreateAccount.RootDataDir, "")
return path
}

View File

@ -1,14 +1,16 @@
package pairing
import (
"regexp"
"testing"
"github.com/stretchr/testify/suite"
"gopkg.in/go-playground/validator.v9"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/status-im/status-go/protocol/requests"
)
func TestConfigTestSuite(t *testing.T) {
@ -75,30 +77,17 @@ func (s *ConfigTestSuite) TestValidationKeyUID() {
}
func (s *ConfigTestSuite) TestValidationNotEndKeyUID() {
nodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", "/dummy/path")
nodeConfig.RootDataDir = "/tmp"
require.NoError(s.T(), err, "nodeConfigForLocalPairSync should not return error")
s.T().Run("Valid keystore path without keyUID", func(t *testing.T) {
r := &ReceiverConfig{
NodeConfig: nodeConfig,
KeystorePath: "some/path/",
DeviceType: "phone",
KDFIterations: 1,
SettingCurrentNetwork: "mainnet",
}
assert.NoError(t, setDefaultNodeConfig(r.NodeConfig))
assert.NoError(t, validateAndVerifyNodeConfig(r, r), "ReceiverConfig validation should pass")
})
keyUIDPattern := regexp.MustCompile(`^0x[0-9a-fA-F]{64}$`)
s.T().Run("Invalid keystore path with keyUID", func(t *testing.T) {
r := &ReceiverConfig{
NodeConfig: nodeConfig,
KeystorePath: "some/path/0x130cc0ebdaecd220c1d6dea0ef01d575ef5364506785745049eb98ddf49cb54e",
DeviceType: "phone",
KDFIterations: 1,
SettingCurrentNetwork: "mainnet",
}
assert.NoError(t, setDefaultNodeConfig(r.NodeConfig))
assert.Error(t, validateAndVerifyNodeConfig(r, r), "ReceiverConfig validation should fail")
})
r := &ReceiverConfig{
CreateAccount: &requests.CreateAccount{
RootDataDir: "/tmp",
KdfIterations: 1,
DeviceName: "device-1",
},
}
keystorePath := r.AbsoluteKeystorePath()
s.Require().True(len(keystorePath) <= 66 || !keyUIDPattern.MatchString(keystorePath[len(keystorePath)-66:]))
s.Require().NoError(validateReceiverConfig(r, r), "ReceiverConfig validation should pass")
}

View File

@ -14,13 +14,9 @@ import (
"github.com/status-im/status-go/protocol/protobuf"
)
const keystoreDir = "keystore"
var (
ErrKeyFileAlreadyExists = errors.New("key file already exists")
ErrKeyUIDEmptyAsSender = errors.New("keyUID must be provided as sender")
ErrNodeConfigNilAsReceiver = errors.New("node config must be provided as receiver")
ErrLoggedInKeyUIDConflict = errors.New("logged in keyUID not same as keyUID in payload")
ErrKeyFileAlreadyExists = errors.New("key file already exists")
ErrLoggedInKeyUIDConflict = errors.New("logged in keyUID not same as keyUID in payload")
)
// AccountPayload represents the payload structure a Server handles

View File

@ -13,9 +13,11 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/common/dbsetup"
"github.com/status-im/status-go/images"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/server/servertest"
"github.com/status-im/status-go/t/utils"
)
@ -62,21 +64,14 @@ func setupTestDB(t *testing.T) (*multiaccounts.Database, func()) {
}
}
func makeKeystores(t *testing.T) (string, string) {
func makeKeystore(t *testing.T) string {
keyStoreDir := t.TempDir()
emptyKeyStoreDir := t.TempDir()
keyStoreDir = filepath.Join(keyStoreDir, keystoreDir, keyUID)
// TODO test case where the keystore dir does not yet exist because the device is new
emptyKeyStoreDir = filepath.Join(emptyKeyStoreDir, keystoreDir)
keyStoreDir = filepath.Join(keyStoreDir, api.DefaultKeystoreRelativePath)
err := os.MkdirAll(keyStoreDir, 0777)
require.NoError(t, err)
err = os.MkdirAll(emptyKeyStoreDir, 0777)
require.NoError(t, err)
return keyStoreDir, emptyKeyStoreDir
return keyStoreDir
}
func initKeys(t *testing.T, keyStoreDir string) {
@ -116,7 +111,7 @@ func (pms *PayloadMarshallerSuite) SetupTest() {
db1, db1td := setupTestDB(pms.T())
db2, db2td := setupTestDB(pms.T())
keystore1, keystore2 := makeKeystores(pms.T())
keystore1 := filepath.Join(makeKeystore(pms.T()), keyUID)
pms.teardown = func() {
db1td()
db2td()
@ -134,8 +129,10 @@ func (pms *PayloadMarshallerSuite) SetupTest() {
}
pms.config2 = &ReceiverConfig{
DB: db2,
KeystorePath: keystore2,
DB: db2,
CreateAccount: &requests.CreateAccount{
RootDataDir: pms.T().TempDir(),
},
}
}
@ -293,7 +290,7 @@ func (pms *PayloadMarshallerSuite) TestPayloadMarshaller_StorePayloads() {
pms.Require().NoError(err)
// TEST PairingPayloadRepository 2 Store()
keys := getFiles(pms.T(), filepath.Join(pms.config2.KeystorePath, keyUID))
keys := getFiles(pms.T(), filepath.Join(pms.config2.AbsoluteKeystorePath(), keyUID))
pms.Require().Len(keys, 2)
pms.Require().Len(keys[utils.GetAccount1PKFile()], 489)

View File

@ -13,7 +13,7 @@ import (
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/signal"
)
@ -126,9 +126,12 @@ func NewAccountPayloadStorer(p *AccountPayload, config *ReceiverConfig) (*Accoun
return ppr, nil
}
if config.CreateAccount != nil {
ppr.kdfIterations = config.CreateAccount.KdfIterations
ppr.keystorePath = config.AbsoluteKeystorePath()
}
ppr.multiaccountsDB = config.DB
ppr.kdfIterations = config.KDFIterations
ppr.keystorePath = config.KeystorePath
ppr.loggedInKeyUID = config.LoggedInKeyUID
return ppr, nil
}
@ -173,7 +176,7 @@ func (aps *AccountPayloadStorer) storeKeys(keyStorePath string) error {
// If lastDir == keystoreDir we presume we need to create the rest of the keystore path
// else we presume the provided keystore is valid
if lastDir == keystoreDir {
if lastDir == api.DefaultKeystoreRelativePath {
if aps.multiaccount == nil || aps.multiaccount.KeyUID == "" {
return fmt.Errorf("no known Key UID")
}
@ -237,10 +240,8 @@ type RawMessageStorer struct {
payload *RawMessagesPayload
syncRawMessageHandler *SyncRawMessageHandler
accountPayload *AccountPayload
nodeConfig *params.NodeConfig
settingCurrentNetwork string
createAccount *requests.CreateAccount
deviceType string
deviceName string
}
func NewRawMessageStorer(backend *api.GethStatusBackend, payload *RawMessagesPayload, accountPayload *AccountPayload, config *ReceiverConfig) *RawMessageStorer {
@ -248,10 +249,8 @@ func NewRawMessageStorer(backend *api.GethStatusBackend, payload *RawMessagesPay
syncRawMessageHandler: NewSyncRawMessageHandler(backend),
payload: payload,
accountPayload: accountPayload,
nodeConfig: config.NodeConfig,
settingCurrentNetwork: config.SettingCurrentNetwork,
deviceType: config.DeviceType,
deviceName: config.DeviceName,
createAccount: config.CreateAccount,
}
}
@ -259,7 +258,7 @@ func (r *RawMessageStorer) Store() error {
if r.accountPayload == nil || r.accountPayload.multiaccount == nil {
return fmt.Errorf("no known multiaccount when storing raw messages")
}
return r.syncRawMessageHandler.HandleRawMessage(r.accountPayload, r.nodeConfig, r.settingCurrentNetwork, r.deviceType, r.deviceName, r.payload)
return r.syncRawMessageHandler.HandleRawMessage(r.accountPayload, r.createAccount, r.deviceType, r.payload)
}
/*
@ -443,7 +442,7 @@ func (kfps *KeystoreFilesPayloadStorer) storeKeys(keyStorePath string) error {
// If lastDir == keystoreDir we presume we need to create the rest of the keystore path
// else we presume the provided keystore is valid
if lastDir == keystoreDir {
if lastDir == api.DefaultKeystoreRelativePath {
keyStorePath = filepath.Join(keyStorePath, kfps.loggedInKeyUID)
_, err := os.Stat(keyStorePath)
if os.IsNotExist(err) {

View File

@ -4,7 +4,6 @@ import (
"context"
"crypto/ecdsa"
"fmt"
"path/filepath"
"strings"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
@ -12,9 +11,9 @@ import (
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/signal"
)
@ -88,39 +87,15 @@ func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rm
return
}
func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload, nodeConfig *params.NodeConfig, settingCurrentNetwork, deviceType string, deviceName string, rmp *RawMessagesPayload) (err error) {
account := accountPayload.multiaccount
func (s *SyncRawMessageHandler) HandleRawMessage(
accountPayload *AccountPayload,
createAccountRequest *requests.CreateAccount,
deviceType string,
rmp *RawMessagesPayload) (err error) {
activeAccount, _ := s.backend.GetActiveAccount()
if activeAccount == nil { // not login yet
s.backend.UpdateRootDataDir(nodeConfig.RootDataDir)
// because client don't know keyUID before received data, we need help client to update keystore dir
keystoreDir := filepath.Join(nodeConfig.KeyStoreDir, account.KeyUID)
nodeConfig.KeyStoreDir = keystoreDir
var chatKey *ecdsa.PrivateKey
if accountPayload.chatKey != "" {
chatKeyHex := strings.Trim(accountPayload.chatKey, "0x")
chatKey, err = ethcrypto.HexToECDSA(chatKeyHex)
if err != nil {
return err
}
}
if accountPayload.exist {
err = s.backend.StartNodeWithAccount(*account, accountPayload.password, nodeConfig, chatKey)
} else {
accountManager := s.backend.AccountManager()
err = accountManager.InitKeystore(filepath.Join(nodeConfig.RootDataDir, keystoreDir))
if err != nil {
return err
}
rmp.setting.DeviceName = deviceName
rmp.setting.InstallationID = nodeConfig.ShhextConfig.InstallationID
rmp.setting.CurrentNetwork = settingCurrentNetwork
err = s.backend.StartNodeWithAccountAndInitialConfig(*account, accountPayload.password, *rmp.setting, nodeConfig, rmp.profileKeypair.Accounts, chatKey)
}
err = s.login(accountPayload, createAccountRequest, rmp)
if err != nil {
return err
}
@ -152,3 +127,46 @@ func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload,
return nil
}
func (s *SyncRawMessageHandler) login(accountPayload *AccountPayload, createAccountRequest *requests.CreateAccount, rmp *RawMessagesPayload) error {
account := accountPayload.multiaccount
installationID := multidevice.GenerateInstallationID()
nodeConfig, err := api.DefaultNodeConfig(installationID, createAccountRequest)
if err != nil {
return err
}
keystoreRelativePath, err := s.backend.InitKeyStoreDirWithAccount(nodeConfig.RootDataDir, account.KeyUID)
nodeConfig.KeyStoreDir = keystoreRelativePath
if err != nil {
return err
}
var chatKey *ecdsa.PrivateKey
if accountPayload.chatKey != "" {
chatKeyHex := strings.Trim(accountPayload.chatKey, "0x")
chatKey, err = ethcrypto.HexToECDSA(chatKeyHex)
if err != nil {
return err
}
}
if accountPayload.exist {
return s.backend.StartNodeWithAccount(*account, accountPayload.password, nodeConfig, chatKey)
}
// Override some of received settings
rmp.setting.DeviceName = createAccountRequest.DeviceName
rmp.setting.InstallationID = installationID
rmp.setting.CurrentNetwork = api.DefaultCurrentNetwork
return s.backend.StartNodeWithAccountAndInitialConfig(
*account,
accountPayload.password,
*rmp.setting,
nodeConfig,
rmp.profileKeypair.Accounts,
chatKey,
)
}

View File

@ -6,6 +6,7 @@ import (
"crypto/rand"
"encoding/json"
"net"
"runtime"
"time"
"github.com/ethereum/go-ethereum/log"
@ -296,11 +297,12 @@ func StartUpReceiverServer(backend *api.GethStatusBackend, configJSON string) (s
if err != nil {
return "", err
}
receiverConf := conf.ReceiverConfig
if err = setDefaultNodeConfig(receiverConf.NodeConfig); err != nil {
return "", err
}
err = validateAndVerifyNodeConfig(conf, receiverConf)
// This is a temporal solution to allow clients not to pass DeviceType.
// Check DeviceType deprecation reason for more info.
conf.ReceiverConfig.DeviceType = runtime.GOOS
err = validateReceiverConfig(conf, conf.ReceiverConfig)
if err != nil {
return "", err
}

View File

@ -20,19 +20,13 @@ import (
"github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/tt"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
accservice "github.com/status-im/status-go/services/accounts"
@ -58,8 +52,6 @@ const (
expectedKDFIterations = 1024
)
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet}
func TestSyncDeviceSuite(t *testing.T) {
suite.Run(t, new(SyncDeviceSuite))
}
@ -79,72 +71,37 @@ func (s *SyncDeviceSuite) SetupTest() {
func (s *SyncDeviceSuite) prepareBackendWithAccount(mnemonic, tmpdir string) *api.GethStatusBackend {
backend := s.prepareBackendWithoutAccount(tmpdir)
accountManager := backend.AccountManager()
accGenerator := accountManager.AccountsGenerator()
var (
generatedAccountInfo generator.GeneratedAndDerivedAccountInfo
err error
)
if len(mnemonic) > 0 {
generatedAccountInfo.GeneratedAccountInfo, err = accGenerator.ImportMnemonic(mnemonic, "")
require.NoError(s.T(), err)
generatedAccountInfo.Derived, err = accGenerator.DeriveAddresses(generatedAccountInfo.ID, paths)
require.NoError(s.T(), err)
displayName, err := common.RandomAlphabeticalString(8)
s.Require().NoError(err)
deviceName, err := common.RandomAlphanumericString(8)
s.Require().NoError(err)
createAccount := requests.CreateAccount{
RootDataDir: tmpdir,
KdfIterations: dbsetup.ReducedKDFIterationsNumber,
DisplayName: displayName,
DeviceName: deviceName,
Password: s.password,
CustomizationColor: "primary",
}
if mnemonic == "" {
_, err = backend.CreateAccountAndLogin(&createAccount)
} else {
generatedAccountInfos, err := accGenerator.GenerateAndDeriveAddresses(12, 1, "", paths)
require.NoError(s.T(), err)
generatedAccountInfo = generatedAccountInfos[0]
}
account := multiaccounts.Account{
KeyUID: generatedAccountInfo.KeyUID,
KDFIterations: dbsetup.ReducedKDFIterationsNumber,
}
err = accountManager.InitKeystore(filepath.Join(tmpdir, keystoreDir, account.KeyUID))
require.NoError(s.T(), err)
err = backend.OpenAccounts()
require.NoError(s.T(), err)
derivedAddresses := generatedAccountInfo.Derived
_, err = accGenerator.StoreDerivedAccounts(generatedAccountInfo.ID, s.password, paths)
require.NoError(s.T(), err)
settings, err := defaultSettings(generatedAccountInfo.GeneratedAccountInfo, derivedAddresses, nil)
require.NoError(s.T(), err)
account.Name = settings.Name
nodeConfig, err := nodeConfigForLocalPairSync(settings.InstallationID, account.KeyUID, tmpdir)
nodeConfig.RootDataDir = tmpdir
require.NoError(s.T(), err)
require.NoError(s.T(), setDefaultNodeConfig(nodeConfig))
walletDerivedAccount := derivedAddresses[pathDefaultWallet]
walletAccount := &accounts.Account{
PublicKey: types.Hex2Bytes(walletDerivedAccount.PublicKey),
KeyUID: generatedAccountInfo.KeyUID,
Address: types.HexToAddress(walletDerivedAccount.Address),
ColorID: "",
Wallet: true,
Path: pathDefaultWallet,
Name: "Ethereum account",
_, err = backend.RestoreAccountAndLogin(&requests.RestoreAccount{
Mnemonic: mnemonic,
FetchBackup: false,
CreateAccount: createAccount,
})
}
chatDerivedAccount := derivedAddresses[pathDefaultChat]
chatAccount := &accounts.Account{
PublicKey: types.Hex2Bytes(chatDerivedAccount.PublicKey),
KeyUID: generatedAccountInfo.KeyUID,
Address: types.HexToAddress(chatDerivedAccount.Address),
Name: settings.Name,
Chat: true,
Path: pathDefaultChat,
}
s.Require().NoError(err)
accounts := []*accounts.Account{walletAccount, chatAccount}
err = backend.StartNodeWithAccountAndInitialConfig(account, s.password, *settings, nodeConfig, accounts, nil)
require.NoError(s.T(), err)
multiaccounts, err := backend.GetAccounts()
require.NoError(s.T(), err)
require.NotEmpty(s.T(), multiaccounts[0].ColorHash)
accs, err := backend.GetAccounts()
s.Require().NoError(err)
s.Require().NotEmpty(accs[0].ColorHash)
return backend
}
@ -163,7 +120,7 @@ func (s *SyncDeviceSuite) pairAccounts(serverBackend *api.GethStatusBackend, ser
serverActiveAccount, err := serverBackend.GetActiveAccount()
require.NoError(s.T(), err)
serverKeystorePath := filepath.Join(serverDir, keystoreDir, serverActiveAccount.KeyUID)
serverKeystorePath := filepath.Join(serverDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
serverConfig := &SenderServerConfig{
SenderConfig: &SenderConfig{
KeystorePath: serverKeystorePath,
@ -182,27 +139,21 @@ func (s *SyncDeviceSuite) pairAccounts(serverBackend *api.GethStatusBackend, ser
// Start receiving client
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientDir, keystoreDir))
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientDir, api.DefaultKeystoreRelativePath))
require.NoError(s.T(), err)
err = clientBackend.OpenAccounts()
require.NoError(s.T(), err)
clientNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", clientDir)
require.NoError(s.T(), err)
clientKeystoreDir := filepath.Join(clientDir, keystoreDir)
clientPayloadSourceConfig := ReceiverClientConfig{
ReceiverConfig: &ReceiverConfig{
KeystorePath: clientKeystoreDir,
DeviceType: "desktop",
KDFIterations: expectedKDFIterations,
NodeConfig: clientNodeConfig,
SettingCurrentNetwork: currentNetwork,
CreateAccount: &requests.CreateAccount{
RootDataDir: clientDir,
KdfIterations: expectedKDFIterations,
},
},
ClientConfig: new(ClientConfig),
}
clientNodeConfig.RootDataDir = clientDir
clientConfigBytes, err := json.Marshal(clientPayloadSourceConfig)
require.NoError(s.T(), err)
@ -287,24 +238,21 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsSender() {
}()
ctx := context.TODO()
err := serverBackend.AccountManager().InitKeystore(filepath.Join(serverTmpDir, keystoreDir))
err := serverBackend.AccountManager().InitKeystore(filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath))
require.NoError(s.T(), err)
err = serverBackend.OpenAccounts()
require.NoError(s.T(), err)
serverNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", serverTmpDir)
require.NoError(s.T(), err)
serverKeystoreDir := filepath.Join(serverTmpDir, keystoreDir)
serverPayloadSourceConfig := &ReceiverServerConfig{
ReceiverConfig: &ReceiverConfig{
NodeConfig: serverNodeConfig,
KeystorePath: serverKeystoreDir,
DeviceType: "desktop",
KDFIterations: expectedKDFIterations,
SettingCurrentNetwork: currentNetwork,
CreateAccount: &requests.CreateAccount{
RootDataDir: serverTmpDir,
KdfIterations: expectedKDFIterations,
},
},
ServerConfig: new(ServerConfig),
}
serverNodeConfig.RootDataDir = serverTmpDir
serverConfigBytes, err := json.Marshal(serverPayloadSourceConfig)
require.NoError(s.T(), err)
cs, err := StartUpReceiverServer(serverBackend, string(serverConfigBytes))
@ -330,7 +278,7 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsSender() {
// startup sending client
clientActiveAccount, err := clientBackend.GetActiveAccount()
require.NoError(s.T(), err)
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
clientPayloadSourceConfig := SenderClientConfig{
SenderConfig: &SenderConfig{
KeystorePath: clientKeystorePath,
@ -367,14 +315,17 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsSender() {
serverActiveAccount, err := serverBackend.GetActiveAccount()
require.NoError(s.T(), err)
require.Equal(s.T(), serverActiveAccount.Name, clientActiveAccount.Name)
require.Equal(s.T(), serverActiveAccount.KDFIterations, expectedKDFIterations)
require.Equal(s.T(), clientActiveAccount.Name, serverActiveAccount.Name)
require.Equal(s.T(), expectedKDFIterations, serverActiveAccount.KDFIterations)
serverMessenger := serverBackend.Messenger()
clientMessenger := clientBackend.Messenger()
require.True(s.T(), serverMessenger.HasPairedDevices())
require.True(s.T(), clientMessenger.HasPairedDevices())
serverNodeConfig, err := serverBackend.GetNodeConfig()
s.Require().NoError(err)
err = clientMessenger.DisableInstallation(serverNodeConfig.ShhextConfig.InstallationID)
require.NoError(s.T(), err)
require.False(s.T(), clientMessenger.HasPairedDevices())
@ -415,7 +366,7 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
serverActiveAccount, err := serverBackend.GetActiveAccount()
require.NoError(s.T(), err)
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
var config = &SenderServerConfig{
SenderConfig: &SenderConfig{
KeystorePath: serverKeystorePath,
@ -462,24 +413,21 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
_, err = serverMessenger.DeleteMessageForMeAndSync(ctx, publicChatID, serverMessageID)
require.NoError(s.T(), err)
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientTmpDir, keystoreDir))
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath))
require.NoError(s.T(), err)
err = clientBackend.OpenAccounts()
require.NoError(s.T(), err)
clientNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", clientTmpDir)
require.NoError(s.T(), err)
clientKeystoreDir := filepath.Join(clientTmpDir, keystoreDir)
clientPayloadSourceConfig := ReceiverClientConfig{
ReceiverConfig: &ReceiverConfig{
KeystorePath: clientKeystoreDir,
DeviceType: "iphone",
KDFIterations: expectedKDFIterations,
NodeConfig: clientNodeConfig,
SettingCurrentNetwork: currentNetwork,
CreateAccount: &requests.CreateAccount{
RootDataDir: clientTmpDir,
KdfIterations: expectedKDFIterations,
DeviceName: "device-1",
},
},
ClientConfig: new(ClientConfig),
}
clientNodeConfig.RootDataDir = clientTmpDir
clientConfigBytes, err := json.Marshal(clientPayloadSourceConfig)
require.NoError(s.T(), err)
err = StartUpReceivingClient(clientBackend, cs, string(clientConfigBytes))
@ -514,9 +462,13 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
require.True(s.T(), serverMessenger.HasPairedDevices())
require.True(s.T(), clientMessenger.HasPairedDevices())
clientNodeConfig, err := clientBackend.GetNodeConfig()
s.Require().NoError(err)
err = serverMessenger.DisableInstallation(clientNodeConfig.ShhextConfig.InstallationID)
require.NoError(s.T(), err)
require.False(s.T(), serverMessenger.HasPairedDevices())
serverNodeConfig, err := serverBackend.GetNodeConfig()
require.NoError(s.T(), err)
err = clientMessenger.DisableInstallation(serverNodeConfig.ShhextConfig.InstallationID)
@ -739,77 +691,6 @@ func (s *SyncDeviceSuite) TestPairAcceptContactRequest() {
})
}
func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) {
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
syncSettings := &settings.Settings{}
syncSettings.KeyUID = generatedAccountInfo.KeyUID
syncSettings.Address = types.HexToAddress(generatedAccountInfo.Address)
syncSettings.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address)
// Set chat key & name
name, err := alias.GenerateFromPublicKeyString(chatKeyString)
if err != nil {
return nil, err
}
syncSettings.Name = name
syncSettings.PublicKey = chatKeyString
syncSettings.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address)
syncSettings.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address)
syncSettings.Mnemonic = mnemonic
syncSettings.SigningPhrase = "balabala"
syncSettings.SendPushNotifications = true
syncSettings.InstallationID = uuid.New().String()
syncSettings.UseMailservers = true
syncSettings.PreviewPrivacy = true
syncSettings.Currency = "usd"
syncSettings.ProfilePicturesVisibility = 1
syncSettings.LinkPreviewRequestEnabled = true
visibleTokens := make(map[string][]string)
visibleTokens["mainnet"] = []string{"SNT"}
visibleTokensJSON, err := json.Marshal(visibleTokens)
if err != nil {
return nil, err
}
visibleTokenJSONRaw := json.RawMessage(visibleTokensJSON)
syncSettings.WalletVisibleTokens = &visibleTokenJSONRaw
networks := `[{"id":"goerli_rpc","chain-explorer-link":"https://goerli.etherscan.io/address/","name":"Goerli with upstream RPC","config":{"NetworkId":5,"DataDir":"/ethereum/goerli_rpc","UpstreamConfig":{"Enabled":true,"URL":"https://goerli-archival.rpc.grove.city/v1/3ef2018191814b7e1009b8d9"}}},{"id":"mainnet_rpc","chain-explorer-link":"https://etherscan.io/address/","name":"Mainnet with upstream RPC","config":{"NetworkId":1,"DataDir":"/ethereum/mainnet_rpc","UpstreamConfig":{"Enabled":true,"URL":"https://eth-archival.rpc.grove.city/v1/3ef2018191814b7e1009b8d9"}}}]`
var networksRawMessage json.RawMessage = []byte(networks)
syncSettings.Networks = &networksRawMessage
syncSettings.CurrentNetwork = currentNetwork
return syncSettings, nil
}
func nodeConfigForLocalPairSync(installationID, keyUID, tmpDir string) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.LogEnabled = true
nodeConfig.LogLevel = "DEBUG"
nodeConfig.LogDir = tmpDir
nodeConfig.KeyStoreDir = filepath.Join(keystoreDir, keyUID)
nodeConfig.KeycardPairingDataFile = filepath.Join("keycard", "pairings.json")
nodeConfig.ShhextConfig = params.ShhextConfig{
InstallationID: installationID,
}
// need specify cluster config here, otherwise TestPairingThreeDevices will fail due to no messages(CR) received
// TODO(frank) need to figure out why above happen
clusterConfig, err := params.LoadClusterConfigFromFleet(params.FleetProd)
if err != nil {
return nil, err
}
nodeConfig.ClusterConfig = *clusterConfig
return nodeConfig, nil
}
type testTimeSource struct{}
func (t *testTimeSource) GetCurrentTime() uint64 {
@ -926,14 +807,14 @@ func (s *SyncDeviceSuite) TestTransferringKeystoreFiles() {
require.NoError(s.T(), err, "saving seed phrase keypair on client without keystore files")
// check server - server should contain keystore files for imported seed phrase
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
require.True(s.T(), containsKeystoreFile(serverKeystorePath, serverSeedPhraseKp.DerivedFrom[2:]))
for _, acc := range serverSeedPhraseKp.Accounts {
require.True(s.T(), containsKeystoreFile(serverKeystorePath, acc.Address.String()[2:]))
}
// check client - client should not contain keystore files for imported seed phrase
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
require.False(s.T(), containsKeystoreFile(clientKeystorePath, clientSeedPhraseKp.DerivedFrom[2:]))
for _, acc := range clientSeedPhraseKp.Accounts {
require.False(s.T(), containsKeystoreFile(clientKeystorePath, acc.Address.String()[2:]))
@ -1122,14 +1003,14 @@ func (s *SyncDeviceSuite) TestTransferringKeystoreFilesAfterStopUisngKeycard() {
len(serverKp.Keycards) == len(clientKp.Keycards))
// Check server - server should contain keystore files for imported seed phrase
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
require.True(s.T(), containsKeystoreFile(serverKeystorePath, serverKp.DerivedFrom[2:]))
for _, acc := range serverKp.Accounts {
require.True(s.T(), containsKeystoreFile(serverKeystorePath, acc.Address.String()[2:]))
}
// Check client - client should not contain keystore files for imported seed phrase
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
require.False(s.T(), containsKeystoreFile(clientKeystorePath, clientKp.DerivedFrom[2:]))
for _, acc := range clientKp.Accounts {
require.False(s.T(), containsKeystoreFile(clientKeystorePath, acc.Address.String()[2:]))
@ -1306,7 +1187,7 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsReceiver
serverActiveAccount, err := serverBackend.GetActiveAccount()
s.NoError(err)
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
var config = &SenderServerConfig{
SenderConfig: &SenderConfig{
KeystorePath: serverKeystorePath,
@ -1321,20 +1202,16 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsReceiver
cs, err := StartUpSenderServer(serverBackend, string(configBytes))
s.NoError(err)
clientKeystoreDir := filepath.Join(clientTmpDir, keystoreDir)
clientNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", clientTmpDir)
s.NoError(err)
clientPayloadSourceConfig := ReceiverClientConfig{
ReceiverConfig: &ReceiverConfig{
KeystorePath: clientKeystoreDir,
DeviceType: "iphone",
KDFIterations: expectedKDFIterations,
NodeConfig: clientNodeConfig,
SettingCurrentNetwork: currentNetwork,
CreateAccount: &requests.CreateAccount{
RootDataDir: clientTmpDir,
KdfIterations: expectedKDFIterations,
DeviceName: "client-device",
},
},
ClientConfig: new(ClientConfig),
}
clientNodeConfig.RootDataDir = clientTmpDir
clientConfigBytes, err := json.Marshal(clientPayloadSourceConfig)
s.NoError(err)
err = StartUpReceivingClient(clientBackend, cs, string(clientConfigBytes))
@ -1351,20 +1228,17 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsSender()
s.NoError(clientBackend.Logout())
}()
serverNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", serverTmpDir)
s.NoError(err)
serverKeystoreDir := filepath.Join(serverTmpDir, keystoreDir)
serverPayloadSourceConfig := &ReceiverServerConfig{
ReceiverConfig: &ReceiverConfig{
NodeConfig: serverNodeConfig,
KeystorePath: serverKeystoreDir,
DeviceType: "desktop",
KDFIterations: expectedKDFIterations,
SettingCurrentNetwork: currentNetwork,
CreateAccount: &requests.CreateAccount{
RootDataDir: serverTmpDir,
KdfIterations: expectedKDFIterations,
DeviceName: "server-device",
},
},
ServerConfig: new(ServerConfig),
}
serverNodeConfig.RootDataDir = serverTmpDir
serverConfigBytes, err := json.Marshal(serverPayloadSourceConfig)
s.NoError(err)
cs, err := StartUpReceiverServer(serverBackend, string(serverConfigBytes))
@ -1372,7 +1246,7 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsSender()
clientActiveAccount, err := clientBackend.GetActiveAccount()
s.NoError(err)
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
clientPayloadSourceConfig := SenderClientConfig{
SenderConfig: &SenderConfig{
KeystorePath: clientKeystorePath,