diff --git a/network/params.go b/network/params.go index a36dcb018f4ae094388ea14b5285c839e9e09802..a4c4fa45e0c78082a6b37e0d0e3cabf402e2d9bc 100644 --- a/network/params.go +++ b/network/params.go @@ -1,6 +1,7 @@ package network import ( + "encoding/base64" "encoding/json" "gitlab.com/elixxir/client/network/historical" "gitlab.com/elixxir/client/network/message" @@ -98,6 +99,8 @@ func GetParameters(params string) (Params, error) { return p, nil } +type NodeMap map[id.ID]bool + type CMIXParams struct { // RoundTries is the maximum number of rounds to try to send on RoundTries uint @@ -118,8 +121,7 @@ type CMIXParams struct { // BlacklistedNodes is a list of nodes to not send to; will skip a round // with these nodes in it. - // TODO: Make it not omitted from JSON marshalling - BlacklistedNodes map[id.ID]bool `json:"-"` + BlacklistedNodes NodeMap // Critical indicates if the message is critical. The system will track that // the round it sends on completes and will auto resend in the event the @@ -137,7 +139,8 @@ func GetDefaultCMIXParams() CMIXParams { RetryDelay: 1 * time.Second, SendTimeout: 3 * time.Second, DebugTag: "External", - //unused single so components that require one have a channel to wait on + // Unused stoppable so components that require one have a channel to + // wait on Stop: stoppable.NewSingle("cmixParamsDefault"), } } @@ -154,3 +157,40 @@ func GetCMIXParameters(params string) (CMIXParams, error) { } return p, nil } + +// MarshalJSON adheres to the json.Marshaler interface. +func (nm NodeMap) MarshalJSON() ([]byte, error) { + stringMap := make(map[string]bool, len(nm)) + for nid, b := range nm { + stringMap[base64.StdEncoding.EncodeToString(nid.Marshal())] = b + } + + return json.Marshal(stringMap) +} + +// UnmarshalJSON adheres to the json.Unmarshaler interface. +func (nm *NodeMap) UnmarshalJSON(data []byte) error { + stringMap := make(map[string]bool) + err := json.Unmarshal(data, &stringMap) + if err != nil { + return err + } + + newNM := make(NodeMap) + for nidString, bString := range stringMap { + nidBytes, err := base64.StdEncoding.DecodeString(nidString) + if err != nil { + return err + } + nid, err := id.Unmarshal(nidBytes) + if err != nil { + return err + } + + newNM[*nid] = bString + } + + *nm = newNM + + return nil +} diff --git a/network/params_test.go b/network/params_test.go new file mode 100644 index 0000000000000000000000000000000000000000..c23f4e544a92cd0b1fb2c60ae7518c7cc274cd3d --- /dev/null +++ b/network/params_test.go @@ -0,0 +1,74 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 xx network SEZC // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file // +//////////////////////////////////////////////////////////////////////////////// + +package network + +import ( + "encoding/json" + "gitlab.com/xx_network/primitives/id" + "reflect" + "testing" + "time" +) + +func TestCMIXParams_JSON_Marshal_Unmarshal(t *testing.T) { + p := CMIXParams{ + RoundTries: 5, + Timeout: 3 * time.Second, + RetryDelay: 2 * time.Nanosecond, + SendTimeout: 24 * time.Hour, + DebugTag: "Tag", + BlacklistedNodes: NodeMap{ + *id.NewIdFromString("node0", id.Node, t): true, + *id.NewIdFromString("node1", id.Node, t): true, + *id.NewIdFromString("node2", id.Node, t): false, + *id.NewIdFromString("node3", id.Node, t): true, + }, + Critical: true, + } + + data, err := json.Marshal(p) + if err != nil { + t.Errorf("Failed to JSON marshal CMIXParams: %+v", err) + } + + var newP CMIXParams + err = json.Unmarshal(data, &newP) + if err != nil { + t.Errorf("Failed to JSON unmarshal CMIXParams: %+v", err) + } + + if !reflect.DeepEqual(p, newP) { + t.Errorf("Marshalled and unmarshalled CMIXParams does not match "+ + "original.\nexpected: %+v\nreceived: %+v", p, newP) + } +} + +func TestNodeMap_MarshalJSON_UnmarshalJSON(t *testing.T) { + nm := NodeMap{ + *id.NewIdFromString("node0", id.Node, t): true, + *id.NewIdFromString("node1", id.Node, t): true, + *id.NewIdFromString("node2", id.Node, t): false, + *id.NewIdFromString("node3", id.Node, t): true, + } + + data, err := json.Marshal(nm) + if err != nil { + t.Errorf("Failed to JSON marshal NodeMap: %+v", err) + } + + newNM := make(NodeMap) + err = json.Unmarshal(data, &newNM) + if err != nil { + t.Errorf("Failed to JSON unmarshal NodeMap: %+v", err) + } + + if !reflect.DeepEqual(nm, newNM) { + t.Errorf("Marshalled and unmarshalled NodeMap does not match original."+ + "\nexpected: %v\nreceived: %v", nm, newNM) + } +}