substrate学习笔记11:无分叉runtime升级

1 介绍

substrate框架的特性之一就是支持无分叉运行时升级。无分叉升级时以区块链自身能力支持和保护的方式增强区块链运行时的一种手段,区块链的运行时定义了区块链可以保持的状态,还定义了改变该装填的逻辑。

substrate可以在不分叉的情况下更新runtime,因为运行时的定义本身就是substrate链中的一个元素,网络参与者可以通过交易函数,特别是set_code函数来更新该值。由于运行时状态的更新受到区块链共识机制和加密安全的约束,网络参与者可以在不分叉的情况下使用不受信任分发的更新或者扩展的运行时逻辑,甚至不需要发布新的区块链客户端。

在本节中,我们将学习:

  • 使用sudo调用将schelduler pallet包含到runtime中;
  • 调用runtime升级。

2 sudo升级

本节的这一部分将引导使用Sudo pallet启动substrate链和启动简单的运行时升级。

2.1 启动node-template节点

我们可以运行如下命令来执行note-template节点:

cargo run --release -- --dev

默认情况下,node-tmplate的chainspec中会配置alice账户为sudo权限的账户。因此,在本节中,我们也就是用alice的账户去升级。

2.2 运行时升级资源记账

substrate中的可调度函数的调用始终和权重相关,该权重用于资源的记账。frame中的system模块将外部交易限制为区块长度和区块权重限制。system中的set_code函数旨在消耗一个块中的最大的权重。

2.3 使用sudo进行调度

sudo pallet提供了sudo相关的功能,要求root权限用户才能使用。

为了在FRAME的保护措施中解决资源计费问题,Sudo托盘提供Sudo_unchecked_weight函数,该函数提供与Sudo函数相同的功能,但接受一个附加参数,该参数用于指定用于调用的权重(可能为零)。sudo_unchecked_weight函数将用于调用本教程本节中的运行时升级;在下一节中,调度器托盘将用于管理set_code功能消耗的资源。

2.4 准备升级runtime

2.4.1 添加schelduler pallet

在runtime/cargo.toml中添加如下:

[dependencies.pallet-scheduler]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
tag = 'devhub/latest'
version = '4.0.0-dev'

#--snip--

[features]
default = ['std']
std = [
    #--snip--
    'pallet-scheduler/std',
    #--snip--
]

在runtime/src/lib.rs中添加如下:

// Define the types required by the Scheduler pallet.
parameter_types! {
    pub MaximumSchedulerWeight: Weight = 10_000_000;
    pub const MaxScheduledPerBlock: u32 = 50;
}

// Configure the runtime's implementation of the Scheduler pallet.
impl pallet_scheduler::Config for Runtime {
    type Event = Event;
    type Origin = Origin;
    type PalletsOrigin = OriginCaller;
    type Call = Call;
    type MaximumWeight = MaximumSchedulerWeight;
    type ScheduleOrigin = frame_system::EnsureRoot<AccountId>;
    type MaxScheduledPerBlock = MaxScheduledPerBlock;
    type WeightInfo = ();
    type OriginPrivilegeCmp = EqualPrivilegeOnly;
}

// Add the Scheduler pallet inside the construct_runtime! macro.
construct_runtime!(
    pub enum Runtime where
        Block = Block,
        NodeBlock = opaque::Block,
        UncheckedExtrinsic = UncheckedExtrinsic
    {
        /*** snip ***/
        Scheduler: pallet_scheduler,
    }
);

然后在runtime/src/lib.rs的顶部添加:

pub use frame_support::traits::EqualPrivilegeOnly;

然后在runtime/src/lib.rs中找到RuntimeVersion结构体,将其中的spec_version的值加1,如下:

pub const VERSION: RuntimeVersion = RuntimeVersion {
    spec_name: create_runtime_str!("node-template"),
    impl_name: create_runtime_str!("node-template"),
    authoring_version: 1,
    spec_version: 101,  // *Increment* this value, the template uses 100 as a base
    impl_version: 1,
    apis: RUNTIME_API_VERSIONS,
    transaction_version: 1,
};

2.4.2 编译升级后的runtime

这里我们只需要编译runtime,node部分吧不需要变化,因此使用如下命令:

cargo build --release -p node-template-runtime

这里需要注意的是,此时不要停止之前运行的node-template,要保持运行!!!

2.5 升级runtime

打开polkadot-js-app(地址:https://polkadot.js.org/apps/#/extrinsics?rpc=ws://127.0.0.1:9944)连接本地节点。然后选择developer->Extrinsics->Submission,账户选择alice,在submit the following extrinsic中选择sudo,右边对应的方法选择sudoUncheckedWeight,然在Call中选择system,右边的框中选择setcode。在下面的code中双击选择target/release/wbuild/node-template-runtime/node_template_runtime.compact.wasm文件上传 ,weight中输入0,最后点击Submit Transaction提交。

接下来,我们将:

  • 升级runtime版本;
  • 使用secheduler pallet来调用runtime升级。

3 调度升级

3.1 准备升级的运行时

修改runtime/src/lib.rs中如下:

pub const VERSION: RuntimeVersion = RuntimeVersion {
    spec_name: create_runtime_str!("node-template"),
    impl_name: create_runtime_str!("node-template"),
    authoring_version: 1,
    spec_version: 102,  // *Increment* this value.
    impl_version: 1,
    apis: RUNTIME_API_VERSIONS,
    transaction_version: 1,
};

/*** snip ***/

parameter_types! {
    pub const ExistentialDeposit: u128 = 1000;  // Update this value.
    pub const MaxLocks: u32 = 50;
}

/*** snip ***/

3.2 编译升级的运行时

另起一个终端,之前运行的节点不要停止运行,然后运行如下命令:

cargo build --release -p node-template-runtime

这里需要注意的是,之前的节点不要关闭,还是要保持运行。

3.3 升级运行时

打开polkadot-js-app(地址:https://polkadot.js.org/apps/#/sudo?rpc=ws://127.0.0.1:9944),然后选择developer->sudo,然后在submit the following change中选择scheduler,右边也选择schedule,when中填写要输入的区块高度,call中选择system,右边选择setcode,然后在code中选择target/release/wbuild/node-template-runtime/node_template_runtime.compact.wasm上传,然后提交交易,发起升级交易完成,将在高度311升级。

4 参考资料

docs.substrate.io/tutorials/v3/for...

5 github地址

github.com/anonymousGiga/substrate...

本作品采用《CC 协议》,转载必须注明作者和本文链接
令狐一冲
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!