diff --git a/assets/bootstrapSnapshot.PreCortina17.tar.gz b/assets/bootstrapSnapshot.PreCortina17.tar.gz new file mode 100644 index 000000000..f194ef15d Binary files /dev/null and b/assets/bootstrapSnapshot.PreCortina17.tar.gz differ diff --git a/assets/bootstrapSnapshot.tar.gz b/assets/bootstrapSnapshot.tar.gz index f194ef15d..e77e9fdbc 100644 Binary files a/assets/bootstrapSnapshot.tar.gz and b/assets/bootstrapSnapshot.tar.gz differ diff --git a/assets/bootstrapSnapshotSingleNode.PreCortina17.tar.gz b/assets/bootstrapSnapshotSingleNode.PreCortina17.tar.gz new file mode 100644 index 000000000..ceb1b6ded Binary files /dev/null and b/assets/bootstrapSnapshotSingleNode.PreCortina17.tar.gz differ diff --git a/assets/bootstrapSnapshotSingleNode.tar.gz b/assets/bootstrapSnapshotSingleNode.tar.gz index ceb1b6ded..e5f1cbaae 100644 Binary files a/assets/bootstrapSnapshotSingleNode.tar.gz and b/assets/bootstrapSnapshotSingleNode.tar.gz differ diff --git a/assets/sha256sum.PreCortina17.txt b/assets/sha256sum.PreCortina17.txt new file mode 100644 index 000000000..f77f2c559 --- /dev/null +++ b/assets/sha256sum.PreCortina17.txt @@ -0,0 +1 @@ +0c522b9bd798d5b4421a9e8088d9836c984c758640f8089e89c9b15c5a63bf5c assets/bootstrapSnapshot.PreCortina17.tar.gz diff --git a/assets/sha256sum.txt b/assets/sha256sum.txt index 5525c7fbb..7b5225bc9 100644 --- a/assets/sha256sum.txt +++ b/assets/sha256sum.txt @@ -1 +1 @@ -0c522b9bd798d5b4421a9e8088d9836c984c758640f8089e89c9b15c5a63bf5c assets/bootstrapSnapshot.tar.gz +28b06cb8ec5a7814332b9be273d7b3fbb79a44f3192084b8136598c73dd13688 assets/bootstrapSnapshot.tar.gz diff --git a/assets/sha256sumSingleNode.PreCortina17.txt b/assets/sha256sumSingleNode.PreCortina17.txt new file mode 100644 index 000000000..20e77d62d --- /dev/null +++ b/assets/sha256sumSingleNode.PreCortina17.txt @@ -0,0 +1 @@ +cf7416649355aadea88c0a9c6bb3a2f193209000177c64b9dbda18a184a11558 assets/bootstrapSnapshotSingleNode.PreCortina17.tar.gz diff --git a/assets/sha256sumSingleNode.txt b/assets/sha256sumSingleNode.txt index f40a97d0b..417477c05 100644 --- a/assets/sha256sumSingleNode.txt +++ b/assets/sha256sumSingleNode.txt @@ -1 +1 @@ -cf7416649355aadea88c0a9c6bb3a2f193209000177c64b9dbda18a184a11558 assets/bootstrapSnapshotSingleNode.tar.gz +6113f25a6de27f277137b18df06be80501af00f2c1aab579bd82bab3ef789e1e assets/bootstrapSnapshotSingleNode.tar.gz diff --git a/cmd/networkcmd/clean.go b/cmd/networkcmd/clean.go index 624b0a3e7..790c59c61 100644 --- a/cmd/networkcmd/clean.go +++ b/cmd/networkcmd/clean.go @@ -48,7 +48,7 @@ func clean(*cobra.Command, []string) error { configSingleNodeEnabled := app.Conf.GetConfigBoolValue(constants.ConfigSingleNodeEnabledKey) - if _, err := subnet.SetDefaultSnapshot(app.GetSnapshotsDir(), true, configSingleNodeEnabled); err != nil { + if _, err := subnet.SetDefaultSnapshot(app.GetSnapshotsDir(), true, "", configSingleNodeEnabled); err != nil { app.Log.Warn("failed resetting default snapshot", zap.Error(err)) } diff --git a/cmd/subnetcmd/deploy.go b/cmd/subnetcmd/deploy.go index b10357e0c..da9a0da27 100644 --- a/cmd/subnetcmd/deploy.go +++ b/cmd/subnetcmd/deploy.go @@ -358,7 +358,7 @@ func deploySubnet(cmd *cobra.Command, args []string) error { var vmBin string switch sidecar.VM { case models.SubnetEvm: - vmBin, err = binutils.SetupSubnetEVM(app, sidecar.VMVersion) + _, vmBin, err = binutils.SetupSubnetEVM(app, sidecar.VMVersion) if err != nil { return fmt.Errorf("failed to install subnet-evm: %w", err) } diff --git a/cmd/subnetcmd/upgradecmd/vm.go b/cmd/subnetcmd/upgradecmd/vm.go index 2e2e4851d..6b0005f84 100644 --- a/cmd/subnetcmd/upgradecmd/vm.go +++ b/cmd/subnetcmd/upgradecmd/vm.go @@ -324,7 +324,7 @@ func updateExistingLocalVM(sc models.Sidecar, targetVersion string) error { switch sc.VM { // download the binary and prepare to copy it case models.SubnetEvm: - vmBin, err = binutils.SetupSubnetEVM(app, targetVersion) + _, vmBin, err = binutils.SetupSubnetEVM(app, targetVersion) if err != nil { return fmt.Errorf("failed to install subnet-evm: %w", err) } diff --git a/pkg/binutils/avago.go b/pkg/binutils/avago.go index 320a1ebc7..f9b0a692a 100644 --- a/pkg/binutils/avago.go +++ b/pkg/binutils/avago.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/constants" ) -func SetupAvalanchego(app *application.Avalanche, avagoVersion string) (string, error) { +func SetupAvalanchego(app *application.Avalanche, avagoVersion string) (string, string, error) { binDir := app.GetAvalanchegoBinDir() installer := NewInstaller() diff --git a/pkg/binutils/release.go b/pkg/binutils/release.go index c1fe86b38..763d7a972 100644 --- a/pkg/binutils/release.go +++ b/pkg/binutils/release.go @@ -65,7 +65,7 @@ func InstallBinary( repo string, downloader GithubDownloader, installer Installer, -) (string, error) { +) (string, string, error) { if version == "latest" { // get latest version var err error @@ -74,10 +74,10 @@ func InstallBinary( repo, )) if err != nil { - return "", err + return "", "", err } } else if !semver.IsValid(version) { - return "", fmt.Errorf( + return "", "", fmt.Errorf( "invalid version string. Must be semantic version ex: v1.7.14: %s", version) } @@ -85,16 +85,16 @@ func InstallBinary( exists, err := binChecker.ExistsWithVersion(baseBinDir, binPrefix, version) if err != nil { - return "", fmt.Errorf("failed trying to locate binary %s-%s: %s", binPrefix, version, baseBinDir) + return "", "", fmt.Errorf("failed trying to locate binary %s-%s: %s", binPrefix, version, baseBinDir) } + app.Log.Info("Using binary version", zap.String("version", version)) + if exists { app.Log.Debug(binPrefix + version + " found. Skipping installation") - return filepath.Join(baseBinDir, binPrefix+version), nil + return version, filepath.Join(baseBinDir, binPrefix+version), nil } - app.Log.Info("Using binary version", zap.String("version", version)) - binDir, err := installBinaryWithVersion(app, version, installDir, binPrefix, downloader, installer) - return binDir, err + return version, binDir, err } diff --git a/pkg/binutils/subnetEvm.go b/pkg/binutils/subnetEvm.go index 723a245f5..6b8ee525b 100644 --- a/pkg/binutils/subnetEvm.go +++ b/pkg/binutils/subnetEvm.go @@ -10,14 +10,14 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/constants" ) -func SetupSubnetEVM(app *application.Avalanche, subnetEVMVersion string) (string, error) { +func SetupSubnetEVM(app *application.Avalanche, subnetEVMVersion string) (string, string, error) { // Check if already installed binDir := app.GetSubnetEVMBinDir() subDir := filepath.Join(binDir, subnetEVMBinPrefix+subnetEVMVersion) installer := NewInstaller() downloader := NewSubnetEVMDownloader() - vmDir, err := InstallBinary( + version, vmDir, err := InstallBinary( app, subnetEVMVersion, binDir, @@ -28,5 +28,5 @@ func SetupSubnetEVM(app *application.Avalanche, subnetEVMVersion string) (string downloader, installer, ) - return filepath.Join(vmDir, constants.SubnetEVMBin), err + return version, filepath.Join(vmDir, constants.SubnetEVMBin), err } diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index dbcca0f57..8334cefec 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -79,7 +79,11 @@ const ( DefaultSnapshotName = "default-1654102509" - BootstrapSnapshotRawBranch = "https://github.com/ava-labs/avalanche-cli/raw/main/" + Cortina17Version = "v1.10.17" + + BootstrapSnapshotRawBranch = "https://github.com/ava-labs/avalanche-cli/raw/cchain-warp-snapshot/" + + CurrentBootstrapNamePath = "currentBootstrapName.txt" BootstrapSnapshotArchiveName = "bootstrapSnapshot.tar.gz" BootstrapSnapshotLocalPath = "assets/" + BootstrapSnapshotArchiveName @@ -91,6 +95,16 @@ const ( BootstrapSnapshotSingleNodeURL = BootstrapSnapshotRawBranch + BootstrapSnapshotSingleNodeLocalPath BootstrapSnapshotSingleNodeSHA256URL = BootstrapSnapshotRawBranch + "assets/sha256sumSingleNode.txt" + BootstrapSnapshotPreCortina17ArchiveName = "bootstrapSnapshot.PreCortina17.tar.gz" + BootstrapSnapshotPreCortina17LocalPath = "assets/" + BootstrapSnapshotPreCortina17ArchiveName + BootstrapSnapshotPreCortina17URL = BootstrapSnapshotRawBranch + BootstrapSnapshotPreCortina17LocalPath + BootstrapSnapshotPreCortina17SHA256URL = BootstrapSnapshotRawBranch + "assets/sha256sum.PreCortina17.txt" + + BootstrapSnapshotSingleNodePreCortina17ArchiveName = "bootstrapSnapshotSingleNode.PreCortina17.tar.gz" + BootstrapSnapshotSingleNodePreCortina17LocalPath = "assets/" + BootstrapSnapshotSingleNodePreCortina17ArchiveName + BootstrapSnapshotSingleNodePreCortina17URL = BootstrapSnapshotRawBranch + BootstrapSnapshotSingleNodePreCortina17LocalPath + BootstrapSnapshotSingleNodePreCortina17SHA256URL = BootstrapSnapshotRawBranch + "assets/sha256sumSingleNode.PreCortina17.txt" + CliInstallationURL = "https://raw.githubusercontent.com/ava-labs/avalanche-cli/main/scripts/install.sh" ExpectedCliInstallErr = "resource temporarily unavailable" EIPLimitErr = "AddressLimitExceeded" diff --git a/pkg/plugins/plugin.go b/pkg/plugins/plugin.go index a6e96b376..18257bd8b 100644 --- a/pkg/plugins/plugin.go +++ b/pkg/plugins/plugin.go @@ -52,7 +52,7 @@ func CreatePlugin(app *application.Avalanche, subnetName string, pluginDir strin switch sc.VM { case models.SubnetEvm: - vmSourcePath, err = binutils.SetupSubnetEVM(app, sc.VMVersion) + _, vmSourcePath, err = binutils.SetupSubnetEVM(app, sc.VMVersion) if err != nil { return "", fmt.Errorf("failed to install subnet-evm: %w", err) } @@ -82,7 +82,7 @@ func CreatePluginFromVersion( switch vm { case models.SubnetEvm: - vmSourcePath, err = binutils.SetupSubnetEVM(app, version) + _, vmSourcePath, err = binutils.SetupSubnetEVM(app, version) if err != nil { return "", fmt.Errorf("failed to install subnet-evm: %w", err) } diff --git a/pkg/subnet/local.go b/pkg/subnet/local.go index dbf72f743..86c38dadb 100644 --- a/pkg/subnet/local.go +++ b/pkg/subnet/local.go @@ -16,6 +16,7 @@ import ( "strings" "golang.org/x/exp/maps" + "golang.org/x/mod/semver" "github.com/ava-labs/avalanche-cli/pkg/application" "github.com/ava-labs/avalanche-cli/pkg/binutils" @@ -75,7 +76,7 @@ func NewLocalDeployer(app *application.Avalanche, avagoVersion string, vmBin str type getGRPCClientFunc func(...binutils.GRPCClientOpOption) (client.Client, error) -type setDefaultSnapshotFunc func(string, bool, bool) (bool, error) +type setDefaultSnapshotFunc func(string, bool, string, bool) (bool, error) // DeployToLocalNetwork does the heavy lifting: // * it checks the gRPC is running, if not, it starts it @@ -568,15 +569,15 @@ func (d *LocalDeployer) printExtraEvmInfo(chain string, chainGenesis []byte) err // * if not, it downloads it and installs it (os - and archive dependent) // * returns the location of the avalanchego path func (d *LocalDeployer) SetupLocalEnv() (bool, string, error) { - configSingleNodeEnabled := d.app.Conf.GetConfigBoolValue(constants.ConfigSingleNodeEnabledKey) - needsRestart, err := d.setDefaultSnapshot(d.app.GetSnapshotsDir(), false, configSingleNodeEnabled) + avagoVersion, avagoDir, err := d.setupLocalEnv() if err != nil { - return false, "", fmt.Errorf("failed setting up snapshots: %w", err) + return false, "", fmt.Errorf("failed setting up local environment: %w", err) } - avagoDir, err := d.setupLocalEnv() + configSingleNodeEnabled := d.app.Conf.GetConfigBoolValue(constants.ConfigSingleNodeEnabledKey) + needsRestart, err := d.setDefaultSnapshot(d.app.GetSnapshotsDir(), false, avagoVersion, configSingleNodeEnabled) if err != nil { - return false, "", fmt.Errorf("failed setting up local environment: %w", err) + return false, "", fmt.Errorf("failed setting up snapshots: %w", err) } pluginDir := d.app.GetPluginsDir() @@ -603,7 +604,7 @@ func (d *LocalDeployer) SetupLocalEnv() (bool, string, error) { return needsRestart, avalancheGoBinPath, nil } -func (d *LocalDeployer) setupLocalEnv() (string, error) { +func (d *LocalDeployer) setupLocalEnv() (string, string, error) { return binutils.SetupAvalanchego(d.app, d.avagoVersion) } @@ -667,11 +668,41 @@ func (d *LocalDeployer) removeInstalledPlugin( return d.binaryDownloader.RemoveVM(vmID.String()) } -func getExpectedDefaultSnapshotSHA256Sum(isSingleNode bool) (string, error) { - url := constants.BootstrapSnapshotSHA256URL +func getSnapshotLocs(isSingleNode bool, isPreCortina17 bool) (string, string, string, string) { + bootstrapSnapshotArchiveName := "" + url := "" + shaSumURL := "" + pathInShaSum := "" if isSingleNode { - url = constants.BootstrapSnapshotSingleNodeSHA256URL + if isPreCortina17 { + bootstrapSnapshotArchiveName = constants.BootstrapSnapshotSingleNodePreCortina17ArchiveName + url = constants.BootstrapSnapshotSingleNodePreCortina17URL + shaSumURL = constants.BootstrapSnapshotSingleNodePreCortina17SHA256URL + pathInShaSum = constants.BootstrapSnapshotSingleNodePreCortina17LocalPath + } else { + bootstrapSnapshotArchiveName = constants.BootstrapSnapshotSingleNodeArchiveName + url = constants.BootstrapSnapshotSingleNodeURL + shaSumURL = constants.BootstrapSnapshotSingleNodeSHA256URL + pathInShaSum = constants.BootstrapSnapshotSingleNodeLocalPath + } + } else { + if isPreCortina17 { + bootstrapSnapshotArchiveName = constants.BootstrapSnapshotPreCortina17ArchiveName + url = constants.BootstrapSnapshotPreCortina17URL + shaSumURL = constants.BootstrapSnapshotPreCortina17SHA256URL + pathInShaSum = constants.BootstrapSnapshotPreCortina17LocalPath + } else { + bootstrapSnapshotArchiveName = constants.BootstrapSnapshotArchiveName + url = constants.BootstrapSnapshotURL + shaSumURL = constants.BootstrapSnapshotSHA256URL + pathInShaSum = constants.BootstrapSnapshotLocalPath + } } + return bootstrapSnapshotArchiveName, url, shaSumURL, pathInShaSum +} + +func getExpectedDefaultSnapshotSHA256Sum(isSingleNode bool, isPreCortina17 bool) (string, error) { + _, _, url, path := getSnapshotLocs(isSingleNode, isPreCortina17) resp, err := http.Get(url) if err != nil { return "", fmt.Errorf("failed downloading sha256 sums: %w", err) @@ -684,10 +715,6 @@ func getExpectedDefaultSnapshotSHA256Sum(isSingleNode bool) (string, error) { if err != nil { return "", fmt.Errorf("failed downloading sha256 sums: %w", err) } - path := constants.BootstrapSnapshotLocalPath - if isSingleNode { - path = constants.BootstrapSnapshotSingleNodeLocalPath - } expectedSum, err := utils.SearchSHA256File(sha256FileBytes, path) if err != nil { return "", fmt.Errorf("failed obtaining snapshot sha256 sum: %w", err) @@ -697,11 +724,32 @@ func getExpectedDefaultSnapshotSHA256Sum(isSingleNode bool) (string, error) { // Initialize default snapshot with bootstrap snapshot archive // If force flag is set to true, overwrite the default snapshot if it exists -func SetDefaultSnapshot(snapshotsDir string, forceReset bool, isSingleNode bool) (bool, error) { - bootstrapSnapshotArchivePath := filepath.Join(snapshotsDir, constants.BootstrapSnapshotArchiveName) - if isSingleNode { - bootstrapSnapshotArchivePath = filepath.Join(snapshotsDir, constants.BootstrapSnapshotSingleNodeArchiveName) +func SetDefaultSnapshot(snapshotsDir string, resetCurrentSnapshot bool, avagoVersion string, isSingleNode bool) (bool, error) { + var isPreCortina17 bool + if avagoVersion != "" { + isPreCortina17 = semver.Compare(avagoVersion, constants.Cortina17Version) < 0 + } + bootstrapSnapshotArchiveName, url, _, _ := getSnapshotLocs(isSingleNode, isPreCortina17) + currentBootstrapNamePath := filepath.Join(snapshotsDir, constants.CurrentBootstrapNamePath) + exists, err := storage.FileExists(currentBootstrapNamePath) + if err != nil { + return false, err } + if exists { + currentBootstrapNameBytes, err := os.ReadFile(currentBootstrapNamePath) + if err != nil { + return false, err + } + currentBootstrapName := string(currentBootstrapNameBytes) + if currentBootstrapName != bootstrapSnapshotArchiveName { + // there is a snapshot image change. + resetCurrentSnapshot = true + } + } else { + // we have no ref of currently used snapshot image + resetCurrentSnapshot = true + } + bootstrapSnapshotArchivePath := filepath.Join(snapshotsDir, bootstrapSnapshotArchiveName) defaultSnapshotPath := filepath.Join(snapshotsDir, "anr-snapshot-"+constants.DefaultSnapshotName) defaultSnapshotInUse := false if _, err := os.Stat(defaultSnapshotPath); err == nil { @@ -716,19 +764,14 @@ func SetDefaultSnapshot(snapshotsDir string, forceReset bool, isSingleNode bool) if err != nil { return false, err } - expectedSum, err := getExpectedDefaultSnapshotSHA256Sum(isSingleNode) + expectedSum, err := getExpectedDefaultSnapshotSHA256Sum(isSingleNode, isPreCortina17) if err != nil { ux.Logger.PrintToUser("Warning: failure verifying that the local snapshot is the latest one: %s", err) } else if gotSum != expectedSum { downloadSnapshot = true } } - resetCurrentSnapshot := forceReset if downloadSnapshot { - url := constants.BootstrapSnapshotURL - if isSingleNode { - url = constants.BootstrapSnapshotSingleNodeURL - } resp, err := http.Get(url) if err != nil { return false, fmt.Errorf("failed downloading bootstrap snapshot: %w", err) @@ -760,6 +803,9 @@ func SetDefaultSnapshot(snapshotsDir string, forceReset bool, isSingleNode bool) if err := binutils.InstallArchive("tar.gz", bootstrapSnapshotBytes, snapshotsDir); err != nil { return false, fmt.Errorf("failed installing bootstrap snapshot: %w", err) } + if err := os.WriteFile(currentBootstrapNamePath, []byte(bootstrapSnapshotArchiveName), constants.DefaultPerms755); err != nil { + return false, err + } } return resetCurrentSnapshot, nil } diff --git a/pkg/subnet/local_test.go b/pkg/subnet/local_test.go index d8251d3ec..34b14281f 100644 --- a/pkg/subnet/local_test.go +++ b/pkg/subnet/local_test.go @@ -191,6 +191,6 @@ func getTestClientFunc(...binutils.GRPCClientOpOption) (client.Client, error) { return c, nil } -func fakeSetDefaultSnapshot(string, bool, bool) (bool, error) { +func fakeSetDefaultSnapshot(string, bool, string, bool) (bool, error) { return false, nil }