diff --git a/.github/workflows/software-upgrade-test.yml b/.github/workflows/software-upgrade-test.yml index 94ff83de7..0c3db49fd 100644 --- a/.github/workflows/software-upgrade-test.yml +++ b/.github/workflows/software-upgrade-test.yml @@ -184,9 +184,10 @@ jobs: - name: Create new snapshot file run: | - NEW_SNAPSHOT_PATH=/tmp/elys-snapshot-${{ github.head_ref }}.tar.lz4 + SANITIZED_HEAD_REF=$(echo "${{ github.head_ref }}" | sed 's|/|_|g') + NEW_SNAPSHOT_PATH="/tmp/elys-snapshot-${SANITIZED_HEAD_REF}.tar.lz4" echo "NEW_SNAPSHOT_PATH=$NEW_SNAPSHOT_PATH" >> $GITHUB_ENV - tar -cf - ~/.elys | lz4 -z - > $NEW_SNAPSHOT_PATH + tar -cf - ~/.elys | lz4 -z - > "$NEW_SNAPSHOT_PATH" - name: Upload snapshot run: | diff --git a/cmd/upgrade-assure/get-flags.go b/cmd/upgrade-assure/get-flags.go index f9afc5873..253661705 100644 --- a/cmd/upgrade-assure/get-flags.go +++ b/cmd/upgrade-assure/get-flags.go @@ -19,6 +19,7 @@ const ( flagSkipPrepareValidatorData = "skip-prepare-validator-data" flagSkipSubmitProposal = "skip-submit-proposal" flagSkipUpgradeToNewBinary = "skip-upgrade-to-new-binary" + flagSkipUnbondValidator = "skip-unbond-validator" flagChainId = "chain-id" flagKeyringBackend = "keyring-backend" flagGenesisFilePath = "genesis-file-path" @@ -66,6 +67,7 @@ func getFlags(cmd *cobra.Command) ( skipPrepareValidatorData bool, skipSubmitProposal bool, skipUpgradeToNewBinary bool, + skipUnbondValidator bool, chainId string, keyringBackend string, genesisFilePath string, @@ -151,6 +153,11 @@ func getFlags(cmd *cobra.Command) ( log.Printf(ColorYellow + "skipping upgrade to new binary") } + skipUnbondValidator, _ = cmd.Flags().GetBool(flagSkipUnbondValidator) + if skipUnbondValidator { + log.Printf(ColorYellow + "skipping unbond validator") + } + chainId, _ = cmd.Flags().GetString(flagChainId) if chainId == "" { log.Fatalf(ColorRed + "chain id is required") diff --git a/cmd/upgrade-assure/query-operator-address.go b/cmd/upgrade-assure/query-operator-address.go new file mode 100644 index 000000000..25f87f195 --- /dev/null +++ b/cmd/upgrade-assure/query-operator-address.go @@ -0,0 +1,23 @@ +package main + +import ( + "log" + "os/exec" + "strings" +) + +func queryOperatorAddress(cmdPath, homePath, keyringBackend, validatorName string) string { + // Command and arguments + args := []string{"keys", "show", validatorName, "--bech", "val", "--home", homePath, "--keyring-backend", keyringBackend, "--address"} + + // Execute the command + output, err := exec.Command(cmdPath, args...).CombinedOutput() + if err != nil { + log.Fatalf(ColorRed+"Failed to query validator pubkey: %v", err) + } + + // trim the output + outputStr := strings.TrimSpace(string(output)) + + return outputStr +} diff --git a/cmd/upgrade-assure/unbond-validator.go b/cmd/upgrade-assure/unbond-validator.go new file mode 100644 index 000000000..784e78936 --- /dev/null +++ b/cmd/upgrade-assure/unbond-validator.go @@ -0,0 +1,42 @@ +package main + +import ( + "log" + "os/exec" + "time" +) + +func unbondValidator(cmdPath, validatorKeyName, operatorAddress, validatorSelfDelegation, keyringBackend, chainId, rpc, broadcastMode, homePath string) { + // Command and arguments + args := []string{ + "tx", + "staking", + "unbond", + operatorAddress, + validatorSelfDelegation, + "--from", validatorKeyName, + "--keyring-backend", keyringBackend, + "--chain-id", chainId, + "--node", rpc, + "--broadcast-mode", broadcastMode, + "--fees", "100000uelys", + "--gas", "1000000", + "--home", homePath, + "--output", "json", + "--yes", + } + + // Execute the command + output, err := exec.Command(cmdPath, args...).CombinedOutput() + if err != nil { + log.Fatalf(ColorRed+"Command execution failed: %v", err) + } + + // Parse output to find the transaction hash + txHash, err := parseTxHash(output) + if err != nil { + log.Fatalf(ColorRed+"Failed to parse transaction hash: %v", err) + } + + waitForTxConfirmation(cmdPath, rpc, txHash, 5*time.Minute) +} diff --git a/cmd/upgrade-assure/upgrade-assure.go b/cmd/upgrade-assure/upgrade-assure.go index b99043c2f..76d4dd5b3 100644 --- a/cmd/upgrade-assure/upgrade-assure.go +++ b/cmd/upgrade-assure/upgrade-assure.go @@ -19,7 +19,7 @@ func main() { snapshotUrl, oldBinaryUrl, newBinaryUrl := getArgs(args) // global flags onlyStartWithNewBinary, skipSnapshot, skipChainInit, skipNodeStart, skipProposal, skipBinary, - skipCreateValidator, skipPrepareValidatorData, skipSubmitProposal, skipUpgradeToNewBinary, + skipCreateValidator, skipPrepareValidatorData, skipSubmitProposal, skipUpgradeToNewBinary, skipUnbondValidator, chainId, keyringBackend, genesisFilePath, broadcastMode, dbEngine, // timeouts timeOutToWaitForService, timeOutToWaitForNextBlock, @@ -220,6 +220,16 @@ func main() { queryUpgradeApplied(newBinaryPath, rpc, newVersion) queryUpgradeApplied(newBinaryPath, rpc2, newVersion) + if !skipUnbondValidator { + operatorAddress2 := queryOperatorAddress(newBinaryPath, homePath, keyringBackend, validatorKeyName2) + + // unbound the second validator power + unbondValidator(newBinaryPath, validatorKeyName2, operatorAddress2, validatorSelfDelegation2, keyringBackend, chainId, rpc, broadcastMode, homePath) + + // wait for next block + waitForNextBlock(newBinaryPath, rpc, moniker, timeOutForNextBlock) + } + // stop new binaries stop(newBinaryCmd, newBinaryCmd2) } @@ -241,6 +251,7 @@ func main() { rootCmd.PersistentFlags().Bool(flagSkipPrepareValidatorData, false, "skip prepare validator data") rootCmd.PersistentFlags().Bool(flagSkipSubmitProposal, false, "skip submit proposal") rootCmd.PersistentFlags().Bool(flagSkipUpgradeToNewBinary, false, "skip upgrade to new binary") + rootCmd.PersistentFlags().Bool(flagSkipUnbondValidator, false, "skip unbond validator") rootCmd.PersistentFlags().String(flagChainId, "elystestnet-1", "chain id") rootCmd.PersistentFlags().String(flagKeyringBackend, "test", "keyring backend") rootCmd.PersistentFlags().String(flagGenesisFilePath, "/tmp/genesis.json", "genesis file path")