藏川线前段

--- 摄于 2017 年 9 月 藏川线前段

CKB hardfork features(二)

这次 Fork 的核心内容其实是 VM 的 bugfix 和功能增强(B 指令扩展和指令融合技术),当然也有上篇说到的快照功能。其他功能基本都没有 VM 影响范围大,甚至可以说如果不是 VM 需要升级,这次 Fork 也许会再等一段时间。

显而易见的是,作为验证核心环境的 VM 组件,它的升级并不是一件简单的事情,可以说,事情的复杂程度超出了一般意义上的预期,因为整个升级需要做到永远兼容之前的版本,这是一个非常复杂的问题,在这里,我们不仅需要考虑对过去的兼容,还需要考虑未来可能的扩展,即当下时点去想一个超远期兼容方案。

在整个方案设计中,其实出现了许多方案,这里可以挑选几个具有代表性的方案来说明问题:

通过交易版本号决定运行时

这个方案将 VM 版本的选择让渡到了用户手里,它将启用 Transaction 结构里的 Version 字段,通过这个让使用方能完全确定链上对该交易验证时的环境。看上去似乎没什么问题,但其实它的行为造成的后果并不是我们希望的方向。

新的 VM 将会支持一些新的 syscall,预计这将是后续合约需要的东西,如果被人为指定到了旧版本,这会造成一些不必要的疑惑,同时,虽然区块链系统是一个 legacy 系统,但我们还是期望整体环境能尽可能向最新的方向上迁移,它包含了最新的修复和优化。

通过交易引用的合约位置确定运行时

这是一种代码即法律的体现,合约在什么地方被部署的,那任何引用它的交易都将启用对应时刻的 VM 版本,但这里其实是有不少需要考虑的问题的:

  1. 同时引用 Fork 前后的合约,这个交易的验证环境应该是什么?
  2. 这个方案使得目前 ckb 允许的一种用法永久失效了,会造成不可预期的后果

其实第一个方案相对还好处理,比如强行指定该场景以最新的环境为准,这样就没有不确定的事情了,第二个问题,比如用户用 data 的方式引用 code,来锁定属于他的 cell,这个 lock cell 可以先不上传到链上,在线下先计算好就可以用了,等他想解锁的时候再上传,引用的 hash 不变,那行为就一定是不变的。但如果完全以合约上传的时间来定位启用的运行时环境的话,就会出现不符合用户预期的行为,甚至造成锁定的 cell 完全丢失的情况,这是一个不可接受的选项。

对合约引用方式分开处理

rfc:https://github.com/nervosnetwork/rfcs/pull/238

这就是现在的方案了,引用方式是 data 的合约,通过它的版本来确定运行时环境,引用方式是 type 的合约,永远保证它使用最新的运行时环境,即 type 类型的合约自动升级,data 类型的合约允许存在 legacy,用来确定其行为的一致性。

需要注意的是,从目前来看,我们会存在两个运行时,但可见的未来,也许会变成非常多个,版本选择需要在确定 data 引用时就确定,所以,我们将表达 data 类型的字段的含义进行了扩展,与原有行为兼容,这也是 legacy 系统的无奈之处。

小结

上面的方案只是几个相对比较突出的(咱记得的),其实不止这些,其他的方案取舍可以关注后续官方发布的动态,应该会完整介绍这个问题的前后决策。

VM 环境不同,同样的合约执行,消耗的 cycles 也有可能不同,在运行时切换网络也是一个需要非常小心的问题,下一篇说说网络的动态切换。

评论区

加载更多

登录后评论