Skip to content
Snippets Groups Projects
Commit e0eb654f authored by Jake Taylor's avatar Jake Taylor
Browse files

restructure group chat package

parent 6849207e
No related branches found
No related tags found
3 merge requests!510Release,!207WIP: Client Restructure,!203Symmetric broadcast
......@@ -47,23 +47,18 @@ func NewGroupManager(client *Client, requestFunc GroupRequestFunc,
}
// Create a new group chat manager
// TODO: Need things from storage, services, etc?
m, err := gc.NewManager(&client.api, requestCallback, receiveCallback)
if err != nil {
return nil, err
}
// Start group request and message retrieval workers
err = client.api.AddService(m.StartProcesses)
if err != nil {
return nil, err
}
return &GroupChat{m}, nil
}
// MakeGroup creates a new group and sends a group request to all members in the
// group. The ID of the new group, the rounds the requests were sent on, and the
// status of the send are contained in NewGroupReport.
// status of the sends are contained in NewGroupReport.
func (g *GroupChat) MakeGroup(membership *IdList, name, message []byte) *NewGroupReport {
grp, rounds, status, err := g.m.MakeGroup(membership.list, name, message)
errStr := ""
......@@ -346,6 +341,7 @@ func (gm *GroupMembership) Get(i int) (*GroupMember, error) {
////
// Member Structure
////
// GroupMember represents a member in the group membership list.
type GroupMember struct {
group.Member
......
......@@ -10,9 +10,7 @@ package groupChat
import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/catalog"
gs "gitlab.com/elixxir/client/groupChat/groupStore"
"gitlab.com/elixxir/client/storage/edge"
"gitlab.com/elixxir/crypto/contact"
"gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/crypto/group"
......@@ -94,12 +92,7 @@ func (m Manager) MakeGroup(membership []*id.ID, name, msg []byte) (gs.Group,
roundIDs, status, err := m.sendRequests(g)
if err == nil {
edgeStore := m.store.GetEdge()
edgeStore.Add(edge.Preimage{
Data: g.ID[:],
Type: catalog.Group,
Source: g.ID[:],
}, m.store.GetUser().ReceptionID)
err = m.JoinGroup(g)
}
return g, roundIDs, status, err
......@@ -119,14 +112,13 @@ func (m Manager) buildMembership(members []*id.ID) (group.Membership,
errors.Errorf(maxMembersErr, len(members), group.MaxParticipants)
}
grp := m.store.E2e().GetGroup()
dkl := make(gs.DhKeyList, len(members))
// Lookup partner contact objects from their ID
contacts := make([]contact.Contact, len(members))
var err error
for i, uid := range members {
partner, err := m.store.E2e().GetPartner(uid)
partner, err := m.e2e.GetPartner(uid, m.receptionId)
if err != nil {
return nil, nil, errors.Errorf(getPartnerErr, uid, err)
}
......@@ -139,7 +131,7 @@ func (m Manager) buildMembership(members []*id.ID) (group.Membership,
dkl.Add(partner.GetMyOriginPrivateKey(), group.Member{
ID: partner.GetPartnerID(),
DhKey: partner.GetPartnerOriginPublicKey(),
}, grp)
}, m.grp)
}
// Create new Membership from contact list and client's own contact.
......
......@@ -10,14 +10,12 @@ package groupChat
import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/api"
"gitlab.com/elixxir/client/catalog"
"gitlab.com/elixxir/client/e2e"
gs "gitlab.com/elixxir/client/groupChat/groupStore"
"gitlab.com/elixxir/client/interfaces"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/stoppable"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/edge"
"gitlab.com/elixxir/client/network"
"gitlab.com/elixxir/client/network/message"
"gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/fastRNG"
......@@ -25,15 +23,6 @@ import (
"gitlab.com/xx_network/primitives/id"
)
const (
rawMessageBuffSize = 100
receiveStoppableName = "GroupChatReceive"
receiveListenerName = "GroupChatReceiveListener"
requestStoppableName = "GroupChatRequest"
requestListenerName = "GroupChatRequestListener"
groupStoppableName = "GroupChat"
)
// Error messages.
const (
newGroupStoreErr = "failed to create new group store: %+v"
......@@ -43,84 +32,68 @@ const (
// Manager handles the list of groups a user is a part of.
type Manager struct {
client *api.Client
store *storage.Session
swb interfaces.Switchboard
e2e e2e.Handler
net interfaces.NetworkManager
receptionId *id.ID
rng *fastRNG.StreamGenerator
grp *cyclic.Group
gs *gs.Store
services network.Manager
requestFunc RequestCallback
receiveFunc ReceiveCallback
}
// NewManager generates a new group chat manager. This functions satisfies the
// GroupChat interface.
func NewManager(client *api.Client, requestFunc RequestCallback,
receiveFunc ReceiveCallback) (*Manager, error) {
return newManager(
client,
client.GetUser().ReceptionID.DeepCopy(),
client.GetStorage().E2e().GetDHPublicKey(),
client.GetStorage(),
client.GetSwitchboard(),
client.GetNetworkInterface(),
client.GetRng(),
client.GetStorage().GetKV(),
requestFunc,
receiveFunc,
)
}
// newManager creates a new group chat manager from api.Client parts for easier
// testing.
func newManager(client *api.Client, userID *id.ID, userDhKey *cyclic.Int,
store *storage.Session, swb interfaces.Switchboard,
net interfaces.NetworkManager, rng *fastRNG.StreamGenerator,
kv *versioned.KV, requestFunc RequestCallback,
receiveFunc ReceiveCallback) (*Manager, error) {
// NewManager creates a new group chat manager
func NewManager(services network.Manager, e2e e2e.Handler, net interfaces.NetworkManager, receptionId *id.ID,
rng *fastRNG.StreamGenerator, grp *cyclic.Group, userDhKey *cyclic.Int,
kv *versioned.KV, requestFunc RequestCallback, receiveFunc ReceiveCallback) (*Manager, error) {
// Load the group chat storage or create one if one does not exist
gStore, err := gs.NewOrLoadStore(
kv, group.Member{ID: userID, DhKey: userDhKey})
kv, group.Member{ID: receptionId, DhKey: userDhKey})
if err != nil {
return nil, errors.Errorf(newGroupStoreErr, err)
}
return &Manager{
client: client,
store: store,
swb: swb,
// Define the manager object
m := &Manager{
e2e: e2e,
net: net,
rng: rng,
receptionId: receptionId,
grp: grp,
gs: gStore,
services: services,
requestFunc: requestFunc,
receiveFunc: receiveFunc,
}, nil
}
// StartProcesses starts the reception worker.
func (m *Manager) StartProcesses() (stoppable.Stoppable, error) {
// Start group reception worker
receiveStop := stoppable.NewSingle(receiveStoppableName)
receiveChan := make(chan message.Receive, rawMessageBuffSize)
m.swb.RegisterChannel(receiveListenerName, &id.ID{},
message.Raw, receiveChan)
go m.receive(receiveChan, receiveStop)
// Register listener for incoming e2e group chat requests
e2e.RegisterListener(&id.ZeroUser, catalog.GroupCreationRequest, &requestListener{m: m})
// Start group request worker
requestStop := stoppable.NewSingle(requestStoppableName)
requestChan := make(chan message.Receive, rawMessageBuffSize)
m.swb.RegisterChannel(requestListenerName, &id.ID{},
message.GroupCreationRequest, requestChan)
go m.receiveRequest(requestChan, requestStop)
// Register notifications listener for incoming e2e group chat requests
err = e2e.AddService(catalog.GroupRq, nil)
if err != nil {
return nil, err
}
// Create a multi stoppable
multiStoppable := stoppable.NewMulti(groupStoppableName)
multiStoppable.Add(receiveStop)
multiStoppable.Add(requestStop)
// Register all groups
for _, gId := range m.GetGroups() {
g, exists := m.GetGroup(gId)
if !exists {
jww.WARN.Printf("Unexpected failure to locate GroupID %s", gId.String())
continue
}
return multiStoppable, nil
err = m.JoinGroup(g)
if err != nil {
return nil, err
}
}
return m, nil
}
// JoinGroup adds the group to the list of group chats the user is a part of.
......@@ -131,15 +104,14 @@ func (m Manager) JoinGroup(g gs.Group) error {
return errors.Errorf(joinGroupErr, g.ID, err)
}
edgeStore := m.store.GetEdge()
edgeStore.Add(edge.Preimage{
Data: g.ID[:],
Type: catalog.Group,
Source: g.ID[:],
}, m.store.GetUser().ReceptionID)
newService := message.Service{
Identifier: g.ID[:],
Tag: catalog.Group,
Metadata: g.ID[:],
}
m.services.AddService(m.receptionId, newService, &receptionProcessor{m: &m, g: g})
jww.DEBUG.Printf("Joined group %q with ID %s.", g.Name, g.ID)
return nil
}
......@@ -149,16 +121,14 @@ func (m Manager) LeaveGroup(groupID *id.ID) error {
return errors.Errorf(leaveGroupErr, groupID, err)
}
edgeStore := m.store.GetEdge()
err := edgeStore.Remove(edge.Preimage{
Data: groupID[:],
Type: catalog.Group,
Source: groupID[:],
}, m.store.GetUser().ReceptionID)
delService := message.Service{
Identifier: groupID.Bytes(),
Tag: catalog.Group,
}
m.services.DeleteService(m.receptionId, delService, nil)
jww.DEBUG.Printf("Left group with ID %s.", groupID)
return err
return nil
}
// GetGroups returns a list of all registered groupChat IDs.
......
......@@ -11,10 +11,11 @@ import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
gs "gitlab.com/elixxir/client/groupChat/groupStore"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/stoppable"
"gitlab.com/elixxir/client/network/historical"
"gitlab.com/elixxir/client/network/identity/receptionID"
"gitlab.com/elixxir/crypto/group"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/elixxir/primitives/states"
"gitlab.com/xx_network/primitives/id"
"time"
)
......@@ -30,104 +31,64 @@ const (
"cMix message because MAC verification failed (epoch %d could be off)"
)
// receive starts the group message reception worker that waits for new group
// messages to arrive.
func (m Manager) receive(rawMsgs chan message.Receive, stop *stoppable.Single) {
jww.DEBUG.Print("Starting group message reception worker.")
// Adheres to network.Manager interface for reception processing
type receptionProcessor struct {
m *Manager
g gs.Group
}
for {
select {
case <-stop.Quit():
jww.DEBUG.Print("Stopping group message reception worker.")
stop.ToStopped()
return
case receiveMsg := <-rawMsgs:
// Process incoming group chat messages
func (p *receptionProcessor) Process(message format.Message, receptionID receptionID.EphemeralIdentity, round historical.Round) {
jww.TRACE.Print("Group message reception received cMix message.")
// Attempt to read the message
g, msgID, timestamp, senderID, msg, noFpMatch, err :=
m.readMessage(receiveMsg)
roundTimeStamp := round.Timestamps[states.QUEUED]
msgID, timestamp, senderID, msg, err := decryptMessage(p.g, message, roundTimeStamp)
if err != nil {
if noFpMatch {
jww.TRACE.Printf("Received message not for group chat: %+v",
err)
} else {
jww.WARN.Printf("Group message reception failed to read "+
"cMix message: %+v", err)
}
continue
return
}
jww.DEBUG.Printf("Received group message with ID %s from sender "+
"%s in group %s with ID %s at %s.", msgID, senderID, g.Name,
g.ID, timestamp)
"%s in group %s with ID %s at %s.", msgID, senderID, p.g.Name,
p.g.ID, timestamp)
// If the message was read correctly, send it to the callback
go m.receiveFunc(MessageReceive{
GroupID: g.ID,
go p.m.receiveFunc(MessageReceive{
GroupID: p.g.ID,
ID: msgID,
Payload: msg,
SenderID: senderID,
RecipientID: receiveMsg.RecipientID,
EphemeralID: receiveMsg.EphemeralID,
RecipientID: receptionID.Source,
EphemeralID: receptionID.EphId,
Timestamp: timestamp,
RoundID: receiveMsg.RoundId,
RoundTimestamp: receiveMsg.RoundTimestamp,
RoundID: round.ID,
RoundTimestamp: roundTimeStamp,
})
}
}
}
// readMessage returns the group, message ID, timestamp, sender ID, and message
// of a group message. The encrypted group message data is unmarshalled from a
// cMix message in the message.Receive and then decrypted and the MAC is
// verified. The group is found by finding the group with a matching key
// fingerprint. Returns true if the key fingerprint cannot be found; in this
// case no warning or error should be printed.
func (m *Manager) readMessage(msg message.Receive) (gs.Group, group.MessageID,
time.Time, *id.ID, []byte, bool, error) {
// Unmarshal payload into cMix message
cMixMsg, err := format.Unmarshal(msg.Payload)
if err != nil {
return gs.Group{}, group.MessageID{}, time.Time{}, nil, nil,
false, err
}
// decryptMessage decrypts the group message payload and returns its message ID,
// timestamp, sender ID, and message contents.
func decryptMessage(g gs.Group, cMixMsg format.Message, roundTimestamp time.Time) (
group.MessageID, time.Time, *id.ID, []byte, error) {
// Unmarshal cMix message contents to get public message format
pubMsg, err := unmarshalPublicMsg(cMixMsg.GetContents())
if err != nil {
return gs.Group{}, group.MessageID{}, time.Time{}, nil, nil, false,
return group.MessageID{}, time.Time{}, nil, nil,
errors.Errorf(unmarshalPublicMsgErr, err)
}
// get the group from storage via key fingerprint lookup
g, exists := m.gs.GetByKeyFp(cMixMsg.GetKeyFP(), pubMsg.GetSalt())
if !exists {
return gs.Group{}, group.MessageID{}, time.Time{}, nil, nil, true,
errors.Errorf(findGroupKeyFpErr, cMixMsg.GetKeyFP())
}
// Decrypt the payload and return the messages timestamp, sender ID, and
// message contents
messageID, timestamp, senderID, contents, err := m.decryptMessage(
g, cMixMsg, pubMsg, msg.RoundTimestamp)
return g, messageID, timestamp, senderID, contents, false, err
}
// decryptMessage decrypts the group message payload and returns its message ID,
// timestamp, sender ID, and message contents.
func (m *Manager) decryptMessage(g gs.Group, cMixMsg format.Message,
publicMsg publicMsg, roundTimestamp time.Time) (group.MessageID, time.Time,
*id.ID, []byte, error) {
key, err := getCryptKey(g.Key, publicMsg.GetSalt(), cMixMsg.GetMac(),
publicMsg.GetPayload(), g.DhKeys, roundTimestamp)
key, err := getCryptKey(g.Key, pubMsg.GetSalt(), cMixMsg.GetMac(),
pubMsg.GetPayload(), g.DhKeys, roundTimestamp)
if err != nil {
return group.MessageID{}, time.Time{}, nil, nil, err
}
// Decrypt internal message
decryptedPayload := group.Decrypt(key, cMixMsg.GetKeyFP(),
publicMsg.GetPayload())
pubMsg.GetPayload())
// Unmarshal internal message
intlMsg, err := unmarshalInternalMsg(decryptedPayload)
......
......@@ -11,60 +11,56 @@ import (
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/catalog"
"gitlab.com/elixxir/client/e2e/receive"
gs "gitlab.com/elixxir/client/groupChat/groupStore"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/stoppable"
"gitlab.com/elixxir/crypto/group"
"time"
)
// Error message.
// Error messages
const (
sendMessageTypeErr = "message not of type GroupCreationRequest"
protoUnmarshalErr = "failed to unmarshal request: %+v"
deserializeMembershipErr = "failed to deserialize membership: %+v"
)
// receiveRequest starts the group request reception worker that waits for new
// group requests to arrive.
func (m Manager) receiveRequest(rawMsgs chan message.Receive,
stop *stoppable.Single) {
jww.DEBUG.Print("Starting group message request reception worker.")
for {
select {
case <-stop.Quit():
jww.DEBUG.Print("Stopping group message request reception worker.")
stop.ToStopped()
return
case sendMsg := <-rawMsgs:
// Adheres to receive.Listener interface
type requestListener struct {
m *Manager
}
// Hear waits for new group requests to arrive
func (l *requestListener) Hear(item receive.Message) {
jww.DEBUG.Print("Group message request received message.")
// Generate the group from the request message
g, err := m.readRequest(sendMsg)
g, err := l.m.readRequest(item)
if err != nil {
jww.WARN.Printf("Failed to read message as group request: %+v",
err)
continue
jww.WARN.Printf("Failed to read message as group request: %+v", err)
return
}
// Call request callback with the new group if it does not already
// exist
if _, exists := m.GetGroup(g.ID); !exists {
jww.DEBUG.Printf("Received group request from sender %s for "+
"group %s with ID %s.", sendMsg.Sender, g.Name, g.ID)
if _, exists := l.m.GetGroup(g.ID); !exists {
jww.DEBUG.Printf("Received group request for "+
"group %s with ID %s.", g.Name, g.ID)
go m.requestFunc(g)
}
go l.m.requestFunc(g)
}
}
// Name returns a name, used for debugging
func (l *requestListener) Name() string {
return catalog.GroupRq
}
// readRequest returns the group describes in the group request message. An
// error is returned if the request is of the wrong type or cannot be read.
func (m *Manager) readRequest(msg message.Receive) (gs.Group, error) {
func (m *Manager) readRequest(msg receive.Message) (gs.Group, error) {
// Return an error if the message is not of the right type
if msg.MessageType != message.GroupCreationRequest {
if msg.MessageType != catalog.GroupCreationRequest {
return gs.Group{}, errors.New(sendMessageTypeErr)
}
......@@ -82,7 +78,7 @@ func (m *Manager) readRequest(msg message.Receive) (gs.Group, error) {
}
// get the relationship with the group leader
partner, err := m.store.E2e().GetPartner(membership[0].ID)
partner, err := m.e2e.GetPartner(membership[0].ID, m.receptionId)
if err != nil {
return gs.Group{}, errors.Errorf(getPrivKeyErr, err)
}
......@@ -93,8 +89,7 @@ func (m *Manager) readRequest(msg message.Receive) (gs.Group, error) {
// Generate the DH keys with each group member
privKey := partner.GetMyOriginPrivateKey()
grp := m.store.E2e().GetGroup()
dkl := gs.GenerateDhKeyList(m.gs.GetUser().ID, privKey, membership, grp)
dkl := gs.GenerateDhKeyList(m.gs.GetUser().ID, privKey, membership, m.grp)
// Restore the original public key for the leader so that the membership
// digest generated later is correct
......
......@@ -10,9 +10,10 @@ package groupChat
import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/catalog"
gs "gitlab.com/elixxir/client/groupChat/groupStore"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/interfaces/params"
"gitlab.com/elixxir/client/network"
"gitlab.com/elixxir/client/network/message"
"gitlab.com/elixxir/crypto/group"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/primitives/id"
......@@ -48,8 +49,7 @@ func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, gro
return 0, time.Time{}, group.MessageID{}, errors.Errorf(newCmixMsgErr, err)
}
param := params.GetDefaultCMIX()
param.IdentityPreimage = groupID[:]
param := network.GetDefaultCMIXParams()
param.DebugTag = "group.Message"
rid, _, err := m.net.SendManyCMIX(messages, param)
......@@ -67,10 +67,10 @@ func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, gro
// createMessages generates a list of cMix messages and a list of corresponding
// recipient IDs.
func (m *Manager) createMessages(groupID *id.ID, msg []byte, timestamp time.Time) (
[]message.TargetedCmixMessage, group.MessageID, error) {
[]network.TargetedCmixMessage, group.MessageID, error) {
//make the message ID
cmixMsg := format.NewMessage(m.store.Cmix().GetGroup().GetP().ByteLen())
cmixMsg := format.NewMessage(m.grp.GetP().ByteLen())
_, intlMsg, err := newMessageParts(cmixMsg.ContentsSize())
if err != nil {
return nil, group.MessageID{}, errors.WithMessage(err, "Failed to make message parts for message ID")
......@@ -79,7 +79,7 @@ func (m *Manager) createMessages(groupID *id.ID, msg []byte, timestamp time.Time
g, exists := m.gs.Get(groupID)
if !exists {
return []message.TargetedCmixMessage{}, group.MessageID{},
return []network.TargetedCmixMessage{}, group.MessageID{},
errors.Errorf(newNoGroupErr, groupID)
}
......@@ -91,16 +91,16 @@ func (m *Manager) createMessages(groupID *id.ID, msg []byte, timestamp time.Time
// newMessages is a private function that allows the passing in of a timestamp
// and streamGen instead of a fastRNG.StreamGenerator for easier testing.
func (m *Manager) newMessages(g gs.Group, msg []byte, timestamp time.Time) (
[]message.TargetedCmixMessage, error) {
[]network.TargetedCmixMessage, error) {
// Create list of cMix messages
messages := make([]message.TargetedCmixMessage, 0, len(g.Members))
messages := make([]network.TargetedCmixMessage, 0, len(g.Members))
// Create channels to receive messages and errors on
type msgInfo struct {
msg format.Message
id *id.ID
}
msgChan := make(chan msgInfo, len(g.Members)-1)
msgChan := make(chan network.TargetedCmixMessage, len(g.Members)-1)
errChan := make(chan error, len(g.Members)-1)
// Create cMix messages in parallel
......@@ -117,11 +117,15 @@ func (m *Manager) newMessages(g gs.Group, msg []byte, timestamp time.Time) (
defer rng.Close()
// Add cMix message to list
cMixMsg, err := m.newCmixMsg(g, msg, timestamp, member, rng)
if err != nil {
errChan <- errors.Errorf(newCmixErr, i, member.ID, g.ID, err)
msgChan <- network.TargetedCmixMessage{
Recipient: member.ID,
Payload: msg,
Service: message.Service{
Identifier: g.ID[:],
Tag: catalog.Group,
Metadata: g.ID[:],
},
}
msgChan <- msgInfo{cMixMsg, member.ID}
}(member, i)
}
......@@ -133,10 +137,7 @@ func (m *Manager) newMessages(g gs.Group, msg []byte, timestamp time.Time) (
// Return on the first error that occurs
return nil, err
case info := <-msgChan:
messages = append(messages, message.TargetedCmixMessage{
Recipient: info.id,
Message: info.msg,
})
messages = append(messages, info)
}
}
......@@ -148,7 +149,7 @@ func (m *Manager) newCmixMsg(g gs.Group, msg []byte, timestamp time.Time,
mem group.Member, rng io.Reader) (format.Message, error) {
// Create three message layers
cmixMsg := format.NewMessage(m.store.Cmix().GetGroup().GetP().ByteLen())
cmixMsg := format.NewMessage(m.grp.GetP().ByteLen())
pubMsg, intlMsg, err := newMessageParts(cmixMsg.ContentsSize())
if err != nil {
return cmixMsg, err
......
......@@ -11,9 +11,9 @@ import (
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/catalog"
"gitlab.com/elixxir/client/e2e"
gs "gitlab.com/elixxir/client/groupChat/groupStore"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/interfaces/params"
"gitlab.com/elixxir/crypto/group"
"gitlab.com/xx_network/primitives/id"
"strings"
......@@ -111,23 +111,11 @@ func (m Manager) sendRequests(g gs.Group) ([]id.Round, RequestStatus, error) {
// sendRequest sends the group request to the user via E2E.
func (m Manager) sendRequest(memberID *id.ID, request []byte) ([]id.Round, error) {
sendMsg := message.Send{
Recipient: memberID,
Payload: request,
MessageType: message.GroupCreationRequest,
}
recipent, err := m.store.E2e().GetPartner(memberID)
if err != nil {
return nil, errors.WithMessagef(err, "Failed to send request to %s "+
"because e2e relationship could not be found", memberID)
}
p := params.GetDefaultE2E()
p.IdentityPreimage = recipent.GetGroupRequestPreimage()
p.DebugTag = "group.Request"
p := e2e.GetDefaultParams()
p.LastServiceTag = catalog.GroupRq
p.CMIX.DebugTag = "group.Request"
rounds, _, _, err := m.net.SendE2E(sendMsg, p, nil)
rounds, _, _, err := m.e2e.SendE2E(catalog.GroupCreationRequest, m.receptionId, request, p)
if err != nil {
return nil, errors.Errorf(sendE2eErr, memberID, err)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment