Filecoin Virtual Machine(FVM)

1. 简介

  FVM 是 Filecoin 的虚拟机,不太懂区块链的话可以简单认为和 eth 的 EVM 类似(完全不懂这个就可以不看本文啦),但其实 FVM 更像 dfinity 的 WASM 容器,并且FVM 也是用 WASM 实现的.Filecoin 预计在2022年6月左右引入该功能.这种幅度的变化会影响许多组件:

  1. 链状态层,用于存储和加载用户提供的代码.
  2. 执行层, 用于编译/解释用户提供的代码,运行设计此类代码的状态转换,并验证结果.
  3. gas 模型,用于保护网络并面对用户可编程代码时调节链容量需求/供应动态.
  4. 预先存在的baseline协议,以促进针对系统功能的可编程性.

  Filecoin 虚拟机(FVM)是一个基于IPLD(简单描述:将文件分为固定大小的trunk,然后所有trunk构建一个merkle树,多个版本的文件可以共用相同的trunk,甚至于可以像git一样,新trunk存储旧trunk和对旧trunk的修改就好)的 WASM执行层,能够运行任意用户提供的代码.FVM取代了现有的非可编程执行层 Legacy VM.native actors的逻辑(相当于Filecoin中的智能合约)部署为Wasm 字节码.针对非Filecoin 运行时(例如evm)的foreign actors也通过运行时模拟得到支持.

  本文是对FIP-0030的归纳总结,FIP-0030 为FVM 提供了一个参考的架构,并结识了它各种组件:(a) Machine,(b) Call Manager,(c) Invocation Container, (d)Kernel,(e)Syscalls 和 (f)Externs.定义了actor 代码必须遵守的contract、系统调用可用的目录、IPLD状态操作的机制以及进一步的技术细节.

2. FVM 规范

2.1. 参考实现

filecoin-project/ref-fvm是fvm的一个参考实现,和本规范配套.

2.2. 上下文和 VM 接口

  在 Filecoin 中 VM 是执行层中负责在状态树上应用transactions的组件.这些transactions被封装在消息中,有两种消息:

  • 显示消息 由secp256k1 或 BLS 账户actors 发送到链上,带有签名以证明其真实性
  • 隐式消息 由系统生成,不会出现在链上,也没有签名.比如包括cron ticks 和 reward cycles

VM 实例输入参数简单示范

let machine = Machine::new(
  epoch,                  // 链 epoch
  base_fee,               // 当前有效的基本费用
  base_circ_supply,       // 基础循环供应
  nv,                     // 网络版本
  state_root,             // 初始状态树的根 CID
  blockstore,             // blockstore 在执行期间加载和保存对象
)

  然后将消息应用到机器.每个应用程序都会生成一个返回对象,其中至少包含一个消息回执,一个矿工惩罚和一个矿工tip.

let ApplyRet { receipt, penalty, tip } := machine.apply_message(msg1);
let ApplyRet { receipt, penalty, tip } := machine.apply_message(msg2);
let ApplyRet { receipt, penalty, tip } := machine.apply_message(msg3);

消息回执记录在链上.它保存交易的退出代码、使用的gas,并且(可选)仅在成功时返回数据.
惩罚和 tip 是协议的加密经济规则用来计算块生产者的块奖励数量
一旦调用者处理完所有应用消息,就会刷新机器.这个操作将会计算最终状态根.此操作还可能将新写入的块提交到blockstore

let final_state_root = machine.flush();

2.3. 责任

   FVM 讲消息应用到状态树,它并不负责推进链本身.具体而言,主要负责:

  • 加载链上的Wasm 模块并将他们编译为机器码
  • 对提供的消息执行预先检查
  • 跨actors 路由呼叫, 通过呼叫管理器抽象
  • 处理来自actors的系统调用,并交付结果
  • 必要时与外部环境(filecoin 客户端)交互
  • 管理IPLD状态读取和写入操作
  • 实例化<核心技术设计>中描述的对象堆栈以此应用消息

2.4. 核心技术设计

该图可以作为FVM技术设计的参考

Machine

Machine 是FVM在具体epoch的实例化,在特定的状态根上,准备好接收消息以执行

Call Manager

Call Manager 协议奥处理给定消息所涉及的调用堆栈.这需要配置和销毁Invocation Container,跟踪gas使用情况,并在超过gas限制时停止执行

Invocation Container

Invocation Container(IC)是在单个调用的上下文中运行actor 代码的环境/沙箱.同一actor 的冲入或递归将衍生出另一个IC.
IC 是FVM实现合约的Wasm 引擎的一个实例.合约包括:

  • 可用sysCalls作为可导入的主机提供的函数
  • 表示跨FVM边界的数据的共享类型
  • actore 拥有的内存,用于在Syscalls中交换数据
  • 透明的gas 核算和自动执行暂停
  • (未来)社区通过一些治理过程"blessed"普及Wasm模块的动态连接,以减少actore 字节码大小(例如FVM SDK、IPLD编解码器等)

Syscalls

Syscall是 Wasm 导入提供给actor的函数,允许它与Externs环境交互,并调用在客户端执行(而不是Wasm)的性能更高的复杂操作(例如加密原语)

Kernel

Kernel 是有Call Manager 创建并注入 Invocation Container的对象,它处理Syscalls,并存储调用范围内的状态

Externs

和SYScalls是FVM 提供给actor的函数蕾西,Externs是node 提供给FVM的函数.根据所使用的编程语言,Externs 层可能只是逻辑(如果客户端和FVM都是用相同的语言编写的),或者是FFI 形式的物理表示.

2.5. actors

actors 相当于其他网络中的只能合约: 他们是存在于链上的逻辑片段,可以通过 message 触发.

2.5.1 actor type

我们区分了3中类型的actor:

  1. Built-in actors
  2. Native actors
  3. Foreign actors

built-in actors

built-in actors 是协议定义的actor 类型.到目前为止,这些actor 与 legacy VM一起发布并与其紧密集成.对于Lotus,这些actor 位于 filecoin-project/specs-actors

通过采用通用的、可以值得执行字节码格式,所有Filecoin客户端都可以依赖编译为Wasm自己吗的单个代码库.这加快了协议开发,缩短了协议升级时间.并减少了协调开销.

该代码库位于 filecoin-project/builtin-actors, FIP-0031 通过状态迁移提出了其在网络中的标准化.

这种方法有一些实际意义

  1. 规范actors 成为filecoin的公共代码库,核心开发人员围绕它集中开发工作.
  2. Filecoin 客户端会将规范的Wasm 字节码嵌入到他们的二进制文件中.具体机制取决于实现.
  3. 网络升级将同意在升级时期迁移到内置参与者的确切CodeCID

下面列出了所有built-in actors 的类型

/// The bundled CAR embedded as a byte slice for easy consumption by Rust programs.
///
/// The root CID of the CAR points to an actor index data structure. It is a
/// CBOR-encoded IPLD Map<String, Cid>, enumerating actor name and their
/// respective CIDs.
///
/// The actor names are values from this enumeration:
///
/// - "account"
/// - "cron"
/// - "init"
/// - "market"
/// - "miner"
/// - "multisig"
/// - "paych"
/// - "power"
/// - "reward"
/// - "system"
/// - "verifreg"
///
/// The Filecoin client must import the contents of CAR into the blockstore, but
/// may opt to exclude the index data structure.
pub const BUNDLE_CAR: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/bundle/bundle.car"));

Native user-defined actors

Native user-defined actors 定义的 actor 是专门为 FVM 运行时编写的 actor.
用户可以使用任何可以编译成 Wasm 字节码的编程语言编写本地用户定义的Wasm.但是一些特定语言的开销(例如运行时,垃圾收集,stdlib等)可能会导致Wasm字节码大小和执行开销过大,从而转化为更高的gas成本.使用Rust 编写Native user-defined actors是合理的选择,它缺乏运行时并可以具有通过no_std省略stdlib的能力和及其成熟的Wasm支持.

Foregin actors

Foregin actors 针对非FVM 运行时的智能合约或程序,通过仿真在可以在Filecoin网络中运行.

运行Foregin actors 的能力对于跨链互操作性很有用, 并将Filecoin的范围和实用性扩展到其他区块链,使他们能够更无缝地访问filecoin 网络的存储能力.

我们目标第一个Foregin actors 通过部署EVM 字节码支持eth 智能合约.这允许将现有经过实战考验的eth 智能合约直接且相对无风险地移植到Filecoin 网络.

每个外部运行时都是一个actor 类型,有CodeCID标识.外部运行时的安装就像任何其他actor 类型一样.Foregin actor 实例是通过 InitAcotr 构建的.

总结

对filecoin 来说是很重要的一步,但在整个公链行业里只能说是平平无奇了,我个人还是推崇definity.

引用

filecoin-project/fip-0030

posted @ 2022-04-13 17:12  哪吒young  阅读(1042)  评论(0编辑  收藏  举报