在创建第一个基板链之后,一切正常。
然后我想更进一步来自定义我的demo.rs文件,这是我在做什么:
Demo: demo::{Module, Call, Storage, Event<T>},
Run Code Online (Sandbox Code Playgroud)
和
impl demo::Trait for Runtime {
type Event = Event;
}
Run Code Online (Sandbox Code Playgroud)
./scripts/build.rs./target/release/node-name --dev然后我看到Polkadot Web App上没有列出我更新的外部函数,或者substrate_node_template_runtime_wasm.compact.wasm按照教程中的第 5 步上传文件
所以我必须运行以下代码才能进行更新:
rm -rf ./target
cargo build --release
./target/release/node-name --dev
Run Code Online (Sandbox Code Playgroud)
通过与@shawntabrizi 讨论,他建议使用以下命令
./scripts/build.sh
cargo build --release
./target/release/node-name purge-chain --dev
./target/release/node-name --dev
Run Code Online (Sandbox Code Playgroud)
看来,如果没有purge-chain这两个substrate_node_template_runtime_wasm.compact.wasm,并./target/release/node-name没有更新的。
在这里引用
通过升级运行时,您只需切换出将接收外部和读取存储的代码块。
但我想更深入地了解,升级运行时节点时,build.sh和背后有什么区别cargo build?那是因为在上述情况下没有更新substrate_node_template_runtime_wasm.compact.wasm和/或./target/release/node-name二进制文件吗?
让我们尝试解决您提出的一些不同主题:
build.sh和cargo build有什么区别
Substrate 运行时被编译为 Native 二进制文件和 Wasm blob。在 Substrate v1.0 中,这些编译步骤是分开的。build.sh将您的运行时编译为 Wasm,同时cargo build编译整个节点(如 CLI、数据库等),包括运行时的本机版本。
似乎没有清除链, 和 都
substrate_node_template_runtime_wasm.compact.wasm不会./target/release/node-name更新。
了解这里背景中发生的具体情况非常重要。当您运行节点时,本地会存储一个包含链状态的数据库。因此,如果您启动一个包含./target/release/node-name --dev50 个区块的节点,停止该节点,然后再次启动它,它将从您离开的地方继续(在区块 51 处)。
请记住,作为节点创世配置的一部分,运行时 Wasm 存储在链上,并用于确定您应该运行哪个版本的运行时(本机与 Wasm)。
如果您重新编译 Wasm 和 Native 二进制文件,并运行它而不执行任何其他操作,您将看不到任何差异。即使您的节点二进制文件是全新且更新的,它也使用与旧链状态相同的数据库。这意味着在您的数据库中,您还有旧的 Wasm,当节点检查要使用哪个版本时,它将回退到使用数据库中的 Wasm!
如果您希望节点提取您所做的最新更改,您可以执行以下两项操作之一:
触发 Wasm 运行时的链上升级。这将使您的数据库具有最新的运行时代码,因此您的节点将使用最新的更改。
清除你的链条以重新启动你的创世。这将删除您的 Substrate 区块链的所有旧状态,并最终使用最新的 Wasm 运行时填充链状态,这应该与您的节点一致。
我的建议是:
./scripts/build.sh
cargo build --release
./target/release/node-name purge-chain --dev
./target/release/node-name --dev
Run Code Online (Sandbox Code Playgroud)
将执行第二种方法,清理数据库,并在每次升级运行时逻辑时从块 0 重新启动节点。这通常是开发运行时时最容易做的事情,因为在执行运行时升级时,有许多因素可能会导致意外行为。
我更改了大部分代码,并在其中添加了事件。
不幸的是,您没有在此处共享任何可以帮助调试此问题的代码。但需要注意的是,您不能对运行时的每次更新都使用运行时升级功能。
您应该将区块链视为两个一起工作的独立部分:
当您进行升级时,您基本上是将区块链逻辑从一件事交换到另一件事。从技术上讲,你实际上可以将任何东西交换成任何东西。但实际上,这并不意味着它会起作用。如果你的新逻辑不理解你当前的区块链存储,你就会破坏你的链。
因此,想象一下,您对一个函数进行了更改,该函数假设您拥有与以前完全不同的存储项目……结果不会很好。
一般来说,附加更改对于运行时升级来说就足够了。由于新功能不会影响旧功能,因此您的存储应该始终能够与新的运行时良好配合。但是,如果您进行运行时升级并假设区块链存储发生了某些变化,则您将需要在任何运行时逻辑实际执行之前触发这些存储项的迁移。您可以通过一次性on_initialize调用来完成此操作,该调用会将一组存储项目转换为新格式,但是当您谈论迁移大量数据时,实现细节就开始出现......
无论如何,总而言之,升级运行时的因素太多,可能会导致问题,也许就像您所看到的那样。一般来说,您不应该使用运行时升级来进行初始开发。相反,您通常应该清除链并在运行时迭代之间从头开始。
| 归档时间: |
|
| 查看次数: |
666 次 |
| 最近记录: |