diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ace4829d5840be78e594ad6aaf9f42ec74174d2f..e34283de662aeddaa855cfaf713d3d938ed17670 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,12 +6,6 @@ cache: paths: - vendor/ -variables: - REPO_DIR: gitlab.com/elixxir - REPO_NAME: registration - DOCKER_IMAGE: elixxirlabs/cuda-go:go1.16-cuda11.1 - MIN_CODE_COVERAGE: "0.0" - before_script: - go version || echo "Go executable not found." - echo $CI_BUILD_REF diff --git a/README.md b/README.md index 3e8b9d1c0bf7664cfbaa897c11adc4eb06bc5b5a..abbbf72c068d05c587473907f891b5e09e4d8fe3 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,12 @@ logLevel: 1 # Path to log file logPath: "registration.log" -# Path to the node topology permissioning info -ndfOutputPath: "ndf.json" +# Path to the node topology permissioning info. Contains the full NDF. +fullNdfOutputPath: "ndf.json" + +# Path to the signed partial ndf uploaded to the Internet for clients +# to pull from. +signedPartialNDFOutputPath: "signedPartial.txt" # Path to JSON containing list of IDs exempt from rate limiting whitelistedIdsPath: "whitelistedIds.json" @@ -171,9 +175,8 @@ Note: All times in MS "BatchSize": 64, "MinimumDelay": 60, "RealtimeDelay": 3000, - "Threshold": 10, + "Threshold": 0.3, "NodeCleanUpInterval": 180000, - "Secure": true, "PrecomputationTimeout": 30000, "RealtimeTimeout": 15000, "ResourceQueueTimeout": 180000, diff --git a/cmd/addressSpaceUpdate_test.go b/cmd/addressSpaceUpdate_test.go index 2eb8c6ca248d5d51dec0052972137349d9816109..5274eb2a094e25415f9565306f7a2353f18e845c 100644 --- a/cmd/addressSpaceUpdate_test.go +++ b/cmd/addressSpaceUpdate_test.go @@ -32,7 +32,7 @@ func TestRegistrationImpl_updateAddressSpace(t *testing.T) { } // Create a new state - state, err := storage.NewState(getTestKey(), 8, "", region.GetCountryBins(), nil, nil) + state, err := storage.NewState(getTestKey(), 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Unable to create state: %+v", err) } @@ -94,7 +94,7 @@ func TestRegistrationImpl_updateAddressSpace_NoUpdates(t *testing.T) { } // Create a new state - state, err := storage.NewState(getTestKey(), 8, "", region.GetCountryBins(), nil, nil) + state, err := storage.NewState(getTestKey(), 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Unable to create state: %+v", err) } diff --git a/cmd/bannedNodeTracker_test.go b/cmd/bannedNodeTracker_test.go index 9bbbb5ef1f194768959e0b79b87c0ea453e2b092..507358f7273ac8c5904e19d25a82e66b25b0822c 100644 --- a/cmd/bannedNodeTracker_test.go +++ b/cmd/bannedNodeTracker_test.go @@ -29,7 +29,7 @@ func TestBannedNodeTracker(t *testing.T) { // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) impl := &RegistrationImpl{ State: testState, NDFLock: sync.Mutex{}, diff --git a/cmd/impl.go b/cmd/impl.go index f2b52ff48b0ef6b7594ff71ffc13d58ecc9e6536..5086d88386a3b4236f01860d1b0fe4dbab64c092 100644 --- a/cmd/impl.go +++ b/cmd/impl.go @@ -34,15 +34,16 @@ import ( // The main registration instance object type RegistrationImpl struct { - Comms *registration.Comms - params *Params - schedulingParams *scheduling.SafeParams - State *storage.NetworkState - Stopped *uint32 - permissioningCert *x509.Certificate - ndfOutputPath string - NdfReady *uint32 - certFromFile string + Comms *registration.Comms + params *Params + schedulingParams *scheduling.SafeParams + State *storage.NetworkState + Stopped *uint32 + permissioningCert *x509.Certificate + fullNdfOutputPath string + signedPartialNdfOutputPath string + NdfReady *uint32 + certFromFile string // registration status trackers numRegistered int @@ -125,7 +126,7 @@ func StartRegistration(params Params) (*RegistrationImpl, error) { // Build default parameters regImpl := &RegistrationImpl{ params: ¶ms, - ndfOutputPath: params.NdfOutputPath, + fullNdfOutputPath: params.FullNdfOutputPath, NdfReady: &ndfReady, Stopped: &roundCreationStopped, numRegistered: 0, @@ -180,7 +181,6 @@ func StartRegistration(params Params) (*RegistrationImpl, error) { whitelistedIpAddresses := make([]string, 0) if regImpl.params.WhitelistedIpAddressPath != "" { - // Load whitelisted IP addresses file whitelistFile, err := utils.ReadFile(regImpl.params.WhitelistedIpAddressPath) if err != nil { @@ -191,6 +191,8 @@ func StartRegistration(params Params) (*RegistrationImpl, error) { err = json.Unmarshal(whitelistFile, &whitelistedIpAddresses) if err != nil { jww.WARN.Printf("Could not unmarshal whitelisted IP addresses: %v", err) + } else { + jww.INFO.Printf("Added whitelisted IPs: %+v", whitelistedIpAddresses) } } @@ -198,7 +200,7 @@ func StartRegistration(params Params) (*RegistrationImpl, error) { // Initialize the state tracking object regImpl.State, err = storage.NewState(rsaPrivateKey, uint32(newestAddressSpace.Size), - params.NdfOutputPath, geoBins, whitelistedIds, whitelistedIpAddresses) + params.FullNdfOutputPath, params.SignedPartialNdfOutputPath, geoBins) if err != nil { return nil, err } diff --git a/cmd/nodeMetricTracker.go b/cmd/nodeMetricTracker.go index 79c7d760e2fa69df3711952f82f5d6c1a48c3af8..2a37e2e5a6b65b67ae909250a9e08e1c141dd95e 100644 --- a/cmd/nodeMetricTracker.go +++ b/cmd/nodeMetricTracker.go @@ -72,8 +72,9 @@ func TrackNodeMetrics(impl *RegistrationImpl, quitChan chan struct{}, nodeMetric err = json.Unmarshal(whitelistedIpAddressesFile, &whitelistedIpAddresses) if err != nil { jww.ERROR.Printf("Could not unmarshal whitelisted IP addresses: %v", err) + } else { + jww.INFO.Printf("Added whitelisted IPs: %+v", whitelistedIpAddresses) } - } // Keep track of stale/pruned nodes diff --git a/cmd/nodeMetricTracker_test.go b/cmd/nodeMetricTracker_test.go index 22bf2a7f2aebb4da90ec44baa63803d1b765b135..537ed091aa8898e42731ba2079fe1ea88683612a 100644 --- a/cmd/nodeMetricTracker_test.go +++ b/cmd/nodeMetricTracker_test.go @@ -36,7 +36,7 @@ func TestTrackNodeMetrics(t *testing.T) { testParams.pruneRetentionLimit = 24 * time.Hour testParams.disableNDFPruning = false // Create a new state - state, err := storage.NewState(getTestKey(), 8, "", region.GetCountryBins(), nil, nil) + state, err := storage.NewState(getTestKey(), 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Unable to create state: %+v", err) } diff --git a/cmd/params.go b/cmd/params.go index 2b99bb2278b3414b052eef753c141d0c54bf195b..fba9b62ce9f787fa7d9a291332f0b430b0ec857c 100644 --- a/cmd/params.go +++ b/cmd/params.go @@ -20,14 +20,15 @@ import ( // Params object for reading in configuration data type Params struct { - Address string - CertPath string - KeyPath string - NdfOutputPath string - NsCertPath string - NsAddress string - WhitelistedIdsPath string - WhitelistedIpAddressPath string + Address string + CertPath string + KeyPath string + FullNdfOutputPath string + SignedPartialNdfOutputPath string + NsCertPath string + NsAddress string + WhitelistedIdsPath string + WhitelistedIpAddressPath string cmix ndf.Group e2e ndf.Group diff --git a/cmd/permissioning_test.go b/cmd/permissioning_test.go index fa1374f4e4f216249924ca520455b11e49139012..23e4b6a9ff62a45c6559eadede8d175b4eeb9aaa 100644 --- a/cmd/permissioning_test.go +++ b/cmd/permissioning_test.go @@ -78,7 +78,7 @@ func TestLoadAllRegisteredNodes(t *testing.T) { testParams := Params{ CertPath: testkeys.GetCACertPath(), KeyPath: testkeys.GetCAKeyPath(), - NdfOutputPath: testkeys.GetNDFPath(), + FullNdfOutputPath: testkeys.GetNDFPath(), udbCertPath: testkeys.GetUdbCertPath(), NsCertPath: testkeys.GetUdbCertPath(), WhitelistedIdsPath: testkeys.GetPreApprovedPath(), diff --git a/cmd/poll.go b/cmd/poll.go index deb9fe31e6322541801f9cc8b18a60197d727ffe..4d205f7a5685a50e87840c122b966b77a3d1f5f9 100644 --- a/cmd/poll.go +++ b/cmd/poll.go @@ -421,7 +421,8 @@ func (m *RegistrationImpl) checkConnectivity(n *node.State, nodeIpAddr string, gwID.SetType(id.Gateway) params := connect.GetDefaultHostParams() params.AuthEnabled = false - gwHost, err := connect.NewHost(gwID, n.GetGatewayAddress(), nil, params) + nDb, err := storage.PermissioningDb.GetNodeById(n.GetID()) + gwHost, err := connect.NewHost(gwID, n.GetGatewayAddress(), []byte(nDb.GatewayCertificate), params) //ping the gateway _, isOnline = gwHost.IsOnline() diff --git a/cmd/poll_test.go b/cmd/poll_test.go index 52bd1e256f5f27402e7246977acaf545e95b5b76..32d306942db3c1b6e769462978e567442bc51eaf 100644 --- a/cmd/poll_test.go +++ b/cmd/poll_test.go @@ -994,7 +994,7 @@ func TestVerifyError(t *testing.T) { // Start registration server ndfReady := uint32(0) - state, err := storage.NewState(pk, 8, "", region.GetCountryBins(), nil, nil) + state, err := storage.NewState(pk, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Unable to create state: %+v", err) } diff --git a/cmd/registration_test.go b/cmd/registration_test.go index 3fd4c6c3bd3ea4a3a012825c07d854830853dd73..afad839df7cb80de7b93e5bfbe5edb7c80261e16 100644 --- a/cmd/registration_test.go +++ b/cmd/registration_test.go @@ -14,6 +14,7 @@ import ( "gitlab.com/elixxir/registration/storage" "gitlab.com/elixxir/registration/storage/node" "gitlab.com/elixxir/registration/testkeys" + "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/utils" "os" @@ -35,6 +36,9 @@ var dblck sync.Mutex func TestMain(m *testing.M) { jww.SetStdoutThreshold(jww.LevelDebug) + + connect.TestingOnlyDisableTLS = true + var err error nodeCert, err = utils.ReadFile(testkeys.GetNodeCertPath()) if err != nil { @@ -65,7 +69,7 @@ func TestMain(m *testing.M) { Address: permAddr, CertPath: testkeys.GetCACertPath(), KeyPath: testkeys.GetCAKeyPath(), - NdfOutputPath: testkeys.GetNDFPath(), + FullNdfOutputPath: testkeys.GetNDFPath(), publicAddress: permAddr, udbCertPath: testkeys.GetUdbCertPath(), NsCertPath: testkeys.GetUdbCertPath(), diff --git a/cmd/root.go b/cmd/root.go index c57fabe8ca262917987a93d886b9c8965b05ea51..006cf02b248beddd99e1f03551db2cb3ca54de4f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -86,7 +86,8 @@ var rootCmd = &cobra.Command{ keyPath := viper.GetString("keyPath") localAddress := fmt.Sprintf("0.0.0.0:%d", viper.GetInt("port")) - ndfOutputPath := viper.GetString("ndfOutputPath") + fullNdfOutputPath := viper.GetString("fullNdfOutputPath") + signedPartialNdfOutputPath := viper.GetString("signedPartialNDFOutputPath") whitelistedIdsPath := viper.GetString("whitelistedIdsPath") whitelistedIpAddressesPath := viper.GetString("whitelistedIpAddressesPath") @@ -207,34 +208,35 @@ var rootCmd = &cobra.Command{ // Populate params RegParams = Params{ - Address: localAddress, - CertPath: certPath, - KeyPath: keyPath, - NdfOutputPath: ndfOutputPath, - WhitelistedIdsPath: whitelistedIdsPath, - WhitelistedIpAddressPath: whitelistedIpAddressesPath, - NsCertPath: nsCertPath, - NsAddress: nsAddress, - cmix: *cmix, - e2e: *e2e, - publicAddress: publicAddress, - clientRegistrationAddress: clientRegistration, - schedulingKillTimeout: schedulingKillTimeout, - closeTimeout: closeTimeout, - minimumNodes: viper.GetUint32("minimumNodes"), - udbId: udbId, - udbDhPubKey: udbDhPubKey, - udbCertPath: udbCertPath, - udbAddress: udbAddress, - minGatewayVersion: minGatewayVersion, - minServerVersion: minServerVersion, - minClientVersion: minClientVersion, - addressSpaceSize: uint8(viper.GetUint("addressSpace")), - allowLocalIPs: viper.GetBool("allowLocalIPs"), - disableGeoBinning: viper.GetBool("disableGeoBinning"), - blockchainGeoBinning: viper.GetBool("blockchainGeoBinning"), - onlyScheduleActive: viper.GetBool("onlyScheduleActive"), - enableBlockchain: viper.GetBool("enableBlockchain"), + Address: localAddress, + CertPath: certPath, + KeyPath: keyPath, + FullNdfOutputPath: fullNdfOutputPath, + SignedPartialNdfOutputPath: signedPartialNdfOutputPath, + WhitelistedIdsPath: whitelistedIdsPath, + WhitelistedIpAddressPath: whitelistedIpAddressesPath, + NsCertPath: nsCertPath, + NsAddress: nsAddress, + cmix: *cmix, + e2e: *e2e, + publicAddress: publicAddress, + clientRegistrationAddress: clientRegistration, + schedulingKillTimeout: schedulingKillTimeout, + closeTimeout: closeTimeout, + minimumNodes: viper.GetUint32("minimumNodes"), + udbId: udbId, + udbDhPubKey: udbDhPubKey, + udbCertPath: udbCertPath, + udbAddress: udbAddress, + minGatewayVersion: minGatewayVersion, + minServerVersion: minServerVersion, + minClientVersion: minClientVersion, + addressSpaceSize: uint8(viper.GetUint("addressSpace")), + allowLocalIPs: viper.GetBool("allowLocalIPs"), + disableGeoBinning: viper.GetBool("disableGeoBinning"), + blockchainGeoBinning: viper.GetBool("blockchainGeoBinning"), + onlyScheduleActive: viper.GetBool("onlyScheduleActive"), + enableBlockchain: viper.GetBool("enableBlockchain"), disableNDFPruning: viper.GetBool("disableNDFPruning"), geoIPDBFile: viper.GetString("geoIPDBFile"), @@ -407,10 +409,11 @@ var rootCmd = &cobra.Command{ } stopOnce.Do(stopRounds) stopForKillOnce.Do(stopForKill) + impl.Comms.Shutdown() } ReceiveUSR2Signal(stopEverything) - // Block forever on Signal Handler for safe program exit + // Open Signal Handler for safe program exit stopCh := ReceiveExitSignal() // Block forever to prevent the program ending diff --git a/cmd/version.go b/cmd/version.go index c0500d744414f273c20da9dec06d8f41dcf6fbbf..790e8d85d00d7a357c5de22917058250daf5f7f0 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -16,7 +16,7 @@ import ( ) // Change this value to set the version for this build -const currentVersion = "3.3.0" +const currentVersion = "3.4.0" func printVersion() { fmt.Printf("xx network Permissioning Server v%s -- %s\n\n", diff --git a/cmd/version_vars.go b/cmd/version_vars.go index f68424a2fc69b84f713b2ac7df67b9707c15c7ee..70ce6602d6bfe9ac13e37556dbcd9a180f8d52db 100644 --- a/cmd/version_vars.go +++ b/cmd/version_vars.go @@ -1,10 +1,10 @@ // Code generated by go generate; DO NOT EDIT. // This file was generated by robots at -// 2021-11-11 13:01:22.955006 -0600 CST m=+0.046409656 +// 2022-01-04 12:42:27.697455 -0600 CST m=+0.023805863 package cmd -const GITVERSION = `19f2713 Merge branch 'hotfix/CompletedTS' into 'release'` -const SEMVER = "3.3.0" +const GITVERSION = `9b51133 Merge branch 'dev' into 'release'` +const SEMVER = "3.4.0" const DEPENDENCIES = `module gitlab.com/elixxir/registration go 1.13 @@ -26,12 +26,13 @@ require ( github.com/spf13/cobra v1.1.3 github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/viper v1.7.1 - gitlab.com/elixxir/comms v0.0.4-0.20211101174956-590ba1b47887 - gitlab.com/elixxir/crypto v0.0.7-0.20211022013957-3a7899285c4c - gitlab.com/elixxir/primitives v0.0.3-0.20211102233208-a716d5c670b6 - gitlab.com/xx_network/comms v0.0.4-0.20211014163953-e774276b83ae - gitlab.com/xx_network/crypto v0.0.5-0.20211014163843-57b345890686 - gitlab.com/xx_network/primitives v0.0.4-0.20211014163031-53405cf191fb + gitlab.com/elixxir/comms v0.0.4-0.20220104174855-044783c5c1e6 + gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553 + gitlab.com/elixxir/primitives v0.0.3-0.20220104173924-275cb9d7834f + gitlab.com/xx_network/comms v0.0.4-0.20211227194445-c099754b3cda + gitlab.com/xx_network/crypto v0.0.5-0.20211227194420-f311e8920467 + gitlab.com/xx_network/primitives v0.0.4-0.20211222205802-03e9d7d835b0 google.golang.org/genproto v0.0.0-20210315173758-2651cd453018 // indirect + google.golang.org/protobuf v1.27.1 ) ` diff --git a/go.mod b/go.mod index 79181a74fa3aae16e62798afdaec6da3d6419b56..ba9645e4cccbaedb49f5ea94342df187269d8041 100644 --- a/go.mod +++ b/go.mod @@ -19,11 +19,12 @@ require ( github.com/spf13/cobra v1.1.3 github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/viper v1.7.1 - gitlab.com/elixxir/comms v0.0.4-0.20211101174956-590ba1b47887 - gitlab.com/elixxir/crypto v0.0.7-0.20211022013957-3a7899285c4c - gitlab.com/elixxir/primitives v0.0.3-0.20211102233208-a716d5c670b6 - gitlab.com/xx_network/comms v0.0.4-0.20211014163953-e774276b83ae - gitlab.com/xx_network/crypto v0.0.5-0.20211014163843-57b345890686 - gitlab.com/xx_network/primitives v0.0.4-0.20211014163031-53405cf191fb + gitlab.com/elixxir/comms v0.0.4-0.20220104174855-044783c5c1e6 + gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553 + gitlab.com/elixxir/primitives v0.0.3-0.20220104173924-275cb9d7834f + gitlab.com/xx_network/comms v0.0.4-0.20211227194445-c099754b3cda + gitlab.com/xx_network/crypto v0.0.5-0.20211227194420-f311e8920467 + gitlab.com/xx_network/primitives v0.0.4-0.20211222205802-03e9d7d835b0 google.golang.org/genproto v0.0.0-20210315173758-2651cd453018 // indirect + google.golang.org/protobuf v1.27.1 ) diff --git a/go.sum b/go.sum index b73c4e9a38ad62a7d455711810c6811f3e8edb28..48aa18e6184f0bf3fe2b8502a08c5a8d67642687 100644 --- a/go.sum +++ b/go.sum @@ -269,31 +269,32 @@ github.com/zeebo/blake3 v0.0.4/go.mod h1:YOZo8A49yNqM0X/Y+JmDUZshJWLt1laHsNSn5ny github.com/zeebo/blake3 v0.1.1/go.mod h1:G9pM4qQwjRzF1/v7+vabMj/c5mWpGZ2Wzo3Eb4z0pb4= github.com/zeebo/pcg v0.0.0-20181207190024-3cdc6b625a05/go.mod h1:Gr+78ptB0MwXxm//LBaEvBiaXY7hXJ6KGe2V32X2F6E= github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -gitlab.com/elixxir/comms v0.0.4-0.20211101174956-590ba1b47887 h1:SOQaoEvc6RqImz86jSjsj7wIW3ZhgxXc38GzvRkKdOw= -gitlab.com/elixxir/comms v0.0.4-0.20211101174956-590ba1b47887/go.mod h1:rQpTeFVSn08ocbQeEw5AbMhGWXHfXmQ0y1/ZprAIVVU= +gitlab.com/elixxir/comms v0.0.4-0.20220104174855-044783c5c1e6 h1:MaiS3Mdhjwc3aNKonKJf9FSgnShwXQ6FnAI1QENDi7o= +gitlab.com/elixxir/comms v0.0.4-0.20220104174855-044783c5c1e6/go.mod h1:r4xZgd+DPDujHTJZ6Y8+JXM2Ae2rZHa6rFggOPxs/Gc= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c= gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA= -gitlab.com/elixxir/crypto v0.0.7-0.20211022013957-3a7899285c4c h1:HIr2HBhZqSAKdPRBdEY0/qravISL619O2yuTY/DQTdo= -gitlab.com/elixxir/crypto v0.0.7-0.20211022013957-3a7899285c4c/go.mod h1:teuTEXyqsqo4N/J1sshcTg9xYOt+wNTurop7pkZOiCg= +gitlab.com/elixxir/crypto v0.0.7-0.20211230230452-bca020488964/go.mod h1:fexaw14nwGMlT6vL9eIJ1ixgiomyAp88hSHl0Yx0/xU= +gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553 h1:BPwepGZspxgiY4QMUwVFMgVIEs8ziuMcT/uXmPQQ9Gs= +gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553/go.mod h1:fexaw14nwGMlT6vL9eIJ1ixgiomyAp88hSHl0Yx0/xU= gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg= gitlab.com/elixxir/primitives v0.0.0-20200804170709-a1896d262cd9/go.mod h1:p0VelQda72OzoUckr1O+vPW0AiFe0nyKQ6gYcmFSuF8= gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc= gitlab.com/elixxir/primitives v0.0.1/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE= -gitlab.com/elixxir/primitives v0.0.3-0.20211014164029-06022665b576/go.mod h1:zZy8AlOISFm5IG4G4sylypnz7xNBfZ5mpXiibqJT8+8= -gitlab.com/elixxir/primitives v0.0.3-0.20211102233208-a716d5c670b6 h1:ymWyFBFLcRQiuSId54dq8PVeiV4W7a9737kV46Thjlk= -gitlab.com/elixxir/primitives v0.0.3-0.20211102233208-a716d5c670b6/go.mod h1:zZy8AlOISFm5IG4G4sylypnz7xNBfZ5mpXiibqJT8+8= +gitlab.com/elixxir/primitives v0.0.3-0.20211230224340-fc0905d8776e/go.mod h1:zA+1Lp9fGPo6pl1QxtMoNPLeZJ1O5m4kcH7HNxePQnQ= +gitlab.com/elixxir/primitives v0.0.3-0.20220104173924-275cb9d7834f h1:zg3oYk+a6Wmq9tGRwka3GjJR1XRZIVCsOMpBGxtF2yc= +gitlab.com/elixxir/primitives v0.0.3-0.20220104173924-275cb9d7834f/go.mod h1:zA+1Lp9fGPo6pl1QxtMoNPLeZJ1O5m4kcH7HNxePQnQ= gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw= -gitlab.com/xx_network/comms v0.0.4-0.20211014163953-e774276b83ae h1:jmZWmSm8eH40SX5B5uOw2XaYoHYqVn8daTfa6B80AOs= -gitlab.com/xx_network/comms v0.0.4-0.20211014163953-e774276b83ae/go.mod h1:wR9Vx0KZLrIs0g2Efcp0UwFPStjcDRWkg/DJLVQI2vw= +gitlab.com/xx_network/comms v0.0.4-0.20211227194445-c099754b3cda h1:oWl8TuAgdx/6J9lwdH8wYGSb4W6D5TG1AZkzbA8EzbE= +gitlab.com/xx_network/comms v0.0.4-0.20211227194445-c099754b3cda/go.mod h1:5arueRMa2MNa6dALnfJwyZOhqhV53Gqc+tlHRz+Ycjw= gitlab.com/xx_network/crypto v0.0.3/go.mod h1:DF2HYvvCw9wkBybXcXAgQMzX+MiGbFPjwt3t17VRqRE= gitlab.com/xx_network/crypto v0.0.4/go.mod h1:+lcQEy+Th4eswFgQDwT0EXKp4AXrlubxalwQFH5O0Mk= -gitlab.com/xx_network/crypto v0.0.5-0.20211014163843-57b345890686 h1:mEjKISxi9LrguYgz6evroFwsfxH78/hYmr32yws+WV0= -gitlab.com/xx_network/crypto v0.0.5-0.20211014163843-57b345890686/go.mod h1:GeUUB5eMlu7G1u7LXpClfOyUYsSDxAhiZBf+RZeGftc= +gitlab.com/xx_network/crypto v0.0.5-0.20211227194420-f311e8920467 h1:LkZtWBYrM2e7QRf5aaBAcy7s7CpYGhAqgXRFVCdBRy4= +gitlab.com/xx_network/crypto v0.0.5-0.20211227194420-f311e8920467/go.mod h1:c+x0w3Xk6QZe5w2Redn5SiaBpqAhgNSfwBr0JGa/yyo= gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA= gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug= gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVkHy+QogOB6F/qc= -gitlab.com/xx_network/primitives v0.0.4-0.20211014163031-53405cf191fb h1:0K9dyxFpDYzH9jYLwzg3+bRj9a0uJjwjQkMeIdTxduQ= -gitlab.com/xx_network/primitives v0.0.4-0.20211014163031-53405cf191fb/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE= +gitlab.com/xx_network/primitives v0.0.4-0.20211222205802-03e9d7d835b0 h1:IHHb59DJEKk02HgfxddqK2ilvkRMAUdPIBFn8rmjjIg= +gitlab.com/xx_network/primitives v0.0.4-0.20211222205802-03e9d7d835b0/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE= gitlab.com/xx_network/ring v0.0.3-0.20210527191221-ce3f170aabd5 h1:FY+4Rh1Q2rgLyv10aKJjhWApuKRCR/054XhreudfAvw= gitlab.com/xx_network/ring v0.0.3-0.20210527191221-ce3f170aabd5/go.mod h1:aLzpP2TiZTQut/PVHR40EJAomzugDdHXetbieRClXIM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/scheduling/nodeStateChange_test.go b/scheduling/nodeStateChange_test.go index 0a29e59b05732ddaf4b76f41a7eac3942e6844d6..bc77f06889af3eaa6da18a017323b56426d4a073 100644 --- a/scheduling/nodeStateChange_test.go +++ b/scheduling/nodeStateChange_test.go @@ -35,7 +35,7 @@ func TestHandleNodeStateChance_Waiting(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -91,7 +91,7 @@ func TestHandleNodeStateChance_Waiting_SetNodeToOnline(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -154,7 +154,7 @@ func TestHandleNodeStateChance_Standby(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -234,7 +234,7 @@ func TestHandleNodeStateChance_Standby_NoRound(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -295,7 +295,7 @@ func TestHandleNodeUpdates_Completed(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -374,7 +374,7 @@ func TestHandleNodeUpdates_Completed_NoRound(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -429,7 +429,7 @@ func TestHandleNodeUpdates_Error(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -491,7 +491,7 @@ func TestHandleNodeUpdates_BannedNode(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -585,7 +585,7 @@ func TestKillRound(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -638,7 +638,7 @@ func TestHandleNodeUpdates_Precomputing_RoundError(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -688,7 +688,7 @@ func TestHandleNodeUpdates_Realtime(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -743,7 +743,7 @@ func TestHandleNodeUpdates_Realtime_RoundError(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -794,7 +794,7 @@ func TestHandleNodeUpdates_Realtime_UpdateError(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -853,7 +853,7 @@ func TestHandleNodeUpdates_RoundErrored(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -907,7 +907,7 @@ func TestHandleNodeUpdates_NOT_STARTED(t *testing.T) { privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() diff --git a/scheduling/params.go b/scheduling/params.go index 3da502cb833046e62999eb2619025e74feb2ac53..e46712f84c4d8695dacbb0efdc9f1fc691646f34 100644 --- a/scheduling/params.go +++ b/scheduling/params.go @@ -34,8 +34,6 @@ func (s *SafeParams) SafeCopy() Params { // JSONable structure which defines the parameters of the Scheduler type Params struct { - // selects if the secure or simple node selection algorithm is used - Secure bool // number of nodes in a team TeamSize uint32 // number of slots in a batch diff --git a/scheduling/pool_test.go b/scheduling/pool_test.go index d796fc5231323267e44f2645e7e974c48b3b9340..7e6482e03c5316bd77387eda2d8b8a0c4051c8c6 100644 --- a/scheduling/pool_test.go +++ b/scheduling/pool_test.go @@ -200,7 +200,7 @@ func setupNodeMap(t *testing.T) *storage.NetworkState { // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() diff --git a/scheduling/schedule.go b/scheduling/schedule.go index 2ebc20ec5b1d2c14e8dbd488a3c4c65a35f9e553..5c22b443bbcce2df325dbeae375bda2dcff2c01c 100644 --- a/scheduling/schedule.go +++ b/scheduling/schedule.go @@ -37,7 +37,7 @@ const ( timeToInactive = 3 * time.Minute ) -type roundCreator func(params Params, pool *waitingPool, roundID id.Round, +type roundCreator func(params Params, pool *waitingPool, threshold int, roundID id.Round, state *storage.NetworkState, rng io.Reader) (protoRound, error) func ParseParams(serialParam []byte) *SafeParams { @@ -147,14 +147,9 @@ func Scheduler(params *SafeParams, state *storage.NetworkState, killchan chan ch // Select the correct round creator var createRound roundCreator - // Identify which teaming algorithm we will be using - if params.Secure { - jww.INFO.Printf("Using Secure Teaming Algorithm") - createRound = createSecureRound - } else { - jww.INFO.Printf("Using Simple Teaming Algorithm") - createRound = createSimpleRound - } + // Set teaming algorithm + jww.INFO.Printf("Using Secure Teaming Algorithm") + createRound = createSecureRound // Channel to communicate that a round has timed out roundTimeoutTracker := make(chan id.Round, 1000) @@ -246,13 +241,10 @@ func Scheduler(params *SafeParams, state *storage.NetworkState, killchan chan ch numNodesInPool := pool.Len() // Create a new round if the pool is full - var teamFormationThreshold uint32 - if paramsCopy.Secure { - teamFormationThreshold = uint32(paramsCopy.Threshold * float64(state.CountActiveNodes())) - } else { - teamFormationThreshold = paramsCopy.TeamSize - } - if numNodesInPool >= int(teamFormationThreshold) && killed == nil { + var teamFormationThreshold int + teamSize := int(paramsCopy.TeamSize) + teamFormationThreshold = int(paramsCopy.Threshold * float64(state.CountActiveNodes())) + if numNodesInPool >= teamFormationThreshold && numNodesInPool >= teamSize && killed == nil { // Increment round ID currentID, err := state.IncrementRoundID() @@ -262,9 +254,8 @@ func Scheduler(params *SafeParams, state *storage.NetworkState, killchan chan ch } stream := rng.GetStream() - defer stream.Close() - - newRound, err := createRound(paramsCopy, pool, currentID, state, stream) + newRound, err := createRound(paramsCopy, pool, teamFormationThreshold, currentID, state, stream) + stream.Close() if err != nil { return err } diff --git a/scheduling/secureCreateRound.go b/scheduling/secureCreateRound.go index 3d8b784dd370bda0b97dadeed31b8b1fd841e2d2..002cb23f9f327bfeeeb307c653fd1ade5cd7aca4 100644 --- a/scheduling/secureCreateRound.go +++ b/scheduling/secureCreateRound.go @@ -29,11 +29,11 @@ import ( // We shall assume geographical distance causes latency in a naive // manner, as delineated here: // https://docs.google.com/document/d/1oyjIDlqC54u_eoFzQP9SVNU2IqjnQOjpUYd9aqbg5X0/edit# -func createSecureRound(params Params, pool *waitingPool, roundID id.Round, +func createSecureRound(params Params, pool *waitingPool, threshold int, roundID id.Round, state *storage.NetworkState, rng io.Reader) (protoRound, error) { // Pick nodes from the pool - nodes, err := pool.PickNRandAtThreshold(int(params.Threshold), int(params.TeamSize)) + nodes, err := pool.PickNRandAtThreshold(threshold, int(params.TeamSize)) if err != nil { return protoRound{}, errors.Errorf("Failed to pick random node group: %v", err) } diff --git a/scheduling/secureCreateRound_test.go b/scheduling/secureCreateRound_test.go index 2db0857aee62f3d3219233bc6bbbc8e0d5665f55..d3a838976bad6a7df369a17ce810bf1b8c984f4f 100644 --- a/scheduling/secureCreateRound_test.go +++ b/scheduling/secureCreateRound_test.go @@ -21,14 +21,14 @@ func TestCreateRound(t *testing.T) { testParams := Params{ TeamSize: 9, BatchSize: 32, - Threshold: 1, + Threshold: 0.3, NodeCleanUpInterval: 3, } // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -58,7 +58,7 @@ func TestCreateRound(t *testing.T) { prng := mathRand.New(mathRand.NewSource(42)) - _, err = createSecureRound(testParams, testpool, roundID, testState, prng) + _, err = createSecureRound(testParams, testpool, int(testParams.Threshold*float64(testParams.TeamSize)), roundID, testState, prng) if err != nil { t.Errorf("Error in happy path: %v", err) } @@ -78,7 +78,7 @@ func TestCreateRound_Error_NotEnoughForTeam(t *testing.T) { // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -108,7 +108,7 @@ func TestCreateRound_Error_NotEnoughForTeam(t *testing.T) { } prng := mathRand.New(mathRand.NewSource(42)) - _, err = createSecureRound(testParams, testpool, roundID, testState, prng) + _, err = createSecureRound(testParams, testpool, int(testParams.Threshold*float64(testParams.TeamSize)), roundID, testState, prng) if err != nil { return } @@ -132,7 +132,7 @@ func TestCreateRound_Error_NotEnoughForThreshold(t *testing.T) { // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -162,7 +162,7 @@ func TestCreateRound_Error_NotEnoughForThreshold(t *testing.T) { } prng := mathRand.New(mathRand.NewSource(42)) - _, err = createSecureRound(testParams, testpool, roundID, testState, prng) + _, err = createSecureRound(testParams, testpool, int(testParams.Threshold*float64(testParams.TeamSize)), roundID, testState, prng) if err != nil { return } diff --git a/scheduling/simpleCreateRound.go b/scheduling/simpleCreateRound.go deleted file mode 100644 index 93c693ce4dd7c58c4fc5bf1c7e8871a105e6f212..0000000000000000000000000000000000000000 --- a/scheduling/simpleCreateRound.go +++ /dev/null @@ -1,67 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// - -package scheduling - -import ( - "github.com/pkg/errors" - "gitlab.com/elixxir/registration/storage" - "gitlab.com/elixxir/registration/storage/node" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" - "gitlab.com/xx_network/primitives/region" - "io" - "time" -) - -// createSimpleRound.go contains the logic to construct a team for a round and -// add that round to the network state - -// createSimpleRound.go builds a team for a round out of a pool and round id and places -// this round into the network state -func createSimpleRound(params Params, pool *waitingPool, roundID id.Round, - state *storage.NetworkState, rng io.Reader) (protoRound, error) { - - nodes, err := pool.PickNRandAtThreshold(int(params.TeamSize), int(params.TeamSize)) - - if err != nil { - return protoRound{}, errors.Errorf("Failed to pick random node group: %v", err) - } - - var newRound protoRound - - //build the topology - - nodeIds := make([]*id.ID, 0, len(nodes)) - countries := make(map[id.ID]string) - for _, n := range nodes { - nodeIds = append(nodeIds, n.GetID()) - countries[*n.GetID()] = n.GetOrdering() - } - - // Generate a team based on latency - bestOrder, _, err := region.OrderNodeTeam(nodeIds, countries, region.GetCountryBins(), - region.CreateSetLatencyTableWeights(region.CreateLinkTable()), rng) - if err != nil { - return protoRound{}, errors.WithMessage(err, - "Failed to generate optimal ordering") - } - - // Parse the node list to get the order - nodeStateList := make([]*node.State, 0, params.TeamSize) - for _, n := range bestOrder { - nodeStateList = append(nodeStateList, state.GetNodeMap().GetNode(n)) - } - - // Construct the proto-round object - newRound.Topology = connect.NewCircuit(bestOrder) - newRound.ID = roundID - newRound.BatchSize = params.BatchSize - newRound.NodeStateList = nodeStateList - newRound.ResourceQueueTimeout = params.ResourceQueueTimeout * time.Millisecond - return newRound, nil - -} diff --git a/scheduling/simpleCreateRound_test.go b/scheduling/simpleCreateRound_test.go deleted file mode 100644 index fee76f34bb87ea9ea0c3c467c96840db7e1778fb..0000000000000000000000000000000000000000 --- a/scheduling/simpleCreateRound_test.go +++ /dev/null @@ -1,270 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// -package scheduling - -import ( - "crypto/rand" - "gitlab.com/elixxir/registration/storage" - "gitlab.com/elixxir/registration/storage/node" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/crypto/signature/rsa" - "gitlab.com/xx_network/primitives/id" - "gitlab.com/xx_network/primitives/region" - mathRand "math/rand" - "reflect" - "testing" -) - -// Happy path -func TestCreateRound_Random(t *testing.T) { - // Build params for scheduling - testParams := Params{ - TeamSize: 5, - BatchSize: 32, - Threshold: 0, - NodeCleanUpInterval: 3, - Secure: false, - } - - // Build network state - privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) - if err != nil { - t.Errorf("Failed to create test state: %v", err) - t.FailNow() - } - - // Build node list - nodeList := make([]*id.ID, testParams.TeamSize) - nodeStateList := make([]*node.State, testParams.TeamSize) - - // Build pool - testPool := NewWaitingPool() - - for i := 0; i < int(testParams.TeamSize); i++ { - nid := id.NewIdFromUInt(uint64(i), id.Node, t) - nodeList[i] = nid - err := testState.GetNodeMap().AddNode(nodeList[i], "US", "", "", 0) - if err != nil { - t.Errorf("Couldn't add node: %v", err) - t.FailNow() - } - nodeState := testState.GetNodeMap().GetNode(nid) - nodeStateList[i] = nodeState - testPool.Add(nodeState) - } - - roundID, err := testState.IncrementRoundID() - if err != nil { - t.Errorf("IncrementRoundID() failed: %+v", err) - } - prng := mathRand.New(mathRand.NewSource(42)) - testProtoRound, err := createSecureRound(testParams, testPool, roundID, testState, prng) - if err != nil { - t.Errorf("Happy path of createSimpleRound failed: %v", err) - } - - if testProtoRound.ID != roundID { - t.Errorf("ProtoRound's id returned unexpected value!"+ - "\n\tExpected: %d"+ - "\n\tReceived: %d", roundID, testProtoRound.ID) - } - - if testParams.BatchSize != testProtoRound.BatchSize { - t.Errorf("ProtoRound's batchsize returned unexpected value!"+ - "\n\tExpected: %v"+ - "\n\tReceived: %v", testParams.BatchSize, testProtoRound.BatchSize) - - } - -} - -// Error path: Provide a node ordering that is invalid -func TestCreateRound_BadOrdering(t *testing.T) { - // Build scheduling params - testParams := Params{ - TeamSize: 5, - BatchSize: 32, - } - - // Build network state - privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) - if err != nil { - t.Errorf("Failed to create test state: %v", err) - t.FailNow() - } - - // Build a node list that will be invalid - nodeList := make([]*id.ID, testParams.TeamSize) - for i := uint64(0); i < uint64(len(nodeList)); i++ { - nodeList[i] = id.NewIdFromUInt(i, id.Node, t) - // Input an invalid ordering to node - err := testState.GetNodeMap().AddNode(nodeList[i], "BadNumber", "", "", 0) - if err != nil { - t.Errorf("Couldn't add node: %v", err) - t.FailNow() - } - } - - // Build pool - testPool := NewWaitingPool() - - roundID, err := testState.IncrementRoundID() - if err != nil { - t.Errorf("IncrementRoundID() failed: %+v", err) - } - - // Invalid ordering will cause this to fail - prng := mathRand.New(mathRand.NewSource(42)) - _, err = createSimpleRound(testParams, testPool, roundID, testState, prng) - if err != nil { - return - } - - t.Errorf("Expected error case: passed in an ordering to nodes which were not numbers should result " + - "in an error") - -} - -// Test that the system semi-optimal gets done when both -// random ordering and semioptimal ordering are set to true -func TestCreateSimpleRound_SemiOptimal(t *testing.T) { - // Build scheduling params - testParams := Params{ - TeamSize: 9, - BatchSize: 32, - Threshold: 1, - Secure: false, - NodeCleanUpInterval: 3, - } - - // Build network state - privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) - if err != nil { - t.Errorf("Failed to create test state: %v", err) - t.FailNow() - } - - // Build the nodes - nodeList := make([]*id.ID, testParams.TeamSize) - nodeStateList := make([]*node.State, testParams.TeamSize) - testPool := NewWaitingPool() - - // Craft regions for nodes - regions := []string{"CR", "GB", "SK", - "HR", "IQ", "BF", "RU", "CX"} - - for i := uint64(0); i < uint64(len(nodeList)); i++ { - // Randomize the regions of the nodes - index := mathRand.Intn(8) - - // Generate a test id - nid := id.NewIdFromUInt(i, id.Node, t) - nodeList[i] = nid - - // Add the node to that node map - // Place the node in a random region - err := testState.GetNodeMap().AddNode(nodeList[i], regions[index], "", "", 0) - if err != nil { - t.Errorf("Couldn't add node: %v", err) - t.FailNow() - } - - // Add the node to the pool - nodeState := testState.GetNodeMap().GetNode(nid) - nodeStateList[i] = nodeState - testPool.Add(nodeState) - } - - initialTopology := connect.NewCircuit(nodeList) - - roundID, err := testState.IncrementRoundID() - if err != nil { - t.Errorf("IncrementRoundID() failed: %+v", err) - } - prng := mathRand.New(mathRand.NewSource(42)) - - testProtoRound, err := createSimpleRound(testParams, testPool, roundID, testState, prng) - if err != nil { - t.Errorf("Happy path of createSimpleRound failed: %v", err) - } - - // Check that shuffling has actually occurred, should not be the initial topology - // which is inefficient - if reflect.DeepEqual(initialTopology, testProtoRound.Topology) { - t.Errorf("Highly unlikely initial topology identical to resulting after shuffling. " + - "Possile shuffling is broken") - } - -} - -// Test that the system semi-optimal gets done when both -// random ordering and semioptimal ordering are set to true -func TestCreateSimpleRound_SemiOptimal_BadRegion(t *testing.T) { - // Build scheduling params - testParams := Params{ - TeamSize: 9, - BatchSize: 32, - Threshold: 1, - Secure: false, - NodeCleanUpInterval: 3, - } - - // Build network state - privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) - if err != nil { - t.Errorf("Failed to create test state: %v", err) - t.FailNow() - } - - // Build the nodes - nodeList := make([]*id.ID, testParams.TeamSize) - nodeStateList := make([]*node.State, testParams.TeamSize) - testPool := NewWaitingPool() - - badRegion := "Mars" - - for i := uint64(0); i < uint64(len(nodeList)); i++ { - // Generate a test id - nid := id.NewIdFromUInt(i, id.Node, t) - nodeList[i] = nid - - // Add the node to that node map - // Place the node in a random region - err := testState.GetNodeMap().AddNode(nodeList[i], badRegion, "", "", 0) - if err != nil { - t.Errorf("Couldn't add node: %v", err) - t.FailNow() - } - - // Add the node to the pool - nodeState := testState.GetNodeMap().GetNode(nid) - nodeStateList[i] = nodeState - testPool.Add(nodeState) - } - - // Generate round id - roundID, err := testState.IncrementRoundID() - if err != nil { - t.Errorf("IncrementRoundID() failed: %+v", err) - } - prng := mathRand.New(mathRand.NewSource(42)) - - _, err = createSimpleRound(testParams, testPool, roundID, testState, prng) - if err != nil { - return - } - - t.Errorf("Expected error path: Test should fail when receiving bad region %v!", badRegion) - -} diff --git a/scheduling/startRound_test.go b/scheduling/startRound_test.go index 1f32f2e2daf7bdc5095940f5390e85fd213317e9..bae07eac2008e8afc0c33766180ccd977926bc73 100644 --- a/scheduling/startRound_test.go +++ b/scheduling/startRound_test.go @@ -25,8 +25,7 @@ func TestStartRound(t *testing.T) { testParams := Params{ TeamSize: 8, BatchSize: 32, - Threshold: 1, - Secure: false, + Threshold: 0.3, NodeCleanUpInterval: 3, } @@ -39,7 +38,7 @@ func TestStartRound(t *testing.T) { // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -70,7 +69,7 @@ func TestStartRound(t *testing.T) { } prng := mathRand.New(mathRand.NewSource(42)) - testProtoRound, err := createSecureRound(testParams, testPool, roundID, testState, prng) + testProtoRound, err := createSecureRound(testParams, testPool, int(testParams.Threshold*float64(testParams.TeamSize)), roundID, testState, prng) if err != nil { t.Errorf("Happy path of createSimpleRound failed: %v", err) } @@ -94,8 +93,7 @@ func TestStartRound_BadState(t *testing.T) { testParams := Params{ TeamSize: 8, BatchSize: 32, - Threshold: 1, - Secure: false, + Threshold: 0.3, NodeCleanUpInterval: 3, } @@ -108,7 +106,7 @@ func TestStartRound_BadState(t *testing.T) { // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -143,7 +141,7 @@ func TestStartRound_BadState(t *testing.T) { testState.GetRoundMap().AddRound_Testing(badState, t) prng := mathRand.New(mathRand.NewSource(42)) - testProtoRound, err := createSecureRound(testParams, testPool, roundID, testState, prng) + testProtoRound, err := createSecureRound(testParams, testPool, int(testParams.Threshold*float64(testParams.TeamSize)), roundID, testState, prng) if err != nil { t.Errorf("Happy path of createSimpleRound failed: %v", err) } @@ -163,20 +161,18 @@ func TestStartRound_BadState(t *testing.T) { // Error path func TestStartRound_BadNode(t *testing.T) { - // Build params for scheduling // Build params for scheduling testParams := Params{ TeamSize: 8, BatchSize: 32, - Threshold: 1, - Secure: false, + Threshold: 0.3, NodeCleanUpInterval: 3, } // Build network state privKey, _ := rsa.GenerateKey(rand.Reader, 2048) - testState, err := storage.NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + testState, err := storage.NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("Failed to create test state: %v", err) t.FailNow() @@ -208,7 +204,7 @@ func TestStartRound_BadNode(t *testing.T) { badState := round.NewState_Testing(roundID, states.COMPLETED, nil, t) prng := mathRand.New(mathRand.NewSource(42)) - testProtoRound, err := createSecureRound(testParams, testPool, roundID, testState, prng) + testProtoRound, err := createSecureRound(testParams, testPool, int(testParams.Threshold*float64(testParams.TeamSize)), roundID, testState, prng) if err != nil { t.Errorf("Happy path of createSimpleRound failed: %v", err) } diff --git a/storage/state.go b/storage/state.go index 921a24bba3a627f9f734cfb4813bffd4aceed987..fa1acc4188d00d25621aa735bdd0001a64864d4e 100644 --- a/storage/state.go +++ b/storage/state.go @@ -26,6 +26,7 @@ import ( "gitlab.com/xx_network/primitives/ndf" "gitlab.com/xx_network/primitives/region" "gitlab.com/xx_network/primitives/utils" + "google.golang.org/protobuf/proto" "strconv" "strings" "sync" @@ -69,7 +70,12 @@ type NetworkState struct { // Address space size addressSpaceSize *uint32 - ndfOutputPath string + // Output path to the full ndf + fullNdfOutputPath string + + // Output path to the signed partial ndf provided to client + // by uploading the file + signedPartialNdfOutputPath string // round adder buffer channel roundUpdatesToAddCh chan *dataStructures.Round @@ -81,8 +87,8 @@ type NetworkState struct { // NewState returns a new NetworkState object. func NewState(rsaPrivKey *rsa.PrivateKey, addressSpaceSize uint32, - ndfOutputPath string, geoBins map[string]region.GeoBin, - whitelistedIds []string, whitelistedIpAddresses []string) (*NetworkState, error) { + fullNdfOutputPath string, signedPartialNdfOutputPath string, + geoBins map[string]region.GeoBin) (*NetworkState, error) { fullNdf, err := dataStructures.NewNdf(&ndf.NetworkDefinition{}) if err != nil { @@ -94,19 +100,20 @@ func NewState(rsaPrivKey *rsa.PrivateKey, addressSpaceSize uint32, } state := &NetworkState{ - rounds: round.NewStateMap(), - roundUpdates: dataStructures.NewUpdates(), - update: make(chan node.UpdateNotification, updateBufferLength), - nodes: node.NewStateMap(), - unprunedNdf: &ndf.NetworkDefinition{}, - fullNdf: fullNdf, - partialNdf: partialNdf, - rsaPrivateKey: rsaPrivKey, - addressSpaceSize: &addressSpaceSize, - pruneList: make(map[id.ID]bool), - ndfOutputPath: ndfOutputPath, - roundUpdatesToAddCh: make(chan *dataStructures.Round, 500), - geoBins: geoBins, + rounds: round.NewStateMap(), + roundUpdates: dataStructures.NewUpdates(), + update: make(chan node.UpdateNotification, updateBufferLength), + nodes: node.NewStateMap(), + unprunedNdf: &ndf.NetworkDefinition{}, + fullNdf: fullNdf, + partialNdf: partialNdf, + rsaPrivateKey: rsaPrivKey, + addressSpaceSize: &addressSpaceSize, + pruneList: make(map[id.ID]bool), + fullNdfOutputPath: fullNdfOutputPath, + signedPartialNdfOutputPath: signedPartialNdfOutputPath, + roundUpdatesToAddCh: make(chan *dataStructures.Round, 500), + geoBins: geoBins, } //begin the thread that reads and adds round updates @@ -187,9 +194,11 @@ func NewState(rsaPrivKey *rsa.PrivateKey, addressSpaceSize uint32, } // CountActiveNodes returns a count of active nodes in the state -// NOTE: Accounts for pruned, but not stale nodes func (s *NetworkState) CountActiveNodes() int { - return len(s.GetFullNdf().Get().Nodes) + s.pruneListMux.Lock() + defer s.pruneListMux.Unlock() + + return len(s.unprunedNdf.Nodes) - len(s.pruneList) } // Adds pruned nodes, used by disabledNodes @@ -399,9 +408,26 @@ func (s *NetworkState) UpdateNdf(newNdf *ndf.NetworkDefinition) (err error) { return err } - err = outputToJSON(newNdf, s.ndfOutputPath) + // Output full NDF to file + err = outputToJSON(newNdf, s.fullNdfOutputPath) + if err != nil { + jww.ERROR.Printf("unable to output full NDF JSON file: %+v", err) + } + + // Marshal signed partial NDF + signedPartialNdfMarshal, err := proto.Marshal(s.partialNdf.GetPb()) + if err != nil { + jww.ERROR.Printf("unable to marshal partial ndf") + } + + // Base64 encode the signed marshaled NDF + signedPartialEncoded := base64.StdEncoding.EncodeToString(signedPartialNdfMarshal) + + // Output signed partial ndf to file + err = utils.WriteFile(s.signedPartialNdfOutputPath, + []byte(signedPartialEncoded), utils.FilePerms, utils.DirPerms) if err != nil { - jww.ERROR.Printf("unable to output NDF JSON file: %+v", err) + jww.ERROR.Printf("unable to output signed partial NDF to file: %+v", err) } jww.INFO.Printf("Full NDF updated to: %s", base64.StdEncoding.EncodeToString(s.fullNdf.GetHash())) diff --git a/storage/state_test.go b/storage/state_test.go index eb8f0d881dca211d7389016d0b5b85f74e6f3fcb..6db9f61c803325c165b57ccd4017f88dc70f0349 100644 --- a/storage/state_test.go +++ b/storage/state_test.go @@ -59,7 +59,7 @@ func TestNewState(t *testing.T) { } // Generate new NetworkState - state, err := NewState(privateKey, 8, "", region.GetCountryBins(), nil, nil) + state, err := NewState(privateKey, 8, "", "", region.GetCountryBins()) if err != nil { t.Errorf("NewState() produced an unexpected error:\n%v", err) } @@ -446,7 +446,7 @@ func generateTestNetworkState() (*NetworkState, *rsa.PrivateKey, error) { } // Generate new NetworkState using the private key - state, err := NewState(privKey, 8, "", region.GetCountryBins(), nil, nil) + state, err := NewState(privKey, 8, "", "", region.GetCountryBins()) if err != nil { return state, privKey, fmt.Errorf("NewState() produced an unexpected error:\n+%v", err) }