diff --git a/cmd/goal/defaultNetworkTemplate.json b/cmd/goal/defaultNetworkTemplate.json new file mode 100644 index 0000000000..2ca207bf44 --- /dev/null +++ b/cmd/goal/defaultNetworkTemplate.json @@ -0,0 +1,46 @@ +{ + "Genesis": { + "NetworkName": "Default Network Template", + "RewardsPoolBalance": 0, + "FirstPartKeyRound": 0, + "LastPartKeyRound": 30000, + "Wallets": [ + { + "Name": "Wallet1", + "Stake": 40, + "Online": true + }, + { + "Name": "Wallet2", + "Stake": 40, + "Online": true + }, + { + "Name": "Wallet3", + "Stake": 20, + "Online": false + } + ] + }, + "Nodes": [ + { + "Name": "Node", + "IsRelay": false, + "Wallets": [ + { + "Name": "Wallet1", + "ParticipationOnly": false + }, + { + "Name": "Wallet2", + "ParticipationOnly": false + }, + { + "Name": "Wallet3", + "ParticipationOnly": false + } + ] + } + ] +} + diff --git a/cmd/goal/network.go b/cmd/goal/network.go index d7212123f5..ddad6f99d1 100644 --- a/cmd/goal/network.go +++ b/cmd/goal/network.go @@ -17,9 +17,12 @@ package main import ( + _ "embed" "fmt" + "io" "os" "path/filepath" + "strings" "github.com/spf13/cobra" @@ -45,7 +48,6 @@ func init() { networkCreateCmd.Flags().StringVarP(&networkName, "network", "n", "", "Specify the name to use for the private network") networkCreateCmd.Flags().StringVarP(&networkTemplateFile, "template", "t", "", "Specify the path to the template file for the network") - networkCreateCmd.MarkFlagRequired("template") networkCreateCmd.Flags().BoolVarP(&noImportKeys, "noimportkeys", "K", false, "Do not import root keys when creating the network (by default will import)") networkCreateCmd.Flags().BoolVar(&noClean, "noclean", false, "Prevents auto-cleanup on error - for diagnosing problems") networkCreateCmd.Flags().BoolVar(&devModeOverride, "devMode", false, "Forces the configuration to enable DevMode, returns an error if the template is not compatible with DevMode.") @@ -73,6 +75,9 @@ The basic idea is that we create one or more data directories and wallets to for }, } +//go:embed defaultNetworkTemplate.json +var defaultNetworkTemplate string + var networkCreateCmd = &cobra.Command{ Use: "create", Short: "Create a private named network from a template", @@ -83,10 +88,25 @@ var networkCreateCmd = &cobra.Command{ if err != nil { panic(err) } - networkTemplateFile, err := filepath.Abs(networkTemplateFile) - if err != nil { - panic(err) + + var templateReader io.Reader + + if networkTemplateFile == "" { + templateReader = strings.NewReader(defaultNetworkTemplate) + } else { + networkTemplateFile, err = filepath.Abs(networkTemplateFile) + if err != nil { + panic(err) + } + file, err := os.Open(networkTemplateFile) + if err != nil { + reportErrorf(errorCreateNetwork, err) + } + + defer file.Close() + templateReader = file } + // Make sure target directory does not exist or is empty if util.FileExists(networkRootDir) && !util.IsEmpty(networkRootDir) { reportErrorf(infoNetworkAlreadyExists, networkRootDir) @@ -104,7 +124,7 @@ var networkCreateCmd = &cobra.Command{ consensus, _ = config.PreloadConfigurableConsensusProtocols(dataDir) } - network, err := netdeploy.CreateNetworkFromTemplate(networkName, networkRootDir, networkTemplateFile, binDir, !noImportKeys, nil, consensus, devModeOverride) + network, err := netdeploy.CreateNetworkFromTemplate(networkName, networkRootDir, templateReader, binDir, !noImportKeys, nil, consensus, devModeOverride) if err != nil { if noClean { reportInfof(" ** failed ** - Preserving network rootdir '%s'", networkRootDir) diff --git a/netdeploy/network.go b/netdeploy/network.go index 1d5e503de3..520f185a3c 100644 --- a/netdeploy/network.go +++ b/netdeploy/network.go @@ -19,6 +19,7 @@ package netdeploy import ( "encoding/json" "fmt" + "io" "os" "path/filepath" "sort" @@ -57,15 +58,18 @@ type Network struct { // CreateNetworkFromTemplate uses the specified template to deploy a new private network // under the specified root directory. -func CreateNetworkFromTemplate(name, rootDir, templateFile, binDir string, importKeys bool, nodeExitCallback nodecontrol.AlgodExitErrorCallback, consensus config.ConsensusProtocols, overrideDevMode bool) (Network, error) { +func CreateNetworkFromTemplate(name, rootDir string, templateReader io.Reader, binDir string, importKeys bool, nodeExitCallback nodecontrol.AlgodExitErrorCallback, consensus config.ConsensusProtocols, overrideDevMode bool) (Network, error) { n := Network{ rootDir: rootDir, nodeExitCallback: nodeExitCallback, } n.cfg.Name = name - n.cfg.TemplateFile = templateFile - template, err := loadTemplate(templateFile) + var err error + template := defaultNetworkTemplate + + err = loadTemplateFromReader(templateReader, &template) + if err == nil { if overrideDevMode { template.Genesis.DevMode = true @@ -73,9 +77,11 @@ func CreateNetworkFromTemplate(name, rootDir, templateFile, binDir string, impor template.Nodes[0].IsRelay = false } } - err = template.Validate() + } else { + return n, err } - if err != nil { + + if err = template.Validate(); err != nil { return n, err } diff --git a/netdeploy/networkTemplate.go b/netdeploy/networkTemplate.go index 4d5aa67b95..34cd01e1b6 100644 --- a/netdeploy/networkTemplate.go +++ b/netdeploy/networkTemplate.go @@ -165,16 +165,16 @@ func loadTemplate(templateFile string) (NetworkTemplate, error) { } defer f.Close() - if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { - // for arm machines, use smaller key dilution - template.Genesis.PartKeyDilution = 100 - } - err = loadTemplateFromReader(f, &template) return template, err } func loadTemplateFromReader(reader io.Reader, template *NetworkTemplate) error { + + if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { + // for arm machines, use smaller key dilution + template.Genesis.PartKeyDilution = 100 + } dec := json.NewDecoder(reader) return dec.Decode(template) } diff --git a/test/framework/fixtures/libgoalFixture.go b/test/framework/fixtures/libgoalFixture.go index 7294bafc40..c0527fdd62 100644 --- a/test/framework/fixtures/libgoalFixture.go +++ b/test/framework/fixtures/libgoalFixture.go @@ -96,7 +96,9 @@ func (f *LibGoalFixture) setup(test TestingTB, testName string, templateFile str os.RemoveAll(f.rootDir) templateFile = filepath.Join(f.testDataDir, templateFile) importKeys := false // Don't automatically import root keys when creating folders, we'll import on-demand - network, err := netdeploy.CreateNetworkFromTemplate("test", f.rootDir, templateFile, f.binDir, importKeys, f.nodeExitWithError, f.consensus, false) + file, err := os.Open(templateFile) + f.failOnError(err, "Template file could not be opened: %v") + network, err := netdeploy.CreateNetworkFromTemplate("test", f.rootDir, file, f.binDir, importKeys, f.nodeExitWithError, f.consensus, false) f.failOnError(err, "CreateNetworkFromTemplate failed: %v") f.network = network diff --git a/test/scripts/test_private_network.sh b/test/scripts/test_private_network.sh index 1886a6548e..f1adc7f62b 100755 --- a/test/scripts/test_private_network.sh +++ b/test/scripts/test_private_network.sh @@ -23,6 +23,18 @@ ${GOPATH}/bin/goal network stop -r ${NETROOTPATH} ${GOPATH}/bin/goal network delete -r ${NETROOTPATH} +# default network with no template specified + +rm -rf ${NETROOTPATH} + +${GOPATH}/bin/goal network create -r ${NETROOTPATH} + +${GOPATH}/bin/goal network start -r ${NETROOTPATH} + +${GOPATH}/bin/goal network stop -r ${NETROOTPATH} + +${GOPATH}/bin/goal network delete -r ${NETROOTPATH} + echo "----------------------------------------------------------------------" echo " DONE: test_private_network" echo "----------------------------------------------------------------------"