Skip to content
Snippets Groups Projects
Commit 5e49015e authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

wip implementation of nod ein cmd, tests need to be fixed

parent b9f4fd72
No related branches found
No related tags found
No related merge requests found
Showing with 115 additions and 156 deletions
......@@ -109,7 +109,7 @@ func GenerateRounds(nodeCount int, BatchSize uint64,
}
maxInt := grp.NewMaxInt()
// Run the GENERATION step
// RunFirstNode the GENERATION step
generations := make([]*services.ThreadController, nodeCount)
for i := 0; i < nodeCount; i++ {
// Since round.Z is generated on creation of the Generation precomp,
......@@ -344,7 +344,7 @@ func MultiNodePrecomp(nodeCount int, BatchSize uint64,
//go DecryptPermuteTranslate(decrypts[nodeCount-1].OutChannel,
// permutes[0].InChannel)
// Run Share -- Then save the result to both rounds
// RunFirstNode Share -- Then save the result to both rounds
// Note that the outchannel for N1Share is the input channel for N2share
shareMsg := services.Slot(&precomputation.SlotShare{
PartialRoundPublicCypherKey: grp.GetGCyclic()})
......@@ -593,7 +593,7 @@ func PrecompIterations(nodeCount int, batchSize uint64, iterations int) {
*/
}
// Run realtime simulation for given number of of iterations
// RunFirstNode realtime simulation for given number of of iterations
func RealtimeIterations(nodeCount int, batchSize uint64, iterations int) {
/* prime := large.NewInt(0)
prime.SetString(PRIME, 16)
......
......@@ -43,7 +43,7 @@ func init() {
var benchmarkCmd = &cobra.Command{
Use: "benchmark",
Short: "Server benchmarking tests",
Long: "Run internal benchmark funcs by specifying node & batch sizes",
Long: "RunFirstNode internal benchmark funcs by specifying node & batch sizes",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Running benchmarks for %d nodes with %d batch "+
"size and %d iterations...\n", nodeCount,
......
......@@ -8,7 +8,14 @@
package cmd
import (
"fmt"
"gitlab.com/elixxir/crypto/csprng"
"gitlab.com/elixxir/crypto/signature"
"gitlab.com/elixxir/server/globals"
"gitlab.com/elixxir/server/io"
"gitlab.com/elixxir/server/node"
"gitlab.com/elixxir/server/server"
"time"
//"encoding/binary"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/viper"
......@@ -22,7 +29,6 @@ import (
//"gitlab.com/elixxir/server/globals"
//"gitlab.com/elixxir/server/io"
"runtime"
"strings"
//"sync/atomic"
//"time"
)
......@@ -46,8 +52,6 @@ func StartServer(vip *viper.Viper) {
jww.FATAL.Println("Unable to load params from viper")
}
fmt.Printf("conf: %v\n", params.Index)
//Check that there is a gateway
if len(params.Gateways) < 1 {
// No gateways in config file or passed via command line
......@@ -56,80 +60,38 @@ func StartServer(vip *viper.Viper) {
return
}
//get the index of the server
// Initialize the backend
//dbAddress := params.Database.Addresses[serverIdx]
dbAddress := params.Database.Addresses[params.Index]
/*users := globals.NewUserRegistry(
userDatabase := globals.NewUserRegistry(
params.Database.Username,
params.Database.Password,
params.Database.Name,
dbAddress,
)*/
)
// Load group from viper
// TODO: when you go back to hook up the new round/DSA stuff to main,
// these should be assigned variables in there.
jww.INFO.Printf("%v", viper.GetStringMapString(
"cryptographicParameters.cMix"))
//Build DSA key
rng := csprng.NewSystemRNG()
grp := params.Groups.CMix
e2eGrp := params.Groups.E2E
// TODO: Add a Stringer interface to cyclic.Group
jww.INFO.Printf("cMix Group: %d", grp.GetFingerprint())
jww.INFO.Printf("E2E Group: %d", e2eGrp.GetFingerprint())
jww.INFO.Print("Server list: " + strings.Join(params.NodeAddresses, ","))
// Start mix servers on localServer
localServer := params.NodeAddresses[serverIdx]
jww.INFO.Printf("Starting server on %v\n", localServer)
// ensure that the Node ID is populated
// viperNodeID := uint64(viper.GetInt("nodeid"))
// nodeIDbytes := make([]byte, binary.MaxVarintLen64)
// var num int
// if viperNodeID == 0 {
// num = binary.PutUvarint(nodeIDbytes, uint64(serverIndex))
// } else {
// num = binary.PutUvarint(nodeIDbytes, viperNodeID)
// }
//globals.ID = new(id.Node).SetBytes(nodeIDbytes[:num])
// Set skipReg from config file
//globals.SkipRegServer = viper.GetBool("skipReg")
// certPath := viper.GetString("certPath")
// keyPath := viper.GetString("keyPath")
// gatewayCertPath := viper.GetString("gatewayCertPath")
// Set the certPaths explicitly to avoid data races
//connect.ServerCertPath = certPath
//connect.GatewayCertPath = gatewayCertPath
// Kick off Comms server
//go node.StartServer(localServer, io.NewServerImplementation(),
// certPath, keyPath)
// TODO Replace these concepts with a better system
//globals.IsLastNode = serverIndex == len(io.Servers)-1
//io.NextServer = io.Servers[(serverIndex+1)%len(io.Servers)]
// Block until we can reach every server
//io.VerifyServersOnline()
//globals.RoundRecycle = make(chan *globals.Round, PRECOMP_BUFFER_SIZE)
// Run as many as half the number of nodes times the number of
// passthroughs (which is 4).
//numPrecompSimultaneous = int((uint64(len(io.Servers)) * 4) / 2)
//if globals.IsLastNode {
// realtimeSignal := &sync.Cond{L: &sync.Mutex{}}
// io.RoundCh = make(chan *string, PRECOMP_BUFFER_SIZE)
// io.MessageCh = make(chan *realtime.Slot, messageBufferSize)
// // Last Node handles when realtime and precomp get run
// go RunRealTime(batchSize, io.MessageCh, io.RoundCh, realtimeSignal)
// go RunPrecomputation(io.RoundCh, realtimeSignal)
//}
// Main loop
//run()
dsaParams := signature.CustomDSAParams(grp.GetP(), grp.GetQ(), grp.GetG())
privKey := dsaParams.PrivateKeyGen(rng)
pubKey := privKey.PublicKeyGen()
// Create instance
instance := server.CreateServerInstance(params, userDatabase, pubKey, privKey)
// initialize the network
instance.InitNetwork(node.NewImplementation)
//FIXME: check that all other nodes are online
//Begin the resource queue
instance.Run()
//Start runners for first node
if instance.IsFirstNode() {
instance.InitFirstNode()
instance.RunFirstNode(instance.GetNetwork(), instance.GetTopology(),
5*time.Second, io.TransmitCreateNewRound)
}
}
......@@ -293,7 +293,7 @@ func TestDecryptGraph(t *testing.T) {
KeysADExpected := grp.NewIntBuffer(g.GetExpandedBatchSize(), grp.NewInt(1))
CypherADExpected := grp.NewIntBuffer(g.GetExpandedBatchSize(), grp.NewInt(1))
//Run the graph
//RunFirstNode the graph
g.Run()
//Send inputs into the graph
......
......@@ -164,7 +164,7 @@ func TestGenerateGraph(t *testing.T) {
//stream := g.GetStream().(*GenerateStream)
//Run the graph
//RunFirstNode the graph
g.Run()
//Send inputs into the graph
......
......@@ -263,9 +263,7 @@ func TestReveal_Graph(t *testing.T) {
}
// Run the graph
// RunFirstNode the graph
g.Run()
// Send inputs into the graph
......
......@@ -196,7 +196,7 @@ func TestShare_Graph(t *testing.T) {
// Build i/o used for testing
PubicCypherKeyExpected := grp.ExpG(roundBuffer.Z, grp.NewInt(1))
// Run the graph
// RunFirstNode the graph
g.Run()
// Send inputs into the graph
......
......@@ -256,7 +256,6 @@ func TestStrip_Graph(t *testing.T) {
stream := g.GetStream().(*StripStream)
CypherMsgExpected := grp.NewIntBuffer(g.GetExpandedBatchSize(), grp.NewInt(1))
CypherADExpected := grp.NewIntBuffer(g.GetExpandedBatchSize(), grp.NewInt(1))
......@@ -275,7 +274,7 @@ func TestStrip_Graph(t *testing.T) {
MessagePrecomputationExpected := grp.NewIntBuffer(g.GetExpandedBatchSize(), grp.NewInt(1))
ADPrecomputationExpected := grp.NewIntBuffer(g.GetExpandedBatchSize(), grp.NewInt(1))
// Run the graph
// RunFirstNode the graph
g.Run()
// Send inputs into the graph
......@@ -302,7 +301,6 @@ func TestStrip_Graph(t *testing.T) {
cryptops.RootCoprime(s.Grp, CypherADExpected.Get(i), s.Z, tmp)
s.Grp.Set(CypherADExpected.Get(i), tmp)
// Compute inverse
cryptops.Inverse(s.Grp, MessagePrecomputationExpected.Get(i), MessagePrecomputationExpected.Get(i))
cryptops.Inverse(s.Grp, ADPrecomputationExpected.Get(i), ADPrecomputationExpected.Get(i))
......
......@@ -12,8 +12,8 @@ import (
// TransmitCreateNewRound is run on first node to tell other nodes to create the
// round. It does not follow the transmitter interface because it is run
// custom through the first node runner.
func TransmitCreateNewRound(network *node.NodeComms, roundID id.Round,
topology *circuit.Circuit) error {
func TransmitCreateNewRound(network *node.NodeComms,
topology *circuit.Circuit, roundID id.Round) error {
//Every node receives the same roundInfo
roundInfo := &mixmessages.RoundInfo{ID: uint64(roundID)}
......
......@@ -44,7 +44,7 @@ func TestTransmitCreateNewRound(t *testing.T) {
ln := server.LastNode{}
ln.Initialize()
err := TransmitCreateNewRound(comms[0], rndID, topology)
err := TransmitCreateNewRound(comms[0], topology, rndID)
if err != nil {
t.Errorf("TransmitFinishRealtime: Unexpected error: %+v", err)
......@@ -94,7 +94,7 @@ func TestTransmitCreateNewRound_Error(t *testing.T) {
ln := server.LastNode{}
ln.Initialize()
err := TransmitCreateNewRound(comms[0], rndID, topology)
err := TransmitCreateNewRound(comms[0], topology, rndID)
if err == nil {
t.Error("SendFinishRealtime: error did not occur when provoked")
......
......@@ -97,7 +97,7 @@ func TestEndToEndCryptopsWith2Nodes(t *testing.T) {
go benchmark.PermuteEncryptTranslate(N2Permute.OutChannel, N1Encrypt.InChannel,
Node2Round, grp)
// Run Generate
// RunFirstNode Generate
genMsg := services.Slot(&precomputation.SlotGeneration{Slot: 0})
N1Generation.InChannel <- &genMsg
_ = <-N1Generation.OutChannel
......@@ -110,7 +110,7 @@ func TestEndToEndCryptopsWith2Nodes(t *testing.T) {
// TODO: Pre-can the keys to use here if necessary.
// Run Share -- Then save the result to both rounds
// RunFirstNode Share -- Then save the result to both rounds
// Note that the outchannel for N1Share is the input channel for N2share
shareMsg := services.Slot(&precomputation.SlotShare{
PartialRoundPublicCypherKey: grp.GetGCyclic()})
......
......@@ -21,20 +21,16 @@ type Params struct {
Index int
Database DB
SkipReg bool `yaml:"skipReg"`
Path Paths
//Network Identity Params
Batch uint32
Groups Groups
Paths Paths
NodeAddresses []string
// these are base64 strings, so instance creation must base64 decode these
// before using them as node IDs
NodeIDs []string
Gateways []string
Batch uint32
// Public and private keys
PublicKey string
PrivateKey string
}
// NewParams returns a params object if it is able to
......@@ -53,22 +49,18 @@ func NewParams(vip *viper.Viper) (*Params, error) {
params.SkipReg = vip.GetBool("skipReg")
params.Path.Cert = vip.GetString("path.cert")
params.Path.GatewayCert = vip.GetString("path.gateway_cert")
params.Path.Key = vip.GetString("path.key")
params.Path.Log = vip.GetString("path.log")
params.Batch = vip.GetUint32("batch")
params.Groups.CMix = toGroup(vip.GetStringMapString("groups.cmix"))
params.Groups.E2E = toGroup(vip.GetStringMapString("groups.e2e"))
params.Paths.Cert = vip.GetString("cert")
params.Paths.Key = vip.GetString("key")
params.Paths.Log = vip.GetString("log")
params.NodeAddresses = vip.GetStringSlice("nodeAddresses")
params.NodeIDs = vip.GetStringSlice("nodeIDs")
params.Gateways = vip.GetStringSlice("gateways")
params.Batch = vip.GetUint32("batch")
params.PublicKey = vip.GetString("publicKey")
params.PrivateKey = vip.GetString("privateKey")
params.Groups = NewGroups(vip)
return &params, nil
}
......@@ -37,6 +37,7 @@ gateways:
- "127.0.0.1:80"
- "127.0.0.1:80"
batch: 20
dsakey:
publicKey: "pubkey"
privateKey: "privkey"
...
\ No newline at end of file
......@@ -16,7 +16,7 @@ func TestNewParams_ReturnsParamsWhenGivenValidViper(t *testing.T) {
expectedParams := Params{
Database: ExpectedDB,
Groups: ExpectedGroups,
Paths: ExpectedPaths,
Path: ExpectedPaths,
NodeAddresses: []string{"127.0.0.1:80", "127.0.0.1:80",
"127.0.0.1:80"},
Gateways: []string{"127.0.0.1:80", "127.0.0.1:80", "127.0.0.1:80"},
......@@ -78,7 +78,7 @@ func TestNewParams_ReturnsParamsWhenGivenValidViper(t *testing.T) {
t.Errorf("Groups object did not match expected values for CMIX")
}
if !reflect.DeepEqual(expectedParams.Paths, params.Paths) {
if !reflect.DeepEqual(expectedParams.Path, params.Path) {
t.Errorf("Paths value does not match expected value")
}
......
......@@ -12,6 +12,7 @@ package conf
// and have this one contain the actual file obj
type Paths struct {
Cert string
GatewayCert string
Key string
Log string
}
......@@ -17,6 +17,7 @@ var ExpectedPaths = Paths{
Cert: "~/.elixxir/cert.crt",
Key: "~/.elixxir/key.pem",
Log: "~/.elixxir/server.log",
GatewayCert: "~/.elixxir/gateway.log",
}
// This test checks that unmarshalling the path.yaml file
......@@ -31,7 +32,7 @@ func TestPaths_UnmarshallingFileEqualsExpected(t *testing.T) {
t.Errorf("Unable to decode into struct, %v", err)
}
if !reflect.DeepEqual(ExpectedPaths, actual.Paths) {
if !reflect.DeepEqual(ExpectedPaths, actual.Path) {
t.Errorf("Paths object did not match ExpectedPaths values")
}
......
......@@ -29,10 +29,10 @@ type firstNode struct {
// to create the round
type RoundCreationTransmitter func(*node.NodeComms, *circuit.Circuit, id.Round) error
// Run is a long running process on the first node which creates new rounds at
// RunFirstNode is a long running process on the first node which creates new rounds at
// the correct time. It can only be called once. It is passed a function through
// which to interface with the network
func (fn *firstNode) Run(network *node.NodeComms,
func (fn *firstNode) RunFirstNode(network *node.NodeComms,
topology *circuit.Circuit, fullRoundTimeout time.Duration,
transmitter RoundCreationTransmitter) {
fn.runOnce.Do(
......
......@@ -5,10 +5,10 @@ import (
"fmt"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/comms/connect"
"gitlab.com/elixxir/comms/node"
"gitlab.com/elixxir/crypto/csprng"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/large"
"gitlab.com/elixxir/crypto/signature"
"gitlab.com/elixxir/primitives/circuit"
"gitlab.com/elixxir/primitives/id"
......@@ -27,13 +27,12 @@ type Instance struct {
userReg globals.UserRegistry
pubKey *signature.DSAPublicKey
privKey *signature.DSAPrivateKey
regPubKey *signature.DSAPublicKey
topology *circuit.Circuit
thisNode *id.Node
graphGenerator services.GraphGenerator
firstNode
LastNode
params conf.Params
params *conf.Params
}
func (i *Instance) GetTopology() *circuit.Circuit {
......@@ -79,18 +78,14 @@ func (i *Instance) GetPrivKey() *signature.DSAPrivateKey {
return i.privKey
}
//GetRegPubKey returns the registration server DSA public key
func (i *Instance) GetRegPubKey() *signature.DSAPublicKey {
return i.regPubKey
}
//GetSkipReg returns the skipReg parameter
func (i *Instance) GetSkipReg() bool {
return i.params.SkipReg
}
//GetBatchSize returns the batch size
func (i *Instance) GetBatchSize() uint32 {
return i.params.BatchSize
return i.params.Batch
}
// FIXME Populate this from the YAML or something
......@@ -108,9 +103,22 @@ func (i *Instance) InitLastNode() {
i.LastNode.Initialize()
}
//IsFirstNode returns if the node is first node
func (i *Instance) IsFirstNode() bool {
return i.topology.IsFirstNode(i.thisNode)
}
//IsLastNode returns if the node is last node
func (i *Instance) IsLastNode() bool {
return i.topology.IsLastNode(i.thisNode)
}
// Create a server instance. To actually kick off the server,
// call Run() on the resulting ServerInstance.
func CreateServerInstance(params conf.Params, db globals.UserRegistry) *Instance {
// call RunFirstNode() on the resulting ServerInstance.
func CreateServerInstance(params *conf.Params, db globals.UserRegistry,
publicKey *signature.DSAPublicKey, privateKey *signature.DSAPrivateKey) *Instance {
//TODO: build system wide error handeling
PanicHandler := func(g, m string, err error) {
panic(fmt.Sprintf("Error in module %s of graph %s: %s", g, m, err.Error()))
}
......@@ -144,25 +152,13 @@ func CreateServerInstance(params conf.Params, db globals.UserRegistry) *Instance
jww.ERROR.Panic("One or more node IDs didn't base64 decode correctly")
}
instance.topology = circuit.New(nodeIDs)
instance.thisNode = instance.topology.GetNodeAtIndex(params.ThisNodeIndex)
instance.thisNode = instance.topology.GetNodeAtIndex(params.Index)
// Create a node id object with the random bytes
// Generate DSA Private/Public key pair
rng := csprng.NewSystemRNG()
grp := params.Groups.CMix
dsaParams := signature.CustomDSAParams(grp.GetP(), grp.GetQ(), grp.GetG())
instance.privKey = dsaParams.PrivateKeyGen(rng)
instance.pubKey = instance.privKey.PublicKeyGen()
instance.pubKey = publicKey
instance.privKey = privateKey
// Hardcoded registration server publicKey
instance.regPubKey = signature.ReconstructPublicKey(dsaParams,
large.NewIntFromString("1ae3fd4e9829fb464459e05bca392bec5067152fb43a569ad3c3b68bbcad84f0"+
"ff8d31c767da3eabcfc0870d82b39568610b52f2b72b493bbede6e952c9a7fd4"+
"4a8161e62a9046828c4a65f401b2f054ebf7376e89dab547d8a3c3d46891e78a"+
"cfc4015713cbfb5b0b6cab0f8dfb46b891f3542046ace4cab984d5dfef4f52d4"+
"347dc7e52f6a7ea851dda076f0ed1fef86ec6b5c2a4807149906bf8e0bf70b30"+
"1147fea88fd95009edfbe0de8ffc1a864e4b3a24265b61a1c47a4e9307e7c84f"+
"9b5591765b530f5859fa97b22ce9b51385d3d13088795b2f9fd0cb59357fe938"+
"346117df2acf2bab22d942de1a70e8d5d62fc0e99d8742a0f16df94ce3a0abbb", 16))
// TODO: For now set this to false, but value should come from config file
instance.params.SkipReg = false
......@@ -191,17 +187,27 @@ func GenerateId() *id.Node {
return nid
}
// TODO(sb) Should there be a version of this that uses the network definition
// file to create all the connections in the network?
// Initializes the network on this server instance
// After the network object is created, you still need to use it to connect
// to other servers in the network using ConnectToNode or ConnectToGateway.
// Additionally, to clean up the network object (especially in tests), call
// Shutdown() on the network object.
func (i *Instance) InitNetwork(addr string,
makeImplementation func(*Instance) *node.Implementation,
certPath string, keyPath string) *node.NodeComms {
i.network = node.StartNode(addr, makeImplementation(i), certPath, keyPath)
func (i *Instance) InitNetwork(
makeImplementation func(*Instance) *node.Implementation) *node.NodeComms {
addr := i.params.NodeAddresses[i.params.Index]
i.network = node.StartNode(addr, makeImplementation(i), i.params.Path.Cert,
i.params.Path.Key)
tlsCert := connect.NewCredentialsFromFile(i.params.Path.Cert, "")
for x := 0; x < len(i.params.NodeIDs); x++ {
i.network.ConnectToNode(i.topology.GetNodeAtIndex(x), i.params.NodeAddresses[x],
tlsCert)
}
i.network.ConnectToGateway(i.thisNode.NewGateway(),
i.params.Gateways[i.params.Index], tlsCert)
return i.network
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment