摘要

x/upgrade 是 Cosmos SDK 模块的一种实现,用于帮助正在运行的 Cosmos 链平滑升级到新的(含破坏性变更的)软件版本。它通过提供一个 PreBlocker 钩子来实现这一点:当达到预定义的升级区块高度后,阻止区块链状态机继续推进。 该模块并不规定治理如何决定执行升级,而只提供一种安全协调升级的机制。如果没有软件层面的升级支持,升级一条在线链是有风险的,因为所有验证者都需要在流程中的完全相同位置暂停其状态机。如果这一步没有正确完成,就可能出现难以恢复的状态不一致。

概念

计划

x/upgrade 模块定义了一个 Plan 类型,用于安排在线升级的发生时间。Plan 可以被安排在某个特定的区块高度执行。 当一个冻结的候选发布版本以及相应的升级 Handler(见下文)达成一致后,就会创建一个 Plan,其中 Plan 的 Name 对应某个特定的 Handler。通常,Plan 是通过治理提案流程创建的,在投票通过后被安排执行。Plan 的 Info 可以包含与升级相关的各种元数据,通常是应用特定的升级信息,会写入链上,例如验证者可自动升级到的 git commit。
type Plan struct {
    Name   string
  Height int64
  Info   string
}

Sidecar 进程

如果运行应用二进制的操作员还运行了一个 sidecar 进程,以辅助自动下载并升级二进制文件,那么 Info 可以让这一过程无缝完成。这个工具就是 Cosmovisor。

Handler

x/upgrade 模块支持从主版本 X 升级到主版本 Y。为实现这一点,节点操作员必须先将当前二进制升级到一个新的二进制版本,该版本包含与新版本 Y 对应的 Handler。默认假设这个版本已经经过充分测试,并获得了社区的整体认可。这个 Handler 定义了在新二进制 Y 能够成功运行链之前,需要执行哪些状态迁移。自然地,这个 Handler 是应用特定的,而不是按模块定义的。注册 Handler 通过应用中的 Keeper#SetUpgradeHandler 完成。
type UpgradeHandler func(Context, Plan, VersionMap) (VersionMap, error)
在每次执行 EndBlock 时,x/upgrade 模块都会检查是否存在应当执行的 Plan(即是否安排在当前高度)。如果存在,就执行对应的 Handler。如果预期某个 Plan 应当执行,但没有注册 Handler,或者二进制升级得太早,节点将以可控方式 panic 并退出。

StoreLoader

x/upgrade 模块还支持将存储迁移作为升级的一部分来处理。StoreLoader 设置了在新二进制能够成功运行链之前需要执行的迁移。这一 StoreLoader 也是应用特定的,而不是按模块定义的。注册该 StoreLoader 通过应用中的 app#SetStoreLoader 完成。
func UpgradeStoreLoader (upgradeHeight int64, storeUpgrades *store.StoreUpgrades)

baseapp.StoreLoader
如果存在已计划的升级,并且达到升级高度,旧二进制会在 panic 之前将 Plan 写入磁盘。 这条信息对于确保 StoreUpgrades 在正确的高度、针对预期升级平稳执行至关重要。它避免了新二进制在每次重启时都重复执行 StoreUpgrades 的可能性。此外,如果同一高度计划了多个升级,Name 将确保这些 StoreUpgrades 只会在计划中的升级处理器内执行。

提案

通常,Plan 是通过治理中的提案进行提出和提交的,提案中包含一条 MsgSoftwareUpgrade 消息。 该提案遵循标准治理流程。如果提案通过,则针对特定 Handler 的 Plan 会被持久化并安排执行。升级也可以通过在新提案中更新 Plan.Height 来延后或提前。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L29-L41

取消升级提案

升级提案可以被取消。存在一种启用治理的 MsgCancelUpgrade 消息类型,它可以嵌入提案中,经投票后如果通过,就会移除已安排的升级 Plan。 当然,这要求在升级真正执行之前足够早地意识到该升级并不是一个好主意,以便留出投票时间。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L48-L57
如果希望具备这种可能性,那么升级高度应当设置为自升级提案开始起的 2 * (VotingPeriod + DepositPeriod) + (SafetyDelta)。其中 SafetyDelta 是指升级提案通过之后,到意识到这是个坏主意(由于链外社会共识)的这段可用时间。 在原始 MsgSoftwareUpgrade 提案仍处于投票期间时,也可以提出 MsgCancelUpgrade 提案,只要该 VotingPeriod 结束时间晚于 MsgSoftwareUpgrade 提案。

状态

x/upgrade 模块的内部状态相对精简且简单。状态包含当前处于激活状态的升级 Plan(如果存在),其键为 0x0;如果某个 Plan 被标记为“已完成”,则其键为 0x1。状态还包含应用中所有模块的共识版本。这些版本以大端序 uint64 存储,可通过前缀 0x2 加上对应模块名称(类型为 string)来访问。状态还维护了一个 Protocol Version,可通过键 0x3 访问。
  • Plan: 0x0 -> Plan
  • Done: 0x1 | byte(plan name) -> BigEndian(Block Height)
  • ConsensusVersion: 0x2 | byte(module name) -> BigEndian(Module Consensus Version)
  • ProtocolVersion: 0x3 -> BigEndian(Protocol Version)
x/upgrade 模块不包含 genesis state。

事件

x/upgrade 本身不会发出任何事件。任何与提案相关的事件都由 x/gov 模块发出。

客户端

CLI

用户可以使用 CLI 查询并与 upgrade 模块交互。

查询

query 命令允许用户查询 upgrade 状态。
simd query upgrade --help
applied
applied 命令允许用户查询某个已完成升级实际应用时对应区块高度的区块头。
simd query upgrade applied [upgrade-name] [flags]
如果 upgrade-name 之前已在链上执行过,这会返回其被应用时对应区块的区块头。 这有助于客户端确定在某个区块范围内哪个二进制是有效的,也能提供更多上下文来理解过去的迁移。 示例:
simd query upgrade applied "test-upgrade"
示例输出:
"block_id": {
    "hash": "A769136351786B9034A5F196DC53F7E50FCEB53B48FA0786E1BFC45A0BB646B5",
    "parts": {
      "total": 1,
      "hash": "B13CBD23011C7480E6F11BE4594EE316548648E6A666B3575409F8F16EC6939E"
    }
  },
  "block_size": "7213",
  "header": {
    "version": {
      "block": "11"
    },
    "chain_id": "testnet-2",
    "height": "455200",
    "time": "2021-04-10T04:37:57.085493838Z",
    "last_block_id": {
      "hash": "0E8AD9309C2DC411DF98217AF59E044A0E1CCEAE7C0338417A70338DF50F4783",
      "parts": {
        "total": 1,
        "hash": "8FE572A48CD10BC2CBB02653CA04CA247A0F6830FF19DC972F64D339A355E77D"
      }
    },
    "last_commit_hash": "DE890239416A19E6164C2076B837CC1D7F7822FC214F305616725F11D2533140",
    "data_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "validators_hash": "A31047ADE54AE9072EE2A12FF260A8990BA4C39F903EAF5636B50D58DBA72582",
    "next_validators_hash": "A31047ADE54AE9072EE2A12FF260A8990BA4C39F903EAF5636B50D58DBA72582",
    "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F",
    "app_hash": "28ECC486AFC332BA6CC976706DBDE87E7D32441375E3F10FD084CD4BAF0DA021",
    "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "proposer_address": "2ABC4854B1A1C5AA8403C4EA853A81ACA901CC76"
  },
  "num_txs": "0"
}
module versions
module_versions 命令会获取模块名称及其对应共识版本的列表。 如果在命令后附带某个特定模块名称,则只会返回 该模块的信息。
simd query upgrade module_versions [optional module_name] [flags]
示例:
simd query upgrade module_versions
示例输出:
module_versions:
- name: auth
  version: "2"
- name: authz
  version: "1"
- name: bank
  version: "2"
- name: distribution
  version: "2"
- name: evidence
  version: "1"
- name: feegrant
  version: "1"
- name: genutil
  version: "1"
- name: gov
  version: "2"
- name: ibc
  version: "2"
- name: mint
  version: "1"
- name: params
  version: "1"
- name: slashing
  version: "2"
- name: staking
  version: "2"
- name: transfer
  version: "1"
- name: upgrade
  version: "1"
- name: vesting
  version: "1"
示例:
regen query upgrade module_versions ibc
示例输出:
module_versions:
- name: ibc
  version: "2"
plan
plan 命令会获取当前已安排的升级计划(如果存在)。
regen query upgrade plan [flags]
示例:
simd query upgrade plan
示例输出:
height: "130"
info: ""
name: test-upgrade
time: "0001-01-01T00:00:00Z"
upgraded_client_state: null

交易

upgrade 模块支持以下交易:
  • software-proposal - 提交升级提案:
simd tx upgrade software-upgrade v2 --title="Test Proposal" --summary="testing" --deposit="100000000stake" --upgrade-height 1000000 \
--upgrade-info '{ "binaries": { "linux/amd64":"https://example.com/simd.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f" } }' --from cosmos1..
  • cancel-software-upgrade - 取消先前已提交的升级提案:
simd tx upgrade cancel-software-upgrade --title="Test Proposal" --summary="testing" --deposit="100000000stake" --from cosmos1..

REST

用户可以使用 REST 端点查询 upgrade 模块。

已应用计划

AppliedPlan 按名称查询一个先前已应用的升级计划。
/cosmos/upgrade/v1beta1/applied_plan/{name}
示例:
curl -X GET "http://localhost:1317/cosmos/upgrade/v1beta1/applied_plan/v2.0-upgrade" -H "accept: application/json"
示例输出:
{
  "height": "30"
}

当前计划

CurrentPlan 查询当前升级计划。
/cosmos/upgrade/v1beta1/current_plan
示例:
curl -X GET "http://localhost:1317/cosmos/upgrade/v1beta1/current_plan" -H "accept: application/json"
示例输出:
{
  "plan": "v2.1-upgrade"
}

模块版本

ModuleVersions 从状态中查询模块版本列表。
/cosmos/upgrade/v1beta1/module_versions
示例:
curl -X GET "http://localhost:1317/cosmos/upgrade/v1beta1/module_versions" -H "accept: application/json"
示例输出:
{
  "module_versions": [
    {
      "name": "auth",
      "version": "2"
    },
    {
      "name": "authz",
      "version": "1"
    },
    {
      "name": "bank",
      "version": "2"
    },
    {
      "name": "distribution",
      "version": "2"
    },
    {
      "name": "evidence",
      "version": "1"
    },
    {
      "name": "feegrant",
      "version": "1"
    },
    {
      "name": "genutil",
      "version": "1"
    },
    {
      "name": "gov",
      "version": "2"
    },
    {
      "name": "ibc",
      "version": "2"
    },
    {
      "name": "mint",
      "version": "1"
    },
    {
      "name": "params",
      "version": "1"
    },
    {
      "name": "slashing",
      "version": "2"
    },
    {
      "name": "staking",
      "version": "2"
    },
    {
      "name": "transfer",
      "version": "1"
    },
    {
      "name": "upgrade",
      "version": "1"
    },
    {
      "name": "vesting",
      "version": "1"
    }
  ]
}

gRPC

用户可以使用 gRPC 端点查询 upgrade 模块。

已应用的计划

AppliedPlan 通过名称查询先前已应用的升级计划。
cosmos.upgrade.v1beta1.Query/AppliedPlan
示例:
grpcurl -plaintext \
    -d '{"name":"v2.0-upgrade"}' \
    localhost:9090 \
    cosmos.upgrade.v1beta1.Query/AppliedPlan
示例输出:
{
  "height": "30"
}

当前计划

CurrentPlan 查询当前升级计划。
cosmos.upgrade.v1beta1.Query/CurrentPlan
示例:
grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/CurrentPlan
示例输出:
{
  "plan": "v2.1-upgrade"
}

模块版本

ModuleVersions 从状态中查询模块版本列表。
cosmos.upgrade.v1beta1.Query/ModuleVersions
示例:
grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/ModuleVersions
示例输出:
{
  "module_versions": [
    {
      "name": "auth",
      "version": "2"
    },
    {
      "name": "authz",
      "version": "1"
    },
    {
      "name": "bank",
      "version": "2"
    },
    {
      "name": "distribution",
      "version": "2"
    },
    {
      "name": "evidence",
      "version": "1"
    },
    {
      "name": "feegrant",
      "version": "1"
    },
    {
      "name": "genutil",
      "version": "1"
    },
    {
      "name": "gov",
      "version": "2"
    },
    {
      "name": "ibc",
      "version": "2"
    },
    {
      "name": "mint",
      "version": "1"
    },
    {
      "name": "params",
      "version": "1"
    },
    {
      "name": "slashing",
      "version": "2"
    },
    {
      "name": "staking",
      "version": "2"
    },
    {
      "name": "transfer",
      "version": "1"
    },
    {
      "name": "upgrade",
      "version": "1"
    },
    {
      "name": "vesting",
      "version": "1"
    }
  ]
}

资源

用于进一步了解 x/upgrade 模块的(外部)资源列表。

Abstract

x/upgrade is an implementation of a Cosmos SDK module that facilitates smoothly upgrading a live Cosmos chain to a new (breaking) software version. It accomplishes this by providing a PreBlocker hook that prevents the blockchain state machine from proceeding once a pre-defined upgrade block height has been reached. The module does not prescribe anything regarding how governance decides to do an upgrade, but just the mechanism for coordinating the upgrade safely. Without software support for upgrades, upgrading a live chain is risky because all of the validators need to pause their state machines at exactly the same point in the process. If this is not done correctly, there can be state inconsistencies which are hard to recover from.

Concepts

Plan

The x/upgrade module defines a Plan type in which a live upgrade is scheduled to occur. A Plan can be scheduled at a specific block height. A Plan is created once a (frozen) release candidate along with an appropriate upgrade Handler (see below) is agreed upon, where the Name of a Plan corresponds to a specific Handler. Typically, a Plan is created through a governance proposal process, where if voted upon and passed, will be scheduled. The Info of a Plan may contain various metadata about the upgrade, typically application specific upgrade info to be included on-chain such as a git commit that validators could automatically upgrade to.
type Plan struct {
    Name   string
  Height int64
  Info   string
}

Sidecar Process

If an operator running the application binary also runs a sidecar process to assist in the automatic download and upgrade of a binary, the Info allows this process to be seamless. This tool is Cosmovisor.

Handler

The x/upgrade module facilitates upgrading from major version X to major version Y. To accomplish this, node operators must first upgrade their current binary to a new binary that has a corresponding Handler for the new version Y. It is assumed that this version has fully been tested and approved by the community at large. This Handler defines what state migrations need to occur before the new binary Y can successfully run the chain. Naturally, this Handler is application specific and not defined on a per-module basis. Registering a Handler is done via Keeper#SetUpgradeHandler in the application.
type UpgradeHandler func(Context, Plan, VersionMap) (VersionMap, error)
During each EndBlock execution, the x/upgrade module checks if there exists a Plan that should execute (is scheduled at that height). If so, the corresponding Handler is executed. If the Plan is expected to execute but no Handler is registered or if the binary was upgraded too early, the node will gracefully panic and exit.

StoreLoader

The x/upgrade module also facilitates store migrations as part of the upgrade. The StoreLoader sets the migrations that need to occur before the new binary can successfully run the chain. This StoreLoader is also application specific and not defined on a per-module basis. Registering this StoreLoader is done via app#SetStoreLoader in the application.
func UpgradeStoreLoader (upgradeHeight int64, storeUpgrades *store.StoreUpgrades)

baseapp.StoreLoader
If there’s a planned upgrade and the upgrade height is reached, the old binary writes Plan to the disk before panicking. This information is critical to ensure the StoreUpgrades happens smoothly at the correct height and expected upgrade. It eliminates the chances for the new binary to execute StoreUpgrades multiple times every time on restart. Also, if there are multiple upgrades planned on the same height, the Name will ensure these StoreUpgrades take place only in the planned upgrade handler.

Proposal

Typically, a Plan is proposed and submitted through governance via a proposal containing a MsgSoftwareUpgrade message. This proposal prescribes to the standard governance process. If the proposal passes, the Plan, which targets a specific Handler, is persisted and scheduled. The upgrade can be delayed or hastened by updating the Plan.Height in a new proposal.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L29-L41

Cancelling Upgrade Proposals

Upgrade proposals can be cancelled. There exists a gov-enabled MsgCancelUpgrade message type, which can be embedded in a proposal, voted on and, if passed, will remove the scheduled upgrade Plan. Of course this requires that the upgrade was known to be a bad idea well before the upgrade itself, to allow time for a vote.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L48-L57
If such a possibility is desired, the upgrade height is to be 2 * (VotingPeriod + DepositPeriod) + (SafetyDelta) from the beginning of the upgrade proposal. The SafetyDelta is the time available from the success of an upgrade proposal and the realization it was a bad idea (due to external social consensus). A MsgCancelUpgrade proposal can also be made while the original MsgSoftwareUpgrade proposal is still being voted upon, as long as the VotingPeriod ends after the MsgSoftwareUpgrade proposal.

State

The internal state of the x/upgrade module is relatively minimal and simple. The state contains the currently active upgrade Plan (if one exists) by key 0x0 and if a Plan is marked as “done” by key 0x1. The state contains the consensus versions of all app modules in the application. The versions are stored as big endian uint64, and can be accessed with prefix 0x2 appended by the corresponding module name of type string. The state maintains a Protocol Version which can be accessed by key 0x3.
  • Plan: 0x0 -> Plan
  • Done: 0x1 | byte(plan name) -> BigEndian(Block Height)
  • ConsensusVersion: 0x2 | byte(module name) -> BigEndian(Module Consensus Version)
  • ProtocolVersion: 0x3 -> BigEndian(Protocol Version)
The x/upgrade module contains no genesis state.

Events

The x/upgrade does not emit any events by itself. Any and all proposal related events are emitted through the x/gov module.

Client

CLI

A user can query and interact with the upgrade module using the CLI.

Query

The query commands allow users to query upgrade state.
simd query upgrade --help
applied
The applied command allows users to query the block header for height at which a completed upgrade was applied.
simd query upgrade applied [upgrade-name] [flags]
If upgrade-name was previously executed on the chain, this returns the header for the block at which it was applied. This helps a client determine which binary was valid over a given range of blocks, as well as more context to understand past migrations. Example:
simd query upgrade applied "test-upgrade"
Example Output:
"block_id": {
    "hash": "A769136351786B9034A5F196DC53F7E50FCEB53B48FA0786E1BFC45A0BB646B5",
    "parts": {
      "total": 1,
      "hash": "B13CBD23011C7480E6F11BE4594EE316548648E6A666B3575409F8F16EC6939E"
    }
  },
  "block_size": "7213",
  "header": {
    "version": {
      "block": "11"
    },
    "chain_id": "testnet-2",
    "height": "455200",
    "time": "2021-04-10T04:37:57.085493838Z",
    "last_block_id": {
      "hash": "0E8AD9309C2DC411DF98217AF59E044A0E1CCEAE7C0338417A70338DF50F4783",
      "parts": {
        "total": 1,
        "hash": "8FE572A48CD10BC2CBB02653CA04CA247A0F6830FF19DC972F64D339A355E77D"
      }
    },
    "last_commit_hash": "DE890239416A19E6164C2076B837CC1D7F7822FC214F305616725F11D2533140",
    "data_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "validators_hash": "A31047ADE54AE9072EE2A12FF260A8990BA4C39F903EAF5636B50D58DBA72582",
    "next_validators_hash": "A31047ADE54AE9072EE2A12FF260A8990BA4C39F903EAF5636B50D58DBA72582",
    "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F",
    "app_hash": "28ECC486AFC332BA6CC976706DBDE87E7D32441375E3F10FD084CD4BAF0DA021",
    "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
    "proposer_address": "2ABC4854B1A1C5AA8403C4EA853A81ACA901CC76"
  },
  "num_txs": "0"
}
module versions
The module_versions command gets a list of module names and their respective consensus versions. Following the command with a specific module name will return only that module’s information.
simd query upgrade module_versions [optional module_name] [flags]
Example:
simd query upgrade module_versions
Example Output:
module_versions:
- name: auth
  version: "2"
- name: authz
  version: "1"
- name: bank
  version: "2"
- name: distribution
  version: "2"
- name: evidence
  version: "1"
- name: feegrant
  version: "1"
- name: genutil
  version: "1"
- name: gov
  version: "2"
- name: ibc
  version: "2"
- name: mint
  version: "1"
- name: params
  version: "1"
- name: slashing
  version: "2"
- name: staking
  version: "2"
- name: transfer
  version: "1"
- name: upgrade
  version: "1"
- name: vesting
  version: "1"
Example:
regen query upgrade module_versions ibc
Example Output:
module_versions:
- name: ibc
  version: "2"
plan
The plan command gets the currently scheduled upgrade plan, if one exists.
regen query upgrade plan [flags]
Example:
simd query upgrade plan
Example Output:
height: "130"
info: ""
name: test-upgrade
time: "0001-01-01T00:00:00Z"
upgraded_client_state: null

Transactions

The upgrade module supports the following transactions:
  • software-proposal - submits an upgrade proposal:
simd tx upgrade software-upgrade v2 --title="Test Proposal" --summary="testing" --deposit="100000000stake" --upgrade-height 1000000 \
--upgrade-info '{ "binaries": { "linux/amd64":"https://example.com/simd.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f" } }' --from cosmos1..
  • cancel-software-upgrade - cancels a previously submitted upgrade proposal:
simd tx upgrade cancel-software-upgrade --title="Test Proposal" --summary="testing" --deposit="100000000stake" --from cosmos1..

REST

A user can query the upgrade module using REST endpoints.

Applied Plan

AppliedPlan queries a previously applied upgrade plan by its name.
/cosmos/upgrade/v1beta1/applied_plan/{name}
Example:
curl -X GET "http://localhost:1317/cosmos/upgrade/v1beta1/applied_plan/v2.0-upgrade" -H "accept: application/json"
Example Output:
{
  "height": "30"
}

Current Plan

CurrentPlan queries the current upgrade plan.
/cosmos/upgrade/v1beta1/current_plan
Example:
curl -X GET "http://localhost:1317/cosmos/upgrade/v1beta1/current_plan" -H "accept: application/json"
Example Output:
{
  "plan": "v2.1-upgrade"
}

Module versions

ModuleVersions queries the list of module versions from state.
/cosmos/upgrade/v1beta1/module_versions
Example:
curl -X GET "http://localhost:1317/cosmos/upgrade/v1beta1/module_versions" -H "accept: application/json"
Example Output:
{
  "module_versions": [
    {
      "name": "auth",
      "version": "2"
    },
    {
      "name": "authz",
      "version": "1"
    },
    {
      "name": "bank",
      "version": "2"
    },
    {
      "name": "distribution",
      "version": "2"
    },
    {
      "name": "evidence",
      "version": "1"
    },
    {
      "name": "feegrant",
      "version": "1"
    },
    {
      "name": "genutil",
      "version": "1"
    },
    {
      "name": "gov",
      "version": "2"
    },
    {
      "name": "ibc",
      "version": "2"
    },
    {
      "name": "mint",
      "version": "1"
    },
    {
      "name": "params",
      "version": "1"
    },
    {
      "name": "slashing",
      "version": "2"
    },
    {
      "name": "staking",
      "version": "2"
    },
    {
      "name": "transfer",
      "version": "1"
    },
    {
      "name": "upgrade",
      "version": "1"
    },
    {
      "name": "vesting",
      "version": "1"
    }
  ]
}

gRPC

A user can query the upgrade module using gRPC endpoints.

Applied Plan

AppliedPlan queries a previously applied upgrade plan by its name.
cosmos.upgrade.v1beta1.Query/AppliedPlan
Example:
grpcurl -plaintext \
    -d '{"name":"v2.0-upgrade"}' \
    localhost:9090 \
    cosmos.upgrade.v1beta1.Query/AppliedPlan
Example Output:
{
  "height": "30"
}

Current Plan

CurrentPlan queries the current upgrade plan.
cosmos.upgrade.v1beta1.Query/CurrentPlan
Example:
grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/CurrentPlan
Example Output:
{
  "plan": "v2.1-upgrade"
}

Module versions

ModuleVersions queries the list of module versions from state.
cosmos.upgrade.v1beta1.Query/ModuleVersions
Example:
grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/ModuleVersions
Example Output:
{
  "module_versions": [
    {
      "name": "auth",
      "version": "2"
    },
    {
      "name": "authz",
      "version": "1"
    },
    {
      "name": "bank",
      "version": "2"
    },
    {
      "name": "distribution",
      "version": "2"
    },
    {
      "name": "evidence",
      "version": "1"
    },
    {
      "name": "feegrant",
      "version": "1"
    },
    {
      "name": "genutil",
      "version": "1"
    },
    {
      "name": "gov",
      "version": "2"
    },
    {
      "name": "ibc",
      "version": "2"
    },
    {
      "name": "mint",
      "version": "1"
    },
    {
      "name": "params",
      "version": "1"
    },
    {
      "name": "slashing",
      "version": "2"
    },
    {
      "name": "staking",
      "version": "2"
    },
    {
      "name": "transfer",
      "version": "1"
    },
    {
      "name": "upgrade",
      "version": "1"
    },
    {
      "name": "vesting",
      "version": "1"
    }
  ]
}

Resources

A list of (external) resources to learn more about the x/upgrade module.