Skip to content
Snippets Groups Projects
Select Git revision
  • a842fef528cb21860b945072134d1060f05a13d0
  • release default protected
  • 11-22-implement-kv-interface-defined-in-collectiveversionedkvgo
  • hotfix/TestHostPool_UpdateNdf_AddFilter
  • XX-4719/announcementChannels
  • xx-4717/logLevel
  • jonah/noob-channel
  • master protected
  • XX-4707/tagDiskJson
  • xx-4698/notification-retry
  • hotfix/notifylockup
  • syncNodes
  • hotfix/localCB
  • XX-4677/NewChanManagerMobile
  • XX-4689/DmSync
  • duplicatePrefix
  • XX-4601/HavenInvites
  • finalizedUICallbacks
  • XX-4673/AdminKeySync
  • debugNotifID
  • anne/test
  • v4.7.5
  • v4.7.4
  • v4.7.3
  • v4.7.2
  • v4.7.1
  • v4.6.3
  • v4.6.1
  • v4.5.0
  • v4.4.4
  • v4.3.11
  • v4.3.8
  • v4.3.7
  • v4.3.6
  • v4.3.5
  • v4.2.0
  • v4.3.0
  • v4.3.4
  • v4.3.3
  • v4.3.2
  • v4.3.1
41 results

symmetric_test.go

Blame
  • send.go 6.91 KiB
    ///////////////////////////////////////////////////////////////////////////////
    // Copyright © 2020 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"
    	"errors"
    	"fmt"
    	"gitlab.com/elixxir/client/interfaces/message"
    	"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
    // recipient. Note that both SendE2E and SendUnsafe call SendCMIX.
    // Returns the round ID of the round the payload was sent or an error
    // if it fails.
    
    // This will return an error if:
    //  - the recipient ID is invalid
    //  - the contents are too long for the message structure
    //  - the message cannot be sent
    
    // This will return the round the message was sent on if it is successfully sent
    // This can be used to register a round event to learn about message delivery.
    // on failure a round id of -1 is returned
    func (c *Client) SendCmix(recipient, contents []byte, parameters string) (int, error) {
    	p, err := params.GetCMIXParameters(parameters)
    	if err != nil {
    		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    			err))
    	}
    
    	u, err := id.Unmarshal(recipient)
    	if err != nil {
    		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    			err))
    	}
    
    	msg, err := c.api.NewCMIXMessage(contents)
    	if err != nil {
    		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    			err))
    	}
    
    	rid, _, err := c.api.SendCMIX(msg, u, p)
    	if err != nil {
    		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    			err))
    	}
    	return int(rid), nil
    }
    
    // SendManyCMIX sends many "raw" CMIX message payloads to each of the
    // provided recipients. Used for group chat functionality. Returns the
    // round ID of the round the payload was sent or an error if it fails.
    // This will return an error if:
    //  - any recipient ID is invalid
    //  - any of the the message contents are too long for the message structure
    //  - the message cannot be sent
    
    // This will return the round the message was sent on if it is successfully sent
    // This can be used to register a round event to learn about message delivery.
    // on failure a round id of -1 is returned
    // fixme: cannot use a slice of slices over bindings. Will need to modify this function once
    //  a proper input format has been specified
    // func (c *Client) SendManyCMIX(recipients, contents [][]byte, parameters string) (int, error) {
    //
    //	p, err := params.GetCMIXParameters(parameters)
    //	if err != nil {
    //		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    //			err))
    //	}
    //
    //	// Build messages
    //	messages := make(map[id.ID]format.Message, len(contents))
    //	for i := 0; i < len(contents); i++ {
    //		msg, err := c.api.NewCMIXMessage(contents[i])
    //		if err != nil {
    //			return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    //				err))
    //		}
    //
    //		u, err := id.Unmarshal(recipients[i])
    //		if err != nil {
    //			return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    //				err))
    //		}
    //
    //		messages[*u] = msg
    //	}
    //
    //	rid, _, err := c.api.SendManyCMIX(messages, p)
    //	if err != nil {
    //		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
    //			err))
    //	}
    //	return int(rid), nil
    // }
    
    // SendUnsafe sends an unencrypted payload to the provided recipient
    // with the provided msgType. Returns the list of rounds in which parts
    // of the message were sent or an error if it fails.
    // NOTE: Do not use this function unless you know what you are doing.
    // This function always produces an error message in client logging.
    //
    // Message Types can be found in client/interfaces/message/type.go
    // Make sure to not conflict with ANY default message types with custom types
    func (c *Client) SendUnsafe(recipient, payload []byte,
    	messageType int, parameters string) (*RoundList, error) {
    	p, err := params.GetUnsafeParameters(parameters)
    	if err != nil {
    		return nil, errors.New(fmt.Sprintf("Failed to sendUnsafe: %+v",
    			err))
    	}
    	u, err := id.Unmarshal(recipient)
    	if err != nil {
    		return nil, errors.New(fmt.Sprintf("Failed to sendUnsafe: %+v",
    			err))
    	}
    
    	m := message.Send{
    		Recipient:   u,
    		Payload:     payload,
    		MessageType: message.Type(messageType),
    	}
    
    	rids, err := c.api.SendUnsafe(m, p)
    	if err != nil {
    		return nil, errors.New(fmt.Sprintf("Failed to sendUnsafe: %+v",
    			err))
    	}
    
    	return &RoundList{list: rids}, nil
    }
    
    // SendE2E sends an end-to-end payload to the provided recipient with
    // the provided msgType. Returns the list of rounds in which parts of
    // the message were sent or an error if it fails.
    //
    // Message Types can be found in client/interfaces/message/type.go
    // Make sure to not conflict with ANY default message types
    func (c *Client) SendE2E(recipient, payload []byte, messageType int, parameters string) (*SendReport, error) {
    	p, err := params.GetE2EParameters(parameters)
    	if err != nil {
    		return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err))
    	}
    
    	u, err := id.Unmarshal(recipient)
    	if err != nil {
    		return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err))
    	}
    
    	m := message.Send{
    		Recipient:   u,
    		Payload:     payload,
    		MessageType: message.Type(messageType),
    	}
    
    	rids, mid, ts, err := c.api.SendE2E(m, p)
    	if err != nil {
    		return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err))
    	}
    
    	sr := SendReport{
    		rl:  &RoundList{list: rids},
    		mid: mid,
    		ts:  ts,
    	}
    
    	return &sr, nil
    }
    
    // the send report is the mechanisim by which sendE2E returns a single
    type SendReport struct {
    	rl  *RoundList
    	mid e2e.MessageID
    	ts  time.Time
    }
    
    type SendReportDisk struct {
    	List []id.Round
    	Mid  []byte
    	Ts   int64
    }
    
    func (sr *SendReport) GetRoundList() *RoundList {
    	return sr.rl
    }
    
    func (sr *SendReport) GetMessageID() []byte {
    	return sr.mid[:]
    }
    
    func (sr *SendReport) GetRoundURL() string {
    	if sr.rl != nil && sr.rl.Len() > 0 {
    		return getRoundURL(sr.rl.list[0])
    	}
    	return dashboardBaseURL
    }
    
    // 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,
    		Mid:  sr.mid[:],
    		Ts:   sr.ts.UnixNano(),
    	}
    	return json.Marshal(&srd)
    }
    
    func (sr *SendReport) Unmarshal(b []byte) error {
    	srd := SendReportDisk{}
    	if err := json.Unmarshal(b, &srd); err != nil {
    		return errors.New(fmt.Sprintf("Failed to unmarshal send "+
    			"report: %s", err.Error()))
    	}
    
    	copy(sr.mid[:], srd.Mid)
    	sr.rl = &RoundList{list: srd.List}
    	sr.ts = time.Unix(0, srd.Ts)
    	return nil
    }