substrate學習筆記11:無分叉runtime升級

linghuyichong發表於2022-04-09

substrate框架的特性之一就是支援無分叉執行時升級。無分叉升級時以區塊鏈自身能力支援和保護的方式增強區塊鏈執行時的一種手段,區塊鏈的執行時定義了區塊鏈可以保持的狀態,還定義了改變該裝填的邏輯。

substrate可以在不分叉的情況下更新runtime,因為執行時的定義本身就是substrate鏈中的一個元素,網路參與者可以透過交易函式,特別是set_code函式來更新該值。由於執行時狀態的更新受到區塊鏈共識機制和加密安全的約束,網路參與者可以在不分叉的情況下使用不受信任分發的更新或者擴充套件的執行時邏輯,甚至不需要釋出新的區塊鏈客戶端。

在本節中,我們將學習:

  • 使用sudo呼叫將schelduler pallet包含到runtime中;
  • 呼叫runtime升級。

本節的這一部分將引導使用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.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升級。

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

github.com/anonymousGiga/substrate...

本作品採用《CC 協議》,轉載必須註明作者和本文連結
令狐一衝

相關文章