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  }