Substrate Developer Hub

Substrate Developer Hub

  • 教程
  • 知识库
  • 进阶菜谱
  • API 文档
  • Languages icon简体中文
    • English
    • 协助翻译

›Runtime

开始

  • 总览
  • 安装
  • 在 Windows 系统开始
  • 词汇表

学习 Substrate

  • Extrinsics
  • 交易池
  • 账户摘要
  • 会话密钥
  • 交易权重
  • 链下功能

Runtime

  • Runtime 总览
  • Runtime 的基本类型
  • FRAME
  • Pallets
  • Runtime宏
  • Runtime 元数据
  • Runtime 存储
  • Runtime 来源
  • Runtime 执行流程
  • Runtime事件
  • Runtime 错误
  • 交易费用
  • 链下工作机
  • 调试
  • Runtime 测试
  • 链上随机生成
  • Runtime 升级

智能合约

  • 总览
  • ink! 智能合约
  • ink! 概念
  • ink! 开发
  • EVM 模块
  • ink! 常问问题

整合

  • Polkadot-JS
  • 客户端库
  • 链描述
  • Subkey 工具
  • 内存分析

进阶

  • SCALE 编解码器
  • 共识机制
  • 区块导入过程
  • 执行器
  • 密码学
  • 存储
  • SS58 地址格式

贡献

  • 协助翻译
Translate

Runtime 升级

无分叉runtime升级的能力是Substrate框架用于区块链开发的基础定义特征之一。 这种无分叉升级能力,是通过将状态转换函数的定义(即runtime本身)作为元素,包含在区块链不断变化的runtime状态中实现的。 这使得网络维护人员可以利用区块链无需信任、去中心化共识的特性,从而安全地对runtime进行升级。

在用于runtime开发的FRAME系统中,System库定义了set_code函数,以用于更新runtime的定义。 “如何升级链”的教程对FRAME runtime升级的详细信息进行了描述,并演示了两种执行机制。 该教程演示的两种升级都是严格 相加, 的,这意味着它们通过扩展而不是 更新现有的runtime状态来修改runtime。 如果runtime升级定义了对现有状态的更改,则可能有必要执行“存储迁移”。

Runtime Versioning

In order for the executor to be able to select the appropriate runtime execution environment, it needs to know the spec_name, spec_version and authoring_version of both the native and Wasm runtime.

The runtime provides a runtime version struct. A sample runtime version struct is shown below:

pub const VERSION: RuntimeVersion = RuntimeVersion {
  spec_name: create_runtime_str!("node-template"),
  impl_name: create_runtime_str!("node-template"),
  authoring_version: 1,
  spec_version: 1,
  impl_version: 1,
  apis: RUNTIME_API_VERSIONS,
  transaction_version: 1,
};
  • spec_name: The identifier for the different Substrate runtimes.

  • impl_name: The name of the implementation of the spec. This is of little consequence for the node and serves only to differentiate code of different implementation teams.

  • authoring_version: The version of the authorship interface. An authoring node will not attempt to author blocks unless this is equal to its native runtime.

  • spec_version: The version of the runtime specification. A full node will not attempt to use its native runtime in substitute for the on-chain Wasm runtime unless all of spec_name, spec_version, and authoring_version are the same between Wasm and native.

  • impl_version: The version of the implementation of the specification. Nodes are free to ignore this; it serves only as an indication that the code is different; as long as the other two versions are the same then while the actual code may be different, it is nonetheless required to do the same thing. Non-consensus-breaking optimizations are about the only changes that could be made which would result in only the impl_version changing.

  • transaction_version: The version of the extrinsics interface. This number must be updated in the following circumstances: extrinsic parameters (number, order, or types) have been changed; extrinsics or pallets have been removed; or the pallet order in the construct_runtime! macro or extrinsic order in a pallet has been changed. If this number is updated, then the spec_version must also be updated.

  • apis is a list of supported runtime APIs along with their versions.

As mentioned above, the executor always verifies that the native runtime has the same consensus-driven logic before it chooses to execute it, independent of whether the version is higher or lower.

Note: The runtime versioning is manually set. Thus the executor can still make inappropriate decisions if the runtime version is misrepresented.

Accessing the Runtime Version

The runtime version is useful for application or integration developers that are building on a FRAME runtime. The FRAME runtime system exposes this information by way of the state.getRuntimeVersion RPC endpoint, which accepts an optional block identifier. Most developers building on a FRAME-based blockchain will use the runtime's metadata to understand the APIs the runtime exposes and the requirements for interacting with these APIs. The runtime's metadata should only change when the chain's runtime spec_version changes.

Forkless Runtime Upgrades

Traditional blockchains require a hard fork when upgrading the state transition function of their chain. This requires node operators to stop their nodes and manually upgrade to the latest executable. For distributed production networks, coordination of a hard fork upgrades can be a complex process.

The culmination of the properties listed on this page allows for Substrate-based blockchains to perform "forkless runtime upgrades". This means that the upgrade of the runtime logic can happen in real time without causing a fork in the network.

To perform a forkless runtime upgrade, Substrate uses existing runtime logic to update the Wasm runtime stored on the blockchain to a new consensus-breaking version with new logic. This upgrade gets pushed out to all syncing nodes on the network as a part of the consensus process. Once the Wasm runtime is upgraded, the executor will see that the native runtime spec_name, spec_version, or authoring_version no longer matches this new Wasm runtime. As a result, it will fall back to execute the canonical Wasm runtime instead of using the native runtime in any of the execution processes.

Storage Migrations

Storage migrations are custom, one-time functions that allow developers to rework existing storage in order to convert it to conform to updated expectations. For instance, imagine a runtime upgrade that changes the data type used to represent user balances from an unsigned integer to a signed integer - in this case, the storage migration would read the existing value as an unsigned integer and write back an updated value that has been converted to a signed integer. Failure to perform a storage migration when needed will result in the runtime execution engine misinterpreting the storage values that represent the runtime state and lead to undefined behavior. Substrate runtime storage migrations fall into a category of storage management broadly referred to as "data migrations".

Storage Migrations with FRAME

FRAME storage migrations are implemented by way of the OnRuntimeUpgrade trait, which specifies a single function, on_runtime_upgrade. This function provides a hook that allows runtime developers to specify logic that will run immediately after a runtime upgrade but before any extrinsics or even the on_initialize function has executed.

Preparing for a Migration

Preparing for a storage migration means understanding the changes that are defined by a runtime upgrade. The Substrate repository uses the D1-runtime-migration label to designate such changes.

Writing a Migration

Each runtime migration will be different, but there are certain conventions and best practices that should be followed.

  • Extract migrations into reusable functions and write tests for them.
  • Include logging in migrations to assist in debugging.
  • Remember that migrations are executed within the context of the upgraded runtime, which means that migration code may need to include deprecated types, as in this example.
  • Use storage versions to make migrations safer by making them more declarative, as in this example.

Ordering Migrations

By default, FRAME will order the execution of on_runtime_upgrade functions according to the order in which the pallets appear in the construct_runtime! macro - in particular, they will run in reverse (top-to-bottom) order. FRAME exposes a capability to inject storage migrations in a custom order, if needed (see an example here).

FRAME storage migrations will run in this order:

  1. frame_system::on_runtime_upgrade
  2. 自定义的on_runtime_upgrade顺序,如上所述
  3. 按照上述顺序,包含在runtime里的pallet内定义的所有on_runtime_upgrade函数

Testing Migrations

It is important to test storage migrations and a number of utilities exist to assist in this process. The Substrate Debug Kit includes a Remote Externalities tool that allows storage migration unit testing to be safely performed on live chain data. The Fork Off Substrate script makes it easy to create a chain specification that can be used to bootstrap a local test chain for testing runtime upgrades and storage migrations.

进一步学习

  • Parity Runtime Engineer Alexander Popiak maintains a Substrate Migrations repository with lots of helpful information about Substrate runtime upgrades and storage migrations.
← 链上随机生成总览 →
  • Runtime Versioning
    • Accessing the Runtime Version
  • Forkless Runtime Upgrades
  • Storage Migrations
    • Storage Migrations with FRAME
    • Preparing for a Migration
    • Writing a Migration
    • Ordering Migrations
    • Testing Migrations
  • 进一步学习
Substrate Developer Hub
开发者中心
教程知识库进阶菜谱API 文档
社区
社区主页通讯Substrate 技术聊天室Substrate 研讨会Stack Overflow推特聚会活动
更多
Substrate Builders 计划BlogSubstrate GitHub开发者中心 GitHub隐私政策使用条款Cookie 设置
Copyright © 2021 Parity Technologies