08-wasm 模块,以及在链中是否已使用 x/wasm 模块 的前提下分别推荐采用哪些方式。以下文档仅适用于 Cosmos SDK 链。
导入 08-wasm 模块
08-wasm 目前还没有稳定版本。要使用它,你需要在项目中导入包含该模块的 git commit,并确保 ibc-go 和 wasmvm 的版本兼容。为此,请在你的项目中使用目标 git commit 运行以下命令:
app.go 设置
下面的示例代码展示了在 app.go 中集成 08-wasm 模块到链二进制所需的关键接入点。由于 08-wasm 本身也是一个轻客户端模块,请一并查看 集成轻客户端 章节以获取更多信息:
Keeper 实例化
在实例化08-wasm 的 keeper 时,有两种推荐方式。具体选择哪一种,取决于链是否已经集成 x/wasm。
如果存在 x/wasm
如果集成该模块的链使用了 x/wasm,我们建议让 08-wasm 和 x/wasm 共享同一个 Wasm VM 实例。虽然仍然可以使用两个独立的 Wasm VM 实例,但必须格外注意确保这两个实例在 VM 存储 blob 和各种缓存时不要共享同一个目录,否则很可能出现意外行为(从 x/wasm v0.51 和 08-wasm v0.2.0+ibc-go-v8.3-wasmvm-v2.0 开始,这种做法无论如何都会被禁止,因为 wasmvm v2.0.0 及以上版本不允许两个不同的 Wasm VM 实例共享同一个数据目录)。
为了共享 Wasm VM 实例,请按照以下指引进行。请注意,这要求 x/wasm 版本为 v0.41 或以上。
- 在
app.go中按你选择的参数实例化 Wasm VM。 - 基于这个 Wasm VM 实例创建一个
Option。 - 将上一步创建的 option 加入一个切片中,并将其传给
x/wasm NewKeeper构造函数。 - 将 Wasm VM 实例的指针传给
08-wasm的NewKeeperWithVM构造函数。
如果不存在 x/wasm
如果链没有使用 x/wasm,虽然仍然可以使用上一节中的方法
(例如在 app.go 中实例化一个 Wasm VM,并将其传给 08-wasm 的 NewKeeperWithVM 构造函数),但由于这种情况下不需要与其他模块共享 Wasm VM 实例,你也可以改用 NewKeeperWithConfig 构造函数,并按需提供 Wasm VM 的配置参数。NewKeeperWithConfig 会创建一个 Wasm VM 实例。可设置的参数包括:
DataDir是 Wasm blobs 和各类缓存所在的目录。例如,在wasmd中,这一项被设置为主目录下的wasm文件夹。在下面的代码片段中,我们将该字段设置为主目录下的ibc_08-wasm_client_data文件夹。SupportedCapabilities是链支持的能力列表。wasmd将其设置为所有可用能力,但 08-wasm 实际上只需要iterator。MemoryCacheSize用于设置内存缓存的大小(单位 MiB),例如可用于模块缓存。它不是共识关键参数,应按节点级别进行定义,通常在 100 到 1000 MB 范围内。wasmd会读取这个值。默认值为 256。ContractDebugMode是一个用于启用或禁用将合约调试日志打印到 STDOUT 的标志。在生产环境中应设为 false。默认值为 false。
wasmd 的示例。08-wasm 的使用者不能配置这个参数。
下面的示例代码展示了使用这种方式构造 keeper 的方法:
WasmConfig 类型定义,以了解每个可配置参数的更多信息。其中一些参数支持节点级配置。此外,还提供了 DefaultWasmConfig 函数,用于返回包含默认值的配置。
选项
08-wasm 模块提供了一套受 x/wasm 启发的 options API。
当前唯一可用的选项是 WithQueryPlugins,它允许为 08-wasm 模块注册自定义查询插件。使用这套 API 是可选的,只有当链希望为 08-wasm 模块注册自定义查询插件时才需要使用。
WithQueryPlugins
默认情况下,08-wasm 模块不会为轻客户端合约配置任何 querier 选项。不过,可以为 QueryRequest::Custom 和 QueryRequest::Stargate 注册自定义查询插件。
假设 keeper 尚未实例化,下面的示例代码展示了如何为 08-wasm 模块注册查询插件。
首先,我们构造一个带有所需查询插件的 QueryPlugins 对象:
Stargate querier 会将用户定义的查询路由允许列表追加到 08-wasm 模块定义的默认列表之后。
defaultAcceptList 定义了一个单独的查询路由:"/ibc.core.client.v1.Query/VerifyMembership"。这使得轻客户端智能合约可以将其工作流中的部分步骤委托给其他轻客户端,以进行辅助证明验证。例如,由数据可用性提供者提供的区块和交易数据的包含证明。
QueryPlugins 对象中的任意字段保留为 nil。
然后,我们将 QueryPlugins 对象传递给 WithQueryPlugins 选项:
NewKeeperWithConfig 或 NewKeeperWithVM 构造函数:
更新 AllowedClients
如果链的 02-client 子模块参数 AllowedClients 包含单个通配符元素 "*",那么无需进行任何额外操作即可允许创建 08-wasm 客户端。不过,如果该参数包含一个客户端类型列表(例如 [06-solomachine, 07-tendermint]),那么为了使用 08-wasm 模块,链必须更新核心 IBC 的 AllowedClients 参数。这可以在应用升级处理器中直接配置,示例代码如下:
Creating clients 小节底部的示例)。
将模块添加到存储中
作为升级迁移的一部分,你还必须将该模块添加到升级存储中。添加快照支持
为了使用08-wasm 模块,链必须在快照管理器中注册 WasmSnapshotter 扩展。该 snapshotter 负责在链创建快照时,将 Wasm VM 实例的外部状态(即合约代码)持久化到磁盘。这段代码 应放置在 app.go 中的 NewSimApp 函数里。
启动时固定字节码
Wasm 字节码应在每次应用启动时固定到 WasmVM 缓存中,因此应将这段代码放置在app.go 中的 NewSimApp 函数里。
Learn how to integrate the
08-wasm module in a chain binary and about the recommended approaches depending on whether the x/wasm module is already used in the chain. The following document only applies for Cosmos SDK chains.
Importing the 08-wasm module
08-wasm has no stable releases yet. To use it, you need to import the git commit that contains the module with the compatible versions of ibc-go and wasmvm. To do so, run the following command with the desired git commit in your project:
app.go setup
The sample code below shows the relevant integration points in app.go required to set up the 08-wasm module in a chain binary. Since 08-wasm is a light client module itself, please check out as well the section Integrating light clients for more information:
Keeper instantiation
When it comes to instantiating08-wasm’s keeper, there are two recommended ways of doing it. Choosing one or the other will depend on whether the chain already integrates x/wasm or not.
If x/wasm is present
If the chain where the module is integrated uses x/wasm then we recommend that both 08-wasm and x/wasm share the same Wasm VM instance. Having two separate Wasm VM instances is still possible, but care should be taken to make sure that both instances do not share the directory when the VM stores blobs and various caches, otherwise unexpected behaviour is likely to happen (from x/wasm v0.51 and 08-wasm v0.2.0+ibc-go-v8.3-wasmvm-v2.0 this will be forbidden anyway, since wasmvm v2.0.0 and above will not allow two different Wasm VM instances to shared the same data folder).
In order to share the Wasm VM instance, please follow the guideline below. Please note that this requires x/wasm v0.41 or above.
- Instantiate the Wasm VM in
app.gowith the parameters of your choice. - Create an
Optionwith this Wasm VM instance. - Add the option created in the previous step to a slice and pass it to the
x/wasm NewKeeperconstructor function. - Pass the pointer to the Wasm VM instance to
08-wasmNewKeeperWithVMconstructor function.
If x/wasm is not present
If the chain does not use x/wasm, even though it is still possible to use the method above from the previous section
(e.g. instantiating a Wasm VM in app.go an pass it to 08-wasm’s NewKeeperWithVM constructor function, since there would be no need in this case to share the Wasm VM instance with another module, you can use the NewKeeperWithConfig constructor function and provide the Wasm VM configuration parameters of your choice instead. A Wasm VM instance will be created in NewKeeperWithConfig. The parameters that can set are:
DataDiris the directory for Wasm blobs and various caches. As an example, inwasmdthis is set to thewasmfolder under the home directory. In the code snippet below we set this field to theibc_08-wasm_client_datafolder under the home directory.SupportedCapabilitiesis a list of capabilities supported by the chain.wasmdsets this to all the available capabilities, but 08-wasm only requiresiterator.MemoryCacheSizesets the size in MiB of an in-memory cache for e.g. module caching. It is not consensus-critical and should be defined on a per-node basis, often in the range 100 to 1000 MB.wasmdreads this value of. Default value is 256.ContractDebugModeis a flag to enable/disable printing debug logs from the contract to STDOUT. This should be false in production environments. Default value is false.
wasmd. This parameter is not configurable by users of 08-wasm.
The following sample code shows how the keeper would be constructed using this method:
WasmConfig type definition for more information on each of the configurable parameters. Some parameters allow node-level configurations. There is additionally the function DefaultWasmConfig available that returns a configuration with the default values.
Options
The08-wasm module comes with an options API inspired by the one in x/wasm.
Currently the only option available is the WithQueryPlugins option, which allows registration of custom query plugins for the 08-wasm module. The use of this API is optional and it is only required if the chain wants to register custom query plugins for the 08-wasm module.
WithQueryPlugins
By default, the 08-wasm module does not configure any querier options for light client contracts. However, it is possible to register custom query plugins for QueryRequest::Custom and QueryRequest::Stargate.
Assuming that the keeper is not yet instantiated, the following sample code shows how to register query plugins for the 08-wasm module.
We first construct a QueryPlugins object with the desired query plugins:
Stargate querier appends the user defined accept list of query routes to a default list defined by the 08-wasm module.
The defaultAcceptList defines a single query route: "/ibc.core.client.v1.Query/VerifyMembership". This allows for light client smart contracts to delegate parts of their workflow to other light clients for auxiliary proof verification. For example, proof of inclusion of block and tx data by a data availability provider.
QueryPlugins object as nil if you do not want to register a query plugin for that query type.
Then, we pass the QueryPlugins object to the WithQueryPlugins option:
NewKeeperWithConfig or NewKeeperWithVM constructor function during Keeper instantiation:
Updating AllowedClients
If the chain’s 02-client submodule parameter AllowedClients contains the single wildcard "*" element, then it is not necessary to do anything in order to allow the creation of 08-wasm clients. However, if the parameter contains a list of client types (e.g. ["06-solomachine", "07-tendermint"]), then in order to use the 08-wasm module chains must update the AllowedClients parameter of core IBC. This can be configured directly in the application upgrade handler with the sample code below:
Creating clients for an example of how to do this).
Adding the module to the store
As part of the upgrade migration you must also add the module to the upgrades store.Adding snapshot support
In order to use the08-wasm module chains are required to register the WasmSnapshotter extension in the snapshot manager. This snapshotter takes care of persisting the external state, in the form of contract code, of the Wasm VM instance to disk when the chain is snapshotted. This code should be placed in NewSimApp function in app.go.
Pin byte codes at start
Wasm byte codes should be pinned to the WasmVM cache on every application start, therefore this code should be placed inNewSimApp function in app.go.