From e3672e564ba384d7f35cddfbb7edf44c4689bca1 Mon Sep 17 00:00:00 2001
From: Jake Taylor <jake@elixxir.io>
Date: Mon, 4 Jan 2021 16:15:50 -0600
Subject: [PATCH] add ability to pass in params via bindings

---
 api/client.go                    | 12 ++++++------
 bindings/client.go               | 19 +++++++++++++++----
 bindings/send.go                 | 28 ++++++++++++++++++++++------
 interfaces/params/CMIX.go        | 25 ++++++++++++++++++++++++-
 interfaces/params/E2E.go         | 25 ++++++++++++++++++++++++-
 interfaces/params/Unsafe.go      | 22 ++++++++++++++++++++++
 interfaces/params/keyExchange.go | 25 ++++++++++++++++++++++++-
 interfaces/params/message.go     | 13 ++++++++++++-
 interfaces/params/network.go     | 21 +++++++++++++++++++++
 interfaces/params/node.go        | 22 ----------------------
 interfaces/params/rounds.go      | 13 ++++++++++++-
 network/message/critical.go      |  4 ++--
 12 files changed, 184 insertions(+), 45 deletions(-)
 delete mode 100644 interfaces/params/node.go

diff --git a/api/client.go b/api/client.go
index f7f879de1..68270dc0d 100644
--- a/api/client.go
+++ b/api/client.go
@@ -143,7 +143,7 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password [
 }
 
 // Login initalizes a client object from existing storage.
-func Login(storageDir string, password []byte) (*Client, error) {
+func Login(storageDir string, password []byte, parameters params.Network) (*Client, error) {
 	jww.INFO.Printf("Login()")
 	// Use fastRNG for RNG ops (AES fortuna based RNG using system RNG)
 	rngStreamGen := fastRNG.NewStreamGenerator(12, 3,
@@ -157,11 +157,11 @@ func Login(storageDir string, password []byte) (*Client, error) {
 	}
 
 	//execute the rest of the loading as normal
-	return loadClient(storageSess, rngStreamGen)
+	return loadClient(storageSess, rngStreamGen, parameters)
 }
 
 // Login initalizes a client object from existing storage.
-func loadClient(session *storage.Session, rngStreamGen *fastRNG.StreamGenerator) (c *Client, err error) {
+func loadClient(session *storage.Session, rngStreamGen *fastRNG.StreamGenerator, parameters params.Network) (c *Client, err error) {
 
 	// Set up a new context
 	c = &Client{
@@ -216,7 +216,7 @@ func loadClient(session *storage.Session, rngStreamGen *fastRNG.StreamGenerator)
 
 	// Initialize network and link it to context
 	c.network, err = network.NewManager(c.storage, c.switchboard, c.rng, c.comms,
-		params.GetDefaultNetwork(), def)
+		parameters, def)
 	if err != nil {
 		return nil, err
 	}
@@ -263,7 +263,7 @@ func loadClient(session *storage.Session, rngStreamGen *fastRNG.StreamGenerator)
 //		Responds to confirmations of successful rekey operations
 //   - Auth Callback (/auth/callback.go)
 //      Handles both auth confirm and requests
-func (c *Client) StartNetworkFollower() error {
+func (c *Client) StartNetworkFollower(parameters params.Rekey) error {
 	jww.INFO.Printf("StartNetworkFollower()")
 
 	err := c.status.toStarting()
@@ -281,7 +281,7 @@ func (c *Client) StartNetworkFollower() error {
 	}
 	c.runner.Add(stopFollow)
 	// Key exchange
-	c.runner.Add(keyExchange.Start(c.switchboard, c.storage, c.network, params.GetDefaultRekey()))
+	c.runner.Add(keyExchange.Start(c.switchboard, c.storage, c.network, parameters))
 
 	err = c.status.toRunning()
 	if err != nil {
diff --git a/bindings/client.go b/bindings/client.go
index 2789061f4..c4f933a08 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -15,6 +15,7 @@ import (
 	"gitlab.com/elixxir/client/api"
 	"gitlab.com/elixxir/client/interfaces/contact"
 	"gitlab.com/elixxir/client/interfaces/message"
+	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/interfaces/utility"
 	"gitlab.com/elixxir/comms/mixmessages"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
@@ -75,8 +76,13 @@ func NewPrecannedClient(precannedID int, network, storageDir string, password []
 // memory and stored as securely as possible using the memguard library.
 // Login does not block on network connection, and instead loads and
 // starts subprocesses to perform network operations.
-func Login(storageDir string, password []byte) (*Client, error) {
-	client, err := api.Login(storageDir, password)
+func Login(storageDir string, password []byte, parameters string) (*Client, error) {
+	p, err := params.GetNetworkParameters(parameters)
+	if err != nil {
+		return nil, errors.New(fmt.Sprintf("Failed to login: %+v", err))
+	}
+
+	client, err := api.Login(storageDir, password, p)
 	if err != nil {
 		return nil, errors.New(fmt.Sprintf("Failed to login: %+v", err))
 	}
@@ -170,8 +176,13 @@ func UnmarshalSendReport(b []byte) (*SendReport, error) {
 //		Responds to sent rekeys and executes them
 //   - KeyExchange Confirm (/keyExchange/confirm.go)
 //		Responds to confirmations of successful rekey operations
-func (c *Client) StartNetworkFollower() error {
-	if err := c.api.StartNetworkFollower(); err != nil {
+func (c *Client) StartNetworkFollower(parameters string) error {
+	p, err := params.GetRekeyParameters(parameters)
+	if err != nil {
+		return errors.New(fmt.Sprintf("Failed to start the "+
+			"network follower: %+v", err))
+	}
+	if err := c.api.StartNetworkFollower(p); err != nil {
 		return errors.New(fmt.Sprintf("Failed to start the "+
 			"network follower: %+v", err))
 	}
diff --git a/bindings/send.go b/bindings/send.go
index f9c116d5b..605fddd26 100644
--- a/bindings/send.go
+++ b/bindings/send.go
@@ -30,7 +30,13 @@ import (
 // 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) (int, error) {
+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",
@@ -43,7 +49,7 @@ func (c *Client) SendCmix(recipient, contents []byte) (int, error) {
 			err))
 	}
 
-	rid, err := c.api.SendCMIX(msg, params.GetDefaultCMIX())
+	rid, err := c.api.SendCMIX(msg, p)
 	if err != nil {
 		return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
 			err))
@@ -60,7 +66,12 @@ func (c *Client) SendCmix(recipient, contents []byte) (int, error) {
 // 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) (*RoundList, error) {
+	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",
@@ -73,7 +84,7 @@ func (c *Client) SendUnsafe(recipient, payload []byte,
 		MessageType: message.Type(messageType),
 	}
 
-	rids, err := c.api.SendUnsafe(m, params.GetDefaultUnsafe())
+	rids, err := c.api.SendUnsafe(m, p)
 	if err != nil {
 		return nil, errors.New(fmt.Sprintf("Failed to sendUnsafe: %+v",
 			err))
@@ -88,7 +99,12 @@ func (c *Client) SendUnsafe(recipient, payload []byte,
 //
 // 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) (*SendReport, error) {
+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))
@@ -100,7 +116,7 @@ func (c *Client) SendE2E(recipient, payload []byte, messageType int) (*SendRepor
 		MessageType: message.Type(messageType),
 	}
 
-	rids, mid, err := c.api.SendE2E(m, params.GetDefaultE2E())
+	rids, mid, err := c.api.SendE2E(m, p)
 	if err != nil {
 		return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err))
 	}
diff --git a/interfaces/params/CMIX.go b/interfaces/params/CMIX.go
index 8c5505999..203bb7187 100644
--- a/interfaces/params/CMIX.go
+++ b/interfaces/params/CMIX.go
@@ -7,7 +7,10 @@
 
 package params
 
-import "time"
+import (
+	"encoding/json"
+	"time"
+)
 
 type CMIX struct {
 	//maximum number of rounds to try and send on
@@ -23,3 +26,23 @@ func GetDefaultCMIX() CMIX {
 		RetryDelay: 1 * time.Second,
 	}
 }
+
+func (c *CMIX) MarshalJSON() ([]byte, error) {
+	return json.Marshal(c)
+}
+
+func (c *CMIX) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, c)
+}
+
+// Obtain default CMIX parameters, or override with given parameters if set
+func GetCMIXParameters(params string) (CMIX, error) {
+	p := GetDefaultCMIX()
+	if len(params) > 0 {
+		err := p.UnmarshalJSON([]byte(params))
+		if err != nil {
+			return CMIX{}, err
+		}
+	}
+	return p, nil
+}
diff --git a/interfaces/params/E2E.go b/interfaces/params/E2E.go
index a62b5ad58..db9599cd2 100644
--- a/interfaces/params/E2E.go
+++ b/interfaces/params/E2E.go
@@ -7,7 +7,10 @@
 
 package params
 
-import "fmt"
+import (
+	"encoding/json"
+	"fmt"
+)
 
 type E2E struct {
 	Type SendType
@@ -20,6 +23,26 @@ func GetDefaultE2E() E2E {
 	}
 }
 
+func (e *E2E) MarshalJSON() ([]byte, error) {
+	return json.Marshal(e)
+}
+
+func (e *E2E) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, e)
+}
+
+// Obtain default E2E parameters, or override with given parameters if set
+func GetE2EParameters(params string) (E2E, error) {
+	p := GetDefaultE2E()
+	if len(params) > 0 {
+		err := p.UnmarshalJSON([]byte(params))
+		if err != nil {
+			return E2E{}, err
+		}
+	}
+	return p, nil
+}
+
 type SendType uint8
 
 const (
diff --git a/interfaces/params/Unsafe.go b/interfaces/params/Unsafe.go
index 19654d88e..19e9fed23 100644
--- a/interfaces/params/Unsafe.go
+++ b/interfaces/params/Unsafe.go
@@ -7,6 +7,8 @@
 
 package params
 
+import "encoding/json"
+
 type Unsafe struct {
 	CMIX
 }
@@ -14,3 +16,23 @@ type Unsafe struct {
 func GetDefaultUnsafe() Unsafe {
 	return Unsafe{CMIX: GetDefaultCMIX()}
 }
+
+func (u *Unsafe) MarshalJSON() ([]byte, error) {
+	return json.Marshal(u)
+}
+
+func (u *Unsafe) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, u)
+}
+
+// Obtain default Unsafe parameters, or override with given parameters if set
+func GetUnsafeParameters(params string) (Unsafe, error) {
+	p := GetDefaultUnsafe()
+	if len(params) > 0 {
+		err := p.UnmarshalJSON([]byte(params))
+		if err != nil {
+			return Unsafe{}, err
+		}
+	}
+	return p, nil
+}
diff --git a/interfaces/params/keyExchange.go b/interfaces/params/keyExchange.go
index 203703d22..7d76b8fb9 100644
--- a/interfaces/params/keyExchange.go
+++ b/interfaces/params/keyExchange.go
@@ -7,7 +7,10 @@
 
 package params
 
-import "time"
+import (
+	"encoding/json"
+	"time"
+)
 
 type Rekey struct {
 	RoundTimeout time.Duration
@@ -18,3 +21,23 @@ func GetDefaultRekey() Rekey {
 		RoundTimeout: time.Minute,
 	}
 }
+
+func (r *Rekey) MarshalJSON() ([]byte, error) {
+	return json.Marshal(r)
+}
+
+func (r *Rekey) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, r)
+}
+
+// Obtain default Rekey parameters, or override with given parameters if set
+func GetRekeyParameters(params string) (Rekey, error) {
+	p := GetDefaultRekey()
+	if len(params) > 0 {
+		err := p.UnmarshalJSON([]byte(params))
+		if err != nil {
+			return Rekey{}, err
+		}
+	}
+	return p, nil
+}
diff --git a/interfaces/params/message.go b/interfaces/params/message.go
index cc452a85f..16d1fde29 100644
--- a/interfaces/params/message.go
+++ b/interfaces/params/message.go
@@ -7,7 +7,10 @@
 
 package params
 
-import "time"
+import (
+	"encoding/json"
+	"time"
+)
 
 type Messages struct {
 	MessageReceptionBuffLen        uint
@@ -24,3 +27,11 @@ func GetDefaultMessage() Messages {
 		GarbledMessageWait:             15 * time.Minute,
 	}
 }
+
+func (m *Messages) MarshalJSON() ([]byte, error) {
+	return json.Marshal(m)
+}
+
+func (m *Messages) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, m)
+}
diff --git a/interfaces/params/network.go b/interfaces/params/network.go
index cf7a2b1a1..8e9f57ef6 100644
--- a/interfaces/params/network.go
+++ b/interfaces/params/network.go
@@ -8,6 +8,7 @@
 package params
 
 import (
+	"encoding/json"
 	"time"
 )
 
@@ -36,3 +37,23 @@ func GetDefaultNetwork() Network {
 	n.Messages = GetDefaultMessage()
 	return n
 }
+
+func (n *Network) MarshalJSON() ([]byte, error) {
+	return json.Marshal(n)
+}
+
+func (n *Network) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, n)
+}
+
+// Obtain default Network parameters, or override with given parameters if set
+func GetNetworkParameters(params string) (Network, error) {
+	p := GetDefaultNetwork()
+	if len(params) > 0 {
+		err := p.UnmarshalJSON([]byte(params))
+		if err != nil {
+			return Network{}, err
+		}
+	}
+	return p, nil
+}
diff --git a/interfaces/params/node.go b/interfaces/params/node.go
deleted file mode 100644
index 150cc71f3..000000000
--- a/interfaces/params/node.go
+++ /dev/null
@@ -1,22 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright © 2020 xx network SEZC                                          //
-//                                                                           //
-// Use of this source code is governed by a license that can be found in the //
-// LICENSE file                                                              //
-///////////////////////////////////////////////////////////////////////////////
-
-package params
-
-//import (
-//	"time"
-//)
-
-type NodeKeys struct {
-	WorkerPoolSize uint
-}
-
-func GetDefaultNodeKeys() NodeKeys {
-	return NodeKeys{
-		WorkerPoolSize: 10,
-	}
-}
diff --git a/interfaces/params/rounds.go b/interfaces/params/rounds.go
index 73e5ac613..8370f7096 100644
--- a/interfaces/params/rounds.go
+++ b/interfaces/params/rounds.go
@@ -7,7 +7,10 @@
 
 package params
 
-import "time"
+import (
+	"encoding/json"
+	"time"
+)
 
 type Rounds struct {
 	// maximum number of times to attempt to retrieve a round from a gateway
@@ -39,3 +42,11 @@ func GetDefaultRounds() Rounds {
 		LookupRoundsBufferLen:     2000,
 	}
 }
+
+func (r *Rounds) MarshalJSON() ([]byte, error) {
+	return json.Marshal(r)
+}
+
+func (r *Rounds) UnmarshalJSON(b []byte) error {
+	return json.Unmarshal(b, r)
+}
diff --git a/network/message/critical.go b/network/message/critical.go
index c6dbfbd9f..e43cee7aa 100644
--- a/network/message/critical.go
+++ b/network/message/critical.go
@@ -44,7 +44,7 @@ func (m *Manager) processCriticalMessages(quitCh <-chan struct{}) {
 func (m *Manager) criticalMessages() {
 	critMsgs := m.Session.GetCriticalMessages()
 	// try to send every message in the critical messages and the raw critical
-	// messages buffer in paralell
+	// messages buffer in parallel
 
 	//critical messages
 	for msg, param, has := critMsgs.Next(); has; msg, param, has = critMsgs.Next() {
@@ -60,7 +60,7 @@ func (m *Manager) criticalMessages() {
 				return
 			}
 			jww.INFO.Printf("critical RoundIDs: %v", rounds)
-			//wait on the results to make sure the rounds were sucesfull
+			//wait on the results to make sure the rounds were successful
 			sendResults := make(chan ds.EventReturn, len(rounds))
 			roundEvents := m.Instance.GetRoundEvents()
 			for _, r := range rounds {
-- 
GitLab