摘要
x/upgrade
是 Cosmos SDK 模块的一个实现,旨在帮助平滑地将一个正在运行的 Cosmos 链升级到新的(可能存在不兼容的)软件版本。它通过提供一个 PreBlocker
钩子来实现这一点,当达到预定义的升级区块高度时,该钩子会阻止区块链状态机继续执行。
该模块并未规定治理如何决定进行升级,而只是提供了一个机制,用于安全地协调升级。没有软件支持进行升级的情况下,升级一个正在运行的链是有风险的,因为所有验证人需要在完全相同的点暂停各自的状态机。如果这一过程没有正确执行,可能会导致状态不一致,且恢复起来非常困难。
概念
Plan
x/upgrade
模块定义了一个Plan
类型,用于安排实时升级的发生。Plan
可以在特定的区块高度安排。Plan
在达成一致后创建,其中包含一个(已冻结的)发布候选版本以及一个适当的升级处理器(见下文),Plan
的名称对应于一个特定的处理器。通常,Plan
通过治理提案流程创建,如果提案通过投票并通过,则会被安排。Plan
的Info
可以包含关于升级的各种元数据,通常是特定于应用程序的升级信息,这些信息会被包含在链上,例如验证人可以自动升级的 git 提交。
type Plan struct {
Name string
Height int64
Info string
}
辅助进程
Handler
x/upgrade
模块便于从主要版本X升级到主要版本Y。为了实现这一点,节点操作员必须首先将当前的二进制文件升级到具有对应于新版本Y的处理器的新二进制文件。假设该版本已由社区全面测试并批准。这个处理器定义了在新二进制Y成功运行链之前需要进行哪些状态迁移。显然,这个处理器是特定于应用程序的,而不是按模块定义的。注册一个处理器是在应用程序中通过 Keeper#SetUpgradeHandler
完成的。
type UpgradeHandler func(Context, Plan, VersionMap) (VersionMap, error)
在每次 EndBlock
执行期间,x/upgrade
模块会检查是否存在应该执行的计划(是否在该高度安排)。如果是这样,执行相应的处理器。如果计划预期执行但没有注册处理器,或者二进制文件被提前升级,节点将优雅地崩溃并退出。
StoreLoader
x/upgrade
模块还在升级过程中促进存储迁移。StoreLoader
设置需要在新二进制文件成功运行链之前进行的迁移。这个 StoreLoader
也是特定于应用程序的,而不是按模块定义的。注册此 StoreLoader
是通过应用程序中的 app#SetStoreLoader
完成的。
func UpgradeStoreLoader (upgradeHeight int64, storeUpgrades *store.StoreUpgrades) baseapp.StoreLoader
如果有计划中的升级,并且达到了升级高度,旧的二进制文件会在崩溃之前将计划写入磁盘。
此信息对于确保 StoreUpgrades
在正确的高度和预期升级时顺利发生至关重要。它消除了每次重新启动时,新二进制文件执行 StoreUpgrades
多次的可能性。此外,如果在相同高度上有多个计划的升级,Name
将确保这些 StoreUpgrades
只在计划的升级处理器中发生。
提案
通常,Plan
通过治理提案的方式提交,其中包含一个 MsgSoftwareUpgrade
消息。此提案遵循标准治理流程。如果提案通过,目标特定处理器的计划将被持久化并安排。升级可以通过在新的提案中更新 Plan.Height
来延迟或加速。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L29-L41
取消升提案
升级提案可以被取消。存在一个支持治理的 MsgCancelUpgrade
消息类型,可以嵌入在提案中,进行投票,并且如果通过,将删除已安排的升级计划。当然,这要求升级在实际进行之前就已经被认为是一个不好的主意,从而为投票提供时间。
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L48-L57
如果希望这种可能性,升级高度应为从升级提案开始的 2 * (VotingPeriod + DepositPeriod) + (SafetyDelta)
。SafetyDelta
是从升级提案成功到意识到它是一个糟糕的主意(由于外部社会共识)之间的时间。
MsgCancelUpgrade
提案也可以在原始的 MsgSoftwareUpgrade
提案仍在投票时提出,只要投票期结束时在 MsgSoftwareUpgrade
提案之后。
状态
x/upgrade
模块的内部状态相对简单且最小化。该状态包含当前活动的升级计划(如果存在),通过键 0x0
存储;如果计划被标记为“完成”,则通过键 0x1
存储。状态还包含应用程序中所有应用模块的共识版本。版本以大端格式的 uint64
存储,可以通过前缀 0x2
加上相应模块名称(字符串类型)进行访问。状态还维护一个协议版本,可以通过键 0x3
访问。
Done: 0x1 | byte(plan name) -> BigEndian(Block Height)
ConsensusVersion: 0x2 | byte(module name) -> BigEndian(Module Consensus Version)
ProtocolVersion: 0x3 -> BigEndian(Protocol Version)
x/upgrade
模块不包含创世状态。
事件
x/upgrade
模块本身不发出任何事件。所有与提案相关的事件都是通过 x/gov
模块发出的。
客户端
CLI
用户可以使用CLI查询和与升级模块进行交互。
Query
查询命令允许用户查询升级状态。
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: crisis
version: "1"
- 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
Transactions
升级模块支持以下交易:
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端点查询升级模块。
Applied Plan
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"
示例输出:
Current Plan
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"
}
Module versions
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": "crisis",
"version": "1"
},
{
"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 端点查询升级模块。
Applied Plan
AppliedPlan
查询通过其名称之前应用的升级计划。
cosmos.upgrade.v1beta1.Query/AppliedPlan
示例:
grpcurl -plaintext \
-d '{"name":"v2.0-upgrade"}' \
localhost:9090 \
cosmos.upgrade.v1beta1.Query/AppliedPlan
示例输出:
Current Plan
CurrentPlan
查询当前的升级计划。
cosmos.upgrade.v1beta1.Query/CurrentPlan
示例:
grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/CurrentPlan
示例输出:
{
"plan": "v2.1-upgrade"
}
Module versions
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": "crisis",
"version": "1"
},
{
"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
模块的(外部)资源列表: