diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ad3e9a50708..440dedeb8a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -109,3 +109,48 @@ jobs: run: | ./contrib/scripts/test_localnet_liveness.sh 100 5 50 localhost if: env.GIT_DIFF + + upgrade-test: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3.1.0 + with: + fetch-depth: 0 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - uses: technote-space/get-diff-action@v6.0.1 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + - name: Install GaiaV7 + run: | + git checkout v7.1.0 + make build + cp ./build/gaiad ./build/gaiad7 + if: env.GIT_DIFF + - name: Install GaiaV8 + run: | + git checkout - + make build + cp ./build/gaiad ./build/gaiad8 + if: env.GIT_DIFF + - name: Install Cosmovisor + run: | + go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@v1.0.0 + if: env.GIT_DIFF + - name: Start GaiaV7 + run: | + ./contrib/scripts/run-gaia-v7.sh > v7.out 2>&1 & + if: env.GIT_DIFF + - name: Submit Upgrade Commands + run: | + ./contrib/scripts/run-upgrade-commands.sh 15 + if: env.GIT_DIFF + - name: Check for successful upgrade + run: | + ./contrib/scripts/test_upgrade.sh 20 5 16 localhost + if: env.GIT_DIFF diff --git a/app/upgrades/v8/upgrades.go b/app/upgrades/v8/upgrades.go index 0d022f71195..de6a562b7b4 100644 --- a/app/upgrades/v8/upgrades.go +++ b/app/upgrades/v8/upgrades.go @@ -3,8 +3,10 @@ package v8 import ( "errors" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" icacontrollertypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/types" icahosttypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/host/types" @@ -12,20 +14,60 @@ import ( "github.com/cosmos/gaia/v8/app/keepers" ) +func FixBankMetadata(ctx sdk.Context, keepers *keepers.AppKeepers) error { + malformedDenom := "uatomu" + correctDenom := "uatom" + + atomMetaData, foundMalformed := keepers.BankKeeper.GetDenomMetaData(ctx, malformedDenom) + if foundMalformed { + // save it with the correct denom + keepers.BankKeeper.SetDenomMetaData(ctx, atomMetaData) + + // delete the old format + key := keepers.GetKey(banktypes.ModuleName) + store := ctx.KVStore(key) + oldDenomMetaDataStore := prefix.NewStore(store, banktypes.DenomMetadataPrefix) + oldDenomMetaDataStore.Delete([]byte(malformedDenom)) + + // confirm whether the old key is still accessible + foundMalformed = keepers.BankKeeper.HasDenomMetaData(ctx, malformedDenom) + if foundMalformed { + return errors.New("malformed 'uatomu' denom not fixed") + } + } + + // proceed with the original intention of populating the missing Name and Symbol fields + atomMetaData, foundCorrect := keepers.BankKeeper.GetDenomMetaData(ctx, correctDenom) + if !foundCorrect { + return errors.New("atom denom not found") + } + + atomMetaData.Name = "Cosmos Hub Atom" + atomMetaData.Symbol = "ATOM" + keepers.BankKeeper.SetDenomMetaData(ctx, atomMetaData) + + return nil +} + func CreateUpgradeHandler( mm *module.Manager, configurator module.Configurator, keepers *keepers.AppKeepers, ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - // Add atom name and symbol into the bank keeper - atomMetaData, found := keepers.BankKeeper.GetDenomMetaData(ctx, "uatom") - if !found { - return nil, errors.New("atom denom not found") + ctx.Logger().Info("start to run module migrations...") + + vm, err := mm.RunMigrations(ctx, configurator, vm) + if err != nil { + return vm, err + } + + ctx.Logger().Info("running the rest of the upgrade handler...") + + err = FixBankMetadata(ctx, keepers) + if err != nil { + return vm, err } - atomMetaData.Name = "Cosmos Hub Atom" - atomMetaData.Symbol = "ATOM" - keepers.BankKeeper.SetDenomMetaData(ctx, atomMetaData) // Enable controller chain controllerParams := icacontrollertypes.Params{ @@ -42,8 +84,8 @@ func CreateUpgradeHandler( keepers.ICAHostKeeper.SetParams(ctx, hostParams) keepers.ICAControllerKeeper.SetParams(ctx, controllerParams) - ctx.Logger().Info("start to run module migrations...") + ctx.Logger().Info("upgrade complete") - return mm.RunMigrations(ctx, configurator, vm) + return vm, err } } diff --git a/app/upgrades/v8/upgrades_test.go b/app/upgrades/v8/upgrades_test.go new file mode 100644 index 00000000000..08f7833ddd2 --- /dev/null +++ b/app/upgrades/v8/upgrades_test.go @@ -0,0 +1,61 @@ +package v8_test + +import ( + "fmt" + "testing" + + tmrand "github.com/tendermint/tendermint/libs/rand" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/store/prefix" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + gaiahelpers "github.com/cosmos/gaia/v8/app/helpers" + v8 "github.com/cosmos/gaia/v8/app/upgrades/v8" + "github.com/stretchr/testify/require" +) + +func TestFixBankMetadata(t *testing.T) { + app := gaiahelpers.Setup(t) + ctx := app.BaseApp.NewContext(false, tmproto.Header{ + ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), + Height: 1, + }) + + cdc := app.AppCodec() + + malformedDenom := "uatomu" + denomMetaData := banktypes.Metadata{ + Name: "Cosmos Hub Atom", + Symbol: "ATOM", + Description: "The native staking token of the Cosmos Hub.", + DenomUnits: []*banktypes.DenomUnit{ + {"uatom", uint32(0), []string{"microatom"}}, + {"matom", uint32(3), []string{"milliatom"}}, + {"atom", uint32(6), nil}, + }, + Base: "uatom", + Display: "atom", + } + + // add the old format + key := app.AppKeepers.GetKey(banktypes.ModuleName) + store := ctx.KVStore(key) + oldDenomMetaDataStore := prefix.NewStore(store, banktypes.DenomMetadataPrefix) + m := cdc.MustMarshal(&denomMetaData) + oldDenomMetaDataStore.Set([]byte(malformedDenom), m) + + correctDenom := "uatom" + + _, foundCorrect := app.AppKeepers.BankKeeper.GetDenomMetaData(ctx, correctDenom) + require.False(t, foundCorrect) + + err := v8.FixBankMetadata(ctx, &app.AppKeepers) + require.NoError(t, err) + + _, foundCorrect = app.AppKeepers.BankKeeper.GetDenomMetaData(ctx, correctDenom) + require.True(t, foundCorrect) + + _, foundMalformed := app.AppKeepers.BankKeeper.GetDenomMetaData(ctx, malformedDenom) + require.False(t, foundMalformed) + +} diff --git a/contrib/denom.json b/contrib/denom.json new file mode 100644 index 00000000000..71c0a9df440 --- /dev/null +++ b/contrib/denom.json @@ -0,0 +1,30 @@ + + +[{ + "base": "uatom", + "denom_units": [ + { + "aliases": [ + "microatom" + ], + "denom": "uatom", + "exponent": 0 + }, + { + "aliases": [ + "milliatom" + ], + "denom": "matom", + "exponent": 3 + }, + { + "aliases": [], + "denom": "atom", + "exponent": 6 + } + ], + "description": "The native staking token of the Cosmos Hub.", + "display": "atom", + "name": "asdf", + "symbol": "asdf" +}] \ No newline at end of file diff --git a/contrib/scripts/run-gaia-v7.sh b/contrib/scripts/run-gaia-v7.sh new file mode 100755 index 00000000000..b91ee0ad00a --- /dev/null +++ b/contrib/scripts/run-gaia-v7.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +set -o errexit -o nounset + +NODE_HOME=$(realpath ./build/.gaia) +echo "NODE_HOME = ${NODE_HOME}" +BINARY=$NODE_HOME/cosmovisor/genesis/bin/gaiad +echo "BINARY = ${BINARY}" +CHAINID=cosmoshub-4 + +USER_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" + +if ! test -f "./build/gaiad7"; then + echo "gaiad v7 does not exist" + exit +fi + + +rm -rf ./build/.gaia + +mkdir -p "$NODE_HOME"/cosmovisor/genesis/bin +cp ./build/gaiad7 "$NODE_HOME"/cosmovisor/genesis/bin/gaiad +$BINARY init upgrader --chain-id $CHAINID --home "$NODE_HOME" + + +if ! test -f "./build/gaiad8"; then + echo "gaiad v8 does not exist" + exit +fi + +mkdir -p "$NODE_HOME"/cosmovisor/upgrades/v8-Rho/bin +cp ./build/gaiad8 "$NODE_HOME"/cosmovisor/upgrades/v8-Rho/bin/gaiad + +GOPATH=$(go env GOPATH) + +export DAEMON_NAME=gaiad +export DAEMON_HOME=$NODE_HOME +COSMOVISOR=$GOPATH/bin/cosmovisor + + +$BINARY config chain-id $CHAINID --home $NODE_HOME +$BINARY config keyring-backend test --home $NODE_HOME +tmp=$(mktemp) + +# add bank part of genesis +jq --argjson foo "$(jq -c '.' contrib/denom.json)" '.app_state.bank.denom_metadata = $foo' $NODE_HOME/config/genesis.json > "$tmp" && mv "$tmp" $NODE_HOME/config/genesis.json + +# replace default stake token with uatom +sed -i -e 's/stake/uatom/g' $NODE_HOME/config/genesis.json +# min deposition amount (this one isn't working) +sed -i -e 's%"amount": "10000000",%"amount": "1",%g' $NODE_HOME/config/genesis.json +# min voting power that a proposal requires in order to be a valid proposal +sed -i -e 's%"quorum": "0.334000000000000000",%"quorum": "0.000000000000000001",%g' $NODE_HOME/config/genesis.json +# the minimum proportion of "yes" votes requires for the proposal to pass +sed -i -e 's%"threshold": "0.500000000000000000",%"threshold": "0.000000000000000001",%g' $NODE_HOME/config/genesis.json +# voting period to 30s +sed -i -e 's%"voting_period": "172800s"%"voting_period": "30s"%g' $NODE_HOME/config/genesis.json + +echo $USER_MNEMONIC | $BINARY --home $NODE_HOME keys add val --recover --keyring-backend=test +$BINARY add-genesis-account val 10000000000000000000000000uatom --home $NODE_HOME --keyring-backend test +$BINARY gentx val 1000000000uatom --home $NODE_HOME --chain-id $CHAINID +$BINARY collect-gentxs --home $NODE_HOME + +sed -i.bak'' 's/minimum-gas-prices = ""/minimum-gas-prices = "0uatom"/' $NODE_HOME/config/app.toml + +perl -i~ -0777 -pe 's/# Enable defines if the API server should be enabled. +enable = false/# Enable defines if the API server should be enabled. +enable = true/g' $NODE_HOME/config/app.toml + +$COSMOVISOR start --home $NODE_HOME --x-crisis-skip-assert-invariants + diff --git a/contrib/scripts/run-upgrade-commands.sh b/contrib/scripts/run-upgrade-commands.sh new file mode 100755 index 00000000000..d1fb03ca322 --- /dev/null +++ b/contrib/scripts/run-upgrade-commands.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +set -o errexit -o nounset + +UPGRADE_HEIGHT=$1 + +if [ -z "$1" ]; then + echo "Need to add an upgrade height" + exit 1 +fi + +# NODE_HOME=./build/.gaia +NODE_HOME=$(realpath ./build/.gaia) +echo "NODE_HOME = ${NODE_HOME}" + +BINARY=$NODE_HOME/cosmovisor/genesis/bin/gaiad +echo "BINARY = ${BINARY}" + +USER_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" +CHAINID=cosmoshub-4 + +if test -f "$BINARY"; then + + echo "wait 10 seconds for blockchain to start" + sleep 10 + + $BINARY config chain-id $CHAINID --home $NODE_HOME + $BINARY config output json --home $NODE_HOME + $BINARY config keyring-backend test --home $NODE_HOME + $BINARY config --home $NODE_HOME + + + key=$($BINARY keys show val --home $NODE_HOME) + if [ key == "" ]; then + echo $USER_MNEMONIC | $BINARY --home $NODE_HOME keys add val --recover --keyring-backend=test + fi + + # $BINARY keys list --home $NODE_HOME + + echo "\n" + echo "Submitting proposal... \n" + $BINARY tx gov submit-proposal software-upgrade v8-Rho \ + --title v8-Rho \ + --deposit 10000000uatom \ + --upgrade-height $UPGRADE_HEIGHT \ + --upgrade-info "upgrade to v8-Rho" \ + --description "upgrade to v8-Rho" \ + --gas auto \ + --fees 400uatom \ + --from val \ + --keyring-backend test \ + --chain-id $CHAINID \ + --home $NODE_HOME \ + --node tcp://localhost:26657 \ + --yes + echo "Done \n" + + sleep 6 + echo "Casting vote... \n" + + $BINARY tx gov vote 1 yes \ + --from val \ + --keyring-backend test \ + --chain-id $CHAINID \ + --home $NODE_HOME \ + --gas auto \ + --fees 400uatom \ + --node tcp://localhost:26657 \ + --yes + + echo "Done \n" + +else + echo "Please build gaia v7 and move to ./build/gaiad7" +fi diff --git a/contrib/scripts/test_localnet_liveness.sh b/contrib/scripts/test_localnet_liveness.sh index ce5c85c385b..53765c18156 100755 --- a/contrib/scripts/test_localnet_liveness.sh +++ b/contrib/scripts/test_localnet_liveness.sh @@ -32,8 +32,6 @@ fi echo "running 'sh test_localnet_liveness.sh iterations=$ITER sleep=$SLEEP num-blocks=$NUMBLOCKS node-address=$NODEADDR'" -docker_containers=($(docker ps -q -f name=umeed --format='{{.Names}}')) - while [ ${CNT} -lt $ITER ]; do curr_block=$(curl -s $NODEADDR:26657/status | jq -r '.result.sync_info.latest_block_height') diff --git a/contrib/scripts/test_upgrade.sh b/contrib/scripts/test_upgrade.sh new file mode 100755 index 00000000000..a3be816148c --- /dev/null +++ b/contrib/scripts/test_upgrade.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +CNT=0 +ITER=$1 +SLEEP=$2 +NUMBLOCKS=$3 +NODEADDR=$4 + +if [ -z "$1" ]; then + echo "Invalid argument: missing number of iterations" + echo "sh test_upgrade.sh " + exit 1 +fi + +if [ -z "$2" ]; then + echo "Invalid argument: missing sleep duration" + echo "sh test_upgrade.sh " + exit 1 +fi + +if [ -z "$3" ]; then + echo "Invalid argument: missing number of blocks" + echo "sh test_upgrade.sh " + exit 1 +fi + +if [ -z "$4" ]; then + echo "Invalid argument: missing node address" + echo "sh test_upgrade.sh " + exit 1 +fi + +echo "running 'sh test_upgrade.sh iterations=$ITER sleep=$SLEEP num-blocks=$NUMBLOCKS node-address=$NODEADDR'" + +started=false +first_version="" + +while [ ${CNT} -lt $ITER ]; do + curr_block=$(curl -s $NODEADDR:26657/status | jq -r '.result.sync_info.latest_block_height') + curr_version=$(curl -s $NODEADDR:1317/cosmos/base/tendermint/v1beta1/node_info | jq -r '.application_version.version') + + + # tail v7.out + + if [[ $started = "false" && $curr_version != "" && $curr_version != "null" ]]; then + started=true + first_version=$curr_version + echo "First version: ${first_version}" + fi + + echo "count is ${CNT}, iteration ${ITER}, version is " $curr_version + + if [[ "$started" = "true" && ${curr_block} -gt ${NUMBLOCKS} && "$curr_version" != $first_version && "$curr_version" != "" && "$curr_version" != "null" ]]; then + echo "new version running" + exit 0 + fi + + if [[ ${curr_block} -gt ${NUMBLOCKS} ]]; then + echo "Failed: produced ${curr_block} without upgrading" + exit 1 + fi + + + CNT=$(($CNT+1)) + + sleep $SLEEP +done + +echo "Failed: timeout reached" +exit 1