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()
require.NoError(t, err)
address := crypto.PubkeyToAddress(pkey.PublicKey)
keyUIDHex := sha256.Sum256(gethcrypto.FromECDSAPub(&pkey.PublicKey))
keyUID := types.EncodeHex(keyUIDHex[:])
db, err := accounts.NewDB(backend.appDB)
require.NoError(t, err)
_, err = backend.AccountManager().ImportAccount(pkey, password)
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")
require.EqualError(t, err, "could not decrypt key with given password")
require.Nil(t, key)
@ -580,32 +593,53 @@ func TestBackendGetVerifiedAccount(t *testing.T) {
require.NoError(t, err)
derivedInfo := derivedInfos[newPath]
partialAcc := &accounts.Account{
Address: types.HexToAddress(derivedInfo.Address),
Type: accounts.AccountTypeGenerated,
PublicKey: types.Hex2Bytes(derivedInfo.PublicKey),
Path: newPath,
Wallet: false,
Name: "PartialAccount",
keypair := &accounts.Keypair{
KeyUID: walletInfo.KeyUID,
Name: "profile keypair",
Type: accounts.KeypairTypeProfile,
Accounts: []*accounts.Account{
&accounts.Account{
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
key, err := backend.getVerifiedWalletAccount(partialAcc.Address.Hex(), password)
key, err := backend.getVerifiedWalletAccount(keypair.Accounts[0].Address.Hex(), password)
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) {
pkey, err := crypto.GenerateKey()
require.NoError(t, err)
address := crypto.PubkeyToAddress(pkey.PublicKey)
keyUIDHex := sha256.Sum256(gethcrypto.FromECDSAPub(&pkey.PublicKey))
keyUID := types.EncodeHex(keyUIDHex[:])
db, err := accounts.NewDB(backend.appDB)
require.NoError(t, err)
defer db.Close()
_, err = backend.AccountManager().ImportAccount(pkey, password)
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)
require.NoError(t, err)
require.Equal(t, address, key.Address)
@ -636,7 +670,12 @@ func TestLoginWithKey(t *testing.T) {
require.NotNil(t, b.statusNode.HTTPServer())
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.StopNode())
@ -677,7 +716,12 @@ func TestVerifyDatabasePassword(t *testing.T) {
require.NoError(t, b.OpenAccounts())
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.StopNode())
@ -738,7 +782,8 @@ func TestDeleteMultiaccount(t *testing.T) {
s,
&params.NodeConfig{},
nil)
require.NoError(t, err)
require.Error(t, err)
require.True(t, err == accounts.ErrKeypairWithoutAccounts)
err = backend.OpenAccounts()
require.NoError(t, err)
@ -839,17 +884,22 @@ func TestConvertAccount(t *testing.T) {
found = keystoreContainsFileForAccount(keyStoreDir, chatAddress)
require.True(t, found)
var accountsToStore []*accounts.Account
accountsToStore = append(accountsToStore, &accounts.Account{
Address: types.HexToAddress(chatAddress),
DerivedFrom: masterAddress,
profileKeypair := &accounts.Keypair{
KeyUID: genAccInfo.KeyUID,
Type: accounts.AccountTypeGenerated,
PublicKey: types.Hex2Bytes(accountInfo.PublicKey),
Path: pathEIP1581Chat,
Wallet: false,
Chat: true,
Name: "GeneratedAccount",
Name: "Profile Name",
Type: accounts.KeypairTypeProfile,
DerivedFrom: masterAddress,
}
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 {
@ -860,25 +910,24 @@ func TestConvertAccount(t *testing.T) {
if p == pathDefaultWalletAccount ||
p == customWalletPath1 ||
p == customWalletPath2 {
accountsToStore = append(accountsToStore, &accounts.Account{
Address: types.HexToAddress(dAccInfo.Address),
KeyUID: genAccInfo.KeyUID,
Wallet: false,
Chat: false,
Type: accounts.AccountTypeGenerated,
Path: p,
Name: "derivacc" + p,
Hidden: false,
DerivedFrom: masterAddress,
Removed: false,
profileKeypair.Accounts = append(profileKeypair.Accounts, &accounts.Account{
Address: types.HexToAddress(dAccInfo.Address),
KeyUID: genAccInfo.KeyUID,
Wallet: false,
Chat: false,
Type: accounts.AccountTypeGenerated,
Path: p,
Name: "derivacc" + p,
Hidden: false,
Removed: false,
})
}
}
account := multiaccounts.Account{
Name: "foo",
Name: profileKeypair.Name,
Timestamp: 1,
KeyUID: genAccInfo.KeyUID,
KeyUID: profileKeypair.KeyUID,
}
err = backend.ensureAppDBOpened(account, password)
@ -904,7 +953,7 @@ func TestConvertAccount(t *testing.T) {
err = backend.saveAccountsAndSettings(
s,
&params.NodeConfig{},
accountsToStore)
profileKeypair.Accounts)
require.NoError(t, err)
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/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
@ -84,7 +85,8 @@ func setupWalletTest(t *testing.T, password string) (backend *GethStatusBackend,
WalletRootAddress: types.HexToAddress(walletRootAddress)}
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
err = backend.StartNode(config)

View File

@ -38,24 +38,38 @@ func TestIsOwnAccount(t *testing.T) {
func TestUnmarshal(t *testing.T) {
data := `
{
"key-uid": "0xbc14c321b74652e57c7f26eb30d597ea27cbdf36cba5c85d24f12748153a035e",
"public-key": "0x0465f6d4f1172524fc057954c8a3f8e34f991558b3d1097189975062f67adda7835da61acb5cda3348b41d211ed0cb07aba668eb12e19e29d98745bebf68d93b61",
"address": "0xf09c9f5Fb9faa22d0C6C593e7157Ceac8B2b0fe4",
"color": "#4360df",
"wallet": true,
"chat": true,
"path": "m/44'/60'/0'/0/0",
"name": "Status account",
"derived-from": "0x6f015A79890Dcb38eFeC1D83772d57159D2eb58b"
"type": "generated",
"emoji": "some-emoji",
"hidden": true,
"clock": 1234,
"removed": true,
"operable": "fully"
}
`
var account Account
err := json.Unmarshal([]byte(data), &account)
require.NoError(t, err)
require.Equal(t, "0xbc14c321b74652e57c7f26eb30d597ea27cbdf36cba5c85d24f12748153a035e", account.KeyUID)
require.Equal(t, []byte("0x0465f6d4f1172524fc057954c8a3f8e34f991558b3d1097189975062f67adda7835da61acb5cda3348b41d211ed0cb07aba668eb12e19e29d98745bebf68d93b61"), account.PublicKey.Bytes())
require.Equal(t, "0xf09c9f5Fb9faa22d0C6C593e7157Ceac8B2b0fe4", account.Address.String())
require.Equal(t, "#4360df", account.Color)
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, "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/eth-node/types"
"github.com/status-im/status-go/multiaccounts/errors"
)
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) {
db, stop := setupTestDB(t)
defer stop()
@ -107,7 +35,7 @@ func TestGetAddresses(t *testing.T) {
{Address: types.Address{0x01}, Chat: true, Wallet: true},
{Address: types.Address{0x02}},
}
require.NoError(t, db.SaveAccounts(accounts))
require.NoError(t, db.SaveOrUpdateAccounts(accounts))
addresses, err := db.GetAddresses()
require.NoError(t, err)
require.Equal(t, []types.Address{{0x01}, {0x02}}, addresses)
@ -119,7 +47,7 @@ func TestGetWalletAddress(t *testing.T) {
address := types.Address{0x01}
_, err := db.GetWalletAddress()
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()
require.NoError(t, err)
require.Equal(t, address, wallet)
@ -131,44 +59,12 @@ func TestGetChatAddress(t *testing.T) {
address := types.Address{0x01}
_, err := db.GetChatAddress()
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()
require.NoError(t, err)
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) {
db, stop := setupTestDB(t)
defer stop()
@ -176,7 +72,7 @@ func TestAddressExists(t *testing.T) {
accounts := []*Account{
{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)
require.NoError(t, err)
@ -191,74 +87,260 @@ func TestAddressDoesntExist(t *testing.T) {
require.False(t, exists)
}
func TestKeypairNameAndIndexWhenAddingNewAccount(t *testing.T) {
func TestWatchOnlyAccounts(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
accountsRegular := []*Account{
// chat account
{Address: types.Address{0x01}, Chat: true, Wallet: false, KeyUID: "0x0001"},
// Status Profile keypair
{Address: types.Address{0x02}, Chat: false, Wallet: true, KeyUID: "0x0001", Path: "m/44'/60'/0'/0/0", LastUsedDerivationIndex: 0, DerivedFrom: "0x1111", KeypairName: "Status Profile"},
{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"},
// check the db
dbAccounts, err := db.GetAccounts()
require.NoError(t, err)
require.Equal(t, 0, len(dbAccounts))
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{
// 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)
err = db.SaveOrUpdateAccounts([]*Account{wo4})
require.NoError(t, err)
err = db.SaveAccounts(accountsCustom)
dbAccounts, err = db.GetAccounts()
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.Equal(t, wo4, dbAcc)
for _, acc := range accs {
if acc.Chat {
continue
}
if acc.KeyUID == accountsRegular[0].KeyUID {
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)
// updated watch onl to save the same account after it's saved
wo4.Name = wo4.Name + "updated"
wo4.Color = "lightgreen"
wo4.Emoji = wo4.Emoji + "updated"
err = db.SaveOrUpdateAccounts([]*Account{wo4})
require.NoError(t, err)
result, err := db.GetAccountsByKeyUID(accountsCustom[0].KeyUID)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
require.Equal(t, 5, len(result))
require.Equal(t, uint64(2), accountsCustom[0].LastUsedDerivationIndex)
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.Equal(t, len(woAccounts)+1, len(dbAccounts))
dbAcc, err = db.GetAccountByAddress(wo4.Address)
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.Equal(t, 6, len(result))
require.Equal(t, uint64(3), accountsRegular[0].LastUsedDerivationIndex)
require.Equal(t, "Status Profile", accountsRegular[0].KeypairName)
dbAccounts, err = db.GetAccounts()
require.NoError(t, err)
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 (
"testing"
"github.com/stretchr/testify/require"
"github.com/status-im/status-go/appdatabase"
"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) {
db, stop := setupTestDB(t)
defer stop()
keycardUID := "00000000000000000000000000000000"
keycard1 := Keycard{
KeycardUID: "00000000000000000000000000000001",
KeycardName: "Card01",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}, {0x04}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000001",
LastUpdateClock: 100,
}
keycard2 := Keycard{
KeycardUID: "00000000000000000000000000000002",
KeycardName: "Card02",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
LastUpdateClock: 200,
}
keycard3 := Keycard{
KeycardUID: "00000000000000000000000000000003",
KeycardName: "Card02 Copy",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
LastUpdateClock: 300,
}
keycard4 := Keycard{
KeycardUID: "00000000000000000000000000000004",
KeycardName: "Card04",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000004",
LastUpdateClock: 400,
}
kp1 := GetProfileKeypairForTest(false)
keycard1 := GetProfileKeycardForTest()
kp2 := GetSeedImportedKeypair1ForTest()
keycard2 := GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy := GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
kp3 := GetSeedImportedKeypair2ForTest()
keycard3 := GetKeycardForSeedImportedKeypair2ForTest()
// Pre-condition
err := db.SaveOrUpdateKeypair(kp1)
require.NoError(t, err)
err = db.SaveOrUpdateKeypair(kp2)
require.NoError(t, err)
err = db.SaveOrUpdateKeypair(kp3)
require.NoError(t, err)
dbKeypairs, err := db.GetKeypairs()
require.NoError(t, err)
require.Equal(t, 3, len(dbKeypairs))
// Test adding key pairs
addedKc, addedAccs, err := db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard1)
addedKc, addedAccs, err := db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
require.NoError(t, err)
require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard2)
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)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
require.NoError(t, err)
require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs)
// this should be added
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(Keycard{
KeycardUID: keycard3.KeycardUID,
KeycardUID: keycard2Copy.KeycardUID,
AccountsAddresses: []types.Address{{0x03}},
LastUpdateClock: keycard3.LastUpdateClock + 1,
LastUpdateClock: keycard2Copy.LastUpdateClock + 1,
})
require.NoError(t, err)
require.Equal(t, false, addedKc)
require.Equal(t, true, addedAccs)
// this should not be added as it has clock value less than last updated clock value
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(Keycard{
KeycardUID: keycard3.KeycardUID,
KeycardUID: keycard2Copy.KeycardUID,
AccountsAddresses: []types.Address{{0x04}},
LastUpdateClock: keycard3.LastUpdateClock,
LastUpdateClock: keycard2Copy.LastUpdateClock,
})
require.NoError(t, err)
require.Equal(t, false, addedKc)
require.Equal(t, false, addedAccs)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(keycard4)
addedKc, addedAccs, err = db.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard3)
require.NoError(t, err)
require.Equal(t, true, addedKc)
require.Equal(t, false, addedAccs)
@ -113,10 +91,10 @@ func TestKeycards(t *testing.T) {
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.
} 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, keycard3.KeycardUID, kp.KeycardUID)
require.Equal(t, keycard3.KeycardName, kp.KeycardName)
require.Equal(t, keycard3.KeycardLocked, kp.KeycardLocked)
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, len(keycard2.AccountsAddresses), len(kp.AccountsAddresses))
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.KeycardName, kp.KeycardName)
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, keycard3.LastUpdateClock+1, 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)
require.Equal(t, len(keycard3.AccountsAddresses), len(kp.AccountsAddresses))
require.Equal(t, keycard3.LastUpdateClock, kp.LastUpdateClock)
}
}
@ -212,20 +190,20 @@ func TestKeycards(t *testing.T) {
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
for i, addr := range keycard4.AccountsAddresses {
err = db.RemoveMigratedAccountsForKeycard(keycard4.KeycardUID, []types.Address{addr}, 1003+uint64(i))
for i, addr := range keycard3.AccountsAddresses {
err = db.RemoveMigratedAccountsForKeycard(keycard3.KeycardUID, []types.Address{addr}, 1003+uint64(i))
require.NoError(t, err)
}
rows, err = db.GetAllKnownKeycardsGroupedByKeyUID()
require.NoError(t, err)
// Test if correct keycard is deleted
deletedKeycard4 := true
deletedKeycard3 := true
for _, kp := range rows {
if kp.KeycardUID == keycard4.KeycardUID {
deletedKeycard4 = false
if kp.KeycardUID == keycard3.KeycardUID {
deletedKeycard3 = false
}
}
require.Equal(t, true, deletedKeycard4)
require.Equal(t, true, deletedKeycard3)
// Test update keycard uid
err = db.UpdateKeycardUID(keycard1.KeycardUID, keycardUID, 1100)
@ -273,3 +251,77 @@ func TestKeycards(t *testing.T) {
}
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/types"
"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/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
@ -671,14 +672,25 @@ func (s *MessengerBackupSuite) TestBackupCommunities() {
s.Require().Equal(clock, lastBackup)
}
func (s *MessengerBackupSuite) TestBackupWalletAccounts() {
func (s *MessengerBackupSuite) TestBackupKeypairs() {
// Create bob1
bob1 := s.m
walletAccounts := getWalletAccountsForTest()
s.NoError(bob1.settings.SaveAccounts(walletAccounts))
bob1Accs, err := bob1.settings.GetAccounts()
s.Require().NoError(err, "bob1.settings.GetAccounts")
s.Len(bob1Accs, len(walletAccounts), "must have all wallet accounts")
profileKp := accounts.GetProfileKeypairForTest(false)
seedKp := accounts.GetSeedImportedKeypair1ForTest()
// Create a main account on bob1
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
bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
@ -700,43 +712,69 @@ func (s *MessengerBackupSuite) TestBackupWalletAccounts() {
)
s.Require().NoError(err)
bob2Accs, err := bob2.settings.GetAccounts()
s.Require().NoError(err, "bob2.settings.GetAccounts")
s.Len(bob2Accs, len(walletAccounts), "must have all wallet accounts")
// Check account is present in the db for bob2
dbProfileKp2, err := bob2.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err)
s.Require().Equal(profileKp.Name, dbProfileKp2.Name)
s.Require().Equal(accounts.SyncedFromBackup, dbProfileKp2.SyncedFrom)
for _, syncedAcc := range bob2Accs {
if syncedAcc.Chat {
for _, acc := range profileKp.Accounts {
if acc.Chat {
continue
}
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)
s.Require().True(contains(dbProfileKp2.Accounts, acc, accounts.SameAccounts))
}
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() {
// Create bob1
bob1 := s.m
allKeycardsToSync := getKeycardsForTest()
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := bob1.settings.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
kp1 := accounts.GetProfileKeypairForTest(false)
keycard1 := accounts.GetProfileKeycardForTest()
kp2 := accounts.GetSeedImportedKeypair1ForTest()
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
bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
@ -760,6 +798,47 @@ func (s *MessengerBackupSuite) TestBackupKeycards() {
syncedKeycards, err := bob2.settings.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards))
s.Require().Equal(4, len(syncedKeycards))
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"
"github.com/status-im/status-go/eth-node/crypto"
"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/tt"
"github.com/status-im/status-go/waku"
@ -73,6 +74,31 @@ func (s *MessengerSyncKeycardChangeSuite) SetupTest() {
err = s.main.EnableInstallation(s.other.installationID)
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() {
@ -94,57 +120,66 @@ func (s *MessengerSyncKeycardChangeSuite) TestAddingNewKeycards() {
dbOnReceiver := s.other.settings
// Add key cards on sender
allKeycardsToSync := getKeycardsForTest()[:2]
for _, kp := range allKeycardsToSync {
added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), kp)
s.Require().NoError(err)
s.Require().Equal(true, added)
}
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
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
_, err := WaitOnMessengerResponse(
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.KeycardActions()) == len(allKeycardsToSync)
return len(r.KeycardActions()) == 2
},
"expected to receive keycard activities",
)
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()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards))
s.Require().Equal(2, len(syncedKeycards))
s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
}
func (s *MessengerSyncKeycardChangeSuite) TestAddingAccountsToKeycard() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add additional accounts to sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.AccountsAddresses = []types.Address{{0x011}, {0x022}, {0x033}, {0x044}}
added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), updatedKeycard)
added, err := s.main.AddKeycardOrAddAccountsIfKeycardIsAdded(context.Background(), keycard2)
s.Require().NoError(err)
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
_, err = WaitOnMessengerResponse(
s.other,
@ -155,35 +190,44 @@ func (s *MessengerSyncKeycardChangeSuite) TestAddingAccountsToKeycard() {
)
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()
s.Require().NoError(err)
s.Require().Equal(1, len(syncedKeycards))
s.Require().True(sameKeycards(syncedKeycards[0], updatedKeycard))
s.Require().Equal(2, len(syncedKeycards))
s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
}
func (s *MessengerSyncKeycardChangeSuite) TestRemovingAccountsFromKeycard() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Remove accounts from sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.AccountsAddresses = updatedKeycard.AccountsAddresses[2:]
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.AccountsAddresses = updatedKeycard1.AccountsAddresses[2:]
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID,
keycardToSync.AccountsAddresses[:2], keycardToSync.LastUpdateClock)
// Remove accounts from sender
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycard1.KeycardUID,
keycard1.AccountsAddresses[:2], updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -196,32 +240,38 @@ func (s *MessengerSyncKeycardChangeSuite) TestRemovingAccountsFromKeycard() {
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Remove all accounts from sender
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID,
keycardToSync.AccountsAddresses, keycardToSync.LastUpdateClock)
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycard1.KeycardUID,
keycard1.AccountsAddresses, keycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -234,6 +284,10 @@ func (s *MessengerSyncKeycardChangeSuite) TestRemovingAllAccountsFromKeycard() {
)
s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(0, len(senderKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(0, len(syncedKeycards))
@ -243,21 +297,22 @@ func (s *MessengerSyncKeycardChangeSuite) TestDeleteKeycard() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// 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)
// Wait for the response
@ -270,6 +325,10 @@ func (s *MessengerSyncKeycardChangeSuite) TestDeleteKeycard() {
)
s.Require().NoError(err)
senderKeycards, err := senderDb.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(0, len(senderKeycards))
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(0, len(syncedKeycards))
@ -279,26 +338,27 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardName() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set new keycard name to sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardName = "New Keycard Name"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardName = "New Keycard Name"
err = s.main.SetKeycardName(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.KeycardName,
updatedKeycard.LastUpdateClock)
// Set new keycard name to sender
err = s.main.SetKeycardName(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.KeycardName,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -311,36 +371,43 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardName() {
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set new keycard name to sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardName = "New Keycard Name"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardName = "New Keycard Name"
updatedKeycard1.LastUpdateClock = updatedKeycard1.LastUpdateClock - 1
err = s.main.SetKeycardName(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.KeycardName,
updatedKeycard.LastUpdateClock)
// Set new keycard name to sender
err = s.main.SetKeycardName(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.KeycardName,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -353,35 +420,40 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardNameWithOlderClock()
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set keycard locked on sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardLocked = true
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardLocked = true
err = s.main.KeycardLocked(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.LastUpdateClock)
err = s.main.KeycardLocked(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -394,35 +466,41 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLocked() {
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set keycard locked on sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardLocked = true
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardLocked = true
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)
// Wait for the response
@ -435,36 +513,41 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardLockedOlderClock() {
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard1.KeycardLocked = true
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
keycardToSync.KeycardLocked = true
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardLocked = false
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardLocked = false
err = s.main.KeycardUnlocked(context.Background(), updatedKeycard.KeycardUID, updatedKeycard.LastUpdateClock)
err = s.main.KeycardUnlocked(context.Background(), updatedKeycard1.KeycardUID, updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -477,36 +560,42 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlocked() {
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard1.KeycardLocked = true
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
keycardToSync.KeycardLocked = true
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardLocked = false
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardLocked = false
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)
// Wait for the response
@ -519,36 +608,42 @@ func (s *MessengerSyncKeycardChangeSuite) TestSettingKeycardUnlockedOlderClock()
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardUID = "00000000000000000000000000000000"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock + 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardUID = "00000000000000000000000000000000"
err = s.main.UpdateKeycardUID(context.Background(), keycardToSync.KeycardUID, updatedKeycard.KeycardUID,
updatedKeycard.LastUpdateClock)
// Update keycard uid on sender
err = s.main.UpdateKeycardUID(context.Background(), keycard1.KeycardUID, updatedKeycard1.KeycardUID,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -561,36 +656,43 @@ func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUid() {
)
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()
s.Require().NoError(err)
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycard on sender
keycardToSync := getKeycardsForTest()[:1][0]
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add the same keycard on receiver
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycardToSync)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Set keycard unlocked on sender
updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.KeycardUID = "00000000000000000000000000000000"
updatedKeycard.LastUpdateClock = updatedKeycard.LastUpdateClock - 1
// Prepare expected keycard for comparison
updatedKeycard1 := accounts.GetProfileKeycardForTest()
updatedKeycard1.KeycardUID = "00000000000000000000000000000000"
updatedKeycard1.LastUpdateClock = updatedKeycard1.LastUpdateClock - 1
err = s.main.UpdateKeycardUID(context.Background(), keycardToSync.KeycardUID, updatedKeycard.KeycardUID,
updatedKeycard.LastUpdateClock)
// Update keycard uid on sender
err = s.main.UpdateKeycardUID(context.Background(), keycard1.KeycardUID, updatedKeycard1.KeycardUID,
updatedKeycard1.LastUpdateClock)
s.Require().NoError(err)
// Wait for the response
@ -603,8 +705,13 @@ func (s *MessengerSyncKeycardChangeSuite) TestUpdatingKeycardUidOldClock() {
)
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()
s.Require().NoError(err)
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"
"github.com/status-im/status-go/eth-node/crypto"
"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/tt"
"github.com/status-im/status-go/waku"
@ -74,6 +74,31 @@ func (s *MessengerSyncKeycardsStateSuite) SetupTest() {
err = s.main.EnableInstallation(s.other.installationID)
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() {
@ -91,92 +116,48 @@ func (s *MessengerSyncKeycardsStateSuite) newMessenger(shh types.Waku) *Messenge
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() {
senderDb := s.main.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
allKeycardsToSync := getKeycardsForTest()
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
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)
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
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)
// Wait for the response
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) == len(allKeycardsToSync)
return len(r.Keypairs) == 3 && len(r.Keycards) == 4
},
"expected to receive keycards",
)
@ -184,47 +165,59 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNoKeycard
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards))
s.Require().Equal(4, len(syncedKeycards))
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() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard1 := accounts.GetProfileKeycardForTest()
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
// Add keycards on sender
allKeycardsToSync := getKeycardsForTest()
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
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
keycardsOnReceiver := getKeycardsForTest()[:2]
keycardsOnReceiver[0].KeycardName = "CardNameToBeChanged-0"
keycardsOnReceiver[0].AccountsAddresses = keycardsOnReceiver[0].AccountsAddresses[2:3]
keycardsOnReceiver[0].LastUpdateClock = keycardsOnReceiver[0].LastUpdateClock - 1
keycardsOnReceiver[1].KeycardName = "CardNameToBeChanged-1"
keycardsOnReceiver[1].LastUpdateClock = keycardsOnReceiver[1].LastUpdateClock - 1
// Add keycards on receiver - partially
keycardR1 := accounts.GetProfileKeycardForTest()
keycardR1.KeycardName = "CardNameToBeChanged-0"
keycardR1.AccountsAddresses = keycardR1.AccountsAddresses[2:3]
keycardR1.LastUpdateClock = keycardR1.LastUpdateClock - 1
for _, kp := range keycardsOnReceiver {
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
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)
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)
return len(r.Keypairs) == 3 && len(r.Keycards) == 2
},
"expected to receive keycards",
)
@ -232,8 +225,67 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasKeycardsO
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards))
s.Require().Equal(2, len(syncedKeycards))
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() {
@ -241,79 +293,54 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfKeycardsWereDeletedO
dbOnReceiver := s.other.settings
// Add keycards on sender
allKeycardsToSync := getKeycardsForTest()[:2]
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycards on receiver
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)
}
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
// Trigger's a sync between devices
err := s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
s.Require().NoError(err)
keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
// 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(syncedKeycards))
s.Require().True(haveSameElements(syncedKeycards, allKeycardsToSync, sameKeycards))
}
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeycardsThanTheSameAreDeletedOnSenderSide() {
senderDb := s.main.settings
dbOnReceiver := s.other.settings
keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest()
// Add keycards on sender
allKeycardsToSync := getKeycardsForTest()[:2]
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
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
keycardsOnReceiver := getKeycardsForTest()
clock, _ := s.other.getLastClockWithRelatedChat()
keycardsOnReceiver[2].KeycardName = "NewerCardName-2"
keycardsOnReceiver[2].LastUpdateClock = clock + 1000
keycardsOnReceiver[3].KeycardName = "NewerCardName-3"
keycardsOnReceiver[3].LastUpdateClock = clock + 1000
for _, kp := range keycardsOnReceiver {
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
s.Require().NoError(err)
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
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)
// Wait for the response
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) >= len(allKeycardsToSync)
return len(r.Keypairs) == 3 && len(r.Keycards) == 2
},
"expected to receive keycards",
)
@ -321,13 +348,9 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeyc
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(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))
}
s.Require().Equal(2, len(syncedKeycards))
s.Require().True(contains(syncedKeycards, keycard1, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
}
func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverAndSenderHasNoKeycardsInCommon() {
@ -335,91 +358,46 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverAndSenderHas
dbOnReceiver := s.other.settings
// Add keycards on sender
allKeycardsToSync := getKeycardsForTest()[:2]
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
keycard1 := accounts.GetProfileKeycardForTest()
// Add keycards on receiver
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
keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest()
for _, kp := range keycardsOnReceiver {
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest()
keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C"
keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy"
keycard2Copy.LastUpdateClock = keycard2Copy.LastUpdateClock + 1
// 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.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
keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest()
// Add keycards on sender
allKeycardsToSync := getKeycardsForTest()
for _, kp := range allKeycardsToSync {
addedKc, addedAccs, err := senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
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)
addedKc, addedAccs, err = senderDb.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard2Copy)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
// Add keycards on receiver
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 {
addedKc, addedAccs, err := dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*kp)
s.Require().NoError(err)
s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs)
}
addedKc, addedAccs, err = dbOnReceiver.AddKeycardOrAddAccountsIfKeycardIsAdded(*keycard1)
s.Require().NoError(err)
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
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)
// Wait for the response
_, err = WaitOnMessengerResponse(
s.other,
func(r *MessengerResponse) bool {
return len(r.AllKnownKeycards()) == len(allKeycardsToSync)
return len(r.Keypairs) == 3 && len(r.Keycards) == 2
},
"expected to receive keycards",
)
@ -427,11 +405,7 @@ func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNewerKeyc
syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards()
s.Require().NoError(err)
s.Require().Equal(len(allKeycardsToSync), len(syncedKeycards))
for _, kc := range allKeycardsToSync[:2] {
s.Require().True(contains(syncedKeycards, kc, sameKeycards))
}
for _, kc := range keycardsOnReceiver {
s.Require().True(contains(syncedKeycards, kc, sameKeycards))
}
s.Require().Equal(2, len(syncedKeycards))
s.Require().True(contains(syncedKeycards, keycard2, accounts.SameKeycards))
s.Require().True(contains(syncedKeycards, keycard2Copy, accounts.SameKeycards))
}

View File

@ -65,145 +65,31 @@ func (s *MessengerSyncWalletSuite) newMessenger(shh types.Waku) *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() {
mainAccount := &accounts.Account{
Address: types.Address{0x01},
Wallet: false,
Chat: true,
}
profileKp := accounts.GetProfileKeypairForTest(false)
// 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
acc1, err := s.m.settings.GetAccounts()
s.Require().NoError(err, "alice.settings.GetAccounts")
s.Len(acc1, 1, "Must have 1 main account")
// 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)
dbProfileKp1, err := s.m.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(profileKp, dbProfileKp1))
// Create new device and add main account to
alicesOtherDevice, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
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()
s.Require().NoError(err, "alicesOtherDevice.settings.GetAccounts")
s.Len(acc2, 1, "Must have 1 main account")
// 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)
// Check account is present in the db
dbProfileKp2, err := alicesOtherDevice.settings.GetKeypairByKeyUID(profileKpOtherDevice.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairs(profileKpOtherDevice, dbProfileKp2))
// Pair devices
im1 := &multidevice.InstallationMetadata{
@ -235,13 +121,36 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() {
err = s.m.EnableInstallation(alicesOtherDevice.installationID)
s.Require().NoError(err)
// Store wallet accounts on alice's device
walletAccounts := getWalletAccountsForTest()
expectedTotalNumOfAccounts := len(walletAccounts) + 1 // plus one for the Status profile account
s.NoError(s.m.settings.SaveAccounts(walletAccounts))
acc1, err = s.m.settings.GetAccounts()
s.Require().NoError(err, "alice.settings.GetAccounts")
s.Len(acc1, expectedTotalNumOfAccounts, "Must have all wallet accounts plus one for the Status profile account")
// Store seed phrase keypair with accounts on alice's device
seedPhraseKp := accounts.GetSeedImportedKeypair1ForTest()
err = s.m.settings.SaveOrUpdateKeypair(seedPhraseKp)
s.Require().NoError(err, "seed phrase keypair alice.settings.SaveOrUpdateKeypair")
dbSeedPhraseKp1, err := s.m.settings.GetKeypairByKeyUID(seedPhraseKp.KeyUID)
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
err = s.m.SyncDevices(context.Background(), "ens-name", "profile-image", nil)
@ -253,45 +162,43 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() {
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 nil
})
s.Require().NoError(err)
acc2, err = alicesOtherDevice.settings.GetAccounts()
s.Require().NoError(err, "alicesOtherDevice.settings.GetAccounts")
s.Len(acc2, expectedTotalNumOfAccounts, "Must have all wallet accounts plus one for the Status profile account")
dbProfileKp2, err = s.m.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(profileKp, dbProfileKp2, true, "", accounts.AccountFullyOperable))
for _, syncedAcc := range acc2 {
if syncedAcc.Chat {
continue
}
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)
}
dbSeedPhraseKp2, err := alicesOtherDevice.settings.GetKeypairByKeyUID(seedPhraseKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(seedPhraseKp, dbSeedPhraseKp2, true, "", accounts.AccountNonOperable))
// Updates alice's accounts attributes
for _, acc := range walletAccounts {
acc.Name = acc.Name + "New"
acc.Color = "lightblue"
s.Require().NoError(s.m.SaveAccount(acc))
}
dbPrivKeyKp2, err := alicesOtherDevice.settings.GetKeypairByKeyUID(privKeyKp.KeyUID)
s.Require().NoError(err)
s.Require().True(accounts.SameKeypairsWithDifferentSyncedFrom(privKeyKp, dbPrivKeyKp2, true, "", accounts.AccountNonOperable))
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
// via watch account changes subscription
@ -302,36 +209,46 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() {
return err
}
if len(response.Accounts) != 1 {
if len(response.Keypairs) != 1 {
return errors.New("no sync wallet account received")
}
return nil
})
s.Require().NoError(err)
acc2, err = alicesOtherDevice.settings.GetAccounts()
s.Require().NoError(err, "alicesOtherDevice.settings.GetAccounts")
s.Len(acc2, expectedTotalNumOfAccounts, "Must have all wallet accounts plus one for the Status profile account")
// check on alice's other device
dbProfileKp2, err = alicesOtherDevice.settings.GetKeypairByKeyUID(profileKp.KeyUID)
s.Require().NoError(err)
s.Require().Equal(profileKpUpdated.Name, dbProfileKp2.Name)
for _, syncedAcc := range acc2 {
if syncedAcc.Chat {
continue
// Update accounts on alice's primary device
profileKpUpdated = accounts.GetProfileKeypairForTest(false)
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 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
}
if len(response.Accounts) != len(accountsToUpdate) {
return errors.New("no sync wallet account received")
}
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))
}
}