Skip to content

How to upgrade ibc go

Carlos Rodriguez edited this page Jun 10, 2022 · 12 revisions

This is a step-by-step guide of how to upgrade ibc-go to a newer version. The example explained in this guide assumes the following:

  • An upgrade of ibc-go from v2 to v3.
  • A chain running locally with a single validator node.
  • A chain that starts from clean state.
  • A chain with 2 accounts (1 validator, 1 wallet).
  • The chain binary is gaiad.

Therefore based on your own situation, you might need to adjust the parameters or commands presented here.

Step 1: change the gov parameters in genesis.json

For the purposes of this example we are going to change some of the gov parameters in the genesis.json file, so that we can complete the upgrade faster. These are the changes needed:

"gov": {
  "starting_proposal_id": "1",
  "deposits": [],
  "votes": [],
  "proposals": [],
  "deposit_params": {
    "min_deposit": [
      {
        "denom": "stake",
-       "amount": "10000000"
+       "amount": "100"
      }
    ],
    "max_deposit_period": "172800s"
  },
  "voting_params": {
-   "voting_period": "172800s"
+   "voting_period": "180s"
  },
  "tally_params": {
    "quorum": "0.334000000000000000",
-   "threshold": "0.500000000000000000",
+   "threshold": "0.300000000000000000",
    "veto_threshold": "0.334000000000000000"
  }
},

The amount is decreased so that a smaller minimum deposit amount is needed to vote for the software upgrade proposal. The voting period is also decreased, so that we don't need to wait very long before the proposal passes. The threshold is also decreased to make sure that voting yes with the single validator account in the chain is enough to make the proposal pass. The voting period will not start until the proposal's deposit equals the minimim deposit amount. To learn more about the gov module, please read the Cosmos SDK documentation.

Step 2: submit proposal for software upgrade

This is the command that we need to run:

./gaiad tx gov submit-proposal software-upgrade v3 \
--upgrade-height 50 \
--title v3 \
--description v3 \
--deposit 100stake \
--from validator \
--chain-id chain1 \
--keyring-backend test \
--home ../../gm/chain1 \
--node http://localhost:27000

The upgrade height is the block height at which the chain will panic if the proposal is accepted. It must be a block height that is committed after the voting period finishes (the proposal will not be considered as passed if the voting period finishes after the upgrade height, even if enough voting power has voted yes for the proposal). To find out the current block height we can run the command ./gaiad status --node http://localhost:27000, which would give a similar output as this:

{
  "NodeInfo": {
    "protocol_version": {
      "p2p": "8",
      "block": "11",
      "app": "0"
    },
    "id": "55656b6e7e80499c2ca5727aa7e6516b6ac61cbd",
    "listen_addr": "tcp://0.0.0.0:27003",
    "network": "chain1",
    "version": "v0.34.15",
    "channels": "40202122233038606100",
    "moniker": "chain1",
    "other": {
      "tx_index": "on",
      "rpc_address": "tcp://0.0.0.0:27000"
    }
  },
  "SyncInfo": {
    "latest_block_hash": "1C99A7BD5CC6014D604CCBF135BC46C329B2FF8E368DD21AD2E48404E7F8F8B9",
    "latest_app_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "latest_block_height": "1",
    "latest_block_time": "2021-11-05T10:07:02.833229Z",
    "earliest_block_hash": "1C99A7BD5CC6014D604CCBF135BC46C329B2FF8E368DD21AD2E48404E7F8F8B9",
    "earliest_app_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "earliest_block_height": "1",
    "earliest_block_time": "2021-11-05T10:07:02.833229Z",
    "catching_up": false
  },
  "ValidatorInfo": {
    "Address": "C177A466BCB22688D7C197B5DE28CCBEB0D64090",
    "PubKey": {
      "type": "tendermint/PubKeyEd25519",
      "value": "j3nRik8uLd7xcA7VG8zsa7v7zhA/6iM5u6+w4V1I1zk="
    },
    "VotingPower": "10"
  }
}

The latest_block_height is 1, so we chose 50 for the upgrade height to make sure that the voting period will finish before block height 50 is reached.

We can now query the chain to get the proposal information by executing the command ./gaiad q gov proposals --node http://localhost:27000, which would give a similar output as this:

pagination:
  next_key: null
  total: "0"
proposals:
- content:
    '@type': /cosmos.upgrade.v1beta1.SoftwareUpgradeProposal
    description: v3
    plan:
      height: "75"
      info: ""
      name: v3
      time: "0001-01-01T00:00:00Z"
      upgraded_client_state: null
    title: v3
  deposit_end_time: "2022-03-03T20:34:56.984921Z"
  final_tally_result:
    abstain: "0"
    "no": "0"
    no_with_veto: "0"
    "yes": "0"
  proposal_id: "1"
  status: PROPOSAL_STATUS_VOTING_PERIOD
  submit_time: "2022-03-01T20:34:56.984921Z"
  total_deposit:
  - amount: "100"
    denom: stake
  voting_end_time: "2022-03-01T20:37:56.984921Z"
  voting_start_time: "2022-03-01T20:34:56.984921Z"

Step 3: vote for the proposal

We vote yes for the proposal by executing the following command:

./gaiad tx gov vote 1 yes \
--from validator \
--chain-id chain1 \
--keyring-backend test
--home ../../gm/chain1 \
--node http://localhost:27000

Now we wait 180 seconds for the voting period to finish and when the block height reaches 50, then we can check that the proposal has passed by executing the command ./gaiad q gov proposals --node http://localhost:27000, which would give a similar output as this:

pagination:
  next_key: null
  total: "0"
proposals:
- content:
    '@type': /cosmos.upgrade.v1beta1.SoftwareUpgradeProposal
    description: v3
    plan:
      height: "75"
      info: ""
      name: v3
      time: "0001-01-01T00:00:00Z"
      upgraded_client_state: null
    title: v3
  deposit_end_time: "2022-03-03T20:34:56.984921Z"
  final_tally_result:
    abstain: "0"
    "no": "0"
    no_with_veto: "0"
    "yes": "10000000"
  proposal_id: "1"
  status: PROPOSAL_STATUS_PASSED
  submit_time: "2022-03-01T20:34:56.984921Z"
  total_deposit:
  - amount: "100"
    denom: stake
  voting_end_time: "2022-03-01T20:37:56.984921Z"
  voting_start_time: "2022-03-01T20:34:56.984921Z"

If we check the logs of the chain, then we can see that it has panicked at the expected block height:

[90m9:41PM[0m [1m[31mERR[0m[0m UPGRADE "v3" NEEDED at height: 75: 
[90m9:41PM[0m [1m[31mERR[0m[0m CONSENSUS FAILURE!!! [36merr=[0m"UPGRADE \"v3\" NEEDED at height: 75: " [36mmodule=[0mconsensus [36mstack=[0m"goroutine 117 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngit.luolix.top/tendermint/tendermint/consensus.(*State).receiveRoutine.func2()\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:726 +0x4c\npanic({0x5474b40, 0xc000c860e0})\n\truntime/panic.go:1038 +0x215\ngit.luolix.top/cosmos/cosmos-sdk/x/upgrade.BeginBlocker({{0x7ffeefbff74d, 0x35}, 0xc0000e79b0, {0x5bb62d0, 0xc000c87660}, {0x5c0ea38, 0xc00107f920}, 0xc001313e30, {0x5ba67a0, 0xc00119b1e0}}, ...)\n\tgit.luolix.top/cosmos/cosmos-sdk@v0.44.6/x/upgrade/abci.go:54 +0xc1f\ngit.luolix.top/cosmos/cosmos-sdk/x/upgrade.AppModule.BeginBlock(...)\n\tgit.luolix.top/cosmos/cosmos-sdk@v0.44.6/x/upgrade/module.go:130\ngit.luolix.top/cosmos/cosmos-sdk/types/module.(*Manager).BeginBlock(_, {{0x5be8028, 0xc000190008}, {0x5c13fe0, 0xc001142c80}, {{0xb, 0x0}, {0xc0012b6b9a, 0x6}, 0x4b, ...}, ...}, ...)\n\tgit.luolix.top/cosmos/cosmos-sdk@v0.44.6/types/module/module.go:465 +0x218\ngit.luolix.top/cosmos/gaia/v6/app.(*GaiaApp).BeginBlocker(...)\n\tgit.luolix.top/cosmos/gaia/v6/app/app.go:628\ngit.luolix.top/cosmos/cosmos-sdk/baseapp.(*BaseApp).BeginBlock(_, {{0xc003efff40, 0x20, 0x20}, {{0xb, 0x0}, {0xc0012b6b9a, 0x6}, 0x4b, {0x22385870, ...}, ...}, ...})\n\tgit.luolix.top/cosmos/cosmos-sdk@v0.44.6/baseapp/abci.go:194 +0x9dc\ngit.luolix.top/tendermint/tendermint/abci/client.(*localClient).BeginBlockSync(_, {{0xc003efff40, 0x20, 0x20}, {{0xb, 0x0}, {0xc0012b6b9a, 0x6}, 0x4b, {0x22385870, ...}, ...}, ...})\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/abci/client/local_client.go:280 +0x118\ngit.luolix.top/tendermint/tendermint/proxy.(*appConnConsensus).BeginBlockSync(_, {{0xc003efff40, 0x20, 0x20}, {{0xb, 0x0}, {0xc0012b6b9a, 0x6}, 0x4b, {0x22385870, ...}, ...}, ...})\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/proxy/app_conn.go:81 +0x55\ngit.luolix.top/tendermint/tendermint/state.execBlockOnProxyApp({0x5be8d80, 0xc00007b440}, {0x5bfd5b0, 0xc00133ee80}, 0xc000e33c20, {0x5c0f368, 0xc00133e210}, 0x4a)\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/state/execution.go:307 +0x3dd\ngit.luolix.top/tendermint/tendermint/state.(*BlockExecutor).ApplyBlock(_, {{{0xb, 0x0}, {0xc000e81040, 0x8}}, {0xc000e81048, 0x6}, 0x1, 0x4a, {{0xc003abc7a0, ...}, ...}, ...}, ...)\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/state/execution.go:140 +0x171\ngit.luolix.top/tendermint/tendermint/consensus.(*State).finalizeCommit(0xc00104e700, 0x4b)\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:1635 +0x9fd\ngit.luolix.top/tendermint/tendermint/consensus.(*State).tryFinalizeCommit(0xc00104e700, 0x4b)\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:1546 +0x305\ngit.luolix.top/tendermint/tendermint/consensus.(*State).enterCommit.func1()\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:1481 +0x87\ngit.luolix.top/tendermint/tendermint/consensus.(*State).enterCommit(0xc00104e700, 0x4b, 0x0)\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:1519 +0xc06\ngit.luolix.top/tendermint/tendermint/consensus.(*State).addVote(0xc00104e700, 0xc003e288c0, {0x0, 0x0})\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:2132 +0xb6e\ngit.luolix.top/tendermint/tendermint/consensus.(*State).tryAddVote(0xc00104e700, 0xc003e288c0, {0x0, 0x4076aa6})\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:1930 +0x2c\ngit.luolix.top/tendermint/tendermint/consensus.(*State).handleMsg(0xc00104e700, {{0x5ba75e0, 0xc004152120}, {0x0, 0x0}})\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:838 +0x40b\ngit.luolix.top/tendermint/tendermint/consensus.(*State).receiveRoutine(0xc00104e700, 0x0)\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:782 +0x512\ncreated by github.com/tendermint/tendermint/consensus.(*State).OnStart\n\tgit.luolix.top/tendermint/tendermint@v0.34.15/consensus/state.go:378 +0x12f\n"

Step 4: swap the chain binary with the new ibc-go version

We stop the chain and swap the binary now. The new binary includes an upgrade handler that will execute upgrade logic. After restarting the chain, the log shows that the upgrade is executed:

[90m9:42PM[0m [32mINF[0m applying upgrade "v3" at height: 75
[90m9:42PM[0m [32mINF[0m created new capability [36mmodule=[0mibc [36mname=[0mports/icahost
[90m9:42PM[0m [32mINF[0m port binded [36mmodule=[0mx/ibc/port [36mport=[0micahost
[90m9:42PM[0m [32mINF[0m claimed capability [36mcapability=[0m2 [36mmodule=[0micahost [36mname=[0mports/icahost
[90m9:42PM[0m [32mINF[0m start to run module migrations...

In this particular example the upgrade has set the host and controller submodule params of ICS-27. And we can check that those parameters are set:

> ./gaiad q interchain-accounts controller params --height 100 --node http://localhost:27000`
controller_enabled: true
> ./gaiad q interchain-accounts host params --height 100 --node http://localhost:27000`
allow_messages:
- /cosmos.bank.v1beta1.MsgSend
host_enabled: true