diff --git a/indexedDb/implementation.go b/indexedDb/implementation.go index 1d8d804074140da708672192358375f6a3ebe4dd..14c3d851b376f5480d6df9370cadcb404258915c 100644 --- a/indexedDb/implementation.go +++ b/indexedDb/implementation.go @@ -160,11 +160,17 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, // Attempt a lookup on the MessageID if it is non-zero to find an existing // entry for it. This occurs any time a sender receives their own message // from the mixnet. + emptyID := cryptoChannel.MessageID{} + jww.DEBUG.Printf("messageID: %s, blank messageID: %s", + messageID.String(), + emptyID) if !messageID.Equals(cryptoChannel.MessageID{}) { + jww.DEBUG.Printf("non-empty messageID detected") uuid, err := w.msgIDLookup(messageID) - if err != nil { - // message is already in the database, no insert necessary - return uuid + if err == nil && uuid != 0 { + jww.WARN.Printf("found MessageID, will upsert: %d", + uuid) + msgToInsert.ID = uuid } } @@ -234,7 +240,7 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, // receives their own message from the mixnet. if !messageID.Equals(cryptoChannel.MessageID{}) { uuid, err := w.msgIDLookup(messageID) - if err != nil { + if err == nil { // message is already in the database, no insert necessary return uuid } @@ -283,7 +289,7 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID cryptoChannel.Messag newMessage.MessageID = messageID.Bytes() } - if round.ID == 0 { + if round.ID != 0 { newMessage.Round = uint64(round.ID) } @@ -377,7 +383,19 @@ func (w *wasmModel) receiveHelper(newMessage *Message) (uint64, if err != nil { return 0, errors.Errorf("Upserting Message failed: %+v", err) } - res, _ := addReq.Result() + res, err := addReq.Result() + // NOTE: Sometimes the insert fails to return an error but hits + // a duplicate insert, so this fallthrough returns the uuid entry in + // that case. + if res.IsUndefined() { + msgID := cryptoChannel.MessageID{} + copy(msgID[:], newMessage.MessageID) + uuid, errLookup := w.msgIDLookup(msgID) + if uuid != 0 && errLookup == nil { + return uuid, nil + } + return 0, errors.Errorf("uuid lookup failure: %+v", err) + } uuid := uint64(res.Int()) jww.DEBUG.Printf( "Successfully stored message from %s, id %d", diff --git a/indexedDb/implementation_test.go b/indexedDb/implementation_test.go index f47117f7171ce9851b05a5017745c3b4651370c8..e76b2737aef2b3f854d12b7c319f0c8b86e6e375 100644 --- a/indexedDb/implementation_test.go +++ b/indexedDb/implementation_test.go @@ -126,7 +126,7 @@ func TestWasmModel_JoinChannel_LeaveChannel(t *testing.T) { } } -// Test wasmModel.UpdateSentStatus happy path and ensure fields don't change. +// Test UUID gets returned when different messages are added func TestWasmModel_UUIDTest(t *testing.T) { testString := "testHello" eventModel, err := newWASMModel(testString, dummyCallback) @@ -167,3 +167,46 @@ func TestWasmModel_UUIDTest(t *testing.T) { } } } + +// TestWasmModel_DuplicateReceives tests if the same message ID being sent +// always returns the same uuid +func TestWasmModel_DuplicateReceives(t *testing.T) { + testString := "testHello" + eventModel, err := newWASMModel(testString, dummyCallback) + if err != nil { + t.Fatalf("%+v", err) + } + + cid := channel.Identity{ + Codename: "codename123", + PubKey: []byte{8, 6, 7, 5}, + Color: "#FFFFFF", + Extension: "gif", + CodesetVersion: 0, + } + + uuids := make([]uint64, 10) + + msgID := channel.MessageID{} + copy(msgID[:], testString) + for i := 0; i < 10; i++ { + // Store a test message + channelID := id.NewIdFromBytes([]byte(testString), t) + rnd := rounds.Round{ID: id.Round(42)} + uuid := eventModel.ReceiveMessage(channelID, msgID, + "test", testString+fmt.Sprintf("%d", i), cid, time.Now(), + time.Hour, rnd, 0, channels.Sent) + uuids[i] = uuid + } + + _, _ = eventModel.dump(messageStoreName) + + for i := 0; i < 10; i++ { + for j := i + 1; j < 10; j++ { + if uuids[i] != uuids[j] { + t.Fatalf("uuid failed: %d[%d] != %d[%d]", + uuids[i], i, uuids[j], j) + } + } + } +} diff --git a/indexedDb/init.go b/indexedDb/init.go index 9f107ba0cb695e42b41f8d133f261a0703c58ce9..81676053b9998d89e81bc1136b9bdba4b8092360 100644 --- a/indexedDb/init.go +++ b/indexedDb/init.go @@ -102,8 +102,13 @@ func v1Upgrade(db *idb.Database) error { if err != nil { return err } + + messageStoreMessageIndexOpts := idb.IndexOptions{ + Unique: true, + MultiEntry: false, + } _, err = messageStore.CreateIndex(messageStoreMessageIndex, - js.ValueOf(messageStoreMessage), indexOpts) + js.ValueOf(messageStoreMessage), messageStoreMessageIndexOpts) if err != nil { return err }