以一个开发者视角来看 ckb 2021 的 hardfork 内容(一)

从这篇开始,咱就开始剧透 ckb 在今年的硬分叉修改内容了,当然,其实这也算不上剧透,因为 RFC 仓库中的 PR 是公开的,修改内容都早已公示出去了,只是实现相对落后一点,从目前的进度来看,剩下还未实现的修改已经不多了,当然,除了实现,还需要大量的测试用来保证行为的正确性和一致性。

这篇主要介绍的是咱参与开发的第一个特性,允许在全网传播消耗 cycle 巨大的交易,这是对之前版本限制的放开,也是只有在 fork 版本打开才能达到全网通行的特性之一。

变化内容

严格意义上来说,这个修改并不属于 break change 范畴,只是它依赖于 hardfork 的 VM 功能,所以被捆绑到了 hardfork 之后。还有一个原因是虽然对大交易传播的限制并不是写在共识规则里,但它是写在 p2p 网络的链路里,只有在 hardfork 的时机,才有可能全网更新 binary 让特性能顺利全网通用。

在 ckb 主网上线之前,我们做了一个简单的测试,用户可以用一个非常大的交易让某些性能相对差的节点验证时间超时,即用大交易对某些节点 DDOS,让它无法正常跟上全网。随即,我们将全网默认允许执行的 cycles 做了限制,将其设定在 70_000_000 这个数字上,大致相当于一个交易验证上限在 10 分钟,具体是哪个类型的 CPU 执行时间,因年代久远已经丢失了,这就简单的对 DOS 攻击做了一个一刀切的限制,但这也限制了正常的大交易的传播,这也是上线期间的取舍。

本次 VM 升级带来了 resume/suspend 功能,即交易验证可以分段执行和挂起,不再是只能执行到无法执行为止了,这样的功能给上述的防 DOS 带来了新的解决方案,可以将这种不常见的大交易单独做一个验证通道,慢速执行,并且在其他地方需要计算资源的时候挂起执行,这样一来,既规避了 DOS 攻击带来的无法同步问题,又能移除不必要的限制,释放了 ckb 上业务的潜能。

设计与实现

交易执行的重点在于几个状态机的切换和交易插入队列的入口确定,以及对空闲时段的确定和大交易执行的挂起时机等等,相对来说功能不算复杂。

需要区分的是,交易来源及需要如何处理:

来源 处理方式 Fork 版本是否必须加上
RPC 提交 阻塞或挂起执行大交易 挂起方式不是第一版必须实现的,可以暂时忽略
Compact block 新鲜交易就地阻塞执行 与原有方式一致,不需要修改
Sync 交易就地阻塞执行 与原有方式一致,不需要修改
Relay transaction 将大交易插入分段执行队列,小交易阻塞执行 必须在 fork 版本实现

基于上述的变化,首先由咱做了一个 demo 版本,正常可用,然后由于咱对交易池的部分逻辑并不是特别清楚,在接入交易池的时候做得不是很好,又由 zhangsoledad 基于咱的实现重构了一版:PR,之后合入 ckb 主支的应该是重构之后的版本,至于咱的实现,在代码合入之后应该会被删除。

原文:CKB hardfork features(一) 略有修改

4 Likes

感谢介绍 好希望之后能看到这一系列关于 hardfork 的解说内容
弱弱小弟我这边有些问题想要请教

  1. 我们怎么判断什么交易属于大型交易?
  2. 慢速验证的意思指的是大型交易会比较慢被打包或者确认吗?
  3. 大型交易的验证通道是什么样的节点可以去做验证?
  1. 以当前版本的 ckb,toml[tx_pool] 分段里有一个默认配置 max_tx_verify_cycles = 70_000_000,这个 cycles 就是大交易的分界线,大于这个数就进入大交易队列
  2. 小交易验证是一气呵成,大交易验证是分段执行,每次新块验证都将会打断 大交易 的执行,从效果上来看,造成的后果是传播到全网的速度会比普通交易慢很多,尤其是在交易多的情况下,如果都是空块,可以认为传播不受影响
  3. 在 hardfork 版本之后,所有节点都可以验证这个交易,可以通过配置文件配置来人为控制 大交易的分界线
1 Like

基本了解了 谢谢解惑
再多问一个
3. 大型交易的验证可以通过配置文件来人为控制,是指我们可以透过修改配置文件来决定我们要验证多大 cycle 的交易吗?

是指通过配置文件决定多大的交易进入分段执行队列,这个对于不同 cpu 有不同的指标,节点不能拒绝验证大交易,机器性能差的节点可以酌情将指标改小。

任何一个块里面打包了大交易,全网节点想要跟上最新块,就必须要验证该交易,性能差的节点通过分段验证的 cache 可以在空闲时间验证相对大的交易,让新块验证的时间因为有分段验证 cache 而降低。

如果节点有拒绝大交易验证的权利,那么当一个全新的大交易通过新块传播到本地的时候,因为该块符合共识规则,为了跟上全网节点,就必须在无 cache 的前提下硬性执行通过,这个时间可能会造成性能差的机器越来越跟不上最新,如果这是一个挖矿节点,那相当于该节点一直处于挖叔块的过程中,这是不可取的策略

原来如此,谢谢,分段执行的这个概念有点新颖,没有你的解释还没有办法完全理解
那目前就我们所知,会有什么类型的交易可能超过 70000000 这个 cycle 数吗?
看起来要执行大交易也要考量到可能会比较慢被验证这个点。

就现在来看,一笔交易由多个私钥签发,当数量达到一定程度的时候,就可能会到达 70000000,如果不放开,相当于强迫用户将一笔交易拆分为多笔,这也是目前存在的一个问题,尤其对交易所而言。

在未来,当 chain lock 成为流行标准的时候,不可避免的在一个签名上可能存在多次验证,有些加密算法 cycle 耗用会比 secp 多得多,组合起来就更多了

那看起来在这次的硬分叉以后,我们可望看到互操作性这个 CKB 的优势,以及在交易所等多签的流通,都能在没有 cycel 限制之后能够进一步的提升。再次谢谢解惑。