From 4591098a7f68fb3864c7e7f7182702aa7cd9a924 Mon Sep 17 00:00:00 2001
From: Benjamin Wenger <ben@elixxir.ioo>
Date: Tue, 21 Dec 2021 10:03:13 -0800
Subject: [PATCH] fixed an issue where multiple notifications will be received
 for a single e2e message. replaced the rekey notification with a generic
 silent

---
 api/authenticatedChannel.go   | 6 +++---
 api/client.go                 | 4 ++--
 api/results.go                | 1 -
 auth/callback.go              | 6 +++---
 auth/confirm.go               | 6 +++---
 bindings/notifications.go     | 2 +-
 interfaces/params/E2E.go      | 2 ++
 interfaces/params/E2E_test.go | 3 +++
 interfaces/preimage/types.go  | 2 +-
 keyExchange/rekey.go          | 2 +-
 keyExchange/trigger.go        | 2 +-
 network/message/sendE2E.go    | 9 ++++++---
 storage/e2e/manager.go        | 8 ++++----
 13 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/api/authenticatedChannel.go b/api/authenticatedChannel.go
index 4b5f15c16..b9f89afa4 100644
--- a/api/authenticatedChannel.go
+++ b/api/authenticatedChannel.go
@@ -119,10 +119,10 @@ func (c *Client) MakePrecannedAuthenticatedChannel(precannedID uint) (contact.Co
 		Source: precan.ID[:],
 	}, me)
 
-	//rekey
+	//slient (rekey)
 	c.storage.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetRekeyPreimage(),
-		Type:   preimage.Rekey,
+		Data:   sessionPartner.GetSilentPreimage(),
+		Type:   preimage.Silent,
 		Source: precan.ID[:],
 	}, me)
 
diff --git a/api/client.go b/api/client.go
index 6ea04f78c..afb902a2d 100644
--- a/api/client.go
+++ b/api/client.go
@@ -632,7 +632,7 @@ func (c *Client) DeleteContact(partnerId *id.ID) error {
 			"they could not be found", partnerId)
 	}
 	e2ePreimage := partner.GetE2EPreimage()
-	rekeyPreimage := partner.GetRekeyPreimage()
+	rekeyPreimage := partner.GetSilentPreimage()
 	fileTransferPreimage := partner.GetFileTransferPreimage()
 
 	//delete the partner
@@ -651,7 +651,7 @@ func (c *Client) DeleteContact(partnerId *id.ID) error {
 
 	if err = c.storage.GetEdge().Remove(edge.Preimage{
 		Data:   rekeyPreimage,
-		Type:   preimage.Rekey,
+		Type:   preimage.Silent,
 		Source: partnerId[:],
 	}, c.storage.GetUser().ReceptionID); err != nil {
 		jww.WARN.Printf("Failed delete the preimage for rekey "+
diff --git a/api/results.go b/api/results.go
index f39873931..20d4871c5 100644
--- a/api/results.go
+++ b/api/results.go
@@ -166,7 +166,6 @@ func (c *Client) getRoundResults(roundList []id.Round, timeout time.Duration,
 					} else {
 						roundsResults[roundId] = Failed
 						allRoundsSucceeded = false
-
 					}
 				}
 			}
diff --git a/auth/callback.go b/auth/callback.go
index 7f10aa06b..d9abe2a60 100644
--- a/auth/callback.go
+++ b/auth/callback.go
@@ -340,10 +340,10 @@ func (m *Manager) doConfirm(sr *auth.SentRequest, grp *cyclic.Group,
 		Source: sr.GetPartner()[:],
 	}, me)
 
-	//rekey
+	//silent (rekey)
 	m.storage.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetRekeyPreimage(),
-		Type:   preimage.Rekey,
+		Data:   sessionPartner.GetSilentPreimage(),
+		Type:   preimage.Silent,
 		Source: sr.GetPartner()[:],
 	}, me)
 
diff --git a/auth/confirm.go b/auth/confirm.go
index 1afe54b9c..d6bc3b543 100644
--- a/auth/confirm.go
+++ b/auth/confirm.go
@@ -131,10 +131,10 @@ func ConfirmRequestAuth(partner contact.Contact, rng io.Reader,
 		Source: partner.ID[:],
 	}, me)
 
-	//rekey
+	//slient (rekey)
 	storage.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetRekeyPreimage(),
-		Type:   preimage.Rekey,
+		Data:   sessionPartner.GetSilentPreimage(),
+		Type:   preimage.Silent,
 		Source: partner.ID[:],
 	}, me)
 
diff --git a/bindings/notifications.go b/bindings/notifications.go
index c7d4b6055..1a736f722 100644
--- a/bindings/notifications.go
+++ b/bindings/notifications.go
@@ -40,7 +40,7 @@ func (nfmr *NotificationForMeReport) Source() []byte {
 // 	"default"	recipient user ID	A message with no association
 //	"request"	sender user ID		A channel request has been received
 //	"confirm"	sender user ID		A channel request has been accepted
-//	"rekey"		sender user ID		keys with a user have been rotated
+//	"silent"	sender user ID		A message which should not be notified on
 //	"e2e"		sender user ID		reception of an E2E message
 //	"group"		group ID			reception of a group chat message
 //  "endFT"     sender user ID		Last message sent confirming end of file transfer
diff --git a/interfaces/params/E2E.go b/interfaces/params/E2E.go
index 3e0aa95f8..a33ae9fc2 100644
--- a/interfaces/params/E2E.go
+++ b/interfaces/params/E2E.go
@@ -16,6 +16,7 @@ import (
 type E2E struct {
 	Type       SendType
 	RetryCount int
+	OnlyNotifyOnLastSend bool
 	CMIX
 }
 
@@ -23,6 +24,7 @@ func GetDefaultE2E() E2E {
 	return E2E{
 		Type:       Standard,
 		CMIX:       GetDefaultCMIX(),
+		OnlyNotifyOnLastSend: true,
 		RetryCount: 10,
 	}
 }
diff --git a/interfaces/params/E2E_test.go b/interfaces/params/E2E_test.go
index 1f4b599bd..1f88dba4c 100644
--- a/interfaces/params/E2E_test.go
+++ b/interfaces/params/E2E_test.go
@@ -13,6 +13,9 @@ func TestGetDefaultE2E(t *testing.T) {
 	if GetDefaultE2E().Type != Standard {
 		t.Errorf("GetDefaultE2E did not return Standard")
 	}
+	if !GetDefaultE2E().OnlyNotifyOnLastSend  {
+		t.Errorf("GetDefaultE2E did not return OnlyNotifyOnLastSend == true")
+	}
 }
 
 func TestSendType_String(t *testing.T) {
diff --git a/interfaces/preimage/types.go b/interfaces/preimage/types.go
index 52842446a..0b87ef34c 100644
--- a/interfaces/preimage/types.go
+++ b/interfaces/preimage/types.go
@@ -4,7 +4,7 @@ const (
 	Default = "default"
 	Request = "request"
 	Confirm = "confirm"
-	Rekey   = "rekey"
+	Silent  = "silent"
 	E2e     = "e2e"
 	Group   = "group"
 	EndFT   = "endFT"
diff --git a/keyExchange/rekey.go b/keyExchange/rekey.go
index f549d7a57..3a49304ec 100644
--- a/keyExchange/rekey.go
+++ b/keyExchange/rekey.go
@@ -62,7 +62,7 @@ func trigger(instance *network.Instance, sendE2E interfaces.SendE2E,
 			"negotiating status: %s", session, session.NegotiationStatus())
 	}
 
-	rekeyPreimage := manager.GetRekeyPreimage()
+	rekeyPreimage := manager.GetSilentPreimage()
 
 	// send the rekey notification to the partner
 	err := negotiate(instance, sendE2E, sess, negotiatingSession, sendTimeout, rekeyPreimage, stop)
diff --git a/keyExchange/trigger.go b/keyExchange/trigger.go
index b4f6eb69c..6ed48b858 100644
--- a/keyExchange/trigger.go
+++ b/keyExchange/trigger.go
@@ -122,7 +122,7 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager,
 
 	//send the message under the key exchange
 	e2eParams := params.GetDefaultE2E()
-	e2eParams.IdentityPreimage = partner.GetRekeyPreimage()
+	e2eParams.IdentityPreimage = partner.GetSilentPreimage()
 
 	// store in critical messages buffer first to ensure it is resent if the
 	// send fails
diff --git a/network/message/sendE2E.go b/network/message/sendE2E.go
index 52d202393..89f72fd5a 100644
--- a/network/message/sendE2E.go
+++ b/network/message/sendE2E.go
@@ -93,9 +93,12 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E,
 		jww.INFO.Printf("E2E sending %d/%d to %s with msgDigest: %s, key fp: %s",
 			i+i, len(partitions), msg.Recipient, msgEnc.Digest(), key.Fingerprint())
 
+		localParam := param
 		//set the preimage to the default e2e one if it is not already set
-		if param.IdentityPreimage == nil {
-			param.IdentityPreimage = partner.GetE2EPreimage()
+		if localParam.OnlyNotifyOnLastSend && i < len(partitions)-1{
+			localParam.IdentityPreimage = partner.GetSilentPreimage()
+		}else if localParam.IdentityPreimage == nil {
+			localParam.IdentityPreimage = partner.GetE2EPreimage()
 		}
 
 		//send the cmix message, each partition in its own thread
@@ -103,7 +106,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E,
 		go func(i int) {
 			var err error
 			roundIds[i], _, err = m.SendCMIX(m.sender, msgEnc, msg.Recipient,
-				param.CMIX, stop)
+				localParam.CMIX, stop)
 			if err != nil {
 				errCh <- err
 			}
diff --git a/storage/e2e/manager.go b/storage/e2e/manager.go
index f7537fb34..6380b8eb9 100644
--- a/storage/e2e/manager.go
+++ b/storage/e2e/manager.go
@@ -261,10 +261,10 @@ func (m *Manager) GetE2EPreimage() []byte {
 	return preimage.Generate(m.GetRelationshipFingerprintBytes(), preimage.E2e)
 }
 
-// GetRekeyPreimage returns a hash of the unique
-// fingerprint for an E2E rekey message.
-func (m *Manager) GetRekeyPreimage() []byte {
-	return preimage.Generate(m.GetRelationshipFingerprintBytes(), preimage.Rekey)
+// GetSilentPreimage returns a hash of the unique
+// fingerprint for silent messages like E2E rekey message.
+func (m *Manager) GetSilentPreimage() []byte {
+	return preimage.Generate(m.GetRelationshipFingerprintBytes(), preimage.Silent)
 }
 
 // GetFileTransferPreimage returns a hash of the unique
-- 
GitLab