Skip to content
Snippets Groups Projects
Commit 1fdfd583 authored by Jake Taylor's avatar Jake Taylor :lips:
Browse files

Merge branch '2.0/singleusebindings' into 'release'

New bindings for api2.0

See merge request !228
parents 3ebd3c1f d9d2c9dc
No related branches found
No related tags found
2 merge requests!510Release,!228New bindings for api2.0
package bindings
import (
"encoding/json"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/catalog"
"gitlab.com/elixxir/client/fileTransfer"
ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
"gitlab.com/xx_network/primitives/id"
"time"
)
/* File Transfer Structs and Interfaces */
// FileTransfer object is a bindings-layer struct which wraps a fileTransfer.FileTransfer interface
type FileTransfer struct {
ft fileTransfer.FileTransfer
e2eCl *E2e
}
// ReceivedFile is a public struct which represents the contents of an incoming file
// Example JSON:
// {
// "TransferID":"B4Z9cwU18beRoGbk5xBjbcd5Ryi9ZUFA2UBvi8FOHWo=", // ID of the incoming transfer for receiving
// "SenderID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", // ID of sender of incoming file
// "Preview":"aXQncyBtZSBhIHByZXZpZXc=", // Preview of the incoming file
// "Name":"testfile.txt", // Name of incoming file
// "Type":"text file", // Incoming file type
// "Size":2048 // Incoming file size
// }
type ReceivedFile struct {
TransferID []byte
SenderID []byte
Preview []byte
Name string
Type string
Size int
}
// FileSend is a public struct which represents a file to be transferred
// {
// "Name":"testfile.txt", // File name
// "Type":"text file", // File type
// "Preview":"aXQncyBtZSBhIHByZXZpZXc=", // Preview of contents
// "Contents":"VGhpcyBpcyB0aGUgZnVsbCBjb250ZW50cyBvZiB0aGUgZmlsZSBpbiBieXRlcw==" // Full contents of the file
// }
type FileSend struct {
Name string
Type string
Preview []byte
Contents []byte
}
// Progress is a public struct which represents the progress of an in-progress file transfer
// Example JSON:
// {"Completed":false, // Status of transfer (true if done)
// "Transmitted":128, // Bytes transferred so far
// "Total":2048, // Total size of file
// "Err":null // Error status (if any)
// }
type Progress struct {
Completed bool
Transmitted int
Total int
Err error
}
// ReceiveFileCallback is a bindings-layer interface which is called when a file is received
// Accepts the result of calling json.Marshal on a ReceivedFile struct
type ReceiveFileCallback interface {
Callback(payload []byte, err error)
}
// FileTransferSentProgressCallback is a bindings-layer interface which is called with the progress of a sending file
// Accepts the result of calling json.Marshal on a Progress struct & a FilePartTracker interface
type FileTransferSentProgressCallback interface {
Callback(payload []byte, t *FilePartTracker, err error)
}
// FileTransferReceiveProgressCallback is a bindings-layer interface which is called with the progress of a received file
// Accepts the result of calling json.Marshal on a Progress struct & a FilePartTracker interface
type FileTransferReceiveProgressCallback interface {
Callback(payload []byte, t *FilePartTracker, err error)
}
/* Main functions */
// InitFileTransfer creates a bindings-level File Transfer manager
// Accepts e2e client ID and marshalled params JSON
func InitFileTransfer(e2eID int, paramsJSON []byte) (*FileTransfer, error) {
// Get bindings client from singleton
e2eCl, err := e2eTrackerSingleton.get(e2eID)
if err != nil {
return nil, err
}
// Client info
myID := e2eCl.api.GetReceptionIdentity().ID
rng := e2eCl.api.GetRng()
params, err := parseFileTransferParams(paramsJSON)
if err != nil {
return nil, err
}
// Create file transfer manager
m, err := fileTransfer.NewManager(params, myID,
e2eCl.api.GetCmix(), e2eCl.api.GetStorage(), rng)
// Add file transfer processes to client services tracking
err = e2eCl.api.AddService(m.StartProcesses)
if err != nil {
return nil, err
}
// Return wrapped manager
return &FileTransfer{ft: m, e2eCl: e2eCl}, nil
}
// Send is the bindings-level function for sending a File
// Accepts:
// FileSend JSON payload
// Marshalled recipient ID
// Marshalled e2e Params JSON
// Number of retries allowed
// Limit on duration between retries
// FileTransferSentProgressCallback interface
func (f *FileTransfer) Send(payload, recipientID, paramsJSON []byte, retry float32,
period string, callback FileTransferSentProgressCallback) ([]byte, error) {
// Unmarshal recipient ID
recipient, err := id.Unmarshal(recipientID)
if err != nil {
return nil, err
}
// Parse duration to time.Duration
p, err := time.ParseDuration(period)
// Wrap transfer progress callback to be passed to fileTransfer layer
cb := func(completed bool, arrived, total uint16,
st fileTransfer.SentTransfer, t fileTransfer.FilePartTracker, err error) {
prog := &Progress{
Completed: completed,
Transmitted: int(arrived),
Total: int(total),
Err: err,
}
pm, err := json.Marshal(prog)
callback.Callback(pm, &FilePartTracker{t}, err)
}
// Unmarshal payload
fs := &FileSend{}
err = json.Unmarshal(payload, fs)
if err != nil {
return nil, err
}
sendNew := func(transferInfo []byte) error {
resp, err := f.e2eCl.SendE2E(int(catalog.NewFileTransfer), recipientID, transferInfo, paramsJSON)
if err != nil {
return err
}
jww.INFO.Printf("New file transfer message sent: %s", resp)
return nil
}
// Send file
ftID, err := f.ft.Send(recipient, fs.Name, fs.Type, fs.Contents, retry, fs.Preview, cb, p, sendNew)
if err != nil {
return nil, err
}
// Return Transfer ID
return ftID.Bytes(), nil
}
// Receive returns the full file on the completion of the transfer.
// It deletes internal references to the data and unregisters any attached
// progress callback. Returns an error if the transfer is not complete, the
// full file cannot be verified, or if the transfer cannot be found.
//
// Receive can only be called once the progress callback returns that the
// file transfer is complete.
func (f *FileTransfer) Receive(tidBytes []byte) ([]byte, error) {
tid := ftCrypto.UnmarshalTransferID(tidBytes)
return f.ft.Receive(&tid)
}
// CloseSend deletes a file from the internal storage once a transfer has
// completed or reached the retry limit. Returns an error if the transfer
// has not run out of retries.
//
// This function should be called once a transfer completes or errors out
// (as reported by the progress callback).
func (f *FileTransfer) CloseSend(tidBytes []byte) error {
tid := ftCrypto.UnmarshalTransferID(tidBytes)
return f.ft.CloseSend(&tid)
}
/* Callback registration functions */
// RegisterSentProgressCallback allows for the registration of a callback to
// track the progress of an individual sent file transfer.
// SentProgressCallback is auto registered on Send; this function should be
// called when resuming clients or registering extra callbacks.
// Accepts ID of the transfer, callback for transfer progress,
// and period between retries
func (f *FileTransfer) RegisterSentProgressCallback(tidBytes []byte,
callback FileTransferSentProgressCallback, period string) error {
cb := func(completed bool, arrived, total uint16,
st fileTransfer.SentTransfer, t fileTransfer.FilePartTracker, err error) {
prog := &Progress{
Completed: completed,
Transmitted: int(arrived),
Total: int(total),
Err: err,
}
pm, err := json.Marshal(prog)
callback.Callback(pm, &FilePartTracker{t}, err)
}
p, err := time.ParseDuration(period)
if err != nil {
return err
}
tid := ftCrypto.UnmarshalTransferID(tidBytes)
return f.ft.RegisterSentProgressCallback(&tid, cb, p)
}
// RegisterReceivedProgressCallback allows for the registration of a
// callback to track the progress of an individual received file transfer.
// This should be done when a new transfer is received on the
// ReceiveCallback.
// Accepts ID of the transfer, callback for transfer progress and period between retries
func (f *FileTransfer) RegisterReceivedProgressCallback(tidBytes []byte, callback FileTransferReceiveProgressCallback, period string) error {
cb := func(completed bool, received, total uint16,
rt fileTransfer.ReceivedTransfer, t fileTransfer.FilePartTracker, err error) {
prog := &Progress{
Completed: completed,
Transmitted: int(received),
Total: int(total),
Err: err,
}
pm, err := json.Marshal(prog)
callback.Callback(pm, &FilePartTracker{t}, err)
}
p, err := time.ParseDuration(period)
if err != nil {
return err
}
tid := ftCrypto.UnmarshalTransferID(tidBytes)
return f.ft.RegisterReceivedProgressCallback(&tid, cb, p)
}
/* Utility Functions */
func (f *FileTransfer) MaxFileNameLen() int {
return f.ft.MaxFileNameLen()
}
func (f *FileTransfer) MaxFileTypeLen() int {
return f.ft.MaxFileTypeLen()
}
func (f *FileTransfer) MaxFileSize() int {
return f.ft.MaxFileSize()
}
func (f *FileTransfer) MaxPreviewSize() int {
return f.ft.MaxPreviewSize()
}
////////////////////////////////////////////////////////////////////////////////
// File Part Tracker //
////////////////////////////////////////////////////////////////////////////////
// FilePartTracker contains the interfaces.FilePartTracker.
type FilePartTracker struct {
m fileTransfer.FilePartTracker
}
// GetPartStatus returns the status of the file part with the given part number.
// The possible values for the status are:
// 0 = unsent
// 1 = sent (sender has sent a part, but it has not arrived)
// 2 = arrived (sender has sent a part, and it has arrived)
// 3 = received (receiver has received a part)
func (fpt FilePartTracker) GetPartStatus(partNum int) int {
return int(fpt.m.GetPartStatus(uint16(partNum)))
}
// GetNumParts returns the total number of file parts in the transfer.
func (fpt FilePartTracker) GetNumParts() int {
return int(fpt.m.GetNumParts())
}
////////////////////////////////////////////////////////////////////////////////
// Event Reporter //
////////////////////////////////////////////////////////////////////////////////
// EventReport is a public struct which represents the contents of an event report
// Example JSON:
// {"Priority":1,
// "Category":"Test Events",
// "EventType":"Ping",
// "Details":"This is an example of an event report"
// }
type EventReport struct {
Priority int
Category string
EventType string
Details string
}
// ReporterFunc is a bindings-layer interface which receives info from the Event Manager
// Accepts result of json.Marshal on an EventReport object
type ReporterFunc interface {
Report(payload []byte, err error)
}
// reporter is the internal struct to match the event.Reporter interface
type reporter struct {
r ReporterFunc
}
// Report matches the event.Reporter interface, wraps the info in an EventReport struct
// and passes the marshalled struct to the internal callback
func (r *reporter) Report(priority int, category, evtType, details string) {
rep := &EventReport{
Priority: priority,
Category: category,
EventType: evtType,
Details: details,
}
r.r.Report(json.Marshal(rep))
}
package bindings
import (
"encoding/json"
"gitlab.com/elixxir/crypto/fileTransfer"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/id"
"testing"
)
func TestFileTransfer_inputs(t *testing.T) {
fs := &FileSend{
Name: "testfile.txt",
Type: "text file",
Preview: []byte("it's me a preview"),
Contents: []byte("This is the full contents of the file in bytes"),
}
fsm, _ := json.Marshal(fs)
t.Log("FileSend example json:")
t.Log(string(fsm))
t.Log("\n")
tid, _ := fileTransfer.NewTransferID(csprng.NewSystemRNG())
sid := id.NewIdFromString("zezima", id.User, t)
rf := &ReceivedFile{
TransferID: tid.Bytes(),
SenderID: sid.Marshal(),
Preview: []byte("it's me a preview"),
Name: "testfile.txt",
Type: "text file",
Size: 2048,
}
rfm, _ := json.Marshal(rf)
t.Log("ReceivedFile example json:")
t.Log(string(rfm))
t.Log("\n")
p := &Progress{
Completed: false,
Transmitted: 128,
Total: 2048,
Err: nil,
}
pm, _ := json.Marshal(p)
t.Log("Progress example json:")
t.Log(string(pm))
t.Log("\n")
er := &EventReport{
Priority: 1,
Category: "Test Events",
EventType: "Ping",
Details: "This is an example of an event report",
}
erm, _ := json.Marshal(er)
t.Log("EventReport example json:")
t.Log(string(erm))
t.Log("\n")
}
...@@ -11,6 +11,8 @@ package bindings ...@@ -11,6 +11,8 @@ package bindings
import ( import (
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/fileTransfer"
"gitlab.com/elixxir/client/single"
"gitlab.com/elixxir/client/xxdk" "gitlab.com/elixxir/client/xxdk"
) )
...@@ -38,6 +40,40 @@ func GetDefaultE2EParams() []byte { ...@@ -38,6 +40,40 @@ func GetDefaultE2EParams() []byte {
return data return data
} }
// GetDefaultFileTransferParams returns a JSON serialized object with all the
// File transfer parameters and their default values. Call this function and modify
// the json to change file transfer settings.
func GetDefaultFileTransferParams() []byte {
defaultParams := fileTransfer.DefaultParams()
data, err := defaultParams.MarshalJSON()
if err != nil {
jww.FATAL.Panicf("Unexpected error: %+v", err)
}
return data
}
// GetDefaultSingleUseParams returns a JSON serialized object with all the
// single use parameters and their default values. Call this function and modify
// the json to change single use settings.
func GetDefaultSingleUseParams() []byte {
defaultParams := single.GetDefaultRequestParams()
data, err := defaultParams.MarshalJSON()
if err != nil {
jww.FATAL.Panicf("Unexpected error: %+v", err)
}
return data
}
func parseSingleUseParams(data []byte) (single.RequestParams, error) {
p := &single.RequestParams{}
return *p, p.UnmarshalJSON(data)
}
func parseFileTransferParams(data []byte) (fileTransfer.Params, error) {
p := &fileTransfer.Params{}
return *p, p.UnmarshalJSON(data)
}
func parseCMixParams(data []byte) (xxdk.CMIXParams, error) { func parseCMixParams(data []byte) (xxdk.CMIXParams, error) {
p := &xxdk.CMIXParams{} p := &xxdk.CMIXParams{}
err := p.Unmarshal(data) err := p.Unmarshal(data)
......
...@@ -8,7 +8,6 @@ package bindings ...@@ -8,7 +8,6 @@ package bindings
import ( import (
"encoding/json" "encoding/json"
"gitlab.com/elixxir/client/e2e" "gitlab.com/elixxir/client/e2e"
"gitlab.com/elixxir/client/restlike" "gitlab.com/elixxir/client/restlike"
"gitlab.com/elixxir/client/restlike/connect" "gitlab.com/elixxir/client/restlike/connect"
...@@ -34,7 +33,7 @@ type RestlikeMessage struct { ...@@ -34,7 +33,7 @@ type RestlikeMessage struct {
// RestlikeRequest performs a normal restlike request // RestlikeRequest performs a normal restlike request
// request - marshalled RestlikeMessage // request - marshalled RestlikeMessage
// Returns marshalled result RestlikeMessage // Returns marshalled result RestlikeMessage
func RestlikeRequest(clientID int, connectionID int, request []byte) ([]byte, error) { func RestlikeRequest(clientID, connectionID int, request []byte) ([]byte, error) {
paramsJSON := GetDefaultE2EParams() paramsJSON := GetDefaultE2EParams()
cl, err := cmixTrackerSingleton.get(clientID) cl, err := cmixTrackerSingleton.get(clientID)
......
package bindings
import (
"encoding/json"
"gitlab.com/elixxir/client/restlike"
"gitlab.com/elixxir/client/restlike/single"
"gitlab.com/elixxir/crypto/contact"
)
// RestlikeCallback is the public function type bindings can use to make an asynchronous restlike request
// It accepts a json marshalled restlike.Message and an error (the results of calling json.Marshal on the message)
type RestlikeCallback interface {
Callback([]byte, error)
}
// RequestRestLike sends a restlike request to a given contact
// Accepts marshalled contact object as recipient, marshalled RestlikeMessage and params JSON
// Returns json marshalled restlike.Message & error
func RequestRestLike(e2eID int, recipient, request, paramsJSON []byte) ([]byte, error) {
c, err := e2eTrackerSingleton.get(e2eID)
if err != nil {
return nil, err
}
req := single.Request{
Net: c.api.GetCmix(),
Rng: c.api.GetRng().GetStream(),
E2eGrp: c.api.GetStorage().GetE2EGroup(),
}
message := &RestlikeMessage{}
err = json.Unmarshal(request, message)
recipientContact, err := contact.Unmarshal(recipient)
if err != nil {
return nil, err
}
params, err := parseSingleUseParams(paramsJSON)
if err != nil {
return nil, err
}
resp, err := req.Request(recipientContact, restlike.Method(message.Method), restlike.URI(message.URI),
message.Content, &restlike.Headers{
Headers: message.Headers,
Version: 0,
}, params)
if err != nil {
return nil, err
}
return json.Marshal(resp)
}
// AsyncRequestRestLike sends an asynchronous restlike request to a given contact
// Accepts e2e client ID, marshalled contact object as recipient,
// marshalled RestlikeMessage, marshalled Params json, and a RestlikeCallback
// Returns an error, and the RestlikeCallback will be called with the results
// of json marshalling the response when received
func AsyncRequestRestLike(e2eID int, recipient, request, paramsJSON []byte, cb RestlikeCallback) error {
c, err := e2eTrackerSingleton.get(e2eID)
if err != nil {
return err
}
req := single.Request{
Net: c.api.GetCmix(),
Rng: c.api.GetRng().GetStream(),
E2eGrp: c.api.GetStorage().GetE2EGroup(),
}
message := &RestlikeMessage{}
err = json.Unmarshal(request, message)
recipientContact, err := contact.Unmarshal(recipient)
if err != nil {
return err
}
rlcb := func(message *restlike.Message) {
cb.Callback(json.Marshal(message))
}
params, err := parseSingleUseParams(paramsJSON)
if err != nil {
return err
}
return req.AsyncRequest(recipientContact, restlike.Method(message.Method), restlike.URI(message.URI),
message.Content, &restlike.Headers{
Headers: message.Headers,
Version: 0,
}, rlcb, params)
}
package bindings
import (
"encoding/json"
"gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/elixxir/client/cmix/rounds"
"gitlab.com/elixxir/client/single"
"gitlab.com/elixxir/crypto/contact"
"gitlab.com/xx_network/primitives/id"
)
/* PUBLIC WRAPPER METHODS */
// TransmitSingleUse accepts a marshalled recipient contact object, tag, payload, params JSON, SingleUseResponse callback func & a
// Client. Transmits payload to recipient via single use
func TransmitSingleUse(e2eID int, recipient []byte, tag string, payload, paramsJSON []byte, responseCB SingleUseResponse) ([]byte, error) {
e2eCl, err := e2eTrackerSingleton.get(e2eID)
if err != nil {
return nil, err
}
recipientContact, err := contact.Unmarshal(recipient)
if err != nil {
return nil, err
}
rcb := &singleUseResponse{response: responseCB}
params, err := parseSingleUseParams(paramsJSON)
if err != nil {
return nil, err
}
rids, eid, err := single.TransmitRequest(recipientContact, tag, payload, rcb, params, e2eCl.api.GetCmix(), e2eCl.api.GetRng().GetStream(), e2eCl.api.GetStorage().GetE2EGroup())
if err != nil {
return nil, err
}
sr := SingleUseSendReport{
EphID: eid.EphId.Int64(),
ReceptionID: eid.Source.Marshal(),
RoundsList: makeRoundsList(rids),
}
return json.Marshal(sr)
}
// Listen starts a single use listener on a given tag using the passed in client and SingleUseCallback func
func Listen(e2eID int, tag string, cb SingleUseCallback) (StopFunc, error) {
e2eCl, err := e2eTrackerSingleton.get(e2eID)
if err != nil {
return nil, err
}
listener := singleUseListener{scb: cb}
dhpk, err := e2eCl.api.GetReceptionIdentity().GetDHKeyPrivate()
if err != nil {
return nil, err
}
l := single.Listen(tag, e2eCl.api.GetReceptionIdentity().ID, dhpk, e2eCl.api.GetCmix(), e2eCl.api.GetStorage().GetE2EGroup(), listener)
return l.Stop, nil
}
// JSON Types
// SingleUseSendReport is the bindings struct used to represent information returned by single.TransmitRequest
//
// Example json marshalled struct:
// {"Rounds":[1,5,9],
// "EphID":{"EphId":[0,0,0,0,0,0,3,89],
// "Source":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}}
type SingleUseSendReport struct {
RoundsList
ReceptionID []byte
EphID int64
}
// SingleUseResponseReport is the bindings struct used to represent information passed
// to the single.Response callback interface in response to single.TransmitRequest
//
// Example json marshalled struct:
// {"Rounds":[1,5,9],
// "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
// "ReceptionID":{"EphId":[0,0,0,0,0,0,3,89],
// "Source":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"},
// "Err":null}
type SingleUseResponseReport struct {
RoundsList
Payload []byte
ReceptionID []byte
EphID int64
Err error
}
// SingleUseCallbackReport is the bindings struct used to represent single use messages
// received by a callback passed into single.Listen
//
// Example json marshalled struct:
// {"Rounds":[1,5,9],
// "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
// "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
// "EphID":{"EphId":[0,0,0,0,0,0,3,89],
// "Source":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}}
type SingleUseCallbackReport struct {
RoundsList
Payload []byte
Partner *id.ID
EphID int64
ReceptionID []byte
}
// Function types
// StopFunc is the function to stop a listener returned to the bindings layer when one is started
type StopFunc func()
// SingleUseCallback func is passed into Listen and called when messages are received
// Accepts a SingleUseCallbackReport marshalled to json
type SingleUseCallback interface {
Callback(callbackReport []byte, err error)
}
// SingleUseResponse is the public facing callback func passed by bindings clients into TransmitSingleUse
// Accepts a SingleUseResponseReport marshalled to json
type SingleUseResponse interface {
Callback(responseReport []byte, err error)
}
/* CALLBACK WRAPPERS */
/* listener struct */
// singleUseListener is the internal struct used to wrap a SingleUseCallback func,
// which matches the single.Receiver interface
type singleUseListener struct {
scb SingleUseCallback
}
// Callback is called whenever a single use message is heard by the listener, and translates the info to
//a SingleUseCallbackReport which is marshalled & passed to bindings
func (sl singleUseListener) Callback(req *single.Request, eid receptionID.EphemeralIdentity, rl []rounds.Round) {
var rids []id.Round
for _, r := range rl {
rids = append(rids, r.ID)
}
// Todo: what other info from req needs to get to bindings
scr := SingleUseCallbackReport{
Payload: req.GetPayload(),
RoundsList: makeRoundsList(rids),
Partner: req.GetPartner(),
EphID: eid.EphId.Int64(),
ReceptionID: eid.Source.Marshal(),
}
sl.scb.Callback(json.Marshal(scr))
}
/* response struct */
// singleUseResponse is the private struct backing SingleUseResponse, which subscribes to the single.Response interface
type singleUseResponse struct {
response SingleUseResponse
}
// Callback builds a SingleUseSendReport & passes the json marshalled version into the callback
func (sr singleUseResponse) Callback(payload []byte, receptionID receptionID.EphemeralIdentity,
rounds []rounds.Round, err error) {
var rids []id.Round
for _, r := range rounds {
rids = append(rids, r.ID)
}
sendReport := SingleUseResponseReport{
RoundsList: makeRoundsList(rids),
ReceptionID: receptionID.Source.Marshal(),
EphID: receptionID.EphId.Int64(),
Payload: payload,
Err: err,
}
sr.response.Callback(json.Marshal(&sendReport))
}
package bindings
import (
"encoding/json"
"gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/id/ephemeral"
"testing"
"time"
)
func TestSingleUseJsonMarshals(t *testing.T) {
rids := []id.Round{1, 5, 9}
rl := makeRoundsList(rids)
rid := id.NewIdFromString("zezima", id.User, t)
eid, _, _, err := ephemeral.GetId(rid, 16, time.Now().UnixNano())
if err != nil {
t.Fatalf("Failed to generate ephemeral id: %+v", err)
}
ephId := receptionID.EphemeralIdentity{
EphId: eid,
Source: rid,
}
payload := make([]byte, 64)
rng := csprng.NewSystemRNG()
rng.Read(payload)
sendReport := SingleUseSendReport{
RoundsList: rl,
EphID: ephId.EphId.Int64(),
ReceptionID: ephId.Source.Marshal(),
}
srm, err := json.Marshal(sendReport)
if err != nil {
t.Errorf("Failed to marshal send report to JSON: %+v", err)
} else {
t.Logf("Marshalled send report:\n%s\n", string(srm))
}
responseReport := SingleUseResponseReport{
RoundsList: rl,
Payload: payload,
ReceptionID: ephId.Source.Marshal(),
EphID: ephId.EphId.Int64(),
Err: nil,
}
rrm, err := json.Marshal(responseReport)
if err != nil {
t.Errorf("Failed to marshal response report to JSON: %+v", err)
} else {
t.Logf("Marshalled response report:\n%s\n", string(rrm))
}
callbackReport := SingleUseCallbackReport{
RoundsList: rl,
Payload: payload,
Partner: rid,
EphID: ephId.EphId.Int64(),
ReceptionID: ephId.Source.Marshal(),
}
crm, err := json.Marshal(callbackReport)
if err != nil {
t.Errorf("Failed to marshal callback report to JSON: %+v", err)
} else {
t.Logf("Marshalled callback report:\n%s\n", string(crm))
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment