From a764af46c249c56eee19e1fe63ef5826cdc8f2ff Mon Sep 17 00:00:00 2001 From: Benjamin Wenger <ben@elixxir.ioo> Date: Thu, 26 Aug 2021 09:47:52 -0700 Subject: [PATCH] made sende2e return the timestamp in the sent message --- api/send.go | 3 ++- api/utilsInterfaces_test.go | 5 +++-- bindings/message.go | 2 +- bindings/send.go | 17 ++++++++++++++++- cmd/root.go | 2 +- groupChat/sendRequests.go | 2 +- groupChat/utils_test.go | 9 +++++---- interfaces/networkManager.go | 5 +++-- keyExchange/rekey.go | 2 +- keyExchange/trigger.go | 2 +- keyExchange/utils_test.go | 9 +++++---- network/ephemeral/testutil.go | 5 +++-- network/message/critical.go | 2 +- network/message/sendE2E.go | 14 +++++++------- network/send.go | 5 +++-- single/manager_test.go | 4 ++-- 16 files changed, 55 insertions(+), 33 deletions(-) diff --git a/api/send.go b/api/send.go index 5ef62966d..28b843542 100644 --- a/api/send.go +++ b/api/send.go @@ -16,6 +16,7 @@ import ( "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" + "time" ) //This holds all functions to send messages over the network @@ -24,7 +25,7 @@ import ( // the provided msgType. Returns the list of rounds in which parts of // the message were sent or an error if it fails. func (c *Client) SendE2E(m message.Send, param params.E2E) ([]id.Round, - e2e.MessageID, error) { + e2e.MessageID, time.Time, error) { jww.INFO.Printf("SendE2E(%s, %d. %v)", m.Recipient, m.MessageType, m.Payload) return c.network.SendE2E(m, param, nil) diff --git a/api/utilsInterfaces_test.go b/api/utilsInterfaces_test.go index ad97286b7..e421ffdc9 100644 --- a/api/utilsInterfaces_test.go +++ b/api/utilsInterfaces_test.go @@ -20,6 +20,7 @@ import ( "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" + "time" ) // Mock comm struct which returns no historical round data @@ -94,9 +95,9 @@ func (t *testNetworkManagerGeneric) CheckGarbledMessages() { return } func (t *testNetworkManagerGeneric) SendE2E(message.Send, params.E2E, *stoppable.Single) ( - []id.Round, cE2e.MessageID, error) { + []id.Round, cE2e.MessageID, time.Time, error) { rounds := []id.Round{id.Round(0), id.Round(1), id.Round(2)} - return rounds, cE2e.MessageID{}, nil + return rounds, cE2e.MessageID{}, time.Time{}, nil } func (t *testNetworkManagerGeneric) SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error) { diff --git a/bindings/message.go b/bindings/message.go index 44526fa2e..680d9caf7 100644 --- a/bindings/message.go +++ b/bindings/message.go @@ -40,7 +40,7 @@ func (m *Message) GetMessageType() int { // GetTimestampMS returns the message's timestamp in milliseconds func (m *Message) GetTimestampMS() int64 { ts := m.r.Timestamp.UnixNano() - ts = (ts + 999999) / 1000000 + ts = (ts + 500000) / 1000000 return ts } diff --git a/bindings/send.go b/bindings/send.go index 586100d05..cef9c9950 100644 --- a/bindings/send.go +++ b/bindings/send.go @@ -15,6 +15,7 @@ import ( "gitlab.com/elixxir/client/interfaces/params" "gitlab.com/elixxir/crypto/e2e" "gitlab.com/xx_network/primitives/id" + "time" ) // SendCMIX sends a "raw" CMIX message payload to the provided @@ -163,7 +164,7 @@ func (c *Client) SendE2E(recipient, payload []byte, messageType int, parameters MessageType: message.Type(messageType), } - rids, mid, err := c.api.SendE2E(m, p) + rids, mid, ts, err := c.api.SendE2E(m, p) if err != nil { return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err)) } @@ -171,6 +172,7 @@ func (c *Client) SendE2E(recipient, payload []byte, messageType int, parameters sr := SendReport{ rl: &RoundList{list: rids}, mid: mid, + ts: ts, } return &sr, nil @@ -180,6 +182,7 @@ func (c *Client) SendE2E(recipient, payload []byte, messageType int, parameters type SendReport struct { rl *RoundList mid e2e.MessageID + ts time.Time } type SendReportDisk struct { @@ -195,6 +198,18 @@ func (sr *SendReport) GetMessageID() []byte { return sr.mid[:] } +// GetTimestampMS returns the message's timestamp in milliseconds +func (sr *SendReport) GetTimestampMS() int64 { + ts := sr.ts.UnixNano() + ts = (ts + 500000) / 1000000 + return ts +} + +// GetTimestampNano returns the message's timestamp in nanoseconds +func (sr *SendReport) GetTimestampNano() int64 { + return sr.ts.UnixNano() +} + func (sr *SendReport) Marshal() ([]byte, error) { srd := SendReportDisk{ List: sr.rl.list, diff --git a/cmd/root.go b/cmd/root.go index 9ebdc637a..41cd73e10 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -198,7 +198,7 @@ var rootCmd = &cobra.Command{ paramsUnsafe) roundTimeout = paramsUnsafe.Timeout } else { - roundIDs, _, err = client.SendE2E(msg, + roundIDs, _, _, err = client.SendE2E(msg, paramsE2E) roundTimeout = paramsE2E.Timeout } diff --git a/groupChat/sendRequests.go b/groupChat/sendRequests.go index 3e4cc39f2..70c5501ec 100644 --- a/groupChat/sendRequests.go +++ b/groupChat/sendRequests.go @@ -110,7 +110,7 @@ func (m Manager) sendRequest(memberID *id.ID, request []byte) ([]id.Round, error MessageType: message.GroupCreationRequest, } - rounds, _, err := m.net.SendE2E(sendMsg, params.GetDefaultE2E(), nil) + rounds, _, _, err := m.net.SendE2E(sendMsg, params.GetDefaultE2E(), nil) if err != nil { return nil, errors.Errorf(sendE2eErr, memberID, err) } diff --git a/groupChat/utils_test.go b/groupChat/utils_test.go index bdf58edfa..4997976c6 100644 --- a/groupChat/utils_test.go +++ b/groupChat/utils_test.go @@ -36,6 +36,7 @@ import ( "math/rand" "sync" "testing" + "time" ) // newTestManager creates a new Manager for testing. @@ -240,20 +241,20 @@ func (tnm *testNetworkManager) GetE2eMsg(i int) message.Send { return tnm.e2eMessages[i] } -func (tnm *testNetworkManager) SendE2E(msg message.Send, _ params.E2E, _ *stoppable.Single) ([]id.Round, e2e.MessageID, error) { +func (tnm *testNetworkManager) SendE2E(msg message.Send, _ params.E2E, _ *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error) { tnm.Lock() defer tnm.Unlock() tnm.errSkip++ if tnm.sendErr == 1 { - return nil, e2e.MessageID{}, errors.New("SendE2E error") + return nil, e2e.MessageID{}, time.Time{}, errors.New("SendE2E error") } else if tnm.sendErr == 2 && tnm.errSkip%2 == 0 { - return nil, e2e.MessageID{}, errors.New("SendE2E error") + return nil, e2e.MessageID{}, time.Time{}, errors.New("SendE2E error") } tnm.e2eMessages = append(tnm.e2eMessages, msg) - return []id.Round{0, 1, 2, 3}, e2e.MessageID{}, nil + return []id.Round{0, 1, 2, 3}, e2e.MessageID{}, time.Time{}, nil } func (tnm *testNetworkManager) SendUnsafe(message.Send, params.Unsafe) ([]id.Round, error) { diff --git a/interfaces/networkManager.go b/interfaces/networkManager.go index c3bc9f49d..3e40b9bae 100644 --- a/interfaces/networkManager.go +++ b/interfaces/networkManager.go @@ -17,11 +17,12 @@ import ( "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" + "time" ) type NetworkManager interface { // The stoppable can be nil. - SendE2E(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, error) + SendE2E(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error) SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error) SendCMIX(message format.Message, recipient *id.ID, p params.CMIX) (id.Round, ephemeral.Id, error) SendManyCMIX(messages map[id.ID]format.Message, p params.CMIX) (id.Round, []ephemeral.Id, error) @@ -50,4 +51,4 @@ type NetworkManager interface { } //for use in key exchange which needs to be callable inside of network -type SendE2E func(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, error) +type SendE2E func(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error) diff --git a/keyExchange/rekey.go b/keyExchange/rekey.go index f4caacd25..5acc9ba71 100644 --- a/keyExchange/rekey.go +++ b/keyExchange/rekey.go @@ -104,7 +104,7 @@ func negotiate(instance *network.Instance, sendE2E interfaces.SendE2E, e2eParams := params.GetDefaultE2E() e2eParams.Type = params.KeyExchange - rounds, _, err := sendE2E(m, e2eParams, stop) + rounds, _, _, err := sendE2E(m, e2eParams, stop) // If the send fails, returns the error so it can be handled. The caller // should ensure the calling session is in a state where the Rekey will // be triggered next time a key is used diff --git a/keyExchange/trigger.go b/keyExchange/trigger.go index c88d068fe..e25da821f 100644 --- a/keyExchange/trigger.go +++ b/keyExchange/trigger.go @@ -127,7 +127,7 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager, // send fails sess.GetCriticalMessages().AddProcessing(m, e2eParams) - rounds, _, err := net.SendE2E(m, e2eParams, stop) + rounds, _, _, err := net.SendE2E(m, e2eParams, stop) if err != nil { return err } diff --git a/keyExchange/utils_test.go b/keyExchange/utils_test.go index cb0518466..d844f16b4 100644 --- a/keyExchange/utils_test.go +++ b/keyExchange/utils_test.go @@ -31,6 +31,7 @@ import ( "gitlab.com/xx_network/primitives/ndf" "gitlab.com/xx_network/primitives/netTime" "testing" + "time" ) // Generate partner ID for two people, used for smoke tests @@ -67,9 +68,9 @@ func (t *testNetworkManagerGeneric) CheckGarbledMessages() { } func (t *testNetworkManagerGeneric) SendE2E(message.Send, params.E2E, *stoppable.Single) ( - []id.Round, cE2e.MessageID, error) { + []id.Round, cE2e.MessageID, time.Time, error) { rounds := []id.Round{id.Round(0), id.Round(1), id.Round(2)} - return rounds, cE2e.MessageID{}, nil + return rounds, cE2e.MessageID{}, time.Time{}, nil } @@ -169,7 +170,7 @@ func (t *testNetworkManagerFullExchange) CheckGarbledMessages() { // Intended for alice to send to bob. Trigger's Bob's confirmation, chaining the operation // together func (t *testNetworkManagerFullExchange) SendE2E(message.Send, params.E2E, *stoppable.Single) ( - []id.Round, cE2e.MessageID, error) { + []id.Round, cE2e.MessageID, time.Time, error) { rounds := []id.Round{id.Round(0), id.Round(1), id.Round(2)} alicePrivKey := aliceSession.E2e().GetDHPrivateKey() @@ -193,7 +194,7 @@ func (t *testNetworkManagerFullExchange) SendE2E(message.Send, params.E2E, *stop bobSwitchboard.Speak(confirmMessage) - return rounds, cE2e.MessageID{}, nil + return rounds, cE2e.MessageID{}, time.Time{}, nil } func (t *testNetworkManagerFullExchange) SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error) { diff --git a/network/ephemeral/testutil.go b/network/ephemeral/testutil.go index 3b443dfe3..c5cbd8b7c 100644 --- a/network/ephemeral/testutil.go +++ b/network/ephemeral/testutil.go @@ -10,6 +10,7 @@ package ephemeral import ( "gitlab.com/elixxir/client/network/gateway" "testing" + "time" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/interfaces" @@ -34,7 +35,7 @@ type testNetworkManager struct { } func (t *testNetworkManager) SendE2E(m message.Send, _ params.E2E, _ *stoppable.Single) ([]id.Round, - e2e.MessageID, error) { + e2e.MessageID, time.Time, error) { rounds := []id.Round{ id.Round(0), id.Round(1), @@ -43,7 +44,7 @@ func (t *testNetworkManager) SendE2E(m message.Send, _ params.E2E, _ *stoppable. t.msg = m - return rounds, e2e.MessageID{}, nil + return rounds, e2e.MessageID{}, time.Time{}, nil } func (t *testNetworkManager) SendUnsafe(m message.Send, _ params.Unsafe) ([]id.Round, error) { diff --git a/network/message/critical.go b/network/message/critical.go index 84b88da60..9c5b6bff7 100644 --- a/network/message/critical.go +++ b/network/message/critical.go @@ -54,7 +54,7 @@ func (m *Manager) criticalMessages(stop *stoppable.Single) { jww.INFO.Printf("Resending critical message to %s ", msg.Recipient) //send the message - rounds, _, err := m.SendE2E(msg, param, stop) + rounds, _, _, err := m.SendE2E(msg, param, stop) //if the message fail to send, notify the buffer so it can be handled //in the future and exit if err != nil { diff --git a/network/message/sendE2E.go b/network/message/sendE2E.go index 7b468ad1a..e26dcb6de 100644 --- a/network/message/sendE2E.go +++ b/network/message/sendE2E.go @@ -23,9 +23,9 @@ import ( ) func (m *Manager) SendE2E(msg message.Send, param params.E2E, - stop *stoppable.Single) ([]id.Round, e2e.MessageID, error) { + stop *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error) { if msg.MessageType == message.Raw { - return nil, e2e.MessageID{}, errors.Errorf("Raw (%d) is a reserved "+ + return nil, e2e.MessageID{}, time.Time{}, errors.Errorf("Raw (%d) is a reserved "+ "message type", msg.MessageType) } //timestamp the message @@ -35,7 +35,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E, partitions, internalMsgId, err := m.partitioner.Partition(msg.Recipient, msg.MessageType, ts, msg.Payload) if err != nil { - return nil, e2e.MessageID{}, errors.WithMessage(err, "failed to send unsafe message") + return nil, e2e.MessageID{}, time.Time{}, errors.WithMessage(err, "failed to send unsafe message") } //encrypt then send the partitions over cmix @@ -45,7 +45,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E, // get the key manager for the partner partner, err := m.Session.E2e().GetPartner(msg.Recipient) if err != nil { - return nil, e2e.MessageID{}, errors.WithMessagef(err, + return nil, e2e.MessageID{}, time.Time{}, errors.WithMessagef(err, "Could not send End to End encrypted "+ "message, no relationship found with %s", msg.Recipient) } @@ -83,7 +83,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E, key, err = partner.GetKeyForSending(param.Type) } if err != nil { - return nil, e2e.MessageID{}, errors.WithMessagef(err, + return nil, e2e.MessageID{}, time.Time{}, errors.WithMessagef(err, "Failed to get key for end to end encryption") } @@ -113,7 +113,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E, if numFail > 0 { jww.INFO.Printf("Failed to E2E send %d/%d to %s", numFail, len(partitions), msg.Recipient) - return nil, e2e.MessageID{}, errors.Errorf("Failed to E2E send %v/%v sub payloads:"+ + return nil, e2e.MessageID{}, time.Time{}, errors.Errorf("Failed to E2E send %v/%v sub payloads:"+ " %s", numFail, len(partitions), errRtn) } else { jww.INFO.Printf("Successfully E2E sent %d/%d to %s", @@ -122,5 +122,5 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E, //return the rounds if everything send successfully msgID := e2e.NewMessageID(partner.GetSendRelationshipFingerprint(), internalMsgId) - return roundIds, msgID, nil + return roundIds, msgID, ts, nil } diff --git a/network/send.go b/network/send.go index d54e478c7..8fff3ac15 100644 --- a/network/send.go +++ b/network/send.go @@ -17,6 +17,7 @@ import ( "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" + "time" ) // SendCMIX sends a "raw" CMIX message payload to the provided @@ -63,10 +64,10 @@ func (m *manager) SendUnsafe(msg message.Send, param params.Unsafe) ([]id.Round, // the provided msgType. Returns the list of rounds in which parts of // the message were sent or an error if it fails. func (m *manager) SendE2E(msg message.Send, e2eP params.E2E, stop *stoppable.Single) ( - []id.Round, e2e.MessageID, error) { + []id.Round, e2e.MessageID, time.Time, error) { if !m.Health.IsHealthy() { - return nil, e2e.MessageID{}, errors.New("Cannot send e2e " + + return nil, e2e.MessageID{}, time.Time{}, errors.New("Cannot send e2e " + "message when the network is not healthy") } diff --git a/single/manager_test.go b/single/manager_test.go index 1a62edf84..a787e7462 100644 --- a/single/manager_test.go +++ b/single/manager_test.go @@ -283,8 +283,8 @@ func (tnm *testNetworkManager) GetMsg(i int) format.Message { return tnm.msgs[i] } -func (tnm *testNetworkManager) SendE2E(message.Send, params.E2E, *stoppable.Single) ([]id.Round, e2e.MessageID, error) { - return nil, e2e.MessageID{}, nil +func (tnm *testNetworkManager) SendE2E(message.Send, params.E2E, *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error) { + return nil, e2e.MessageID{}, time.Time{}, nil } func (tnm *testNetworkManager) SendUnsafe(_ message.Send, _ params.Unsafe) ([]id.Round, error) { -- GitLab