tests: tests affected by accounts improvements are fixed

This commit is contained in:
Sale Djenic 2023-05-16 12:50:04 +02:00 committed by saledjenic
parent eeaaf0ce3f
commit 03f93e9f6c
10 changed files with 1540 additions and 867 deletions

View File

@ -555,12 +555,25 @@ func TestBackendGetVerifiedAccount(t *testing.T) {
pkey, err := crypto.GenerateKey() pkey, err := crypto.GenerateKey()
require.NoError(t, err) require.NoError(t, err)
address := crypto.PubkeyToAddress(pkey.PublicKey) address := crypto.PubkeyToAddress(pkey.PublicKey)
keyUIDHex := sha256.Sum256(gethcrypto.FromECDSAPub(&pkey.PublicKey))
keyUID := types.EncodeHex(keyUIDHex[:])
db, err := accounts.NewDB(backend.appDB) db, err := accounts.NewDB(backend.appDB)
require.NoError(t, err) require.NoError(t, err)
_, err = backend.AccountManager().ImportAccount(pkey, password) _, err = backend.AccountManager().ImportAccount(pkey, password)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveAccounts([]*accounts.Account{{Address: address}})) require.NoError(t, db.SaveOrUpdateKeypair(&accounts.Keypair{
KeyUID: keyUID,
Name: "private key keypair",
Type: accounts.KeypairTypeKey,
Accounts: []*accounts.Account{
&accounts.Account{
Address: address,
KeyUID: keyUID,
},
},
}))
key, err := backend.getVerifiedWalletAccount(address.String(), "wrong-password") key, err := backend.getVerifiedWalletAccount(address.String(), "wrong-password")
require.EqualError(t, err, "could not decrypt key with given password") require.EqualError(t, err, "could not decrypt key with given password")
require.Nil(t, key) require.Nil(t, key)
@ -580,32 +593,53 @@ func TestBackendGetVerifiedAccount(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
derivedInfo := derivedInfos[newPath] derivedInfo := derivedInfos[newPath]
partialAcc := &accounts.Account{ keypair := &accounts.Keypair{
Address: types.HexToAddress(derivedInfo.Address), KeyUID: walletInfo.KeyUID,
Type: accounts.AccountTypeGenerated, Name: "profile keypair",
PublicKey: types.Hex2Bytes(derivedInfo.PublicKey), Type: accounts.KeypairTypeProfile,
Path: newPath, Accounts: []*accounts.Account{
Wallet: false, &accounts.Account{
Name: "PartialAccount", Address: types.HexToAddress(derivedInfo.Address),
KeyUID: walletInfo.KeyUID,
Type: accounts.AccountTypeGenerated,
PublicKey: types.Hex2Bytes(derivedInfo.PublicKey),
Path: newPath,
Wallet: false,
Name: "PartialAccount",
},
},
} }
require.NoError(t, db.SaveAccounts([]*accounts.Account{partialAcc})) require.NoError(t, db.SaveOrUpdateKeypair(keypair))
// With partial account we need to dynamically generate private key // With partial account we need to dynamically generate private key
key, err := backend.getVerifiedWalletAccount(partialAcc.Address.Hex(), password) key, err := backend.getVerifiedWalletAccount(keypair.Accounts[0].Address.Hex(), password)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, partialAcc.Address, key.Address) require.Equal(t, keypair.Accounts[0].Address, key.Address)
}) })
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
pkey, err := crypto.GenerateKey() pkey, err := crypto.GenerateKey()
require.NoError(t, err) require.NoError(t, err)
address := crypto.PubkeyToAddress(pkey.PublicKey) address := crypto.PubkeyToAddress(pkey.PublicKey)
keyUIDHex := sha256.Sum256(gethcrypto.FromECDSAPub(&pkey.PublicKey))
keyUID := types.EncodeHex(keyUIDHex[:])
db, err := accounts.NewDB(backend.appDB) db, err := accounts.NewDB(backend.appDB)
require.NoError(t, err) require.NoError(t, err)
defer db.Close() defer db.Close()
_, err = backend.AccountManager().ImportAccount(pkey, password) _, err = backend.AccountManager().ImportAccount(pkey, password)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveAccounts([]*accounts.Account{{Address: address}})) require.NoError(t, db.SaveOrUpdateKeypair(&accounts.Keypair{
KeyUID: keyUID,
Name: "private key keypair",
Type: accounts.KeypairTypeKey,
Accounts: []*accounts.Account{
&accounts.Account{
Address: address,
KeyUID: keyUID,
},
},
}))
key, err := backend.getVerifiedWalletAccount(address.String(), password) key, err := backend.getVerifiedWalletAccount(address.String(), password)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, address, key.Address) require.Equal(t, address, key.Address)
@ -636,7 +670,12 @@ func TestLoginWithKey(t *testing.T) {
require.NotNil(t, b.statusNode.HTTPServer()) require.NotNil(t, b.statusNode.HTTPServer())
address := crypto.PubkeyToAddress(walletKey.PublicKey) address := crypto.PubkeyToAddress(walletKey.PublicKey)
require.NoError(t, b.SaveAccountAndStartNodeWithKey(main, "test-pass", testSettings, conf, []*accounts.Account{{Address: address, Wallet: true}}, keyhex))
settings := testSettings
settings.KeyUID = keyUID
settings.Address = crypto.PubkeyToAddress(walletKey.PublicKey)
require.NoError(t, b.SaveAccountAndStartNodeWithKey(main, "test-pass", settings, conf, []*accounts.Account{{Address: address, KeyUID: keyUID, Wallet: true}}, keyhex))
require.NoError(t, b.Logout()) require.NoError(t, b.Logout())
require.NoError(t, b.StopNode()) require.NoError(t, b.StopNode())
@ -677,7 +716,12 @@ func TestVerifyDatabasePassword(t *testing.T) {
require.NoError(t, b.OpenAccounts()) require.NoError(t, b.OpenAccounts())
address := crypto.PubkeyToAddress(walletKey.PublicKey) address := crypto.PubkeyToAddress(walletKey.PublicKey)
require.NoError(t, b.SaveAccountAndStartNodeWithKey(main, "test-pass", testSettings, conf, []*accounts.Account{{Address: address, Wallet: true}}, keyhex))
settings := testSettings
settings.KeyUID = keyUID
settings.Address = crypto.PubkeyToAddress(walletKey.PublicKey)
require.NoError(t, b.SaveAccountAndStartNodeWithKey(main, "test-pass", settings, conf, []*accounts.Account{{Address: address, KeyUID: keyUID, Wallet: true}}, keyhex))
require.NoError(t, b.Logout()) require.NoError(t, b.Logout())
require.NoError(t, b.StopNode()) require.NoError(t, b.StopNode())
@ -738,7 +782,8 @@ func TestDeleteMultiaccount(t *testing.T) {
s, s,
&params.NodeConfig{}, &params.NodeConfig{},
nil) nil)
require.NoError(t, err) require.Error(t, err)
require.True(t, err == accounts.ErrKeypairWithoutAccounts)
err = backend.OpenAccounts() err = backend.OpenAccounts()
require.NoError(t, err) require.NoError(t, err)
@ -839,17 +884,22 @@ func TestConvertAccount(t *testing.T) {
found = keystoreContainsFileForAccount(keyStoreDir, chatAddress) found = keystoreContainsFileForAccount(keyStoreDir, chatAddress)
require.True(t, found) require.True(t, found)
var accountsToStore []*accounts.Account profileKeypair := &accounts.Keypair{
accountsToStore = append(accountsToStore, &accounts.Account{
Address: types.HexToAddress(chatAddress),
DerivedFrom: masterAddress,
KeyUID: genAccInfo.KeyUID, KeyUID: genAccInfo.KeyUID,
Type: accounts.AccountTypeGenerated, Name: "Profile Name",
PublicKey: types.Hex2Bytes(accountInfo.PublicKey), Type: accounts.KeypairTypeProfile,
Path: pathEIP1581Chat, DerivedFrom: masterAddress,
Wallet: false, }
Chat: true,
Name: "GeneratedAccount", profileKeypair.Accounts = append(profileKeypair.Accounts, &accounts.Account{
Address: types.HexToAddress(chatAddress),
KeyUID: profileKeypair.KeyUID,
Type: accounts.AccountTypeGenerated,
PublicKey: types.Hex2Bytes(accountInfo.PublicKey),
Path: pathEIP1581Chat,
Wallet: false,
Chat: true,
Name: "GeneratedAccount",
}) })
for p, dAccInfo := range derivedAccounts { for p, dAccInfo := range derivedAccounts {
@ -860,25 +910,24 @@ func TestConvertAccount(t *testing.T) {
if p == pathDefaultWalletAccount || if p == pathDefaultWalletAccount ||
p == customWalletPath1 || p == customWalletPath1 ||
p == customWalletPath2 { p == customWalletPath2 {
accountsToStore = append(accountsToStore, &accounts.Account{ profileKeypair.Accounts = append(profileKeypair.Accounts, &accounts.Account{
Address: types.HexToAddress(dAccInfo.Address), Address: types.HexToAddress(dAccInfo.Address),
KeyUID: genAccInfo.KeyUID, KeyUID: genAccInfo.KeyUID,
Wallet: false, Wallet: false,
Chat: false, Chat: false,
Type: accounts.AccountTypeGenerated, Type: accounts.AccountTypeGenerated,
Path: p, Path: p,
Name: "derivacc" + p, Name: "derivacc" + p,
Hidden: false, Hidden: false,
DerivedFrom: masterAddress, Removed: false,
Removed: false,
}) })
} }
} }
account := multiaccounts.Account{ account := multiaccounts.Account{
Name: "foo", Name: profileKeypair.Name,
Timestamp: 1, Timestamp: 1,
KeyUID: genAccInfo.KeyUID, KeyUID: profileKeypair.KeyUID,
} }
err = backend.ensureAppDBOpened(account, password) err = backend.ensureAppDBOpened(account, password)
@ -904,7 +953,7 @@ func TestConvertAccount(t *testing.T) {
err = backend.saveAccountsAndSettings( err = backend.saveAccountsAndSettings(
s, s,
&params.NodeConfig{}, &params.NodeConfig{},
accountsToStore) profileKeypair.Accounts)
require.NoError(t, err) require.NoError(t, err)
err = backend.OpenAccounts() err = backend.OpenAccounts()

View File

@ -7,6 +7,7 @@ import (
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts" "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/multiaccounts/settings"
"github.com/status-im/status-go/params" "github.com/status-im/status-go/params"
@ -84,7 +85,8 @@ func setupWalletTest(t *testing.T, password string) (backend *GethStatusBackend,
WalletRootAddress: types.HexToAddress(walletRootAddress)} WalletRootAddress: types.HexToAddress(walletRootAddress)}
err = backend.saveAccountsAndSettings(s, config, nil) err = backend.saveAccountsAndSettings(s, config, nil)
require.NoError(t, err) require.Error(t, err)
require.True(t, err == accounts.ErrKeypairWithoutAccounts)
// this is for StatusNode().Config() call inside of the getVerifiedWalletAccount // this is for StatusNode().Config() call inside of the getVerifiedWalletAccount
err = backend.StartNode(config) err = backend.StartNode(config)

View File

@ -38,24 +38,38 @@ func TestIsOwnAccount(t *testing.T) {
func TestUnmarshal(t *testing.T) { func TestUnmarshal(t *testing.T) {
data := ` data := `
{ {
"key-uid": "0xbc14c321b74652e57c7f26eb30d597ea27cbdf36cba5c85d24f12748153a035e",
"public-key": "0x0465f6d4f1172524fc057954c8a3f8e34f991558b3d1097189975062f67adda7835da61acb5cda3348b41d211ed0cb07aba668eb12e19e29d98745bebf68d93b61", "public-key": "0x0465f6d4f1172524fc057954c8a3f8e34f991558b3d1097189975062f67adda7835da61acb5cda3348b41d211ed0cb07aba668eb12e19e29d98745bebf68d93b61",
"address": "0xf09c9f5Fb9faa22d0C6C593e7157Ceac8B2b0fe4", "address": "0xf09c9f5Fb9faa22d0C6C593e7157Ceac8B2b0fe4",
"color": "#4360df", "color": "#4360df",
"wallet": true, "wallet": true,
"chat": true,
"path": "m/44'/60'/0'/0/0", "path": "m/44'/60'/0'/0/0",
"name": "Status account", "name": "Status account",
"derived-from": "0x6f015A79890Dcb38eFeC1D83772d57159D2eb58b" "type": "generated",
"emoji": "some-emoji",
"hidden": true,
"clock": 1234,
"removed": true,
"operable": "fully"
} }
` `
var account Account var account Account
err := json.Unmarshal([]byte(data), &account) err := json.Unmarshal([]byte(data), &account)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "0xbc14c321b74652e57c7f26eb30d597ea27cbdf36cba5c85d24f12748153a035e", account.KeyUID)
require.Equal(t, []byte("0x0465f6d4f1172524fc057954c8a3f8e34f991558b3d1097189975062f67adda7835da61acb5cda3348b41d211ed0cb07aba668eb12e19e29d98745bebf68d93b61"), account.PublicKey.Bytes()) require.Equal(t, []byte("0x0465f6d4f1172524fc057954c8a3f8e34f991558b3d1097189975062f67adda7835da61acb5cda3348b41d211ed0cb07aba668eb12e19e29d98745bebf68d93b61"), account.PublicKey.Bytes())
require.Equal(t, "0xf09c9f5Fb9faa22d0C6C593e7157Ceac8B2b0fe4", account.Address.String()) require.Equal(t, "0xf09c9f5Fb9faa22d0C6C593e7157Ceac8B2b0fe4", account.Address.String())
require.Equal(t, "#4360df", account.Color) require.Equal(t, "#4360df", account.Color)
require.Equal(t, true, account.Wallet) require.Equal(t, true, account.Wallet)
require.Equal(t, true, account.Chat)
require.Equal(t, "m/44'/60'/0'/0/0", account.Path) require.Equal(t, "m/44'/60'/0'/0/0", account.Path)
require.Equal(t, "Status account", account.Name) require.Equal(t, "Status account", account.Name)
require.Equal(t, "0x6f015A79890Dcb38eFeC1D83772d57159D2eb58b", account.DerivedFrom) require.Equal(t, "generated", account.Type.String())
require.Equal(t, "some-emoji", account.Emoji)
require.Equal(t, true, account.Hidden)
require.Equal(t, uint64(1234), account.Clock)
require.Equal(t, true, account.Removed)
require.Equal(t, "fully", account.Operable.String())
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/status-im/status-go/appdatabase" "github.com/status-im/status-go/appdatabase"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/errors"
) )
func setupTestDB(t *testing.T) (*Database, func()) { func setupTestDB(t *testing.T) (*Database, func()) {
@ -29,77 +28,6 @@ func setupTestDB(t *testing.T) (*Database, func()) {
} }
} }
func TestSaveAccounts(t *testing.T) {
type testCase struct {
description string
accounts []*Account
err error
}
for _, tc := range []testCase{
{
description: "NoError",
accounts: []*Account{
{Address: types.Address{0x01}, Chat: true, Wallet: true},
{Address: types.Address{0x02}},
},
},
{
description: "UniqueChat",
accounts: []*Account{
{Address: types.Address{0x01}, Chat: true},
{Address: types.Address{0x02}, Chat: true},
},
err: errors.ErrChatNotUnique,
},
{
description: "UniqueWallet",
accounts: []*Account{
{Address: types.Address{0x01}, Wallet: true},
{Address: types.Address{0x02}, Wallet: true},
},
err: errors.ErrWalletNotUnique,
},
} {
t.Run(tc.description, func(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
require.Equal(t, tc.err, db.SaveAccounts(tc.accounts))
})
}
}
func TestUpdateAccounts(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
accounts := []*Account{
{Address: types.Address{0x01}, Chat: true, Wallet: true},
{Address: types.Address{0x02}},
}
require.NoError(t, db.SaveAccounts(accounts))
accounts[0].Chat = false
accounts[1].Chat = true
require.NoError(t, db.SaveAccounts(accounts))
rst, err := db.GetAccounts()
require.NoError(t, err)
require.Equal(t, accounts, rst)
}
func TestDeleteAccount(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
accounts := []*Account{
{Address: types.Address{0x01}, Chat: true, Wallet: true},
}
require.NoError(t, db.SaveAccounts(accounts))
rst, err := db.GetAccounts()
require.NoError(t, err)
require.Equal(t, 1, len(rst))
require.NoError(t, db.DeleteAccount(types.Address{0x01}))
rst2, err := db.GetAccounts()
require.NoError(t, err)
require.Equal(t, 0, len(rst2))
}
func TestGetAddresses(t *testing.T) { func TestGetAddresses(t *testing.T) {
db, stop := setupTestDB(t) db, stop := setupTestDB(t)
defer stop() defer stop()
@ -107,7 +35,7 @@ func TestGetAddresses(t *testing.T) {
{Address: types.Address{0x01}, Chat: true, Wallet: true}, {Address: types.Address{0x01}, Chat: true, Wallet: true},
{Address: types.Address{0x02}}, {Address: types.Address{0x02}},
} }
require.NoError(t, db.SaveAccounts(accounts)) require.NoError(t, db.SaveOrUpdateAccounts(accounts))
addresses, err := db.GetAddresses() addresses, err := db.GetAddresses()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []types.Address{{0x01}, {0x02}}, addresses) require.Equal(t, []types.Address{{0x01}, {0x02}}, addresses)
@ -119,7 +47,7 @@ func TestGetWalletAddress(t *testing.T) {
address := types.Address{0x01} address := types.Address{0x01}
_, err := db.GetWalletAddress() _, err := db.GetWalletAddress()
require.Equal(t, err, sql.ErrNoRows) require.Equal(t, err, sql.ErrNoRows)
require.NoError(t, db.SaveAccounts([]*Account{{Address: address, Wallet: true}})) require.NoError(t, db.SaveOrUpdateAccounts([]*Account{{Address: address, Wallet: true}}))
wallet, err := db.GetWalletAddress() wallet, err := db.GetWalletAddress()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, address, wallet) require.Equal(t, address, wallet)
@ -131,44 +59,12 @@ func TestGetChatAddress(t *testing.T) {
address := types.Address{0x01} address := types.Address{0x01}
_, err := db.GetChatAddress() _, err := db.GetChatAddress()
require.Equal(t, err, sql.ErrNoRows) require.Equal(t, err, sql.ErrNoRows)
require.NoError(t, db.SaveAccounts([]*Account{{Address: address, Chat: true}})) require.NoError(t, db.SaveOrUpdateAccounts([]*Account{{Address: address, Chat: true}}))
chat, err := db.GetChatAddress() chat, err := db.GetChatAddress()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, address, chat) require.Equal(t, address, chat)
} }
func TestGetAccounts(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
accounts := []*Account{
{Address: types.Address{0x01}, Chat: true, Wallet: true},
{Address: types.Address{0x02}, PublicKey: types.HexBytes{0x01, 0x02}},
{Address: types.Address{0x03}, PublicKey: types.HexBytes{0x02, 0x03}},
}
require.NoError(t, db.SaveAccounts(accounts))
rst, err := db.GetAccounts()
require.NoError(t, err)
require.Equal(t, accounts, rst)
}
func TestGetAccountByAddress(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
address := types.Address{0x01}
account := &Account{Address: address, Chat: true, Wallet: true}
dilute := []*Account{
{Address: types.Address{0x02}, PublicKey: types.HexBytes{0x01, 0x02}},
{Address: types.Address{0x03}, PublicKey: types.HexBytes{0x02, 0x03}},
}
accounts := append(dilute, account)
require.NoError(t, db.SaveAccounts(accounts))
rst, err := db.GetAccountByAddress(address)
require.NoError(t, err)
require.Equal(t, account, rst)
}
func TestAddressExists(t *testing.T) { func TestAddressExists(t *testing.T) {
db, stop := setupTestDB(t) db, stop := setupTestDB(t)
defer stop() defer stop()
@ -176,7 +72,7 @@ func TestAddressExists(t *testing.T) {
accounts := []*Account{ accounts := []*Account{
{Address: types.Address{0x01}, Chat: true, Wallet: true}, {Address: types.Address{0x01}, Chat: true, Wallet: true},
} }
require.NoError(t, db.SaveAccounts(accounts)) require.NoError(t, db.SaveOrUpdateAccounts(accounts))
exists, err := db.AddressExists(accounts[0].Address) exists, err := db.AddressExists(accounts[0].Address)
require.NoError(t, err) require.NoError(t, err)
@ -191,74 +87,260 @@ func TestAddressDoesntExist(t *testing.T) {
require.False(t, exists) require.False(t, exists)
} }
func TestKeypairNameAndIndexWhenAddingNewAccount(t *testing.T) { func TestWatchOnlyAccounts(t *testing.T) {
db, stop := setupTestDB(t) db, stop := setupTestDB(t)
defer stop() defer stop()
accountsRegular := []*Account{
// chat account // check the db
{Address: types.Address{0x01}, Chat: true, Wallet: false, KeyUID: "0x0001"}, dbAccounts, err := db.GetAccounts()
// Status Profile keypair require.NoError(t, err)
{Address: types.Address{0x02}, Chat: false, Wallet: true, KeyUID: "0x0001", Path: "m/44'/60'/0'/0/0", LastUsedDerivationIndex: 0, DerivedFrom: "0x1111", KeypairName: "Status Profile"}, require.Equal(t, 0, len(dbAccounts))
{Address: types.Address{0x03}, Chat: false, Wallet: false, KeyUID: "0x0001", Path: "m/44'/60'/0'/0/1", LastUsedDerivationIndex: 1, DerivedFrom: "0x1111", KeypairName: "Status Profile"},
{Address: types.Address{0x04}, Chat: false, Wallet: false, KeyUID: "0x0001", Path: "m/44'/60'/0'/0/2", LastUsedDerivationIndex: 2, DerivedFrom: "0x1111", KeypairName: "Status Profile"}, woAccounts := GetWatchOnlyAccountsForTest()
// try to save keypair with watch only accounts
kp := &Keypair{}
kp.Accounts = append(kp.Accounts, woAccounts...)
err = db.SaveOrUpdateKeypair(kp)
require.Error(t, err)
// check the db after that trying to save keypair with watch only accounts
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, 0, len(dbAccounts))
// save watch only accounts
err = db.SaveOrUpdateAccounts(woAccounts)
require.NoError(t, err)
_, err = db.GetKeypairByKeyUID(woAccounts[0].KeyUID)
require.Error(t, err)
require.True(t, err == ErrDbKeypairNotFound)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(woAccounts), len(dbAccounts))
require.Equal(t, woAccounts, dbAccounts)
// try to save the same watch only account again
err = db.SaveOrUpdateAccounts(woAccounts[:1])
require.NoError(t, err)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(woAccounts), len(dbAccounts))
dbAcc, err := db.GetAccountByAddress(woAccounts[:1][0].Address)
require.NoError(t, err)
require.Equal(t, woAccounts[:1][0], dbAcc)
// try to save new watch only account
wo4 := &Account{
Address: types.Address{0x14},
Type: AccountTypeWatch,
Name: "WatchOnlyAcc4",
Color: "blue",
Emoji: "emoji-1",
} }
accountsCustom := []*Account{ err = db.SaveOrUpdateAccounts([]*Account{wo4})
// Keypair1
{Address: types.Address{0x11}, Chat: false, Wallet: false, KeyUID: "0x0002", Path: "m/44'/60'/0'/0/10", LastUsedDerivationIndex: 0, DerivedFrom: "0x2222", KeypairName: "Keypair11"},
{Address: types.Address{0x12}, Chat: false, Wallet: false, KeyUID: "0x0002", Path: "m/44'/60'/0'/0/11", LastUsedDerivationIndex: 0, DerivedFrom: "0x2222", KeypairName: "Keypair12"},
// Keypair2 out of the default Status' derivation tree
{Address: types.Address{0x22}, Chat: false, Wallet: false, KeyUID: "0x0003", Path: "m/44'/60'/0'/0/0/100", LastUsedDerivationIndex: 0, DerivedFrom: "0x3333", KeypairName: "Keypair21"},
{Address: types.Address{0x23}, Chat: false, Wallet: false, KeyUID: "0x0003", Path: "m/44'/60'/0'/0/1/100", LastUsedDerivationIndex: 0, DerivedFrom: "0x3333", KeypairName: "Keypair22"},
}
err := db.SaveAccounts(accountsRegular)
require.NoError(t, err) require.NoError(t, err)
err = db.SaveAccounts(accountsCustom) dbAccounts, err = db.GetAccounts()
require.NoError(t, err) require.NoError(t, err)
accs, err := db.GetAccounts() require.Equal(t, len(woAccounts)+1, len(dbAccounts))
dbAcc, err = db.GetAccountByAddress(wo4.Address)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, wo4, dbAcc)
for _, acc := range accs { // updated watch onl to save the same account after it's saved
if acc.Chat { wo4.Name = wo4.Name + "updated"
continue wo4.Color = "lightgreen"
} wo4.Emoji = wo4.Emoji + "updated"
if acc.KeyUID == accountsRegular[0].KeyUID { err = db.SaveOrUpdateAccounts([]*Account{wo4})
require.Equal(t, uint64(2), acc.LastUsedDerivationIndex)
require.Equal(t, "Status Profile", acc.KeypairName)
} else if acc.KeyUID == accountsCustom[1].KeyUID {
require.Equal(t, uint64(0), acc.LastUsedDerivationIndex)
require.Equal(t, "Keypair12", acc.KeypairName)
} else if acc.KeyUID == accountsCustom[3].KeyUID {
require.Equal(t, uint64(0), acc.LastUsedDerivationIndex)
require.Equal(t, "Keypair22", acc.KeypairName)
}
}
accountsCustom = []*Account{
// Status Profile keypair
{Address: types.Address{0x05}, Chat: false, Wallet: false, KeyUID: "0x0001", Path: "m/44'/60'/0'/0/100/1", LastUsedDerivationIndex: 2, DerivedFrom: "0x1111", KeypairName: "Status Profile"},
}
err = db.SaveAccounts(accountsCustom)
require.NoError(t, err) require.NoError(t, err)
dbAccounts, err = db.GetAccounts()
result, err := db.GetAccountsByKeyUID(accountsCustom[0].KeyUID)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 5, len(result)) require.Equal(t, len(woAccounts)+1, len(dbAccounts))
require.Equal(t, uint64(2), accountsCustom[0].LastUsedDerivationIndex) dbAcc, err = db.GetAccountByAddress(wo4.Address)
require.Equal(t, "Status Profile", accountsCustom[0].KeypairName)
accountsRegular = []*Account{
// Status Profile keypair
{Address: types.Address{0x06}, Chat: false, Wallet: false, KeyUID: "0x0001", Path: "m/44'/60'/0'/0/3", LastUsedDerivationIndex: 3, DerivedFrom: "0x1111", KeypairName: "Status Profile"},
}
err = db.SaveAccounts(accountsRegular)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, wo4, dbAcc)
result, err = db.GetAccountsByKeyUID(accountsCustom[0].KeyUID) // try to delete keypair for watch only account
err = db.DeleteKeypair(wo4.KeyUID)
require.Error(t, err)
require.True(t, err == ErrDbKeypairNotFound)
// try to delete watch only account
err = db.DeleteAccount(wo4.Address)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 6, len(result)) dbAccounts, err = db.GetAccounts()
require.Equal(t, uint64(3), accountsRegular[0].LastUsedDerivationIndex) require.NoError(t, err)
require.Equal(t, "Status Profile", accountsRegular[0].KeypairName) require.Equal(t, len(woAccounts), len(dbAccounts))
_, err = db.GetAccountByAddress(wo4.Address)
require.Error(t, err)
require.True(t, err == ErrDbAccountNotFound)
}
func TestKeypairs(t *testing.T) {
keypairs := []*Keypair{
GetProfileKeypairForTest(false),
GetSeedImportedKeypair1ForTest(),
GetPrivKeyImportedKeypairForTest(), // in this context (when testing db functions) there is not limitations for private key imported keypair
}
for _, kp := range keypairs {
t.Run("test keypair "+kp.Name, func(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
// check the db
dbKeypairs, err := db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 0, len(dbKeypairs))
dbAccounts, err := db.GetAccounts()
require.NoError(t, err)
require.Equal(t, 0, len(dbAccounts))
expectedLastUsedDerivationIndex := uint64(len(kp.Accounts) - 1)
if kp.Type == KeypairTypeProfile {
expectedLastUsedDerivationIndex-- // subtract one more in case of profile keypair because of chat account
}
// save keypair
err = db.SaveOrUpdateKeypair(kp)
require.NoError(t, err)
dbKeypairs, err = db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 1, len(dbKeypairs))
dbKp, err := db.GetKeypairByKeyUID(kp.KeyUID)
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
kp.LastUsedDerivationIndex = expectedLastUsedDerivationIndex
require.Equal(t, kp, dbKp)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbAccounts))
// delete keypair
err = db.DeleteKeypair(kp.KeyUID)
require.NoError(t, err)
_, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.Error(t, err)
require.True(t, err == ErrDbKeypairNotFound)
// save keypair again to test the flow below
err = db.SaveOrUpdateKeypair(kp)
require.NoError(t, err)
dbKeypairs, err = db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 1, len(dbKeypairs))
ind := len(kp.Accounts) - 1
accToUpdate := kp.Accounts[ind]
// try to save the same account again
err = db.SaveOrUpdateAccounts([]*Account{accToUpdate})
require.NoError(t, err)
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
require.Equal(t, kp, dbKp)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbAccounts))
// update an existing account
accToUpdate.Name = accToUpdate.Name + "updated"
accToUpdate.Color = "green"
accToUpdate.Emoji = accToUpdate.Emoji + "updated"
err = db.SaveOrUpdateAccounts([]*Account{accToUpdate})
require.NoError(t, err)
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbAccounts))
dbAcc, err := db.GetAccountByAddress(accToUpdate.Address)
require.NoError(t, err)
require.Equal(t, accToUpdate, dbAcc)
// update keypair name
kpToUpdate := kp
kpToUpdate.Name = kpToUpdate.Name + "updated"
err = db.SaveOrUpdateKeypair(kp)
require.NoError(t, err)
dbKeypairs, err = db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 1, len(dbKeypairs))
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.NoError(t, err)
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
require.Equal(t, kpToUpdate, dbKp)
// save new account to an existing keypair which is out of the default Status' derivation root path
accToAdd := kp.Accounts[ind]
accToAdd.Address = types.Address{0x08}
accToAdd.Path = "m/44'/60'/0'/0/10"
accToAdd.PublicKey = types.Hex2Bytes("0x000000008")
accToAdd.Name = "Generated Acc 8"
err = db.SaveOrUpdateAccounts([]*Account{accToAdd})
require.NoError(t, err)
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.NoError(t, err)
require.Equal(t, len(kp.Accounts)+1, len(dbKp.Accounts))
require.Equal(t, kp.LastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(kp.Accounts)+1, len(dbAccounts))
dbAcc, err = db.GetAccountByAddress(accToUpdate.Address)
require.NoError(t, err)
require.Equal(t, accToAdd, dbAcc)
// save new account to an existing keypair which follows Status' default derivation root path
accToAdd = kp.Accounts[ind]
accToAdd.Address = types.Address{0x09}
accToAdd.Path = "m/44'/60'/0'/0/3"
accToAdd.PublicKey = types.Hex2Bytes("0x000000009")
accToAdd.Name = "Generated Acc 9"
expectedLastUsedDerivationIndex = 3
if kp.Type == KeypairTypeSeed {
accToAdd.Path = "m/44'/60'/0'/0/2"
expectedLastUsedDerivationIndex = 2
} else if kp.Type == KeypairTypeKey {
accToAdd.Path = "m/44'/60'/0'/0/1"
expectedLastUsedDerivationIndex = 1
}
err = db.SaveOrUpdateAccounts([]*Account{accToAdd})
require.NoError(t, err)
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.NoError(t, err)
require.Equal(t, len(kp.Accounts)+2, len(dbKp.Accounts))
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(kp.Accounts)+2, len(dbAccounts))
dbAcc, err = db.GetAccountByAddress(accToUpdate.Address)
require.NoError(t, err)
require.Equal(t, accToAdd, dbAcc)
// delete account
err = db.DeleteAccount(accToAdd.Address)
require.NoError(t, err)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, len(kp.Accounts)+1, len(dbAccounts))
_, err = db.GetAccountByAddress(accToAdd.Address)
require.Error(t, err)
require.True(t, err == ErrDbAccountNotFound)
for _, acc := range dbAccounts {
err = db.DeleteAccount(acc.Address)
require.NoError(t, err)
}
_, err = db.GetKeypairByKeyUID(kp.KeyUID)
require.Error(t, err)
require.True(t, err == ErrDbKeypairNotFound)
})
}
} }

View File

@ -1,98 +1,76 @@
package keycards package accounts
import ( import (
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/status-im/status-go/appdatabase"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
) )
func setupTestDB(t *testing.T) (*Keycards, func()) {
db, stop, err := appdatabase.SetupTestSQLDB("settings-tests-")
if err != nil {
require.NoError(t, stop())
}
require.NoError(t, err)
d := NewKeycards(db)
return d, func() {
require.NoError(t, stop())
}
}
func TestKeycards(t *testing.T) { func TestKeycards(t *testing.T) {
db, stop := setupTestDB(t) db, stop := setupTestDB(t)
defer stop() defer stop()
keycardUID := "00000000000000000000000000000000" keycardUID := "00000000000000000000000000000000"
keycard1 := Keycard{
KeycardUID: "00000000000000000000000000000001", kp1 := GetProfileKeypairForTest(false)
KeycardName: "Card01", keycard1 := GetProfileKeycardForTest()
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}, {0x04}}, kp2 := GetSeedImportedKeypair1ForTest()
KeyUID: "0000000000000000000000000000000000000000000000000000000000000001", keycard2 := GetKeycardForSeedImportedKeypair1ForTest()
LastUpdateClock: 100,
} keycard2Copy := GetKeycardForSeedImportedKeypair1ForTest()
keycard2 := Keycard{ keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
KeycardUID: "00000000000000000000000000000002", keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
KeycardName: "Card02", keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}}, kp3 := GetSeedImportedKeypair2ForTest()
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002", keycard3 := GetKeycardForSeedImportedKeypair2ForTest()
LastUpdateClock: 200,
} // Pre-condition
keycard3 := Keycard{ err := db.SaveOrUpdateKeypair(kp1)
KeycardUID: "00000000000000000000000000000003", require.NoError(t, err)
KeycardName: "Card02 Copy", err = db.SaveOrUpdateKeypair(kp2)
KeycardLocked: false, require.NoError(t, err)
AccountsAddresses: []types.Address{{0x01}, {0x02}}, err = db.SaveOrUpdateKeypair(kp3)
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002", require.NoError(t, err)
LastUpdateClock: 300, dbKeypairs, err := db.GetKeypairs()
} require.NoError(t, err)
keycard4 := Keycard{ require.Equal(t, 3, len(dbKeypairs))
KeycardUID: "00000000000000000000000000000004",
KeycardName: "Card04",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000004",
LastUpdateClock: 400,
}
// Test adding key pairs // Test adding key pairs
addedKc, addedAccs, err := db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard1) addedKc, addedAccs, err := db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, true, addedKc) require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs) require.Equal(t, false, addedAccs)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard2) addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, true, addedKc) require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs) require.Equal(t, false, addedAccs)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard3) addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, true, addedKc) require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs) require.Equal(t, false, addedAccs)
// this should be added // this should be added
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(Keycard{ addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(Keycard{
KeycardUID: keycard3.KeycardUID, KeycardUID: keycard2Copy.KeycardUID,
AccountsAddresses: []types.Address{{0x03}}, AccountsAddresses: []types.Address{{0x03}},
LastUpdateClock: keycard3.LastUpdateClock + 1, LastUpdateClock: keycard2Copy.LastUpdateClock + 1,
}) })
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, false, addedKc) require.Equal(t, false, addedKc)
require.Equal(t, true, addedAccs) require.Equal(t, true, addedAccs)
// this should not be added as it has clock value less than last updated clock value // this should not be added as it has clock value less than last updated clock value
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(Keycard{ addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(Keycard{
KeycardUID: keycard3.KeycardUID, KeycardUID: keycard2Copy.KeycardUID,
AccountsAddresses: []types.Address{{0x04}}, AccountsAddresses: []types.Address{{0x04}},
LastUpdateClock: keycard3.LastUpdateClock, LastUpdateClock: keycard2Copy.LastUpdateClock,
}) })
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, false, addedKc) require.Equal(t, false, addedKc)
require.Equal(t, false, addedAccs) require.Equal(t, false, addedAccs)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard4) addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard3)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, true, addedKc) require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs) require.Equal(t, false, addedAccs)
@ -113,10 +91,10 @@ func TestKeycards(t *testing.T) {
require.Equal(t, keycard2.KeycardLocked, kp.KeycardLocked) require.Equal(t, keycard2.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keycard2.AccountsAddresses)+1, len(kp.AccountsAddresses)) // Add 1, cause one account is additionally added for the same keycard. require.Equal(t, len(keycard2.AccountsAddresses)+1, len(kp.AccountsAddresses)) // Add 1, cause one account is additionally added for the same keycard.
} else { } else {
require.Equal(t, keycard4.KeycardUID, kp.KeycardUID) require.Equal(t, keycard3.KeycardUID, kp.KeycardUID)
require.Equal(t, keycard4.KeycardName, kp.KeycardName) require.Equal(t, keycard3.KeycardName, kp.KeycardName)
require.Equal(t, keycard4.KeycardLocked, kp.KeycardLocked) require.Equal(t, keycard3.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keycard4.AccountsAddresses), len(kp.AccountsAddresses)) require.Equal(t, len(keycard3.AccountsAddresses), len(kp.AccountsAddresses))
} }
} }
@ -146,18 +124,18 @@ func TestKeycards(t *testing.T) {
require.Equal(t, keycard2.KeycardLocked, kp.KeycardLocked) require.Equal(t, keycard2.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keycard2.AccountsAddresses), len(kp.AccountsAddresses)) require.Equal(t, len(keycard2.AccountsAddresses), len(kp.AccountsAddresses))
require.Equal(t, keycard2.LastUpdateClock, kp.LastUpdateClock) require.Equal(t, keycard2.LastUpdateClock, kp.LastUpdateClock)
} else if kp.KeycardUID == keycard3.KeycardUID { } else if kp.KeycardUID == keycard2Copy.KeycardUID {
require.Equal(t, keycard2Copy.KeycardUID, kp.KeycardUID)
require.Equal(t, keycard2Copy.KeycardName, kp.KeycardName)
require.Equal(t, keycard2Copy.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keycard2Copy.AccountsAddresses)+1, len(kp.AccountsAddresses)) // Add 1, cause one account is additionally added.
require.Equal(t, keycard2Copy.LastUpdateClock+1, kp.LastUpdateClock)
} else {
require.Equal(t, keycard3.KeycardUID, kp.KeycardUID) require.Equal(t, keycard3.KeycardUID, kp.KeycardUID)
require.Equal(t, keycard3.KeycardName, kp.KeycardName) require.Equal(t, keycard3.KeycardName, kp.KeycardName)
require.Equal(t, keycard3.KeycardLocked, kp.KeycardLocked) require.Equal(t, keycard3.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keycard3.AccountsAddresses)+1, len(kp.AccountsAddresses)) // Add 1, cause one account is additionally added. require.Equal(t, len(keycard3.AccountsAddresses), len(kp.AccountsAddresses))
require.Equal(t, keycard3.LastUpdateClock+1, kp.LastUpdateClock) require.Equal(t, keycard3.LastUpdateClock, kp.LastUpdateClock)
} else {
require.Equal(t, keycard4.KeycardUID, kp.KeycardUID)
require.Equal(t, keycard4.KeycardName, kp.KeycardName)
require.Equal(t, keycard4.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keycard4.AccountsAddresses), len(kp.AccountsAddresses))
require.Equal(t, keycard4.LastUpdateClock, kp.LastUpdateClock)
} }
} }
@ -212,20 +190,20 @@ func TestKeycards(t *testing.T) {
require.Equal(t, len(keycard1.AccountsAddresses)-numOfAccountsToRemove, len(rows[0].AccountsAddresses)) require.Equal(t, len(keycard1.AccountsAddresses)-numOfAccountsToRemove, len(rows[0].AccountsAddresses))
// Test deleting accounts one by one, with the last deleted account keycard should be delete as well // Test deleting accounts one by one, with the last deleted account keycard should be delete as well
for i, addr := range keycard4.AccountsAddresses { for i, addr := range keycard3.AccountsAddresses {
err = db.RemoveMigratedAccountsForKeycard(keycard4.KeycardUID, []types.Address{addr}, 1003+uint64(i)) err = db.RemoveMigratedAccountsForKeycard(keycard3.KeycardUID, []types.Address{addr}, 1003+uint64(i))
require.NoError(t, err) require.NoError(t, err)
} }
rows, err = db.GetAllKnownKeycardsGroupedByKeyUID() rows, err = db.GetAllKnownKeycardsGroupedByKeyUID()
require.NoError(t, err) require.NoError(t, err)
// Test if correct keycard is deleted // Test if correct keycard is deleted
deletedKeycard4 := true deletedKeycard3 := true
for _, kp := range rows { for _, kp := range rows {
if kp.KeycardUID == keycard4.KeycardUID { if kp.KeycardUID == keycard3.KeycardUID {
deletedKeycard4 = false deletedKeycard3 = false
} }
} }
require.Equal(t, true, deletedKeycard4) require.Equal(t, true, deletedKeycard3)
// Test update keycard uid // Test update keycard uid
err = db.UpdateKeycardUID(keycard1.KeycardUID, keycardUID, 1100) err = db.UpdateKeycardUID(keycard1.KeycardUID, keycardUID, 1100)
@ -273,3 +251,77 @@ func TestKeycards(t *testing.T) {
} }
require.Equal(t, true, deletedKeycard2And3) require.Equal(t, true, deletedKeycard2And3)
} }
func TestKeycardsRemovalWhenDeletingKeypair(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
kp2 := &Keypair{
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
Name: "Keypair Name 2",
Type: KeypairTypeSeed,
DerivedFrom: "0x0001",
}
kp2.Accounts = append(kp2.Accounts, &Account{Address: types.Address{0x11}, KeyUID: kp2.KeyUID})
kp2.Accounts = append(kp2.Accounts, &Account{Address: types.Address{0x12}, KeyUID: kp2.KeyUID})
keycard2 := Keycard{
KeycardUID: "00000000000000000000000000000002",
KeycardName: "Card02",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x11}, {0x12}},
KeyUID: kp2.KeyUID,
LastUpdateClock: 200,
}
keycard3 := Keycard{
KeycardUID: "00000000000000000000000000000003",
KeycardName: "Card02 Copy",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x11}, {0x12}},
KeyUID: kp2.KeyUID,
LastUpdateClock: 300,
}
// Pre-condition - save keypair
err := db.SaveOrUpdateKeypair(kp2)
require.NoError(t, err)
dbKeypairs, err := db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 1, len(dbKeypairs))
// Pre-condition - save keycards referring to previously added keypair
addedKc, addedAccs, err := db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard2)
require.NoError(t, err)
require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard3)
require.NoError(t, err)
require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs)
// Check db state
keycardsWithSameKeyUID, err := db.GetAllKnownKeycards()
require.NoError(t, err)
require.Equal(t, 2, len(keycardsWithSameKeyUID))
require.Equal(t, len(kp2.KeyUID), len(dbKeypairs[0].KeyUID))
require.Equal(t, len(kp2.KeyUID), len(keycardsWithSameKeyUID[0].KeyUID))
require.Equal(t, len(kp2.KeyUID), len(keycardsWithSameKeyUID[1].KeyUID))
require.Equal(t, len(kp2.Accounts), len(dbKeypairs[0].Accounts))
require.Equal(t, len(kp2.Accounts), len(keycardsWithSameKeyUID[0].AccountsAddresses))
require.Equal(t, len(kp2.Accounts), len(keycardsWithSameKeyUID[1].AccountsAddresses))
// Remove keypair
err = db.DeleteKeypair(kp2.KeyUID)
require.NoError(t, err)
// Check db state after deletion
dbKeypairs, err = db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 0, len(dbKeypairs))
keycardsWithSameKeyUID, err = db.GetAllKnownKeycards()
require.NoError(t, err)
require.Equal(t, 0, len(keycardsWithSameKeyUID))
}

View File

@ -0,0 +1,397 @@
package accounts
import (
"github.com/status-im/status-go/eth-node/types"
)
func GetWatchOnlyAccountsForTest() []*Account {
wo1 := &Account{
Address: types.Address{0x11},
Type: AccountTypeWatch,
Name: "WatchOnlyAcc1",
Color: "blue",
Emoji: "emoji-1",
}
wo2 := &Account{
Address: types.Address{0x12},
Type: AccountTypeWatch,
Name: "WatchOnlyAcc2",
Color: "blue",
Emoji: "emoji-1",
}
wo3 := &Account{
Address: types.Address{0x13},
Type: AccountTypeWatch,
Name: "WatchOnlyAcc3",
Color: "blue",
Emoji: "emoji-1",
}
return []*Account{wo1, wo2, wo3}
}
func GetProfileKeypairForTest(onlyChatAndDefaultWalletAccount bool) *Keypair {
kp := &Keypair{
KeyUID: "0000000000000000000000000000000000000000000000000000000000000001",
Name: "Profile Name",
Type: KeypairTypeProfile,
DerivedFrom: "0x0001",
}
profileAccount := &Account{
Address: types.Address{0x01},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: true,
Type: AccountTypeGenerated,
Path: "m/43'/60'/1581'/0'/0",
PublicKey: types.Hex2Bytes("0x000000001"),
Name: "Profile Name",
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, profileAccount)
defaultWalletAccount := &Account{
Address: types.Address{0x02},
KeyUID: kp.KeyUID,
Wallet: true,
Chat: false,
Type: AccountTypeGenerated,
Path: "m/44'/60'/0'/0/0",
PublicKey: types.Hex2Bytes("0x000000002"),
Name: "Generated Acc 1",
Emoji: "emoji-1",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, defaultWalletAccount)
kp.LastUsedDerivationIndex = 0
if !onlyChatAndDefaultWalletAccount {
generatedWalletAccount1 := &Account{
Address: types.Address{0x03},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeGenerated,
Path: "m/44'/60'/0'/0/1",
PublicKey: types.Hex2Bytes("0x000000003"),
Name: "Generated Acc 2",
Emoji: "emoji-2",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, generatedWalletAccount1)
kp.LastUsedDerivationIndex = 1
generatedWalletAccount2 := &Account{
Address: types.Address{0x04},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeGenerated,
Path: "m/44'/60'/0'/0/2",
PublicKey: types.Hex2Bytes("0x000000004"),
Name: "Generated Acc 3",
Emoji: "emoji-3",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, generatedWalletAccount2)
kp.LastUsedDerivationIndex = 2
}
return kp
}
func GetSeedImportedKeypair1ForTest() *Keypair {
kp := &Keypair{
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
Name: "Seed Imported 1",
Type: KeypairTypeSeed,
DerivedFrom: "0x0002",
}
seedGeneratedWalletAccount1 := &Account{
Address: types.Address{0x21},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeSeed,
Path: "m/44'/60'/0'/0/0",
PublicKey: types.Hex2Bytes("0x000000021"),
Name: "Seed Impo 1 Acc 1",
Emoji: "emoji-1",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, seedGeneratedWalletAccount1)
kp.LastUsedDerivationIndex = 0
seedGeneratedWalletAccount2 := &Account{
Address: types.Address{0x22},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeSeed,
Path: "m/44'/60'/0'/0/1",
PublicKey: types.Hex2Bytes("0x000000022"),
Name: "Seed Impo 1 Acc 2",
Emoji: "emoji-2",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, seedGeneratedWalletAccount2)
kp.LastUsedDerivationIndex = 1
return kp
}
func GetSeedImportedKeypair2ForTest() *Keypair {
kp := &Keypair{
KeyUID: "0000000000000000000000000000000000000000000000000000000000000003",
Name: "Seed Imported 2",
Type: KeypairTypeSeed,
DerivedFrom: "0x0003",
}
seedGeneratedWalletAccount1 := &Account{
Address: types.Address{0x31},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeSeed,
Path: "m/44'/60'/0'/0/0",
PublicKey: types.Hex2Bytes("0x000000031"),
Name: "Seed Impo 2 Acc 1",
Emoji: "emoji-1",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, seedGeneratedWalletAccount1)
kp.LastUsedDerivationIndex = 0
seedGeneratedWalletAccount2 := &Account{
Address: types.Address{0x32},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeSeed,
Path: "m/44'/60'/0'/0/1",
PublicKey: types.Hex2Bytes("0x000000032"),
Name: "Seed Impo 2 Acc 2",
Emoji: "emoji-2",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, seedGeneratedWalletAccount2)
kp.LastUsedDerivationIndex = 1
return kp
}
func GetPrivKeyImportedKeypairForTest() *Keypair {
kp := &Keypair{
KeyUID: "0000000000000000000000000000000000000000000000000000000000000004",
Name: "Priv Key Imported",
Type: KeypairTypeKey,
DerivedFrom: "", // no derived from for private key imported kp
}
privKeyWalletAccount := &Account{
Address: types.Address{0x41},
KeyUID: kp.KeyUID,
Wallet: false,
Chat: false,
Type: AccountTypeKey,
Path: "m",
PublicKey: types.Hex2Bytes("0x000000041"),
Name: "Priv Key Impo Acc",
Emoji: "emoji-1",
Color: "blue",
Hidden: false,
Clock: 0,
Removed: false,
Operable: AccountFullyOperable,
}
kp.Accounts = append(kp.Accounts, privKeyWalletAccount)
return kp
}
func GetProfileKeycardForTest() *Keycard {
profileKp := GetProfileKeypairForTest(false)
keycard1Addresses := []types.Address{}
for _, acc := range profileKp.Accounts {
keycard1Addresses = append(keycard1Addresses, acc.Address)
}
return &Keycard{
KeycardUID: "00000000000000000000000000000001",
KeycardName: "Card01",
KeycardLocked: false,
AccountsAddresses: keycard1Addresses,
KeyUID: profileKp.KeyUID,
LastUpdateClock: 100,
}
}
func GetKeycardForSeedImportedKeypair1ForTest() *Keycard {
seed1Kp := GetSeedImportedKeypair1ForTest()
keycard2Addresses := []types.Address{}
for _, acc := range seed1Kp.Accounts {
keycard2Addresses = append(keycard2Addresses, acc.Address)
}
return &Keycard{
KeycardUID: "00000000000000000000000000000002",
KeycardName: "Card02",
KeycardLocked: false,
AccountsAddresses: keycard2Addresses,
KeyUID: seed1Kp.KeyUID,
LastUpdateClock: 200,
}
}
func GetKeycardForSeedImportedKeypair2ForTest() *Keycard {
seed2Kp := GetSeedImportedKeypair2ForTest()
keycard4Addresses := []types.Address{}
for _, acc := range seed2Kp.Accounts {
keycard4Addresses = append(keycard4Addresses, acc.Address)
}
return &Keycard{
KeycardUID: "00000000000000000000000000000003",
KeycardName: "Card03",
KeycardLocked: false,
AccountsAddresses: keycard4Addresses,
KeyUID: seed2Kp.KeyUID,
LastUpdateClock: 300,
}
}
func SameAccounts(expected, real *Account) bool {
return expected.Address == real.Address &&
expected.KeyUID == real.KeyUID &&
expected.Wallet == real.Wallet &&
expected.Chat == real.Chat &&
expected.Type == real.Type &&
expected.Path == real.Path &&
string(expected.PublicKey) == string(real.PublicKey) &&
expected.Name == real.Name &&
expected.Emoji == real.Emoji &&
expected.Color == real.Color &&
expected.Hidden == real.Hidden &&
expected.Clock == real.Clock &&
expected.Removed == real.Removed
}
func SameAccountsWithDifferentOperable(expected, real *Account, expectedOperableValue AccountOperable) bool {
return SameAccounts(expected, real) && real.Operable == expectedOperableValue
}
func SameKeypairs(expected, real *Keypair) bool {
same := expected.KeyUID == real.KeyUID &&
expected.Name == real.Name &&
expected.Type == real.Type &&
expected.DerivedFrom == real.DerivedFrom &&
expected.LastUsedDerivationIndex == real.LastUsedDerivationIndex &&
expected.Clock == real.Clock &&
len(expected.Accounts) == len(real.Accounts)
if same {
for i := range expected.Accounts {
found := false
for j := range real.Accounts {
if SameAccounts(expected.Accounts[i], real.Accounts[j]) {
found = true
break
}
}
if !found {
return false
}
}
}
return same
}
func SameKeypairsWithDifferentSyncedFrom(expected, real *Keypair, ignoreSyncedFrom bool, expectedSyncedFromValue string,
expectedOperableValue AccountOperable) bool {
same := expected.KeyUID == real.KeyUID &&
expected.Name == real.Name &&
expected.Type == real.Type &&
expected.DerivedFrom == real.DerivedFrom &&
expected.LastUsedDerivationIndex == real.LastUsedDerivationIndex &&
expected.Clock == real.Clock &&
len(expected.Accounts) == len(real.Accounts)
if same && !ignoreSyncedFrom {
same = same && real.SyncedFrom == expectedSyncedFromValue
}
if same {
for i := range expected.Accounts {
found := false
for j := range real.Accounts {
if SameAccountsWithDifferentOperable(expected.Accounts[i], real.Accounts[j], expectedOperableValue) {
found = true
break
}
}
if !found {
return false
}
}
}
return same
}
func SameKeycards(expected, real *Keycard) bool {
same := expected.KeycardUID == real.KeycardUID &&
expected.KeyUID == real.KeyUID &&
expected.KeycardName == real.KeycardName &&
expected.KeycardLocked == real.KeycardLocked &&
expected.LastUpdateClock == real.LastUpdateClock &&
len(expected.AccountsAddresses) == len(real.AccountsAddresses)
if same {
for i := range expected.AccountsAddresses {
found := false
for j := range real.AccountsAddresses {
if expected.AccountsAddresses[i] == real.AccountsAddresses[j] {
found = true
break
}
}
if !found {
return false
}
}
}
return same
}

View File

@ -16,6 +16,7 @@ import (
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/images" "github.com/status-im/status-go/images"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings" "github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests" "github.com/status-im/status-go/protocol/requests"
@ -671,14 +672,25 @@ func (s *MessengerBackupSuite) TestBackupCommunities() {
s.Require().Equal(clock, lastBackup) s.Require().Equal(clock, lastBackup)
} }
func (s *MessengerBackupSuite) TestBackupWalletAccounts() { func (s *MessengerBackupSuite) TestBackupKeypairs() {
// Create bob1 // Create bob1
bob1 := s.m bob1 := s.m
walletAccounts := getWalletAccountsForTest() profileKp := accounts.GetProfileKeypairForTest(false)
s.NoError(bob1.settings.SaveAccounts(walletAccounts)) seedKp := accounts.GetSeedImportedKeypair1ForTest()
bob1Accs, err := bob1.settings.GetAccounts()
s.Require().NoError(err, "bob1.settings.GetAccounts") // Create a main account on bob1
s.Len(bob1Accs, len(walletAccounts), "must have all wallet accounts") err := bob1.settings.SaveOrUpdateKeypair(profileKp)
s.Require().NoError(err, "profile keypair bob1")
err = bob1.settings.SaveOrUpdateKeypair(seedKp)
s.Require().NoError(err, "seed keypair bob1")
// Check account is present in the db for bob1
dbProfileKp1, err := bob1.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(profileKp, dbProfileKp1))
dbSeedKp1, err := bob1.settings.GetKeypairByKeyUID(seedKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(seedKp, dbSeedKp1))
// Create bob2 // Create bob2
bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil) bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
@ -700,43 +712,69 @@ func (s *MessengerBackupSuite) TestBackupWalletAccounts() {
) )
s.Require().NoError(err) s.Require().NoError(err)
bob2Accs, err := bob2.settings.GetAccounts() // Check account is present in the db for bob2
s.Require().NoError(err, "bob2.settings.GetAccounts") dbProfileKp2, err := bob2.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Len(bob2Accs, len(walletAccounts), "must have all wallet accounts") s.Require().NoError(err)
s.Require().Equal(profileKp.Name, dbProfileKp2.Name)
s.Require().Equal(accounts.SyncedFromBackup, dbProfileKp2.SyncedFrom)
for _, syncedAcc := range bob2Accs { for _, acc := range profileKp.Accounts {
if syncedAcc.Chat { if acc.Chat {
continue continue
} }
found := false s.Require().True(contains(dbProfileKp2.Accounts, acc, accounts.SameAccounts))
for _, sentAcc := range walletAccounts {
if syncedAcc.Address == sentAcc.Address {
// Check account values match the expected values
s.Require().Equal(sentAcc.Address, syncedAcc.Address)
s.Require().Equal(sentAcc.Path, syncedAcc.Path)
s.Require().Equal(sentAcc.KeyUID, syncedAcc.KeyUID)
s.Require().Equal(sentAcc.Name, syncedAcc.Name)
s.Require().Equal(sentAcc.Color, syncedAcc.Color)
s.Require().Equal(sentAcc.Type, syncedAcc.Type)
s.Require().Equal(sentAcc.KeypairName, syncedAcc.KeypairName)
s.Require().Equal(sentAcc.DerivedFrom, syncedAcc.DerivedFrom)
found = true
}
}
s.Require().True(found)
} }
dbSeedKp2, err := bob2.settings.GetKeypairByKeyUID(seedKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(seedKp, dbSeedKp2, false, accounts.SyncedFromBackup, accounts.AccountNonOperable))
} }
func (s *MessengerBackupSuite) TestBackupKeycards() { func (s *MessengerBackupSuite) TestBackupKeycards() {
// Create bob1 // Create bob1
bob1 := s.m bob1 := s.m
allKeycardsToSync := getKeycardsForTest()
for _, kp := range allKeycardsToSync { kp1 := accounts.GetProfileKeypairForTest(false)
addedKc, addedAccs, err := bob1.settings.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) keycard1 := accounts.GetProfileKeycardForTest()
s.Require().NoError(err)
s.Require().Equal(true, addedKc) kp2 := accounts.GetSeedImportedKeypair1ForTest()
s.Require().Equal(false, addedAccs) keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
}
keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
kp3 := accounts.GetSeedImportedKeypair2ForTest()
keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest()
// Pre-condition
err := bob1.settings.SaveOrUpdateKeypair(kp1)
s.Require().NoError(err)
err = bob1.settings.SaveOrUpdateKeypair(kp2)
s.Require().NoError(err)
err = bob1.settings.SaveOrUpdateKeypair(kp3)
s.Require().NoError(err)
dbKeypairs, err := bob1.settings.GetKeypairs()
s.Require().NoError(err)
s.Require().Equal(3, len(dbKeypairs))
addedKc, addedAccs, err := bob1.settings.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = bob1.settings.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = bob1.settings.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = bob1.settings.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard3)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Create bob2 // Create bob2
bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil) bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
@ -760,6 +798,47 @@ func (s *MessengerBackupSuite) TestBackupKeycards() {
syncedKeycards, err := bob2.settings.GetAllKnownKeycards() syncedKeycards, err := bob2.settings.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards)) s.Require().Equal(4, len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards)) s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2Copy, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard3, accounts.SameKeycards))
}
func (s *MessengerBackupSuite) TestBackupWatchOnlyAccounts() {
// Create bob1
bob1 := s.m
woAccounts := accounts.GetWatchOnlyAccountsForTest()
err := bob1.settings.SaveOrUpdateAccounts(woAccounts)
s.Require().NoError(err)
dbWoAccounts1, err := bob1.settings.GetWatchOnlyAccounts()
s.Require().NoError(err)
s.Require().Equal(len(woAccounts), len(dbWoAccounts1))
s.Require().True(haveSameElements(woAccounts, dbWoAccounts1, accounts.SameAccounts))
// Create bob2
bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
s.Require().NoError(err)
_, err = bob2.Start()
s.Require().NoError(err)
// Backup
_, err = bob1.BackupData(context.Background())
s.Require().NoError(err)
// Wait for the message to reach its destination
_, err = WaitOnMessengerResponse(
bob2,
func(r *MessengerResponse) bool {
return r.BackupHandled
},
"no messages",
)
s.Require().NoError(err)
dbWoAccounts2, err := bob2.settings.GetWatchOnlyAccounts()
s.Require().NoError(err)
s.Require().Equal(len(woAccounts), len(dbWoAccounts2))
s.Require().True(haveSameElements(woAccounts, dbWoAccounts2, accounts.SameAccounts))
} }

View File

@ -11,6 +11,7 @@ import (
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/protocol/encryption/multidevice" "github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/tt" "github.com/status-im/status-go/protocol/tt"
"github.com/status-im/status-go/waku" "github.com/status-im/status-go/waku"
@ -73,6 +74,31 @@ func (s *MessengerSyncKeycardChangeSuite) SetupTest() {
err = s.main.EnableInstallation(s.other.installationID) err = s.main.EnableInstallation(s.other.installationID)
s.Require().NoError(err) s.Require().NoError(err)
// Pre-condition - both sides have to know about keypairs migrated to a keycards
kp1 := accounts.GetProfileKeypairForTest(false)
kp2 := accounts.GetSeedImportedKeypair1ForTest()
// kp3 := accounts.GetSeedImportedKeypair2ForTest()
err = s.main.settings.SaveOrUpdateKeypair(kp1)
s.Require().NoError(err)
err = s.main.settings.SaveOrUpdateKeypair(kp2)
s.Require().NoError(err)
// err = s.main.settings.SaveOrUpdateKeypair(kp3)
// s.Require().NoError(err)
dbKeypairs, err := s.main.settings.GetKeypairs()
s.Require().NoError(err)
s.Require().Equal(2, len(dbKeypairs))
err = s.other.SaveOrUpdateKeypair(kp1)
s.Require().NoError(err)
err = s.other.SaveOrUpdateKeypair(kp2)
s.Require().NoError(err)
// err = s.other.SaveOrUpdateKeypair(kp3)
// s.Require().NoError(err)
dbKeypairs, err = s.other.settings.GetKeypairs()
s.Require().NoError(err)
s.Require().Equal(2, len(dbKeypairs))
} }
func (s *MessengerSyncKeycardChangeSuite) TearDownTest() { func (s *MessengerSyncKeycardChangeSuite) TearDownTest() {
@ -94,57 +120,66 @@ func (s *MessengerSyncKeycardChangeSuite) TestAddingNewKeycards() {
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
// Add key cards on sender // Add key cards on sender
allKeycardsToSync := getKeycardsForTest()[:2] keycard1 := accounts.GetProfileKeycardForTest()
for _, kp := range allKeycardsToSync {
added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), kp) keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
s.Require().NoError(err)
s.Require().Equal(true, added) added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), keycard1)
} s.Require().NoError(err)
s.Require().Equal(true, added)
added, err = s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), keycard2)
s.Require().NoError(err)
s.Require().Equal(true, added)
// Wait for the response // Wait for the response
_, err := WaitOnMessengerResponse( _, err = WaitOnMessengerResponse(
s.other, s.other,
func(r *MessengerResponse) bool { func(r *MessengerResponse) bool {
return len(r.KeycardActions()) == len(allKeycardsToSync) return len(r.KeycardActions()) == 2
}, },
"expected to receive keycard activities", "expected to receive keycard activities",
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := s.main.settings.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(2, len(senderKeycards))
s.Require().True(contains(senderKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(senderKeycards, keycard2, accounts.SameKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards)) s.Require().Equal(2, len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards)) s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
} }
func (s *MessengerSyncKeycardChangeSuite) TestAddingAccountsToKeycard() { func (s *MessengerSyncKeycardChangeSuite) TestAddingAccountsToKeycard() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add additional accounts to sender // Add additional accounts to sender
updatedKeycard := getKeycardsForTest()[:1][0] added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), keycard2)
updatedKeycard.AccountsAddresses = []types.Address{{0x011}, {0x022}, {0x033}, {0x044}}
added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), updatedKeycard)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, added) s.Require().Equal(true, added)
// Add accounts that we can check for results later
updatedKeycard.AccountsAddresses = append(updatedKeycard.AccountsAddresses, keycardToSync.AccountsAddresses...)
// Wait for the response // Wait for the response
_, err = WaitOnMessengerResponse( _, err = WaitOnMessengerResponse(
s.other, s.other,
@ -155,35 +190,44 @@ func (s *MessengerSyncKeycardChangeSuite) TestAddingAccountsToKeycard() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(2, len(senderKeycards))
s.Require().True(contains(senderKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(senderKeycards, keycard2, accounts.SameKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(2, len(syncedKeycards))
s.Require().True(sameKeycards(syncedKeycards[0], updatedKeycard)) s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
} }
func (s *MessengerSyncKeycardChangeSuite) TestRemovingAccountsFromKeycard() { func (s *MessengerSyncKeycardChangeSuite) TestRemovingAccountsFromKeycard() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Remove accounts from sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.AccountsAddresses = updatedKeycard.AccountsAddresses[2:] updatedKeycard1.AccountsAddresses = updatedKeycard1.AccountsAddresses[2:]
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID, // Remove accounts from sender
keycardToSync.AccountsAddresses[:2], keycardToSync.LastUpdateClock) err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycard1.KeycardUID,
keycard1.AccountsAddresses[:2], updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -196,32 +240,38 @@ func (s *MessengerSyncKeycardChangeSuite) TestRemovingAccountsFromKeycard() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(contains(senderKeycards, updatedKeycard1, accounts.SameKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(updatedKeycard, syncedKeycards[0])) s.Require().True(contains(syncedKeycards, updatedKeycard1, accounts.SameKeycards))
} }
func (s *MessengerSyncKeycardChangeSuite) TestRemovingAllAccountsFromKeycard() { func (s *MessengerSyncKeycardChangeSuite) TestRemovingAllAccountsFromKeycard() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Remove all accounts from sender // Remove all accounts from sender
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID, err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycard1.KeycardUID,
keycardToSync.AccountsAddresses, keycardToSync.LastUpdateClock) keycard1.AccountsAddresses, keycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -234,6 +284,10 @@ func (s *MessengerSyncKeycardChangeSuite) TestRemovingAllAccountsFromKeycard() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(0, len(senderKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(0, len(syncedKeycards)) s.Require().Equal(0, len(syncedKeycards))
@ -243,21 +297,22 @@ func (s *MessengerSyncKeycardChangeSuite) TestDeleteKeycard() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Remove keycard from sender // Remove keycard from sender
err = s.main.DeleteKeycard(context.Background(), keycardToSync.KeycardUID, keycardToSync.LastUpdateClock) err = s.main.DeleteKeycard(context.Background(), keycard1.KeycardUID, keycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -270,6 +325,10 @@ func (s *MessengerSyncKeycardChangeSuite) TestDeleteKeycard() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(0, len(senderKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(0, len(syncedKeycards)) s.Require().Equal(0, len(syncedKeycards))
@ -279,26 +338,27 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardName() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set new keycard name to sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardName = "New Keycard Name" updatedKeycard1.KeycardName = "New Keycard Name"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
err = s.main.SetKeycardName(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.KeycardName, // Set new keycard name to sender
updatedKeycard.LastUpdateClock) err = s.main.SetKeycardName(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.KeycardName,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -311,36 +371,43 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardName() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(updatedKeycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(updatedKeycard, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(updatedKeycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardNameWithOlderClock() { func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardNameWithOlderClock() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set new keycard name to sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardName = "New Keycard Name" updatedKeycard1.KeycardName = "New Keycard Name"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1 updatedKeycard1.LastUpdateClock = updatedKeycard1.LastUpdateClock - 1
err = s.main.SetKeycardName(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.KeycardName, // Set new keycard name to sender
updatedKeycard.LastUpdateClock) err = s.main.SetKeycardName(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.KeycardName,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -353,35 +420,40 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardNameWithOlderClock()
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(keycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(keycardToSync, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(keycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLocked() { func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLocked() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set keycard locked on sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardLocked = true updatedKeycard1.KeycardLocked = true
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
err = s.main.KeycardLocked(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.LastUpdateClock) err = s.main.KeycardLocked(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -394,35 +466,41 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLocked() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(updatedKeycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(updatedKeycard, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(updatedKeycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLockedOlderClock() { func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLockedOlderClock() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set keycard locked on sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardLocked = true updatedKeycard1.KeycardLocked = true
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1 updatedKeycard1.LastUpdateClock = updatedKeycard1.LastUpdateClock - 1
err = s.main.KeycardLocked(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.LastUpdateClock) err = s.main.KeycardLocked(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -435,36 +513,41 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLockedOlderClock() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(keycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(keycardToSync, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(keycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlocked() { func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlocked() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard1.KeycardLocked = true
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
keycardToSync.KeycardLocked = true
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardLocked = false updatedKeycard1.KeycardLocked = false
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
err = s.main.KeycardUnlocked(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.LastUpdateClock) err = s.main.KeycardUnlocked(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -477,36 +560,42 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlocked() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(updatedKeycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(updatedKeycard, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(updatedKeycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlockedOlderClock() { func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlockedOlderClock() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard1.KeycardLocked = true
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
keycardToSync.KeycardLocked = true
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardLocked = false updatedKeycard1.KeycardLocked = false
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1 updatedKeycard1.LastUpdateClock = updatedKeycard1.LastUpdateClock - 1
err = s.main.KeycardLocked(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.LastUpdateClock) err = s.main.KeycardUnlocked(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -519,36 +608,42 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlockedOlderClock()
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(keycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(keycardToSync, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(keycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUid() { func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUid() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardUID = "00000000000000000000000000000000" updatedKeycard1.KeycardUID = "00000000000000000000000000000000"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
err = s.main.UpdateKeycardUID(context.Background(), keycardToSync.KeycardUID, updatedKeycard.KeycardUID, // Update keycard uid on sender
updatedKeycard.LastUpdateClock) err = s.main.UpdateKeycardUID(context.Background(), keycard1.KeycardUID, updatedKeycard1.KeycardUID,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -561,36 +656,43 @@ func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUid() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(updatedKeycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(updatedKeycard, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(updatedKeycard1, syncedKeycards[0]))
} }
func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUidOldClock() { func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUidOldClock() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender // Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver // Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender // Prepare expected keycard for comparison
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard.KeycardUID = "00000000000000000000000000000000" updatedKeycard1.KeycardUID = "00000000000000000000000000000000"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1 updatedKeycard1.LastUpdateClock = updatedKeycard1.LastUpdateClock - 1
err = s.main.UpdateKeycardUID(context.Background(), keycardToSync.KeycardUID, updatedKeycard.KeycardUID, // Update keycard uid on sender
updatedKeycard.LastUpdateClock) err = s.main.UpdateKeycardUID(context.Background(), keycard1.KeycardUID, updatedKeycard1.KeycardUID,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -603,8 +705,13 @@ func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUidOldClock() {
) )
s.Require().NoError(err) s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(1, len(senderKeycards))
s.Require().True(accounts.SameKeycards(keycard1, senderKeycards[0]))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards)) s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(keycardToSync, syncedKeycards[0])) s.Require().True(accounts.SameKeycards(keycard1, syncedKeycards[0]))
} }

View File

@ -11,7 +11,7 @@ import (
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/keycards" "github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/protocol/encryption/multidevice" "github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/tt" "github.com/status-im/status-go/protocol/tt"
"github.com/status-im/status-go/waku" "github.com/status-im/status-go/waku"
@ -74,6 +74,31 @@ func (s *MessengerSyncKeycardsStateSuite) SetupTest() {
err = s.main.EnableInstallation(s.other.installationID) err = s.main.EnableInstallation(s.other.installationID)
s.Require().NoError(err) s.Require().NoError(err)
// Pre-condition - both sides have to know about keypairs migrated to a keycards
kp1 := accounts.GetProfileKeypairForTest(false)
kp2 := accounts.GetSeedImportedKeypair1ForTest()
kp3 := accounts.GetSeedImportedKeypair2ForTest()
err = s.main.settings.SaveOrUpdateKeypair(kp1)
s.Require().NoError(err)
err = s.main.settings.SaveOrUpdateKeypair(kp2)
s.Require().NoError(err)
err = s.main.settings.SaveOrUpdateKeypair(kp3)
s.Require().NoError(err)
dbKeypairs, err := s.main.settings.GetKeypairs()
s.Require().NoError(err)
s.Require().Equal(3, len(dbKeypairs))
err = s.other.SaveOrUpdateKeypair(kp1)
s.Require().NoError(err)
err = s.other.SaveOrUpdateKeypair(kp2)
s.Require().NoError(err)
err = s.other.SaveOrUpdateKeypair(kp3)
s.Require().NoError(err)
dbKeypairs, err = s.other.settings.GetKeypairs()
s.Require().NoError(err)
s.Require().Equal(3, len(dbKeypairs))
} }
func (s *MessengerSyncKeycardsStateSuite) TearDownTest() { func (s *MessengerSyncKeycardsStateSuite) TearDownTest() {
@ -91,92 +116,48 @@ func (s *MessengerSyncKeycardsStateSuite) newMessenger(shh types.Waku) *Messenge
return messenger return messenger
} }
func sameKeycards(a, b *keycards.Keycard) bool {
same := a.KeycardUID == b.KeycardUID &&
a.KeyUID == b.KeyUID &&
a.KeycardName == b.KeycardName &&
a.KeycardLocked == b.KeycardLocked &&
a.LastUpdateClock == b.LastUpdateClock &&
len(a.AccountsAddresses) == len(b.AccountsAddresses)
if same {
for i := range a.AccountsAddresses {
found := false
for j := range b.AccountsAddresses {
if a.AccountsAddresses[i] == b.AccountsAddresses[j] {
found = true
break
}
}
if !found {
return false
}
}
}
return same
}
func getKeycardsForTest() []*keycards.Keycard {
keycard1 := keycards.Keycard{
KeycardUID: "00000000000000000000000000000001",
KeycardName: "Card01",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}, {0x04}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000001",
LastUpdateClock: 100,
}
keycard2 := keycards.Keycard{
KeycardUID: "00000000000000000000000000000002",
KeycardName: "Card02",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
LastUpdateClock: 200,
}
keycard3 := keycards.Keycard{
KeycardUID: "00000000000000000000000000000003",
KeycardName: "Card02 Copy",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
LastUpdateClock: 300,
}
keycard4 := keycards.Keycard{
KeycardUID: "00000000000000000000000000000004",
KeycardName: "Card04",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000004",
LastUpdateClock: 400,
}
return []*keycards.Keycard{&keycard1, &keycard2, &keycard3, &keycard4}
}
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNoKeycards() { func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNoKeycards() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest()
// Add keycards on sender // Add keycards on sender
allKeycardsToSync := getKeycardsForTest() addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
for _, kp := range allKeycardsToSync { s.Require().NoError(err)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) s.Require().Equal(true, addedKc)
s.Require().NoError(err) s.Require().Equal(false, addedAccs)
s.Require().Equal(true, addedKc) addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
s.Require().Equal(false, addedAccs) s.Require().NoError(err)
} s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard3)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Trigger's a sync between devices // Trigger's a sync between devices
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
_, err = WaitOnMessengerResponse( _, err = WaitOnMessengerResponse(
s.other, s.other,
func(r *MessengerResponse) bool { func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) == len(allKeycardsToSync) return len(r.Keypairs) == 3 && len(r.Keycards) == 4
}, },
"expected to receive keycards", "expected to receive keycards",
) )
@ -184,47 +165,59 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNoKeycard
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards)) s.Require().Equal(4, len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards)) s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2Copy, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard3, accounts.SameKeycards))
} }
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasKeycardsOlderThanSender() { func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasKeycardsOlderThanSender() {
senderDb := s.main.settings senderDb := s.main.settings
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
// Add keycards on sender // Add keycards on sender
allKeycardsToSync := getKeycardsForTest() addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
for _, kp := range allKeycardsToSync { s.Require().NoError(err)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) s.Require().Equal(true, addedKc)
s.Require().NoError(err) s.Require().Equal(false, addedAccs)
s.Require().Equal(true, addedKc) addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
s.Require().Equal(false, addedAccs) s.Require().NoError(err)
} s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add keycards on receiver // Add keycards on receiver - partially
keycardsOnReceiver := getKeycardsForTest()[:2] keycardR1 := accounts.GetProfileKeycardForTest()
keycardsOnReceiver[0].KeycardName = "CardNameToBeChanged-0" keycardR1.KeycardName = "CardNameToBeChanged-0"
keycardsOnReceiver[0].AccountsAddresses = keycardsOnReceiver[0].AccountsAddresses[2:3] keycardR1.AccountsAddresses = keycardR1.AccountsAddresses[2:3]
keycardsOnReceiver[0].LastUpdateClock = keycardsOnReceiver[0].LastUpdateClock - 1 keycardR1.LastUpdateClock = keycardR1.LastUpdateClock - 1
keycardsOnReceiver[1].KeycardName = "CardNameToBeChanged-1"
keycardsOnReceiver[1].LastUpdateClock = keycardsOnReceiver[1].LastUpdateClock - 1
for _, kp := range keycardsOnReceiver { keycardR2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) keycardR2.KeycardName = "CardNameToBeChanged-1"
s.Require().NoError(err) keycardR2.LastUpdateClock = keycardR2.LastUpdateClock - 1
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardR1)
} s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardR2)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Trigger's a sync between devices // Trigger's a sync between devices
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
_, err = WaitOnMessengerResponse( _, err = WaitOnMessengerResponse(
s.other, s.other,
func(r *MessengerResponse) bool { func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) == len(allKeycardsToSync) return len(r.Keypairs) == 3 && len(r.Keycards) == 2
}, },
"expected to receive keycards", "expected to receive keycards",
) )
@ -232,8 +225,67 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasKeycardsO
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards)) s.Require().Equal(2, len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards)) s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
}
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasKeycardsNewerThanSender() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
// Add keycards on sender
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add keycards on receiver - partially
keycardR1 := accounts.GetProfileKeycardForTest()
keycardR1.KeycardName = "CardNameToBeChanged-0"
keycardR1.AccountsAddresses = keycardR1.AccountsAddresses[2:3]
keycardR1.LastUpdateClock = keycardR1.LastUpdateClock + 1
keycardR2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycardR2.KeycardName = "CardNameToBeChanged-1"
keycardR2.LastUpdateClock = keycardR2.LastUpdateClock + 1
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardR1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardR2)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Trigger's a sync between devices
err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err)
// Wait for the response
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.Keypairs) == 3 && len(r.Keycards) == 2
},
"expected to receive keycards",
)
s.Require().NoError(err)
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(2, len(syncedKeycards))
s.Require().True(contains(syncedKeycards, keycardR1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycardR2, accounts.SameKeycards))
} }
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfKeycardsWereDeletedOnSenderSide() { func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfKeycardsWereDeletedOnSenderSide() {
@ -241,79 +293,54 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfKeycardsWereDeletedO
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
// Add keycards on sender // Add keycards on sender
allKeycardsToSync := getKeycardsForTest()[:2] keycard1 := accounts.GetProfileKeycardForTest()
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
// Add keycards on receiver keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycardsOnReceiver := getKeycardsForTest()
for _, kp := range keycardsOnReceiver {
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
// Trigger's a sync between devices keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest()
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
s.Require().NoError(err) keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
// Wait for the response keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest()
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) == len(allKeycardsToSync)
},
"expected to receive keycards",
)
s.Require().NoError(err)
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards))
}
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeycardsThanTheSameAreDeletedOnSenderSide() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
// Add keycards on sender // Add keycards on sender
allKeycardsToSync := getKeycardsForTest()[:2] addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
for _, kp := range allKeycardsToSync { s.Require().NoError(err)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) s.Require().Equal(true, addedKc)
s.Require().NoError(err) s.Require().Equal(false, addedAccs)
s.Require().Equal(true, addedKc) addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
s.Require().Equal(false, addedAccs) s.Require().NoError(err)
} s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add keycards on receiver // Add keycards on receiver
keycardsOnReceiver := getKeycardsForTest() addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
clock, _ := s.other.getLastClockWithRelatedChat() s.Require().NoError(err)
keycardsOnReceiver[2].KeycardName = "NewerCardName-2" s.Require().Equal(true, addedKc)
keycardsOnReceiver[2].LastUpdateClock = clock + 1000 s.Require().Equal(false, addedAccs)
keycardsOnReceiver[3].KeycardName = "NewerCardName-3" addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
keycardsOnReceiver[3].LastUpdateClock = clock + 1000 s.Require().NoError(err)
for _, kp := range keycardsOnReceiver { s.Require().Equal(true, addedKc)
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) s.Require().Equal(false, addedAccs)
s.Require().NoError(err) addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
s.Require().Equal(true, addedKc) s.Require().NoError(err)
s.Require().Equal(false, addedAccs) s.Require().Equal(true, addedKc)
} s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard3)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Trigger's a sync between devices // Trigger's a sync between devices
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
_, err = WaitOnMessengerResponse( _, err = WaitOnMessengerResponse(
s.other, s.other,
func(r *MessengerResponse) bool { func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) >= len(allKeycardsToSync) return len(r.Keypairs) == 3 && len(r.Keycards) == 2
}, },
"expected to receive keycards", "expected to receive keycards",
) )
@ -321,13 +348,9 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeyc
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(keycardsOnReceiver), len(syncedKeycards)) s.Require().Equal(2, len(syncedKeycards))
for _, kc := range allKeycardsToSync { s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, kc, sameKeycards)) s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
}
for _, kc := range keycardsOnReceiver {
s.Require().True(contains(syncedKeycards, kc, sameKeycards))
}
} }
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverAndSenderHasNoKeycardsInCommon() { func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverAndSenderHasNoKeycardsInCommon() {
@ -335,91 +358,46 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverAndSenderHas
dbOnReceiver := s.other.settings dbOnReceiver := s.other.settings
// Add keycards on sender // Add keycards on sender
allKeycardsToSync := getKeycardsForTest()[:2] keycard1 := accounts.GetProfileKeycardForTest()
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
// Add keycards on receiver keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycardsOnReceiver := getKeycardsForTest()[2:]
clock, _ := s.other.getLastClockWithRelatedChat()
keycardsOnReceiver[0].KeycardName = "NewerCardName-0"
keycardsOnReceiver[0].LastUpdateClock = clock + 1000
keycardsOnReceiver[1].KeycardName = "NewerCardName-1"
keycardsOnReceiver[1].LastUpdateClock = clock + 1000
for _, kp := range keycardsOnReceiver { keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest()
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
s.Require().NoError(err) keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
s.Require().Equal(true, addedKc) keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
s.Require().Equal(false, addedAccs)
}
// Trigger's a sync between devices keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest()
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err)
// Wait for the response
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) >= len(allKeycardsToSync)
},
"expected to receive keycards",
)
s.Require().NoError(err)
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync)+len(keycardsOnReceiver), len(syncedKeycards))
for _, kc := range allKeycardsToSync {
s.Require().True(contains(syncedKeycards, kc, sameKeycards))
}
for _, kc := range keycardsOnReceiver {
s.Require().True(contains(syncedKeycards, kc, sameKeycards))
}
}
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeycardThanSender() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
// Add keycards on sender // Add keycards on sender
allKeycardsToSync := getKeycardsForTest() addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
for _, kp := range allKeycardsToSync { s.Require().NoError(err)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp) s.Require().Equal(true, addedKc)
s.Require().NoError(err) s.Require().Equal(false, addedAccs)
s.Require().Equal(true, addedKc) addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
s.Require().Equal(false, addedAccs) s.Require().NoError(err)
} s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add keycards on receiver // Add keycards on receiver
keycardsOnReceiver := getKeycardsForTest()[2:] addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
clock, _ := s.other.getLastClockWithRelatedChat() s.Require().NoError(err)
keycardsOnReceiver[0].KeycardName = "NewerCardName-0" s.Require().Equal(true, addedKc)
keycardsOnReceiver[0].LastUpdateClock = clock + 1000 s.Require().Equal(false, addedAccs)
keycardsOnReceiver[1].KeycardName = "NewerCardName-1" addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard3)
keycardsOnReceiver[1].LastUpdateClock = clock + 1000 s.Require().NoError(err)
s.Require().Equal(true, addedKc)
for _, kp := range keycardsOnReceiver { s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
// Trigger's a sync between devices // Trigger's a sync between devices
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
_, err = WaitOnMessengerResponse( _, err = WaitOnMessengerResponse(
s.other, s.other,
func(r *MessengerResponse) bool { func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) == len(allKeycardsToSync) return len(r.Keypairs) == 3 && len(r.Keycards) == 2
}, },
"expected to receive keycards", "expected to receive keycards",
) )
@ -427,11 +405,7 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeyc
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards)) s.Require().Equal(2, len(syncedKeycards))
for _, kc := range allKeycardsToSync[:2] { s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, kc, sameKeycards)) s.Require().True(contains(syncedKeycards, keycard2Copy, accounts.SameKeycards))
}
for _, kc := range keycardsOnReceiver {
s.Require().True(contains(syncedKeycards, kc, sameKeycards))
}
} }

View File

@ -65,145 +65,31 @@ func (s *MessengerSyncWalletSuite) newMessenger(shh types.Waku) *Messenger {
return messenger return messenger
} }
func getWalletAccountsForTest() []*accounts.Account {
defaultAccount := &accounts.Account{
Address: types.Address{0x11},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000001",
Wallet: true,
Chat: false,
Path: "m/44'/60'/0'/0/0",
Name: "Default Account",
Color: "blue",
DerivedFrom: "0x0001",
KeypairName: "Profile Keypair",
LastUsedDerivationIndex: 0,
}
generatedFromDefaultAccount1 := &accounts.Account{
Address: types.Address{0x12},
Type: accounts.AccountTypeGenerated,
KeyUID: defaultAccount.KeyUID,
Path: "m/44'/60'/0'/0/1",
Name: "Generated Acc 1",
Color: "blue",
DerivedFrom: defaultAccount.DerivedFrom,
KeypairName: defaultAccount.KeypairName,
LastUsedDerivationIndex: 1,
}
generatedFromDefaultAccount2 := &accounts.Account{
Address: types.Address{0x13},
Type: accounts.AccountTypeGenerated,
KeyUID: defaultAccount.KeyUID,
Path: "m/44'/60'/0'/0/2",
Name: "Generated Acc 2",
Color: "blue",
DerivedFrom: defaultAccount.DerivedFrom,
KeypairName: defaultAccount.KeypairName,
LastUsedDerivationIndex: 2,
}
seedImportedAccount := &accounts.Account{
Address: types.Address{0x14},
Type: accounts.AccountTypeSeed,
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
Path: "m/44'/60'/0'/0/0",
Name: "Seed Imported Account",
Color: "green",
DerivedFrom: "0x0002",
KeypairName: "Seed Keypair",
LastUsedDerivationIndex: 0,
}
generatedFromSeedImportedAccount1 := &accounts.Account{
Address: types.Address{0x15},
Type: accounts.AccountTypeSeed,
KeyUID: seedImportedAccount.KeyUID,
Path: "m/44'/60'/0'/0/1",
Name: "Generated Seed Account 1",
Color: "green",
DerivedFrom: seedImportedAccount.DerivedFrom,
KeypairName: seedImportedAccount.KeypairName,
LastUsedDerivationIndex: 1,
}
generatedFromSeedImportedAccount2 := &accounts.Account{
Address: types.Address{0x16},
Type: accounts.AccountTypeSeed,
KeyUID: seedImportedAccount.KeyUID,
Path: "m/44'/60'/0'/0/2",
Name: "Generated Seed Account 2",
Color: "green",
DerivedFrom: seedImportedAccount.DerivedFrom,
KeypairName: seedImportedAccount.KeypairName,
LastUsedDerivationIndex: 2,
}
keyImportedAccount := &accounts.Account{
Address: types.Address{0x17},
Type: accounts.AccountTypeKey,
KeyUID: "0000000000000000000000000000000000000000000000000000000000000003",
Path: "m",
Name: "Key Imported Account",
Color: "blue",
KeypairName: "Private Key Keypair",
}
watchOnlyAccount1 := &accounts.Account{
Address: types.Address{0x18},
Type: accounts.AccountTypeWatch,
Name: "Watch Only Account 1",
Color: "green",
}
watchOnlyAccount2 := &accounts.Account{
Address: types.Address{0x19},
Type: accounts.AccountTypeWatch,
Name: "Watch Only Account 1",
Color: "green",
}
return []*accounts.Account{
defaultAccount,
generatedFromDefaultAccount1,
generatedFromDefaultAccount2,
seedImportedAccount,
generatedFromSeedImportedAccount1,
generatedFromSeedImportedAccount2,
keyImportedAccount,
watchOnlyAccount1,
watchOnlyAccount2,
}
}
func (s *MessengerSyncWalletSuite) TestSyncWallets() { func (s *MessengerSyncWalletSuite) TestSyncWallets() {
mainAccount := &accounts.Account{ profileKp := accounts.GetProfileKeypairForTest(false)
Address: types.Address{0x01},
Wallet: false,
Chat: true,
}
// Create a main account on alice // Create a main account on alice
s.NoError(s.m.settings.SaveAccounts([]*accounts.Account{mainAccount})) err := s.m.settings.SaveOrUpdateKeypair(profileKp)
s.Require().NoError(err, "profile keypair alice.settings.SaveOrUpdateKeypair")
// Check account is present in the db // Check account is present in the db
acc1, err := s.m.settings.GetAccounts() dbProfileKp1, err := s.m.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err, "alice.settings.GetAccounts") s.Require().NoError(err)
s.Len(acc1, 1, "Must have 1 main account") s.Require().True(accounts.SameKeypairs(profileKp, dbProfileKp1))
// Check account values match the expected values
s.Require().Equal(mainAccount.Address, acc1[0].Address)
s.Require().Equal(mainAccount.Name, acc1[0].Name)
s.Require().Equal(mainAccount.Color, acc1[0].Color)
s.Require().Equal(mainAccount.Type, acc1[0].Type)
// Create new device and add main account to // Create new device and add main account to
alicesOtherDevice, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil) alicesOtherDevice, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
s.Require().NoError(err) s.Require().NoError(err)
s.NoError(alicesOtherDevice.settings.SaveAccounts([]*accounts.Account{mainAccount}), true) // Store only chat and default wallet account on other device
profileKpOtherDevice := accounts.GetProfileKeypairForTest(true)
err = alicesOtherDevice.settings.SaveOrUpdateKeypair(profileKpOtherDevice)
s.Require().NoError(err, "profile keypair alicesOtherDevice.settings.SaveOrUpdateKeypair")
acc2, err := alicesOtherDevice.settings.GetAccounts() // Check account is present in the db
s.Require().NoError(err, "alicesOtherDevice.settings.GetAccounts") dbProfileKp2, err := alicesOtherDevice.settings.GetKeypairByKeyUID(profileKpOtherDevice.KeyUID)
s.Len(acc2, 1, "Must have 1 main account") s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(profileKpOtherDevice, dbProfileKp2))
// Check account values match the expected values
s.Require().Equal(mainAccount.Address, acc2[0].Address)
s.Require().Equal(mainAccount.Name, acc2[0].Name)
s.Require().Equal(mainAccount.Color, acc2[0].Color)
s.Require().Equal(mainAccount.Type, acc2[0].Type)
// Pair devices // Pair devices
im1 := &multidevice.InstallationMetadata{ im1 := &multidevice.InstallationMetadata{
@ -235,13 +121,36 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() {
err = s.m.EnableInstallation(alicesOtherDevice.installationID) err = s.m.EnableInstallation(alicesOtherDevice.installationID)
s.Require().NoError(err) s.Require().NoError(err)
// Store wallet accounts on alice's device // Store seed phrase keypair with accounts on alice's device
walletAccounts := getWalletAccountsForTest() seedPhraseKp := accounts.GetSeedImportedKeypair1ForTest()
expectedTotalNumOfAccounts := len(walletAccounts) + 1 // plus one for the Status profile account err = s.m.settings.SaveOrUpdateKeypair(seedPhraseKp)
s.NoError(s.m.settings.SaveAccounts(walletAccounts)) s.Require().NoError(err, "seed phrase keypair alice.settings.SaveOrUpdateKeypair")
acc1, err = s.m.settings.GetAccounts()
s.Require().NoError(err, "alice.settings.GetAccounts") dbSeedPhraseKp1, err := s.m.settings.GetKeypairByKeyUID(seedPhraseKp.KeyUID)
s.Len(acc1, expectedTotalNumOfAccounts, "Must have all wallet accounts plus one for the Status profile account") s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(seedPhraseKp, dbSeedPhraseKp1))
// Store private key keypair with accounts on alice's device
privKeyKp := accounts.GetPrivKeyImportedKeypairForTest()
err = s.m.settings.SaveOrUpdateKeypair(privKeyKp)
s.Require().NoError(err, "private key keypair alice.settings.SaveOrUpdateKeypair")
dbPrivKeyKp1, err := s.m.settings.GetKeypairByKeyUID(privKeyKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(privKeyKp, dbPrivKeyKp1))
// Store watch only accounts on alice's device
woAccounts := accounts.GetWatchOnlyAccountsForTest()
err = s.m.settings.SaveOrUpdateAccounts(woAccounts)
s.Require().NoError(err)
dbWoAccounts1, err := s.m.settings.GetWatchOnlyAccounts()
s.Require().NoError(err)
s.Require().Equal(len(woAccounts), len(dbWoAccounts1))
s.Require().True(haveSameElements(woAccounts, dbWoAccounts1, accounts.SameAccounts))
dbAccounts1, err := s.m.settings.GetAccounts()
s.Require().NoError(err)
s.Require().Equal(len(profileKp.Accounts)+len(seedPhraseKp.Accounts)+len(privKeyKp.Accounts)+len(woAccounts), len(dbAccounts1))
// Trigger's a sync between devices // Trigger's a sync between devices
err = s.m.SyncDevices(context.Background(), "ens-name", "profile-image", nil) err = s.m.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
@ -253,45 +162,43 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() {
return err return err
} }
if len(response.Accounts) != len(walletAccounts) { if len(response.Keypairs) != 3 || // 3 keypairs (profile, seed, priv key)
len(response.Accounts) != len(woAccounts) {
return errors.New("no sync wallet account received") return errors.New("no sync wallet account received")
} }
return nil return nil
}) })
s.Require().NoError(err) s.Require().NoError(err)
acc2, err = alicesOtherDevice.settings.GetAccounts() dbProfileKp2, err = s.m.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err, "alicesOtherDevice.settings.GetAccounts") s.Require().NoError(err)
s.Len(acc2, expectedTotalNumOfAccounts, "Must have all wallet accounts plus one for the Status profile account") s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(profileKp, dbProfileKp2, true, "", accounts.AccountFullyOperable))
for _, syncedAcc := range acc2 { dbSeedPhraseKp2, err := alicesOtherDevice.settings.GetKeypairByKeyUID(seedPhraseKp.KeyUID)
if syncedAcc.Chat { s.Require().NoError(err)
continue s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(seedPhraseKp, dbSeedPhraseKp2, true, "", accounts.AccountNonOperable))
}
found := false
for _, sentAcc := range walletAccounts {
if syncedAcc.Address == sentAcc.Address {
// Check account values match the expected values
s.Require().Equal(sentAcc.Address, syncedAcc.Address)
s.Require().Equal(sentAcc.Path, syncedAcc.Path)
s.Require().Equal(sentAcc.KeyUID, syncedAcc.KeyUID)
s.Require().Equal(sentAcc.Name, syncedAcc.Name)
s.Require().Equal(sentAcc.Color, syncedAcc.Color)
s.Require().Equal(sentAcc.Type, syncedAcc.Type)
s.Require().Equal(sentAcc.KeypairName, syncedAcc.KeypairName)
s.Require().Equal(sentAcc.DerivedFrom, syncedAcc.DerivedFrom)
found = true
}
}
s.Require().True(found)
}
// Updates alice's accounts attributes dbPrivKeyKp2, err := alicesOtherDevice.settings.GetKeypairByKeyUID(privKeyKp.KeyUID)
for _, acc := range walletAccounts { s.Require().NoError(err)
acc.Name = acc.Name + "New" s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(privKeyKp, dbPrivKeyKp2, true, "", accounts.AccountNonOperable))
acc.Color = "lightblue"
s.Require().NoError(s.m.SaveAccount(acc)) dbWoAccounts2, err := alicesOtherDevice.settings.GetWatchOnlyAccounts()
} s.Require().NoError(err)
s.Require().Equal(len(woAccounts), len(dbWoAccounts2))
s.Require().True(haveSameElements(woAccounts, dbWoAccounts2, accounts.SameAccounts))
dbAccounts2, err := alicesOtherDevice.settings.GetAccounts()
s.Require().NoError(err)
s.Require().Equal(len(profileKp.Accounts)+len(seedPhraseKp.Accounts)+len(privKeyKp.Accounts)+len(woAccounts), len(dbAccounts2))
s.Require().True(haveSameElements(dbAccounts1, dbAccounts2, accounts.SameAccounts))
// Update keypair name on alice's primary device
profileKpUpdated := accounts.GetProfileKeypairForTest(true)
profileKpUpdated.Name = profileKp.Name + "Updated"
profileKpUpdated.Accounts = profileKp.Accounts[:0]
err = s.m.SaveOrUpdateKeypair(profileKpUpdated)
s.Require().NoError(err, "updated keypair name on alice primary device")
// Sync between devices is triggered automatically // Sync between devices is triggered automatically
// via watch account changes subscription // via watch account changes subscription
@ -302,36 +209,46 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() {
return err return err
} }
if len(response.Accounts) != 1 { if len(response.Keypairs) != 1 {
return errors.New("no sync wallet account received") return errors.New("no sync wallet account received")
} }
return nil return nil
}) })
s.Require().NoError(err) s.Require().NoError(err)
acc2, err = alicesOtherDevice.settings.GetAccounts() // check on alice's other device
s.Require().NoError(err, "alicesOtherDevice.settings.GetAccounts") dbProfileKp2, err = alicesOtherDevice.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Len(acc2, expectedTotalNumOfAccounts, "Must have all wallet accounts plus one for the Status profile account") s.Require().NoError(err)
s.Require().Equal(profileKpUpdated.Name, dbProfileKp2.Name)
for _, syncedAcc := range acc2 { // Update accounts on alice's primary device
if syncedAcc.Chat { profileKpUpdated = accounts.GetProfileKeypairForTest(false)
continue accountsToUpdate := profileKpUpdated.Accounts[2:]
for _, acc := range accountsToUpdate {
acc.Name = acc.Name + "Updated"
acc.Color = acc.Color + "Updated"
acc.Emoji = acc.Emoji + "Updated"
err = s.m.SaveOrUpdateAccount(acc)
s.Require().NoError(err, "updated account on alice primary device")
}
err = tt.RetryWithBackOff(func() error {
response, err := alicesOtherDevice.RetrieveAll()
if err != nil {
return err
} }
found := false
for _, sentAcc := range walletAccounts { if len(response.Accounts) != len(accountsToUpdate) {
if syncedAcc.Address == sentAcc.Address { return errors.New("no sync wallet account received")
// Check account values match the expected values
s.Require().Equal(sentAcc.Address, syncedAcc.Address)
s.Require().Equal(sentAcc.Path, syncedAcc.Path)
s.Require().Equal(sentAcc.KeyUID, syncedAcc.KeyUID)
s.Require().Equal(sentAcc.Name, syncedAcc.Name)
s.Require().Equal(sentAcc.Color, syncedAcc.Color)
s.Require().Equal(sentAcc.Type, syncedAcc.Type)
s.Require().Equal(sentAcc.KeypairName, syncedAcc.KeypairName)
s.Require().Equal(sentAcc.DerivedFrom, syncedAcc.DerivedFrom)
found = true
}
} }
s.Require().True(found) return nil
})
s.Require().NoError(err)
// check on alice's other device
dbProfileKp2, err = alicesOtherDevice.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err)
for _, acc := range accountsToUpdate {
s.Require().True(contains(dbProfileKp2.Accounts, acc, accounts.SameAccounts))
} }
} }