diff --git a/cmd/blockchaincmd/deploy.go b/cmd/blockchaincmd/deploy.go index b517aea02..cf0de7376 100644 --- a/cmd/blockchaincmd/deploy.go +++ b/cmd/blockchaincmd/deploy.go @@ -601,13 +601,26 @@ func deployBlockchain(cmd *cobra.Command, args []string) error { avagoVersionSettings := node.AvalancheGoVersionSettings{} useEtnaDevnet := network.Kind == models.EtnaDevnet if avagoBinaryPath == "" { - ux.Logger.PrintToUser("Local build of Avalanche Go is required to create an Avalanche node using local machine") - ux.Logger.PrintToUser("Please download Avalanche Go repo at https://github.com/ava-labs/avalanchego and build from source through ./scripts/build.sh") - ux.Logger.PrintToUser("Please provide the full path to Avalanche Go binary in the build directory (e.g, xxx/build/avalanchego)") - avagoBinaryPath, err = app.Prompt.CaptureString("Path to Avalanche Go build") + useLatestAvalanchegoPreReleaseVersion := true + useLatestAvalanchegoReleaseVersion := false + if userProvidedAvagoVersion != "" { + useLatestAvalanchegoReleaseVersion = false + useLatestAvalanchegoPreReleaseVersion = false + } + avaGoVersionSetting := node.AvalancheGoVersionSettings{ + UseCustomAvalanchegoVersion: userProvidedAvagoVersion, + UseLatestAvalanchegoPreReleaseVersion: useLatestAvalanchegoPreReleaseVersion, + UseLatestAvalanchegoReleaseVersion: useLatestAvalanchegoReleaseVersion, + } + avalancheGoVersion, err := node.GetAvalancheGoVersion(app, avaGoVersionSetting) if err != nil { return err } + _, avagoDir, err := binutils.SetupAvalanchego(app, avalancheGoVersion) + if err != nil { + return fmt.Errorf("failed installing Avalanche Go version %s: %w", avalancheGoVersion, err) + } + avagoBinaryPath = filepath.Join(avagoDir, "avalanchego") } nodeConfig := map[string]interface{}{} if app.AvagoNodeConfigExists(blockchainName) { diff --git a/cmd/nodecmd/create.go b/cmd/nodecmd/create.go index 1c83df89a..bb66d69b5 100644 --- a/cmd/nodecmd/create.go +++ b/cmd/nodecmd/create.go @@ -137,8 +137,15 @@ will apply to all nodes in the cluster`, func handlePostRun(_ *cobra.Command, _ []string) {} func preCreateChecks(clusterName string) error { - if !flags.EnsureMutuallyExclusive([]bool{useLatestAvalanchegoReleaseVersion, useLatestAvalanchegoPreReleaseVersion, useAvalanchegoVersionFromSubnet != "", useCustomAvalanchegoVersion != ""}) { - return fmt.Errorf("latest avalanchego released version, latest avalanchego pre-released version, custom avalanchego version and avalanchego version based on given subnet, are mutually exclusive options") + if useCustomAvalanchegoVersion != "" || useAvalanchegoVersionFromSubnet != "" { + useLatestAvalanchegoReleaseVersion = false + useLatestAvalanchegoPreReleaseVersion = false + } + if !flags.EnsureMutuallyExclusive([]bool{useLatestAvalanchegoReleaseVersion, useLatestAvalanchegoPreReleaseVersion}) { + return fmt.Errorf("latest avalanchego released version, latest avalanchego pre-released version are mutually exclusive options") + } + if !flags.EnsureMutuallyExclusive([]bool{useAvalanchegoVersionFromSubnet != "", useCustomAvalanchegoVersion != ""}) { + return fmt.Errorf("custom avalanchego version and avalanchego version based on given subnet, are mutually exclusive options") } if useAWS && useGCP { return fmt.Errorf("could not use both AWS and GCP cloud options") diff --git a/cmd/nodecmd/local.go b/cmd/nodecmd/local.go index 2ba631349..1d83b8b85 100644 --- a/cmd/nodecmd/local.go +++ b/cmd/nodecmd/local.go @@ -4,7 +4,9 @@ package nodecmd import ( "fmt" + "path/filepath" + "github.com/ava-labs/avalanche-cli/pkg/binutils" "github.com/ava-labs/avalanche-cli/pkg/cobrautils" "github.com/ava-labs/avalanche-cli/pkg/networkoptions" "github.com/ava-labs/avalanche-cli/pkg/node" @@ -73,7 +75,7 @@ status by running avalanche node status local } networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, createSupportedNetworkOptions) cmd.Flags().BoolVar(&useLatestAvalanchegoReleaseVersion, "latest-avalanchego-version", false, "install latest avalanchego release version on node/s") - cmd.Flags().BoolVar(&useLatestAvalanchegoPreReleaseVersion, "latest-avalanchego-pre-release-version", false, "install latest avalanchego pre-release version on node/s") + cmd.Flags().BoolVar(&useLatestAvalanchegoPreReleaseVersion, "latest-avalanchego-pre-release-version", true, "install latest avalanchego pre-release version on node/s") cmd.Flags().StringVar(&useCustomAvalanchegoVersion, "custom-avalanchego-version", "", "install given avalanchego version on node/s") cmd.Flags().StringVar(&avalanchegoBinaryPath, "avalanchego-path", "", "use this avalanchego binary path") cmd.Flags().StringArrayVar(&bootstrapIDs, "bootstrap-id", []string{}, "nodeIDs of bootstrap nodes") @@ -108,6 +110,9 @@ func newLocalTrackCmd() *cobra.Command { RunE: localTrack, } cmd.Flags().StringVar(&avalanchegoBinaryPath, "avalanchego-path", "", "use this avalanchego binary path") + cmd.Flags().BoolVar(&useLatestAvalanchegoReleaseVersion, "latest-avalanchego-version", false, "install latest avalanchego release version on node/s") + cmd.Flags().BoolVar(&useLatestAvalanchegoPreReleaseVersion, "latest-avalanchego-pre-release-version", true, "install latest avalanchego pre-release version on node/s") + cmd.Flags().StringVar(&useCustomAvalanchegoVersion, "custom-avalanchego-version", "", "install given avalanchego version on node/s") return cmd } @@ -147,11 +152,14 @@ func localStartNode(_ *cobra.Command, args []string) error { StakingCertKeyPath: stakingCertKeyPath, StakingTLSKeyPath: stakingTLSKeyPath, } + if useCustomAvalanchegoVersion != "" { + useLatestAvalanchegoReleaseVersion = false + useLatestAvalanchegoPreReleaseVersion = false + } avaGoVersionSetting := node.AvalancheGoVersionSettings{ UseCustomAvalanchegoVersion: useCustomAvalanchegoVersion, UseLatestAvalanchegoPreReleaseVersion: useLatestAvalanchegoPreReleaseVersion, UseLatestAvalanchegoReleaseVersion: useLatestAvalanchegoReleaseVersion, - UseAvalanchegoVersionFromSubnet: useAvalanchegoVersionFromSubnet, } var ( err error @@ -189,6 +197,26 @@ func localDestroyNode(_ *cobra.Command, args []string) error { } func localTrack(_ *cobra.Command, args []string) error { + if avalanchegoBinaryPath == "" { + if useCustomAvalanchegoVersion != "" { + useLatestAvalanchegoReleaseVersion = false + useLatestAvalanchegoPreReleaseVersion = false + } + avaGoVersionSetting := node.AvalancheGoVersionSettings{ + UseCustomAvalanchegoVersion: useCustomAvalanchegoVersion, + UseLatestAvalanchegoPreReleaseVersion: useLatestAvalanchegoPreReleaseVersion, + UseLatestAvalanchegoReleaseVersion: useLatestAvalanchegoReleaseVersion, + } + avalancheGoVersion, err := node.GetAvalancheGoVersion(app, avaGoVersionSetting) + if err != nil { + return err + } + _, avagoDir, err := binutils.SetupAvalanchego(app, avalancheGoVersion) + if err != nil { + return fmt.Errorf("failed installing Avalanche Go version %s: %w", avalancheGoVersion, err) + } + avalanchegoBinaryPath = filepath.Join(avagoDir, "avalanchego") + } return node.TrackSubnetWithLocalMachine(app, args[0], args[1], avalanchegoBinaryPath) } diff --git a/pkg/networkoptions/network_options.go b/pkg/networkoptions/network_options.go index 3d75b94b4..139863cf1 100644 --- a/pkg/networkoptions/network_options.go +++ b/pkg/networkoptions/network_options.go @@ -375,7 +375,11 @@ func GetNetworkFromCmdLineFlags( return models.UndefinedNetwork, err } } - network = models.NewDevnetNetwork(networkFlags.Endpoint, networkID) + if networkFlags.Endpoint == constants.EtnaDevnetEndpoint { + network = models.NewEtnaDevnetNetwork() + } else { + network = models.NewDevnetNetwork(networkFlags.Endpoint, networkID) + } case Fuji: network = models.NewFujiNetwork() case Mainnet: diff --git a/pkg/node/local.go b/pkg/node/local.go index 5db31a881..49323fd68 100644 --- a/pkg/node/local.go +++ b/pkg/node/local.go @@ -208,9 +208,13 @@ func StartLocalNode( avalancheGoVersion, err = GetAvalancheGoVersion(app, avaGoVersionSetting) if err != nil { return err - } else { - ux.Logger.PrintToUser("Using AvalancheGo version: %s", avalancheGoVersion) } + _, avagoDir, err := binutils.SetupAvalanchego(app, avalancheGoVersion) + if err != nil { + return fmt.Errorf("failed installing Avalanche Go version %s: %w", avalancheGoVersion, err) + } + avalanchegoBinaryPath = filepath.Join(avagoDir, "avalanchego") + ux.Logger.PrintToUser("Using AvalancheGo version: %s", avalancheGoVersion) } serverLogPath := filepath.Join(rootDir, "server.log") sd := subnet.NewLocalDeployer(app, avalancheGoVersion, avalanchegoBinaryPath, "", true) @@ -304,7 +308,7 @@ func StartLocalNode( return err } } - if err := preLocalChecks(anrSettings, avaGoVersionSetting, avalanchegoBinaryPath, useEtnaDevnet, globalNetworkFlags); err != nil { + if err := preLocalChecks(anrSettings, avaGoVersionSetting, useEtnaDevnet, globalNetworkFlags); err != nil { return err } if useEtnaDevnet { @@ -422,7 +426,7 @@ func localClusterDataExists(app *application.Avalanche, clusterName string) bool } // stub for now -func preLocalChecks(anrSettings ANRSettings, avaGoVersionSettings AvalancheGoVersionSettings, avalanchegoBinaryPath string, useEtnaDevnet bool, globalNetworkFlags networkoptions.NetworkFlags) error { +func preLocalChecks(anrSettings ANRSettings, avaGoVersionSettings AvalancheGoVersionSettings, useEtnaDevnet bool, globalNetworkFlags networkoptions.NetworkFlags) error { // expand passed paths if anrSettings.GenesisPath != "" { anrSettings.GenesisPath = utils.ExpandHome(anrSettings.GenesisPath) @@ -434,9 +438,6 @@ func preLocalChecks(anrSettings ANRSettings, avaGoVersionSettings AvalancheGoVer if avaGoVersionSettings.UseCustomAvalanchegoVersion != "" && (avaGoVersionSettings.UseLatestAvalanchegoReleaseVersion || avaGoVersionSettings.UseLatestAvalanchegoPreReleaseVersion) { return fmt.Errorf("specify either --custom-avalanchego-version or --latest-avalanchego-version") } - if avalanchegoBinaryPath != "" && (avaGoVersionSettings.UseLatestAvalanchegoReleaseVersion || avaGoVersionSettings.UseLatestAvalanchegoPreReleaseVersion || avaGoVersionSettings.UseCustomAvalanchegoVersion != "") { - return fmt.Errorf("specify either --avalanchego-path or --latest-avalanchego-version or --custom-avalanchego-version") - } if useEtnaDevnet && (globalNetworkFlags.UseDevnet || globalNetworkFlags.UseFuji) { return fmt.Errorf("etna devnet can only be used with devnet") } diff --git a/tests/e2e/assets/avalanchego b/tests/e2e/assets/avalanchego deleted file mode 100755 index a2be50823..000000000 Binary files a/tests/e2e/assets/avalanchego and /dev/null differ diff --git a/tests/e2e/commands/etna.go b/tests/e2e/commands/etna.go index 246f52352..3caeb5d34 100644 --- a/tests/e2e/commands/etna.go +++ b/tests/e2e/commands/etna.go @@ -81,7 +81,6 @@ func CreateEtnaSubnetEvmConfig( func CreateLocalEtnaDevnetNode( clusterName string, numNodes int, - avalanchegoPath string, ) (string, error) { cmd := exec.Command( CLIBinary, @@ -92,8 +91,6 @@ func CreateLocalEtnaDevnetNode( etnaDevnetFlag, "--num-nodes", fmt.Sprintf("%d", numNodes), - "--avalanchego-path", - avalanchegoPath, "--"+constants.SkipUpdateFlag, ) fmt.Println(cmd) diff --git a/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoA/suite.go b/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoA/suite.go index 2a4821932..3be59448a 100644 --- a/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoA/suite.go +++ b/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoA/suite.go @@ -8,7 +8,6 @@ import ( "regexp" "github.com/ava-labs/avalanche-cli/tests/e2e/commands" - "github.com/ava-labs/avalanche-cli/tests/e2e/utils" ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" ) @@ -35,7 +34,6 @@ var _ = ginkgo.Describe("[Etna AddRemove Validator SOV PoA]", func() { output, err := commands.CreateLocalEtnaDevnetNode( testLocalNodeName, 7, - utils.EtnaAvalancheGoBinaryPath, ) gomega.Expect(err).Should(gomega.BeNil()) fmt.Println(output) diff --git a/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoS/suite.go b/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoS/suite.go index 6f39aad4f..c4a913ad2 100644 --- a/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoS/suite.go +++ b/tests/e2e/testcases/subnet/sov/addRemoveValidatorPoS/suite.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ava-labs/avalanche-cli/tests/e2e/commands" - "github.com/ava-labs/avalanche-cli/tests/e2e/utils" ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" ) @@ -37,7 +36,6 @@ var _ = ginkgo.Describe("[Etna AddRemove Validator SOV PoS]", func() { output, err := commands.CreateLocalEtnaDevnetNode( testLocalNodeName, 7, - utils.EtnaAvalancheGoBinaryPath, ) gomega.Expect(err).Should(gomega.BeNil()) fmt.Println(output) diff --git a/tests/e2e/testcases/subnet/sov/etna/suite.go b/tests/e2e/testcases/subnet/sov/etna/suite.go index ad85ed3d0..ab47d3032 100644 --- a/tests/e2e/testcases/subnet/sov/etna/suite.go +++ b/tests/e2e/testcases/subnet/sov/etna/suite.go @@ -25,20 +25,17 @@ const ( testLocalNodeName = "e2eSubnetTest-local-node" ) -func createEtnaSubnetEvmConfig() { +func createEtnaSubnetEvmConfig(poa, pos bool) { // Check config does not already exist exists, err := utils.SubnetConfigExists(subnetName) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(exists).Should(gomega.BeFalse()) - // Create config - cmd := exec.Command( - CLIBinary, + cmdArgs := []string{ "blockchain", "create", subnetName, "--evm", - "--proof-of-authority", "--validator-manager-owner", ewoqEVMAddress, "--proxy-contract-owner", @@ -46,8 +43,15 @@ func createEtnaSubnetEvmConfig() { "--production-defaults", "--evm-chain-id=99999", "--evm-token=TOK", - "--"+constants.SkipUpdateFlag, - ) + "--" + constants.SkipUpdateFlag, + } + if poa { + cmdArgs = append(cmdArgs, "--proof-of-authority") + } else if pos { + cmdArgs = append(cmdArgs, "--proof-of-stake") + } + + cmd := exec.Command(CLIBinary, cmdArgs...) output, err := cmd.CombinedOutput() fmt.Println(string(output)) if err != nil { @@ -98,7 +102,6 @@ func deployEtnaSubnetEtnaFlag() { subnetName, "--etna-devnet", "--use-local-machine", - avalancheGoPath+"="+utils.EtnaAvalancheGoBinaryPath, "--num-local-nodes=1", "--ewoq", "--change-owner-address", @@ -128,7 +131,6 @@ func deployEtnaSubnetEtnaFlagConvertOnly() { subnetName, "--etna-devnet", "--use-local-machine", - avalancheGoPath+"="+utils.EtnaAvalancheGoBinaryPath, "--num-local-nodes=1", "--convert-only", "--ewoq", @@ -241,15 +243,20 @@ var _ = ginkgo.Describe("[Etna Subnet SOV]", func() { gomega.Expect(err).Should(gomega.BeNil()) commands.CleanNetwork() }) - ginkgo.It("Create Etna Subnet Config & Deploy the Subnet To Public Etna On Local Machine", func() { - createEtnaSubnetEvmConfig() + ginkgo.It("Create Etna POA Subnet Config & Deploy the Subnet To Public Etna On Local Machine", func() { + createEtnaSubnetEvmConfig(true, false) + deployEtnaSubnetEtnaFlag() + }) + + ginkgo.It("Create Etna POS Subnet Config & Deploy the Subnet To Public Etna On Local Machine", func() { + createEtnaSubnetEvmConfig(false, true) deployEtnaSubnetEtnaFlag() }) ginkgo.It("Start Local Node on Etna & Deploy the Subnet To Public Etna using cluster flag", func() { - _, err := commands.CreateLocalEtnaDevnetNode(testLocalNodeName, 1, utils.EtnaAvalancheGoBinaryPath) + _, err := commands.CreateLocalEtnaDevnetNode(testLocalNodeName, 1) gomega.Expect(err).Should(gomega.BeNil()) - createEtnaSubnetEvmConfig() + createEtnaSubnetEvmConfig(true, false) deployEtnaSubnetClusterFlagConvertOnly(testLocalNodeName) _, err = commands.TrackLocalEtnaSubnet(testLocalNodeName, subnetName) gomega.Expect(err).Should(gomega.BeNil()) @@ -258,9 +265,9 @@ var _ = ginkgo.Describe("[Etna Subnet SOV]", func() { }) ginkgo.It("Mix and match network and cluster flags test 1", func() { - _, err := commands.CreateLocalEtnaDevnetNode(testLocalNodeName, 1, utils.EtnaAvalancheGoBinaryPath) + _, err := commands.CreateLocalEtnaDevnetNode(testLocalNodeName, 1) gomega.Expect(err).Should(gomega.BeNil()) - createEtnaSubnetEvmConfig() + createEtnaSubnetEvmConfig(true, false) deployEtnaSubnetClusterFlagConvertOnly(testLocalNodeName) _, err = commands.TrackLocalEtnaSubnet(testLocalNodeName, subnetName) gomega.Expect(err).Should(gomega.BeNil()) @@ -268,7 +275,7 @@ var _ = ginkgo.Describe("[Etna Subnet SOV]", func() { gomega.Expect(err).Should(gomega.BeNil()) }) ginkgo.It("Mix and match network and cluster flags test 2", func() { - createEtnaSubnetEvmConfig() + createEtnaSubnetEvmConfig(true, false) deployEtnaSubnetEtnaFlagConvertOnly() _, err := commands.TrackLocalEtnaSubnet(testLocalNodeName, subnetName) gomega.Expect(err).Should(gomega.BeNil()) diff --git a/tests/e2e/testcases/validatormanager/suite.go b/tests/e2e/testcases/validatormanager/suite.go index cacc9026b..9eaa2daf4 100644 --- a/tests/e2e/testcases/validatormanager/suite.go +++ b/tests/e2e/testcases/validatormanager/suite.go @@ -84,7 +84,6 @@ func createSovereignSubnet() (string, string, error) { subnetName, "--etna-devnet", "--use-local-machine", - avalancheGoPath+"="+utils.EtnaAvalancheGoBinaryPath, "--num-local-nodes=1", "--ewoq", "--convert-only", diff --git a/tests/e2e/utils/constants.go b/tests/e2e/utils/constants.go index 8994ea79e..bb679c557 100644 --- a/tests/e2e/utils/constants.go +++ b/tests/e2e/utils/constants.go @@ -29,7 +29,6 @@ const ( SubnetEvmAllowFeeRecpPath = "tests/e2e/assets/test_subnet_evm_allowFeeRecps_genesis.json" SubnetEvmGenesisBadPath = "tests/e2e/assets/test_subnet_evm_genesis_bad.json" BootstrapValidatorPath = "tests/e2e/assets/test_bootstrap_validator.json" - EtnaAvalancheGoBinaryPath = "tests/e2e/assets/avalanchego" PluginDirExt = "plugins" ledgerSimDir = "./tests/e2e/ledgerSim"