github.com/status-im/status-go@v1.1.0/protocol/messenger_sync_keycards_state_test.go (about) 1 package protocol 2 3 import ( 4 "context" 5 "crypto/ecdsa" 6 "testing" 7 8 "github.com/stretchr/testify/suite" 9 "go.uber.org/zap" 10 11 gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" 12 "github.com/status-im/status-go/eth-node/crypto" 13 "github.com/status-im/status-go/eth-node/types" 14 "github.com/status-im/status-go/multiaccounts/accounts" 15 "github.com/status-im/status-go/protocol/encryption/multidevice" 16 "github.com/status-im/status-go/protocol/tt" 17 "github.com/status-im/status-go/waku" 18 ) 19 20 func TestMessengerSyncKeycardsStateSuite(t *testing.T) { 21 suite.Run(t, new(MessengerSyncKeycardsStateSuite)) 22 } 23 24 type MessengerSyncKeycardsStateSuite struct { 25 suite.Suite 26 main *Messenger // main instance of Messenger paired with `other` 27 other *Messenger 28 privateKey *ecdsa.PrivateKey // private key for the main instance of Messenger 29 30 // If one wants to send messages between different instances of Messenger, 31 // a single Waku service should be shared. 32 shh types.Waku 33 34 logger *zap.Logger 35 } 36 37 func (s *MessengerSyncKeycardsStateSuite) SetupTest() { 38 s.logger = tt.MustCreateTestLogger() 39 40 config := waku.DefaultConfig 41 config.MinimumAcceptedPoW = 0 42 shh := waku.New(&config, s.logger) 43 s.shh = gethbridge.NewGethWakuWrapper(shh) 44 s.Require().NoError(shh.Start()) 45 46 s.main = s.newMessenger(s.shh) 47 s.privateKey = s.main.identity 48 49 var err error 50 // Create new device and add main account to 51 s.other, err = newMessengerWithKey(s.shh, s.main.identity, s.logger, nil) 52 s.Require().NoError(err) 53 54 // Pair devices (main and other) 55 imOther := &multidevice.InstallationMetadata{ 56 Name: "other-device", 57 DeviceType: "other-device-type", 58 } 59 err = s.other.SetInstallationMetadata(s.other.installationID, imOther) 60 s.Require().NoError(err) 61 response, err := s.other.SendPairInstallation(context.Background(), nil) 62 s.Require().NoError(err) 63 s.Require().NotNil(response) 64 65 // Wait for the message to reach its destination 66 _, err = WaitOnMessengerResponse( 67 s.main, 68 func(r *MessengerResponse) bool { return len(r.Installations()) > 0 }, 69 "installation not received", 70 ) 71 s.Require().NoError(err) 72 73 err = s.main.EnableInstallation(s.other.installationID) 74 s.Require().NoError(err) 75 76 // Pre-condition - both sides have to know about keypairs migrated to a keycards 77 kp1 := accounts.GetProfileKeypairForTest(true, true, true) 78 kp2 := accounts.GetSeedImportedKeypair1ForTest() 79 kp3 := accounts.GetSeedImportedKeypair2ForTest() 80 kp1.Clock = 1 81 kp2.Clock = 1 82 kp3.Clock = 1 83 84 err = s.main.settings.SaveOrUpdateKeypair(kp1) 85 s.Require().NoError(err) 86 err = s.main.settings.SaveOrUpdateKeypair(kp2) 87 s.Require().NoError(err) 88 err = s.main.settings.SaveOrUpdateKeypair(kp3) 89 s.Require().NoError(err) 90 dbKeypairs, err := s.main.settings.GetActiveKeypairs() 91 s.Require().NoError(err) 92 s.Require().Equal(3, len(dbKeypairs)) 93 94 kp1.Clock = 0 95 kp2.Clock = 0 96 kp3.Clock = 0 97 98 err = s.other.settings.SaveOrUpdateKeypair(kp1) 99 s.Require().NoError(err) 100 err = s.other.settings.SaveOrUpdateKeypair(kp2) 101 s.Require().NoError(err) 102 err = s.other.settings.SaveOrUpdateKeypair(kp3) 103 s.Require().NoError(err) 104 dbKeypairs, err = s.other.settings.GetActiveKeypairs() 105 s.Require().NoError(err) 106 s.Require().Equal(3, len(dbKeypairs)) 107 } 108 109 func (s *MessengerSyncKeycardsStateSuite) TearDownTest() { 110 TearDownMessenger(&s.Suite, s.other) 111 TearDownMessenger(&s.Suite, s.main) 112 } 113 114 func (s *MessengerSyncKeycardsStateSuite) newMessenger(shh types.Waku) *Messenger { 115 privateKey, err := crypto.GenerateKey() 116 s.Require().NoError(err) 117 118 messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, nil) 119 s.Require().NoError(err) 120 121 return messenger 122 } 123 124 func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverHasNoKeycards() { 125 senderDb := s.main.settings 126 dbOnReceiver := s.other.settings 127 128 keycard1 := accounts.GetProfileKeycardForTest() 129 130 keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest() 131 132 keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest() 133 keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C" 134 keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy" 135 136 keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest() 137 138 // Add keycards on sender 139 err := senderDb.SaveOrUpdateKeycard(*keycard1, 0, false) 140 s.Require().NoError(err) 141 err = senderDb.SaveOrUpdateKeycard(*keycard2, 0, false) 142 s.Require().NoError(err) 143 err = senderDb.SaveOrUpdateKeycard(*keycard2Copy, 0, false) 144 s.Require().NoError(err) 145 err = senderDb.SaveOrUpdateKeycard(*keycard3, 0, false) 146 s.Require().NoError(err) 147 148 // Trigger's a sync between devices 149 err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) 150 s.Require().NoError(err) 151 152 // Wait for the response 153 _, err = WaitOnMessengerResponse( 154 s.other, 155 func(r *MessengerResponse) bool { 156 success := len(r.Keypairs) == 3 157 for _, kp := range r.Keypairs { 158 if kp.KeyUID == keycard1.KeyUID { 159 success = success && len(kp.Keycards) == 1 160 } else if kp.KeyUID == keycard2.KeyUID { 161 success = success && len(kp.Keycards) == 2 162 } else if kp.KeyUID == keycard3.KeyUID { 163 success = success && len(kp.Keycards) == 1 164 } 165 } 166 return success 167 }, 168 "expected to receive keycards", 169 ) 170 s.Require().NoError(err) 171 172 syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() 173 s.Require().NoError(err) 174 s.Require().Equal(4, len(syncedKeycards)) 175 s.Require().True(accounts.Contains(syncedKeycards, keycard1, accounts.SameKeycards)) 176 s.Require().True(accounts.Contains(syncedKeycards, keycard2, accounts.SameKeycards)) 177 s.Require().True(accounts.Contains(syncedKeycards, keycard2Copy, accounts.SameKeycards)) 178 s.Require().True(accounts.Contains(syncedKeycards, keycard3, accounts.SameKeycards)) 179 } 180 181 func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfKeycardsWereDeletedOnSenderSide() { 182 senderDb := s.main.settings 183 dbOnReceiver := s.other.settings 184 185 // Add keycards on sender 186 keycard1 := accounts.GetProfileKeycardForTest() 187 188 keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest() 189 190 keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest() 191 keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C" 192 keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy" 193 194 keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest() 195 196 // Add keycards on sender 197 err := senderDb.SaveOrUpdateKeycard(*keycard1, 0, false) 198 s.Require().NoError(err) 199 err = senderDb.SaveOrUpdateKeycard(*keycard2, 0, false) 200 s.Require().NoError(err) 201 202 // Add keycards on receiver 203 err = dbOnReceiver.SaveOrUpdateKeycard(*keycard1, 0, false) 204 s.Require().NoError(err) 205 err = dbOnReceiver.SaveOrUpdateKeycard(*keycard2, 0, false) 206 s.Require().NoError(err) 207 err = dbOnReceiver.SaveOrUpdateKeycard(*keycard2Copy, 0, false) 208 s.Require().NoError(err) 209 err = dbOnReceiver.SaveOrUpdateKeycard(*keycard3, 0, false) 210 s.Require().NoError(err) 211 212 // Trigger's a sync between devices 213 err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) 214 s.Require().NoError(err) 215 216 // Wait for the response 217 _, err = WaitOnMessengerResponse( 218 s.other, 219 func(r *MessengerResponse) bool { 220 success := len(r.Keypairs) == 3 221 for _, kp := range r.Keypairs { 222 if kp.KeyUID == keycard1.KeyUID { 223 success = success && len(kp.Keycards) == 1 224 } else if kp.KeyUID == keycard2.KeyUID { 225 success = success && len(kp.Keycards) == 1 226 } 227 } 228 return success 229 }, 230 "expected to receive keycards", 231 ) 232 s.Require().NoError(err) 233 234 syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() 235 s.Require().NoError(err) 236 s.Require().Equal(2, len(syncedKeycards)) 237 s.Require().True(accounts.Contains(syncedKeycards, keycard1, accounts.SameKeycards)) 238 s.Require().True(accounts.Contains(syncedKeycards, keycard2, accounts.SameKeycards)) 239 } 240 241 func (s *MessengerSyncKeycardsStateSuite) TestSyncKeycardsIfReceiverAndSenderHasNoKeycardsInCommon() { 242 senderDb := s.main.settings 243 dbOnReceiver := s.other.settings 244 245 // Add keycards on sender 246 keycard1 := accounts.GetProfileKeycardForTest() 247 248 keycard2 := accounts.GetKeycardForSeedImportedKeypair1ForTest() 249 250 keycard2Copy := accounts.GetKeycardForSeedImportedKeypair1ForTest() 251 keycard2Copy.KeycardUID = keycard2Copy.KeycardUID + "C" 252 keycard2Copy.KeycardName = keycard2Copy.KeycardName + "Copy" 253 254 keycard3 := accounts.GetKeycardForSeedImportedKeypair2ForTest() 255 256 // Add keycards on sender 257 err := senderDb.SaveOrUpdateKeycard(*keycard2, 0, false) 258 s.Require().NoError(err) 259 err = senderDb.SaveOrUpdateKeycard(*keycard2Copy, 0, false) 260 s.Require().NoError(err) 261 262 // Add keycards on receiver 263 err = dbOnReceiver.SaveOrUpdateKeycard(*keycard1, 0, false) 264 s.Require().NoError(err) 265 err = dbOnReceiver.SaveOrUpdateKeycard(*keycard3, 0, false) 266 s.Require().NoError(err) 267 268 // Trigger's a sync between devices 269 err = s.main.SyncDevices(context.Background(), "ens-name", "profile-image", nil) 270 s.Require().NoError(err) 271 272 // Wait for the response 273 _, err = WaitOnMessengerResponse( 274 s.other, 275 func(r *MessengerResponse) bool { 276 success := len(r.Keypairs) == 3 277 for _, kp := range r.Keypairs { 278 if kp.KeyUID == keycard2.KeyUID { 279 success = success && len(kp.Keycards) == 2 280 } 281 } 282 return success 283 }, 284 "expected to receive keycards", 285 ) 286 s.Require().NoError(err) 287 288 syncedKeycards, err := dbOnReceiver.GetAllKnownKeycards() 289 s.Require().NoError(err) 290 s.Require().Equal(2, len(syncedKeycards)) 291 s.Require().True(accounts.Contains(syncedKeycards, keycard2, accounts.SameKeycards)) 292 s.Require().True(accounts.Contains(syncedKeycards, keycard2Copy, accounts.SameKeycards)) 293 }