github.com/status-im/status-go@v1.1.0/protocol/messenger_peersyncing_test.go (about) 1 package protocol 2 3 import ( 4 "context" 5 "encoding/hex" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/suite" 10 "go.uber.org/zap" 11 12 gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" 13 "github.com/status-im/status-go/eth-node/crypto" 14 "github.com/status-im/status-go/eth-node/types" 15 "github.com/status-im/status-go/protocol/common" 16 "github.com/status-im/status-go/protocol/communities" 17 "github.com/status-im/status-go/protocol/peersyncing" 18 "github.com/status-im/status-go/protocol/protobuf" 19 "github.com/status-im/status-go/protocol/tt" 20 "github.com/status-im/status-go/waku" 21 ) 22 23 func TestMessengerPeersyncingSuite(t *testing.T) { 24 t.Skip("broken test") // FIXME 25 suite.Run(t, new(MessengerPeersyncingSuite)) 26 } 27 28 type MessengerPeersyncingSuite struct { 29 suite.Suite 30 owner *Messenger 31 bob *Messenger 32 alice *Messenger 33 // If one wants to send messages between different instances of Messenger, 34 // a single Waku service should be shared. 35 shh types.Waku 36 logger *zap.Logger 37 accountsTestData map[string][]string 38 accountsPasswords map[string]string 39 } 40 41 func (s *MessengerPeersyncingSuite) SetupTest() { 42 s.logger = tt.MustCreateTestLogger() 43 peerSyncingLoopInterval = 500 * time.Millisecond 44 45 config := waku.DefaultConfig 46 config.MinimumAcceptedPoW = 0 47 shh := waku.New(&config, s.logger) 48 s.shh = gethbridge.NewGethWakuWrapper(shh) 49 s.Require().NoError(shh.Start()) 50 51 s.owner = s.newMessenger() 52 s.bob = s.newMessenger() 53 s.alice = s.newMessenger() 54 55 s.alice.featureFlags.ResendRawMessagesDisabled = true 56 s.bob.featureFlags.ResendRawMessagesDisabled = true 57 s.owner.featureFlags.ResendRawMessagesDisabled = true 58 59 s.owner.communitiesManager.RekeyInterval = 50 * time.Millisecond 60 61 s.accountsTestData = make(map[string][]string) 62 s.accountsTestData[common.PubkeyToHex(&s.bob.identity.PublicKey)] = []string{bobAddress} 63 s.accountsTestData[common.PubkeyToHex(&s.alice.identity.PublicKey)] = []string{aliceAddress1} 64 65 s.accountsPasswords = make(map[string]string) 66 s.accountsPasswords[common.PubkeyToHex(&s.bob.identity.PublicKey)] = bobPassword 67 s.accountsPasswords[common.PubkeyToHex(&s.alice.identity.PublicKey)] = aliceAddress1 68 69 _, err := s.owner.Start() 70 s.Require().NoError(err) 71 _, err = s.bob.Start() 72 s.Require().NoError(err) 73 _, err = s.alice.Start() 74 s.Require().NoError(err) 75 } 76 77 func (s *MessengerPeersyncingSuite) TearDownTest() { 78 TearDownMessenger(&s.Suite, s.owner) 79 TearDownMessenger(&s.Suite, s.bob) 80 TearDownMessenger(&s.Suite, s.alice) 81 _ = s.logger.Sync() 82 } 83 84 func (s *MessengerPeersyncingSuite) newMessenger() *Messenger { 85 return newTestCommunitiesMessenger(&s.Suite, s.shh, testCommunitiesMessengerConfig{ 86 testMessengerConfig: testMessengerConfig{ 87 logger: s.logger, 88 }, 89 }) 90 } 91 92 func (s *MessengerPeersyncingSuite) joinCommunity(community *communities.Community, owner *Messenger, user *Messenger) { 93 addresses, exists := s.accountsTestData[user.IdentityPublicKeyString()] 94 s.Require().True(exists) 95 password, exists := s.accountsPasswords[user.IdentityPublicKeyString()] 96 s.Require().True(exists) 97 joinCommunity(&s.Suite, community.ID(), s.owner, user, password, addresses) 98 } 99 100 func (s *MessengerPeersyncingSuite) thirdPartyTest(community *communities.Community, chat *Chat) { 101 // We disable resending to make sure that the message is not re-transmitted 102 s.alice.featureFlags.Peersyncing = false 103 s.owner.featureFlags.Peersyncing = true 104 s.bob.featureFlags.Peersyncing = true 105 s.owner.communitiesManager.PermissionChecker = &testPermissionChecker{} 106 107 advertiseCommunityTo(&s.Suite, community, s.owner, s.alice) 108 109 s.joinCommunity(community, s.owner, s.alice) 110 111 chatID := chat.ID 112 inputMessage := common.NewMessage() 113 inputMessage.ChatId = chatID 114 inputMessage.ContentType = protobuf.ChatMessage_TEXT_PLAIN 115 inputMessage.Text = "some text" 116 ctx := context.Background() 117 118 if community.Encrypted() { 119 120 _, err := WaitOnMessengerResponse( 121 s.alice, 122 func(r *MessengerResponse) bool { 123 keys, err := s.alice.encryptor.GetKeysForGroup([]byte(chat.ID)) 124 return err == nil && len(keys) > 0 125 }, 126 "keys not received", 127 ) 128 s.Require().NoError(err) 129 } 130 131 // Send message, it should be received 132 response, err := s.alice.SendChatMessage(ctx, inputMessage) 133 s.Require().NoError(err) 134 s.Require().Len(response.Messages(), 1) 135 messageID := response.Messages()[0].ID 136 137 // Make sure the message makes it to the owner 138 response, err = WaitOnMessengerResponse( 139 s.owner, 140 func(r *MessengerResponse) bool { 141 return len(r.Communities()) > 0 && len(r.Messages()) == 1 && r.Messages()[0].ID == messageID 142 }, 143 "message not received", 144 ) 145 s.Require().NoError(err) 146 s.Require().NotNil(response) 147 148 msg, err := s.owner.peersyncing.AvailableMessages() 149 s.Require().NoError(err) 150 s.Require().Len(msg, 1) 151 152 // Bob joins the community 153 advertiseCommunityTo(&s.Suite, community, s.owner, s.bob) 154 155 s.joinCommunity(community, s.owner, s.bob) 156 157 // Bob should now send an offer 158 _, err = WaitOnMessengerResponse( 159 s.bob, 160 func(r *MessengerResponse) bool { 161 return s.bob.peersyncingOffers[messageID[2:]] != 0 162 }, 163 "offer not sent", 164 ) 165 s.Require().NoError(err) 166 167 // Owner should now reply to the offer 168 _, err = WaitOnMessengerResponse( 169 s.owner, 170 func(r *MessengerResponse) bool { 171 return s.owner.peersyncingRequests[s.bob.myHexIdentity()+messageID[2:]] != 0 172 }, 173 "request not sent", 174 ) 175 s.Require().NoError(err) 176 177 // Bob should receive the message 178 _, err = WaitOnMessengerResponse( 179 s.bob, 180 func(r *MessengerResponse) bool { 181 return len(r.Messages()) == 1 && r.Messages()[0].ID == messageID 182 }, 183 "message not received", 184 ) 185 s.Require().NoError(err) 186 187 } 188 189 // Owner creates a community 190 // Owner sends a message 191 // Alice joins 192 // Alice receives the message 193 func (s *MessengerPeersyncingSuite) TestSyncWithPeerCommunitySender() { 194 195 s.alice.featureFlags.Peersyncing = true 196 s.owner.featureFlags.Peersyncing = true 197 198 // create community and make alice join it 199 community, chat := createCommunity(&s.Suite, s.owner) 200 201 chatID := chat.ID 202 inputMessage := common.NewMessage() 203 inputMessage.ChatId = chatID 204 inputMessage.ContentType = protobuf.ChatMessage_TEXT_PLAIN 205 inputMessage.Text = "some text" 206 207 // Send message, it should be received 208 response, err := s.owner.SendChatMessage(context.Background(), inputMessage) 209 s.Require().NoError(err) 210 211 messageID := response.Messages()[0].ID 212 213 msg, err := s.owner.peersyncing.AvailableMessages() 214 s.Require().NoError(err) 215 s.Require().Len(msg, 1) 216 217 advertiseCommunityTo(&s.Suite, community, s.owner, s.alice) 218 s.joinCommunity(community, s.owner, s.alice) 219 220 // Alice should now receive the message 221 _, err = WaitOnMessengerResponse( 222 s.alice, 223 func(r *MessengerResponse) bool { 224 _, err := s.owner.RetrieveAll() 225 if err != nil { 226 return false 227 } 228 return len(r.Messages()) == 1 && r.Messages()[0].ID == messageID 229 }, 230 "message not received", 231 ) 232 s.Require().NoError(err) 233 } 234 235 // Owner creates a community 236 // Alice joins 237 // Alice sends a message 238 // Owner receives the message 239 // Bob joins the community 240 // They should retrieve the message from the owner 241 242 func (s *MessengerPeersyncingSuite) TestSyncWithPeerCommunityThirdPartyEncrypted() { 243 community, chat := createEncryptedCommunity(&s.Suite, s.owner) 244 s.thirdPartyTest(community, chat) 245 } 246 247 func (s *MessengerPeersyncingSuite) TestSyncWithPeerCommunityThirdPartyNotEncrypted() { 248 community, chat := createCommunity(&s.Suite, s.owner) 249 s.thirdPartyTest(community, chat) 250 } 251 252 func (s *MessengerPeersyncingSuite) TestCanSyncMessageWith() { 253 community, chat := createCommunity(&s.Suite, s.owner) 254 255 advertiseCommunityTo(&s.Suite, community, s.owner, s.alice) 256 s.joinCommunity(community, s.owner, s.alice) 257 258 syncMessage := peersyncing.SyncMessage{ 259 ID: []byte("test-id"), 260 ChatID: []byte(chat.ID), 261 Type: peersyncing.SyncMessageCommunityType, 262 Payload: []byte("some-payload"), 263 Timestamp: 1, 264 } 265 s.Require().NoError(s.owner.peersyncing.Add(syncMessage)) 266 267 community, err := s.owner.communitiesManager.GetByID(community.ID()) 268 s.Require().NoError(err) 269 270 canSyncWithBob, err := s.owner.canSyncCommunityMessageWith(chat, community, &s.bob.identity.PublicKey) 271 s.Require().NoError(err) 272 s.Require().False(canSyncWithBob) 273 274 canSyncWithAlice, err := s.owner.canSyncCommunityMessageWith(chat, community, &s.alice.identity.PublicKey) 275 s.Require().NoError(err) 276 s.Require().True(canSyncWithAlice) 277 } 278 279 func (s *MessengerPeersyncingSuite) TestSyncOneToOne() { 280 s.alice.featureFlags.Peersyncing = true 281 s.owner.featureFlags.Peersyncing = true 282 283 pkString := hex.EncodeToString(crypto.FromECDSAPub(&s.alice.identity.PublicKey)) 284 chat := CreateOneToOneChat(pkString, &s.alice.identity.PublicKey, s.owner.transport) 285 286 chat.LastClockValue = uint64(100000000000000) 287 err := s.owner.SaveChat(chat) 288 s.NoError(err) 289 _, err = s.alice.Join(chat) 290 s.NoError(err) 291 292 chatID := chat.ID 293 inputMessage := common.NewMessage() 294 inputMessage.ChatId = chatID 295 inputMessage.ContentType = protobuf.ChatMessage_TEXT_PLAIN 296 inputMessage.Text = "some text" 297 298 ctx := context.Background() 299 300 // Send message, it should be received 301 response, err := s.alice.SendChatMessage(ctx, inputMessage) 302 s.Require().NoError(err) 303 s.Require().Len(response.Messages(), 1) 304 messageID := response.Messages()[0].ID 305 306 // Make sure the message makes it to the owner 307 response, err = WaitOnMessengerResponse( 308 s.owner, 309 func(r *MessengerResponse) bool { 310 return len(r.Messages()) == 1 && r.Messages()[0].ID == messageID 311 }, 312 "message not received", 313 ) 314 s.Require().NoError(err) 315 s.Require().NotNil(response) 316 317 msg, err := s.owner.peersyncing.AvailableMessages() 318 s.Require().NoError(err) 319 s.Require().Len(msg, 1) 320 321 // Alice should now send an offer 322 _, err = WaitOnMessengerResponse( 323 s.alice, 324 func(r *MessengerResponse) bool { 325 return s.alice.peersyncingOffers[messageID[2:]] != 0 326 }, 327 "offer not sent", 328 ) 329 s.Require().NoError(err) 330 331 // Owner should now reply to the offer 332 _, err = WaitOnMessengerResponse( 333 s.owner, 334 func(r *MessengerResponse) bool { 335 return s.owner.peersyncingRequests[s.alice.myHexIdentity()+messageID[2:]] != 0 336 }, 337 "request not sent", 338 ) 339 s.Require().NoError(err) 340 } 341 342 func (s *MessengerPeersyncingSuite) TestCanSyncOneToOneMessageWith() { 343 s.alice.featureFlags.Peersyncing = true 344 s.owner.featureFlags.Peersyncing = true 345 346 pkString := hex.EncodeToString(crypto.FromECDSAPub(&s.alice.identity.PublicKey)) 347 chat := CreateOneToOneChat(pkString, &s.alice.identity.PublicKey, s.owner.transport) 348 349 chat.LastClockValue = uint64(100000000000000) 350 err := s.owner.SaveChat(chat) 351 s.NoError(err) 352 _, err = s.alice.Join(chat) 353 s.NoError(err) 354 355 syncMessage := peersyncing.SyncMessage{ 356 ID: []byte("test-id"), 357 ChatID: []byte(chat.ID), 358 Type: peersyncing.SyncMessageOneToOneType, 359 Payload: []byte("some-payload"), 360 Timestamp: chat.LastClockValue, 361 } 362 s.Require().NoError(s.owner.peersyncing.Add(syncMessage)) 363 364 canSyncWithBob, err := s.owner.canSyncOneToOneMessageWith(chat, &s.bob.identity.PublicKey) 365 s.Require().NoError(err) 366 s.Require().False(canSyncWithBob) 367 368 canSyncWithAlice, err := s.owner.canSyncOneToOneMessageWith(chat, &s.alice.identity.PublicKey) 369 s.Require().NoError(err) 370 s.Require().True(canSyncWithAlice) 371 }