Starcoin-Framework 升级
开始
首先在阅读之前,需要了解以下概念:
Starcoin-Framework版本号
Move字节码版本号
Starcoin节点版本号
框架升级
假设我们现在完成了 starcoin 和 starcoin-framework 的代码开发,需要升级出去,在正式进入升级前,需要做如下准备。
以下以从 stdlib_version 从 11 升级到 12 为例,讲述升级前的准备工作。
Starcoin-framework 开发完成后,在 framework 工程目录下执行:
mpm package build
这个命令会在 starcoin-framework/build/StarcoinFramework/bytecode_modules 生成最新的 move 字节码文件,后缀名为 mv,starcoin 会加载这些 mv 文件打包到新的区块中。
接着,生成新的 blob 文件用于 DAO 流程发起提案升级。同样在 framework 目录中执行以下命令:
# 该命令会在根目录下build路径下生成更新的mv文件、BuildInfo.yaml等 mpm release --doc --abi --force
这个命令会在 starcoin-framework/release 目录生成一个名为 StarcoinFramework.v0.1.0.blob 的文件(文件名是依靠 Move.toml 的 package 属性控制的),把这个文件名修改成 stdlib.blob,即最为新版本的 blob 文件。
经过上面两步我们有了 12 版本的 mv 和 blob 文件。
这里有些地方不正确参考这里 Starcoin-Framework 合约投票升级流程Starcoin 节点工程的 Cargo.toml 文件中,需要修改framework 在节点工程中的引用版本 hash。hash 值取前面生成 mv 和 blob 文件的时候 framework 的版本 hash。(hash 值可以通过git log 或者 git rev-parse head 查看,也可以去 github 网站查看提交记录。)
在 starcoin/vm/stdlib/compiled/ 中新建名为 12 的目录,然后在 12 下新建子目录 11-12/stdlib 和 stdlib 目录。
接着,将前面生成的 mv 文件放到 12/11-12/stdlib 和 12/stdlib 下,blob 文件放到 12/11-12 下。
回到 starcoin 目录下,执行以下指令生成二进制文件
# 生成stdlib 二进制文件 cargo run --bin stdlib --release # 生成 genesis 文件 cargo run --bin starcoin-genesis --release
其中,cargo run --bin stdlib --release 命令会 check 这些升级文件,没有问题的话不会有报错:
cargo run --bin starcoin-genesis --release 命令则会根据 genesis_config.rs 中各网络节点的版本配置生成对应的 genesis 文件,文件位于 starcoin/genesis/generated 下,按不同网络存放。
运行测试模拟升级过程。其主要测试流程主要在 executor/tests/module_upgrade_test.rs 中的test_stdlib_upgrade 测试函数中。可以执行:
cargo test test_stdlib_upgrade
看是否会报错。该测试用例完整的模拟了 DAO 升级流程。
部署seed节点,执行以下指令(以proxima为例)
kubectl apply -f kube/manifest/starcoin-proxima.yaml --namespace=starcoin-proxima
合约升级
升级Language Version(前提是依赖的Move字节码版本升级了),参考链上Move字节码版本号升级
升级Starcoin-Framework 二进制blob,参考Starcoin-Framework 合约投票升级流程
手动模拟升级
我们可以在开发网上模拟升级流程,可以参看以下视频:
https://weibo.com/l/wblive/p/show/1022:2321324582720893223227
因为我们要模拟 11 升级 12,所以需要将 dev 调整到 11 版本:
临时将 dev 降级为 11
一般情况下,dev 为lastest 版本,为了在本机上测试升级流程,代码中,我们临时修改 dev 的配置为 11,以及相关的配置修改为 11 版本的配置(因为本次 11 升 12 就是为了升级配置,所以这个改成了 11 的配置,若升级其它可以同理修改):启动编译并启动开发网,新建一个账号进行发起升级的投票,例如本例账号为:0x2aba2f351397f2e023c537ee56af0bb1,操作可以参见https://cookbook.starcoin.org/zh/docs/getting-started/accounts/account-manage
此时使用以下命令查看当前 stdlib_version 版本:state get resource 0x1 0x1::Config::Config<0x1::Version::Version>
返回:
{ "ok": { "json": { "payload": { "major": 12 } }, "raw": "0x0c00000000000000" } }
在线上发起提案要求升级 stdlib:
dev module_proposal -m stdlib.blob -v 12 -s 0x2aba2f351397f2e023c537ee56af0bb1
这里即执行命令 module_proposal,-m 表示需要更新到链上去的 blob 文件,后面接全路径文件名,-v 表示升级后的目标版本号,这里是 11 升 12,则填入 12,-s 表示指定提出升级提案的人的地址。
查看刚才提案状态:
dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x2aba2f351397f2e023c537ee56af0bb1 --arg 0
关于在 starcoin console 中调用 stdlib(即 starcoin-framework )合约函数的方法可以看 https://starcoin.atlassian.net/wiki/spaces/jack/pages/161874152 。这一步会返回:
{ "ok": [ 1 ] }
其中的 1 表示提案处于 pending 状态,状态枚举见https://github.com/starcoinorg/starcoin-framework/blob/main/sources/Dao.move 的
Proposal state
使用 sleep 命令越过提案讨论时间:
dev sleep -t 3600000 account unlock dev gen-block
此时若调用 proposal_state 函数查看提案的状态则返回 2,表示提案已经讨论,可以开始投票了。
投票,此时需要执行以下命令:
account execute-function --function 0x1::DaoVoteScripts::cast_vote -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 -s 0x446561d93315a02b812ba250dec72edc --arg 0x2aba2f351397f2e023c537ee56af0bb1 --arg 0 --arg true --arg 1000u128 -b
返回:
txn 0x7571c43442cd6a23a1da66d06d230d7fe1e8fbb4e7fa103ed6cb8549d78aaa7a submitted. { "ok": { "dry_run_output": { "events": [ { "data": "0xe803000000000000000000000000000000000000000000000000000000000001035354430353544300", "event_key": "0x0000000000000000446561d93315a02b812ba250dec72edc", "event_seq_number": "0", "type_tag": "0x00000000000000000000000000000001::Account::WithdrawEvent" }, { "data": "0x0000000000000000446561d93315a02b812ba250dec72edc2aba2f351397f2e023c537ee56af0bb101e8030000000000000000000000000000", "event_key": "0x130000000000000000000000000000000000000000000001", "event_seq_number": "0", "type_tag": "0x00000000000000000000000000000001::Dao::VoteChangedEvent" } ], "explained_status": "Executed", "gas_used": "147763", "status": "Executed", "table_item_write_set": [], ……
注意 "status": "Executed" 才是成功。
投票目前是以股权方式进行的,基金会账号的股权很大,可以用以下方式查看到其投票股权:
dev call --function 0x1::Dao::quorum_votes -t 0x1::STC::STC
其返回值即为投票股权,需要大于这个返回值投票才能通过:
{ "ok": [ 6370273600000000 ] }
halley,Proxima等网络有专门的股权投票权限,见文档:Starcoin-Framework 合约投票升级流程 | 三、执行两阶段升级
dev 网络则可以再次新建一个新的账号用于投票,然后使用dev get-coin的方式给这个账号大量的 token超越这个基金会账号股权。dev get-coin 似乎设置了每次获得 token 的上限,多调用几次即可超越基金会账号股权。使用新账号投票:
account execute-function --function 0x1::DaoVoteScripts::cast_vote -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 -s 0xfa0cabf66c724540132d832e8a1e0367 --arg 0x7907d6176e8feb3ea7eb70a12c42c2af --arg 0 --arg true --arg 12740545600000000u128
投票后再次 sleep 一下查看提案状态,会发现此时状态为 4,表示已通过:
{ "ok": [ 4 ] }
提案通过后,接下来就是执行module-queue,表示对这个通过的提案进行一次公示:
dev module-queue -a 0x7907d6176e8feb3ea7eb70a12c42c2af -i 0
此时若查看提案状态会变成 5:
{ "ok": [ 5 ] }
同样用 dev sleep 命令既可以越过公示期,最终进入执行状态 6,此时执行 module-plan:
dev module-plan -a 0x7907d6176e8feb3ea7eb70a12c42c2af -i 0 -b
执行 module-plan 后若查看提案状态会发现此时状态为 7,表示已提交,这里执行相当于需要两次,即两阶段提交,module-plan 是第一阶段。
module-execute 则是第二阶段:
dev module-exe -m /Volumes/extreme/code/framework-v11-to-v12/starcoin/vm/stdlib/compiled/12/11-12/stdlib.blob -b
执行完这个命令后,升级完成!
可以使用以下命令查看升级是否成功:
state get resource 0x1 0x1::Config::Config<0x1::Version::Version>
返回:
{ "ok": { "json": { "payload": { "major": 12 } }, "raw": "0x0c00000000000000" } }
表明 framework 版本由原来的 11 变成了 12。
技术细节
共识参数调整
若需要调整共识参数请参考:如何调整共识参数