Skip to content
Snippets Groups Projects
Commit 9e8ae93a authored by Richard T. Carback III's avatar Richard T. Carback III
Browse files

Modify send code to use a debug tag that includes a msgDigest. This is set by...

Modify send code to use a debug tag that includes a msgDigest. This is set by higher level sending functions for debugging purposes
parent 8827efe0
No related branches found
No related tags found
3 merge requests!510Release,!427Modify send code to use a debug tag that includes a msgDigest. This is set by...,!340Project/channels
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
package channels package channels
import ( import (
"math"
"time"
"gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix"
"gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/client/cmix/rounds"
cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
...@@ -15,8 +18,6 @@ import ( ...@@ -15,8 +18,6 @@ import (
"gitlab.com/elixxir/crypto/rsa" "gitlab.com/elixxir/crypto/rsa"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/id/ephemeral" "gitlab.com/xx_network/primitives/id/ephemeral"
"math"
"time"
) )
// ValidForever is used as a validUntil lease when sending to denote the // ValidForever is used as a validUntil lease when sending to denote the
...@@ -54,7 +55,8 @@ type Manager interface { ...@@ -54,7 +55,8 @@ type Manager interface {
// it will always be possible to send a payload of 802 bytes at minimum // it will always be possible to send a payload of 802 bytes at minimum
// Them meaning of validUntil depends on the use case. // Them meaning of validUntil depends on the use case.
SendGeneric(channelID *id.ID, messageType MessageType, SendGeneric(channelID *id.ID, messageType MessageType,
msg []byte, validUntil time.Duration, params cmix.CMIXParams) ( msg []byte, validUntil time.Duration, msgDigest string,
params cmix.CMIXParams) (
cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error)
// SendAdminGeneric is used to send a raw message over a channel encrypted // SendAdminGeneric is used to send a raw message over a channel encrypted
...@@ -64,8 +66,8 @@ type Manager interface { ...@@ -64,8 +66,8 @@ type Manager interface {
// return an error. The message must be at most 510 bytes long. // return an error. The message must be at most 510 bytes long.
SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID,
messageType MessageType, msg []byte, validUntil time.Duration, messageType MessageType, msg []byte, validUntil time.Duration,
params cmix.CMIXParams) (cryptoChannel.MessageID, rounds.Round, msgDigest string, params cmix.CMIXParams) (cryptoChannel.MessageID,
ephemeral.Id, error) rounds.Round, ephemeral.Id, error)
// SendMessage is used to send a formatted message over a channel. // SendMessage is used to send a formatted message over a channel.
// Due to the underlying encoding using compression, it isn't // Due to the underlying encoding using compression, it isn't
......
...@@ -9,7 +9,10 @@ package channels ...@@ -9,7 +9,10 @@ package channels
import ( import (
"crypto/ed25519" "crypto/ed25519"
"encoding/base64"
"fmt" "fmt"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix"
...@@ -21,7 +24,6 @@ import ( ...@@ -21,7 +24,6 @@ import (
"gitlab.com/xx_network/primitives/netTime" "gitlab.com/xx_network/primitives/netTime"
"golang.org/x/crypto/blake2b" "golang.org/x/crypto/blake2b"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"time"
) )
const ( const (
...@@ -39,21 +41,25 @@ const messageNonceSize = 4 ...@@ -39,21 +41,25 @@ const messageNonceSize = 4
// possible to define the largest payload that can be sent, but // possible to define the largest payload that can be sent, but
// it will always be possible to send a payload of 802 bytes at minimum // it will always be possible to send a payload of 802 bytes at minimum
func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType,
msg []byte, validUntil time.Duration, params cmix.CMIXParams) ( msg []byte, validUntil time.Duration, msgDigest string,
params cmix.CMIXParams) (
cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) { cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) {
sendPrint := fmt.Sprintf("Sending to ch %s type %d at %s - "+ // Note: We log sends on exit, and append what happened to the message
"contentsHash %d", channelID, messageType, netTime.Now(), hashMsg(msg)) // this cuts down on clutter in the log.
sendPrint := fmt.Sprintf("[ChanSend] Sending %s ch %s type %d at %s - "+
"contentsHash %d", msgDigest, channelID, messageType,
netTime.Now(), hashMsg(msg))
defer jww.INFO.Println(sendPrint) defer jww.INFO.Println(sendPrint)
//find the channel //find the channel
ch, err := m.getChannel(channelID) ch, err := m.getChannel(channelID)
if err != nil { if err != nil {
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{},
ephemeral.Id{}, err
} }
nickname, _ := m.nicknameManager.GetNickname(channelID) nickname, _ := m.GetNickname(channelID)
var msgId cryptoChannel.MessageID var msgId cryptoChannel.MessageID
...@@ -66,18 +72,25 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, ...@@ -66,18 +72,25 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType,
LocalTimestamp: netTime.Now().UnixNano(), LocalTimestamp: netTime.Now().UnixNano(),
} }
// Generate random nonce to be used for message ID generation. This makes it // Generate random nonce to be used for message ID
// so two identical messages sent on the same round have different message IDs // generation. This makes it so two identical messages sent on
// the same round have different message IDs
rng := m.rng.GetStream() rng := m.rng.GetStream()
n, err := rng.Read(chMsg.Nonce) n, err := rng.Read(chMsg.Nonce)
rng.Close() rng.Close()
if err != nil { if err != nil {
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, sendPrint += fmt.Sprintf(", failed to generate nonce: %+v", err)
return cryptoChannel.MessageID{}, rounds.Round{},
ephemeral.Id{},
errors.Errorf("Failed to generate nonce: %+v", err) errors.Errorf("Failed to generate nonce: %+v", err)
} else if n != messageNonceSize { } else if n != messageNonceSize {
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, sendPrint += fmt.Sprintf(", got %d bytes for %d-byte nonce", n,
messageNonceSize)
return cryptoChannel.MessageID{}, rounds.Round{},
ephemeral.Id{},
errors.Errorf( errors.Errorf(
"Generated %d bytes for %-byte nonce", n, messageNonceSize) "Generated %d bytes for %d-byte nonce", n,
messageNonceSize)
} }
usrMsg := &UserMessage{ usrMsg := &UserMessage{
...@@ -117,35 +130,39 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, ...@@ -117,35 +130,39 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType,
return usrMsgSerial, nil return usrMsgSerial, nil
} }
sendPrint += fmt.Sprintf("\n\tDenoting pending send at %s", netTime.Now()) sendPrint += fmt.Sprintf(", pending send %s", netTime.Now())
uuid, err := m.st.denotePendingSend(channelID, &userMessageInternal{ uuid, err := m.st.denotePendingSend(channelID, &userMessageInternal{
userMessage: usrMsg, userMessage: usrMsg,
channelMessage: chMsg, channelMessage: chMsg,
messageID: msgId, messageID: msgId,
}) })
if err != nil { if err != nil {
sendPrint += fmt.Sprintf("\n\tDenoting pending send failed: %s", sendPrint += fmt.Sprintf(", pending send failed %s",
err.Error()) err.Error())
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{},
ephemeral.Id{}, err
} }
sendPrint += fmt.Sprintf("\n\tBroadcasting message at %s", netTime.Now())
sendPrint += fmt.Sprintf(", broadcasting message %s", netTime.Now())
params.DebugTag = fmt.Sprintf("%s-ChanSend-%s", params.DebugTag,
msgDigest)
r, ephid, err := ch.broadcast.BroadcastWithAssembler(assemble, params) r, ephid, err := ch.broadcast.BroadcastWithAssembler(assemble, params)
if err != nil { if err != nil {
sendPrint += fmt.Sprintf("\n\tBroadcasting failed at %s, denoting "+ sendPrint += fmt.Sprintf(", broadcast failed %s, %s",
"failure: %s", netTime.Now(), err.Error()) netTime.Now(), err.Error())
errDenote := m.st.failedSend(uuid) errDenote := m.st.failedSend(uuid)
if errDenote != nil { if errDenote != nil {
sendPrint += fmt.Sprintf("\n\tFailed to denote failure of "+ sendPrint += fmt.Sprintf(", failed to denote failed "+
"broadcast: %s", err.Error()) "broadcast: %s", err.Error())
} }
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{},
ephemeral.Id{}, err
} }
sendPrint += fmt.Sprintf("\n\tBroadcast succeeded at %s, denoting "+ sendPrint += fmt.Sprintf(", broadcast succeeded %s, success!",
"send success", netTime.Now()) netTime.Now())
err = m.st.send(uuid, msgId, r) err = m.st.send(uuid, msgId, r)
if err != nil { if err != nil {
sendPrint += fmt.Sprintf("\n\tDenotation of send success failed: "+ sendPrint += fmt.Sprintf(", broadcast failed: %s ", err.Error())
"%s", err.Error())
} }
return msgId, r, ephid, err return msgId, r, ephid, err
} }
...@@ -157,8 +174,8 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, ...@@ -157,8 +174,8 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType,
// return an error. The message must be at most 510 bytes long. // return an error. The message must be at most 510 bytes long.
func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID,
messageType MessageType, msg []byte, validUntil time.Duration, messageType MessageType, msg []byte, validUntil time.Duration,
params cmix.CMIXParams) (cryptoChannel.MessageID, rounds.Round, ephemeral.Id, msgDigest string, params cmix.CMIXParams) (cryptoChannel.MessageID,
error) { rounds.Round, ephemeral.Id, error) {
//find the channel //find the channel
ch, err := m.getChannel(channelID) ch, err := m.getChannel(channelID)
...@@ -219,6 +236,8 @@ func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, ...@@ -219,6 +236,8 @@ func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID,
if err != nil { if err != nil {
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err
} }
params.DebugTag = fmt.Sprintf("%s-ChanSendAdmin-%s", params.DebugTag,
msgDigest)
r, ephid, err := ch.broadcast.BroadcastRSAToPublicWithAssembler(privKey, r, ephid, err := ch.broadcast.BroadcastRSAToPublicWithAssembler(privKey,
assemble, params) assemble, params)
...@@ -245,6 +264,9 @@ func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, ...@@ -245,6 +264,9 @@ func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID,
func (m *manager) SendMessage(channelID *id.ID, msg string, func (m *manager) SendMessage(channelID *id.ID, msg string,
validUntil time.Duration, params cmix.CMIXParams) ( validUntil time.Duration, params cmix.CMIXParams) (
cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) { cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) {
msgDigest := MakeChanMsgDigest(channelID, Text, []byte(msg))
jww.INFO.Printf("SendMessage(%s)", msgDigest)
txt := &CMIXChannelText{ txt := &CMIXChannelText{
Version: cmixChannelTextVersion, Version: cmixChannelTextVersion,
Text: msg, Text: msg,
...@@ -256,7 +278,8 @@ func (m *manager) SendMessage(channelID *id.ID, msg string, ...@@ -256,7 +278,8 @@ func (m *manager) SendMessage(channelID *id.ID, msg string,
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err
} }
return m.SendGeneric(channelID, Text, txtMarshaled, validUntil, params) return m.SendGeneric(channelID, Text, txtMarshaled, validUntil,
msgDigest, params)
} }
// SendReply is used to send a formatted message over a channel. // SendReply is used to send a formatted message over a channel.
...@@ -269,6 +292,8 @@ func (m *manager) SendReply(channelID *id.ID, msg string, ...@@ -269,6 +292,8 @@ func (m *manager) SendReply(channelID *id.ID, msg string,
replyTo cryptoChannel.MessageID, validUntil time.Duration, replyTo cryptoChannel.MessageID, validUntil time.Duration,
params cmix.CMIXParams) (cryptoChannel.MessageID, rounds.Round, params cmix.CMIXParams) (cryptoChannel.MessageID, rounds.Round,
ephemeral.Id, error) { ephemeral.Id, error) {
msgDigest := MakeChanMsgDigest(channelID, Text, []byte(msg))
jww.INFO.Printf("SendReply(%s to %s)", msgDigest, replyTo)
txt := &CMIXChannelText{ txt := &CMIXChannelText{
Version: cmixChannelTextVersion, Version: cmixChannelTextVersion,
Text: msg, Text: msg,
...@@ -280,7 +305,8 @@ func (m *manager) SendReply(channelID *id.ID, msg string, ...@@ -280,7 +305,8 @@ func (m *manager) SendReply(channelID *id.ID, msg string,
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err
} }
return m.SendGeneric(channelID, Text, txtMarshaled, validUntil, params) return m.SendGeneric(channelID, Text, txtMarshaled, validUntil,
msgDigest, params)
} }
// SendReaction is used to send a reaction to a message over a channel. // SendReaction is used to send a reaction to a message over a channel.
...@@ -290,6 +316,8 @@ func (m *manager) SendReply(channelID *id.ID, msg string, ...@@ -290,6 +316,8 @@ func (m *manager) SendReply(channelID *id.ID, msg string,
func (m *manager) SendReaction(channelID *id.ID, reaction string, func (m *manager) SendReaction(channelID *id.ID, reaction string,
reactTo cryptoChannel.MessageID, params cmix.CMIXParams) ( reactTo cryptoChannel.MessageID, params cmix.CMIXParams) (
cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) { cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) {
msgDigest := MakeChanMsgDigest(channelID, Reaction, []byte(reaction))
jww.INFO.Printf("SendReaction(%s, to %s)", msgDigest, reactTo)
if err := ValidateReaction(reaction); err != nil { if err := ValidateReaction(reaction); err != nil {
return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err
...@@ -307,7 +335,7 @@ func (m *manager) SendReaction(channelID *id.ID, reaction string, ...@@ -307,7 +335,7 @@ func (m *manager) SendReaction(channelID *id.ID, reaction string,
} }
return m.SendGeneric(channelID, Reaction, reactMarshaled, ValidForever, return m.SendGeneric(channelID, Reaction, reactMarshaled, ValidForever,
params) msgDigest, params)
} }
func hashMsg(msg []byte) []byte { func hashMsg(msg []byte) []byte {
...@@ -315,3 +343,14 @@ func hashMsg(msg []byte) []byte { ...@@ -315,3 +343,14 @@ func hashMsg(msg []byte) []byte {
h.Write(msg) h.Write(msg)
return h.Sum(nil) return h.Sum(nil)
} }
// makeMsgdDigest is a debug helper that creates non-unique msg identifier
// This is set as the debug tag on messages and enables some level
// of tracing a message (if it's contents/chan/type are unique)
func MakeChanMsgDigest(channelID *id.ID, messageType MessageType,
msg []byte) string {
data := fmt.Sprintf("ChanSend_%s-%s-%s", channelID, messageType, msg)
h, _ := blake2b.New256(nil)
h.Write([]byte(data))
return base64.RawStdEncoding.EncodeToString(h.Sum(nil))
}
...@@ -10,6 +10,11 @@ package channels ...@@ -10,6 +10,11 @@ package channels
import ( import (
"bytes" "bytes"
"crypto/ed25519" "crypto/ed25519"
"math/rand"
"sync"
"testing"
"time"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/client/cmix/rounds"
...@@ -20,10 +25,6 @@ import ( ...@@ -20,10 +25,6 @@ import (
"gitlab.com/elixxir/ekv" "gitlab.com/elixxir/ekv"
"gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/netTime" "gitlab.com/xx_network/primitives/netTime"
"math/rand"
"sync"
"testing"
"time"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/id/ephemeral" "gitlab.com/xx_network/primitives/id/ephemeral"
...@@ -195,6 +196,7 @@ func TestSendGeneric(t *testing.T) { ...@@ -195,6 +196,7 @@ func TestSendGeneric(t *testing.T) {
messageType, messageType,
msg, msg,
validUntil, validUntil,
"",
*params) *params)
if err != nil { if err != nil {
t.Logf("ERROR %v", err) t.Logf("ERROR %v", err)
...@@ -285,7 +287,8 @@ func TestAdminGeneric(t *testing.T) { ...@@ -285,7 +287,8 @@ func TestAdminGeneric(t *testing.T) {
} }
messageId, roundId, ephemeralId, err := m.SendAdminGeneric(priv, messageId, roundId, ephemeralId, err := m.SendAdminGeneric(priv,
ch.ReceptionID, messageType, msg, validUntil, cmix.GetDefaultCMIXParams()) ch.ReceptionID, messageType, msg, validUntil, "",
cmix.GetDefaultCMIXParams())
if err != nil { if err != nil {
t.Fatalf("Failed to SendAdminGeneric: %v", err) t.Fatalf("Failed to SendAdminGeneric: %v", err)
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment