diff --git a/bindings/channels.go b/bindings/channels.go index 2d74b293ac450c4756e3f2b136cb55b8f9a602d7..fd9306f2b5f4258d391df3a3e5c4bca2e7b48d5f 100644 --- a/bindings/channels.go +++ b/bindings/channels.go @@ -98,12 +98,15 @@ func (cm *ChannelsManager) GetID() int { } // NewChannelsManager constructs a ChannelsManager. +// fixme: this is a work in progress and should not be used +// an event model is implemented in the style of the bindings layer's +// AuthCallbacks. Remove this note when that has been done. // // Parameters: // - e2eID - The tracked e2e object ID. This can be retrieved using [E2e.GetID]. // - udID - The tracked UD object ID. This can be retrieved using // [UserDiscovery.GetID]. -func NewChannelsManager(e2eID, udID, eventModelId int) (*ChannelsManager, error) { +func NewChannelsManager(e2eID, udID int) (*ChannelsManager, error) { // Get user from singleton user, err := e2eTrackerSingleton.get(e2eID) if err != nil { @@ -115,19 +118,16 @@ func NewChannelsManager(e2eID, udID, eventModelId int) (*ChannelsManager, error) return nil, err } - eventModel, err := eventModelTrackerSingleton.get(eventModelId) - if err != nil { - return nil, err - } - nameService, err := udMan.api.StartChannelNameService() if err != nil { return nil, err } // Construct new channels manager + // TODO: Implement a bindings layer event model, pass that in as a parameter + // or the function and pass that into here. m := channels.NewManager(user.api.GetStorage().GetKV(), user.api.GetCmix(), - user.api.GetRng(), nameService, eventModel.api) + user.api.GetRng(), nameService, nil) // Add channel to singleton and return return channelManagerTrackerSingleton.make(m), nil @@ -605,7 +605,6 @@ func constructChannelSendReport(channelMessageId cryptoChannel.MessageID, type ReceivedChannelMessageReport struct { ChannelId []byte MessageId []byte - ReplyTo []byte MessageType int SenderUsername string Content []byte diff --git a/bindings/eventModel.go b/bindings/eventModel.go deleted file mode 100644 index 6e7ef4bcd36676c3e447c743a9243a3d0141e1f2..0000000000000000000000000000000000000000 --- a/bindings/eventModel.go +++ /dev/null @@ -1,311 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright © 2022 xx network SEZC // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file // -/////////////////////////////////////////////////////////////////////////////// - -package bindings - -import ( - "encoding/json" - "github.com/pkg/errors" - jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/client/channels" - "gitlab.com/elixxir/client/cmix/rounds" - cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" - cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/xx_network/crypto/signature/rsa" - "gitlab.com/xx_network/primitives/id" - "sync" - "time" -) - -//////////////////////////////////////////////////////////////////////////////// -// Singleton Tracker // -//////////////////////////////////////////////////////////////////////////////// - -// eventModelTrackerSingleton is used to track EventModel objects -// so that they can be referenced by ID back over the bindings. -var eventModelTrackerSingleton = &eventModelTracker{ - tracked: make(map[int]*EventModel), - count: 0, -} - -// eventModelTracker is a singleton used to keep track of extant -// EventModel objects, preventing race conditions created by passing it -// over the bindings. -type eventModelTracker struct { - tracked map[int]*EventModel - count int - mux sync.RWMutex -} - -// make create an EventModel from an [channels.EventModel], assigns it a -// unique ID, and adds it to the eventModelTracker. -func (emt *eventModelTracker) make(eventModel channels.EventModel) *EventModel { - emt.mux.Lock() - defer emt.mux.Unlock() - - id := emt.count - emt.count++ - - emt.tracked[id] = &EventModel{ - api: eventModel, - id: id, - } - - return emt.tracked[id] -} - -// get an EventModel from the eventModelTracker given its ID. -func (emt *eventModelTracker) get(id int) (*EventModel, error) { - emt.mux.RLock() - defer emt.mux.RUnlock() - - c, exist := emt.tracked[id] - if !exist { - return nil, errors.Errorf( - "Cannot get EventModel for ID %d, does not exist", id) - } - - return c, nil -} - -// delete removes a EventModel from the eventModelTracker. -func (emt *eventModelTracker) delete(id int) { - emt.mux.Lock() - defer emt.mux.Unlock() - - delete(emt.tracked, id) -} - -//////////////////////////////////////////////////////////////////////////////// -// Basic EventModel API // -//////////////////////////////////////////////////////////////////////////////// - -type EventModel struct { - api channels.EventModel - id int -} - -// NewEventModel IS CURRENTLY UNIMPLEMENTED. -func NewEventModel() *EventModel { - return eventModelTrackerSingleton.make(nil) -} - -// JoinChannel is called whenever a channel is joined locally. -// -// Parameters: -// - channelJson - A JSON encoded [ChannelDef]. -func (e *EventModel) JoinChannel(channelJson []byte) { - // Unmarshal channel definition - def := ChannelDef{} - err := json.Unmarshal(channelJson, &def) - if err != nil { - jww.ERROR.Printf("Could not parse channel JSON: %+v", err) - return - } - - // Construct ID using the embedded cryptographic information - channelId, err := cryptoBroadcast.NewChannelID(def.Name, def.Description, - def.Salt, def.PubKey) - if err != nil { - jww.ERROR.Printf("Could not construct channel ID: %+v", err) - return - } - - // Construct public key into object - rsaPubKey, err := rsa.LoadPublicKeyFromPem(def.PubKey) - if err != nil { - jww.ERROR.Printf("Could not read public key: %+v", err) - return - } - - // Construct cryptographic channel object - channel := &cryptoBroadcast.Channel{ - ReceptionID: channelId, - Name: def.Name, - Description: def.Description, - Salt: def.Salt, - RsaPubKey: rsaPubKey, - } - - e.api.JoinChannel(channel) - return -} - -// LeaveChannel is called whenever a channel is left locally. -// -// Parameters: -// - []byte - A JSON marshalled channel ID ([id.ID]). This may be retrieved -// using ChannelsManager.GetChannelId. -func (e *EventModel) LeaveChannel(marshalledChanId []byte) { - - // Unmarshal channel ID - channelId, err := id.Unmarshal(marshalledChanId) - if err != nil { - jww.ERROR.Printf("Could not parse channel ID (%s): %+v", - marshalledChanId, err) - return - } - - e.api.LeaveChannel(channelId) - return -} - -// ReceiveMessage is called whenever a message is received on a given channel -// It may be called multiple times on the same message, it is incumbent on -// the user of the API to filter such called by message ID. -// -// Parameters: -// - reportJson - A JSON marshalled ReceivedChannelMessageReport. -func (e *EventModel) ReceiveMessage(reportJson []byte) { - - // Parse message report - report, err := parseChannelMessageReport(reportJson) - if err != nil { - jww.ERROR.Printf("%+v", err) - return - } - - // Call internal ReceiveMessage - // fixme: the internal API should accept an object, probably - // just move receivedChannelMessageReport to the channels package and export it. - e.api.ReceiveMessage(report.ChannelID, report.MessageID, - report.SenderUsername, report.Content, report.Timestamp, - report.Lease, report.Round) - - return -} - -// ReceiveReply is called whenever a message is received which is a reply -// on a given channel. It may be called multiple times on the same message, -// it is incumbent on the user of the API to filter such called by message ID -// Messages may arrive our of order, so a reply in theory can arrive before -// the initial message, as a result it may be important to buffer replies. -// -// Parameters: -// - reportJson - A JSON marshalled ReceivedChannelMessageReport. -func (e *EventModel) ReceiveReply(reportJson []byte) { - - // Parse message report - report, err := parseChannelMessageReport(reportJson) - if err != nil { - jww.ERROR.Printf("%+v", err) - return - } - - // Call internal ReceiveReply - // fixme: the internal API should accept an object, probably - // just move receivedChannelMessageReport to the channels package and export it. - e.api.ReceiveReply(report.ChannelID, report.MessageID, report.ReplyTo, - report.SenderUsername, report.Content, report.Timestamp, - report.Lease, report.Round) -} - -// ReceiveReaction is called whenever a Content to a message is received -// on a given channel. It may be called multiple times on the same Content, -// it is incumbent on the user of the API to filter such called by message ID -// Messages may arrive our of order, so a reply in theory can arrive before -// the initial message, as a result it may be important to buffer reactions. -// -// Parameters: -// - reportJson - A JSON marshalled ReceivedChannelMessageReport. -func (e *EventModel) ReceiveReaction(reportJson []byte) { - - // Parse message report - report, err := parseChannelMessageReport(reportJson) - if err != nil { - jww.ERROR.Printf("%+v", err) - return - } - - // Call internal ReceiveReaction - // fixme: the internal API should accept an object, probably - // just move receivedChannelMessageReport to the channels package and export it. - e.api.ReceiveReaction(report.ChannelID, report.MessageID, report.ReplyTo, - report.SenderUsername, report.Content, report.Timestamp, report.Lease, - report.Round) -} - -// receivedChannelMessageReport is the Golang representation of -// a channel message report. -type receivedChannelMessageReport struct { - - // Channel ID is the message of the channel this message was received on. - ChannelID *id.ID - - // MessageID is the ID of the channel message received. - MessageID cryptoChannel.MessageID - - // ReplyTo is overloaded to be a reply or react to, - // depending on the context of the received message - // (EventModel.ReceiveReaction or EventModel.ReceiveReply). - ReplyTo cryptoChannel.MessageID - - // SenderUsername is the username of the sender. - SenderUsername string - - // Content is the payload of the message. This is overloaded with - // reaction in the [EventModel.ReceiveReaction]. This may - // either be text or an emoji. - Content string - - // The timestamp of the message. - Timestamp time.Time - - // The duration of this channel message. - Lease time.Duration - - // The round this message was sent on. - Round rounds.Round -} - -// parseChannelMessageReport converts the JSON representation of -// a ReceivedChannelMessageReport into the Golang representation, -// receivedChannelMessageReport. -func parseChannelMessageReport(reportJson []byte) ( - receivedChannelMessageReport, error) { - - // Unmarshal message report - messageReport := ReceivedChannelMessageReport{} - err := json.Unmarshal(reportJson, &messageReport) - if err != nil { - return receivedChannelMessageReport{}, - errors.Errorf("Could not parse received message report (%s): %+v", - reportJson, err) - } - - // Unmarshal channel ID - chanId, err := id.Unmarshal(messageReport.ChannelId) - if err != nil { - return receivedChannelMessageReport{}, - errors.Errorf("Could not parse channel ID (%s): %+v", - messageReport.ChannelId, err) - } - - // Unmarshal message ID - msgId := cryptoChannel.MessageID{} - copy(msgId[:], messageReport.MessageId) - - // Unmarshal reply to/react to message ID - replyTo := cryptoChannel.MessageID{} - copy(replyTo[:], messageReport.ReplyTo) - - // Construct Round - rnd := rounds.Round{ID: id.Round(messageReport.Rounds[0])} - - // Return message report - return receivedChannelMessageReport{ - ChannelID: chanId, - MessageID: msgId, - ReplyTo: replyTo, - SenderUsername: messageReport.SenderUsername, - Content: string(messageReport.Content), - Timestamp: time.Unix(0, messageReport.Timestamp), - Lease: time.Duration(messageReport.Lease), - Round: rnd, - }, nil - -}