Ckb on wasm(一)

前两个月,做了一些让 ckb-types 暴露接口更友好的事情,包括对 molecule 生成代码的行为优化 ,对一些数据结构增加 From trait 实现,ckb-types 以及整个 ckb 库弃用 Pack/Unpack trait 转向 From/Into trait,同时将大部分 builder 接口变成 generic 签名,这样在用户使用的时候,代码量减少,也更加易用。不过很遗憾,虽然改动已经实现完成,并且一度合入主分支,但在 0.119 发版之前,还是被 revert 了,因为 0.119 将开启 testnet 的第二次 hardfork,之后将进入 mainnet 的第二次 hardfork,在期间,用户必须强制升级依赖库,而易用性改动将带来大量的 break change,虽然我已经实现了 90% 以上代码自动修改的工具,但考虑到改动量太大,用户本身也会因为代码改动量而存疑,进而不得不将这些改动 revert 掉,等 hardfork 之后再合并回来。

当前状态

做完上面的事情之后,近一个月,我都在为 ckb on wasm 计划努力实现中,到现在,第一阶段的事情基本做完了,ckb-lightclient 已经可以彻底单独跑在浏览器网页中了,并且支持 indexdb 作为后端存储,目前实现在这个分支里,目前项目状态并没达到 production ready,想要玩的朋友,可以自己切到该分支,进入 light-client-wasm 目录进行调试,默认是实现是 dev 链,需要一些操作:

  1. 基于这个分支编译一个 ckb,创建 dev 链,然后在 ckb.toml 的 p2p listen 中增加 /ip4/127.0.0.1/tcp/8118/ws websocket 监听,并且配上 miner 信息,启动后,将该节点的监听信息包括 (peer id) 更新到 ckb-light-client/config/dev.toml 的 bootnode 上。

  2. 修改 light-client-wasm/src/lib.rs 第 41 行的内容,将它指向 ckb dev 节点的 data/specs/dev.toml 目录

  3. light-client-wasm/src/lib.rs 文件中,找到 fn get_script_example fn get_search_key_example 这两个函数,将它们的实现改成 ckb dev 链的 miner 信息

  4. 默认 js 运行的程序在 light-client-wasm/index.js 内,可以自行调整,默认示例是注册 miner script 并定时查询

  5. $ cd light-client-wasm
    $ npm install && npm run serve
    
  6. 打开 http://localhost:8080/ 开发者界面,可以看到 lightclient 正在工作

计划初期

当然,罗马不是一天建成的,在真正到达今天之前,我们也无法完全肯定 lightclient 一定能跑在 wasm 之上,一开始,我们的计划很简单:

  1. 用最简单的修改去验证,编译到 wasm 是有可行性的
  2. 然后实现一个最简单的 demo 证明必然可以实现
  3. 真正开始实现 ckb on wasm

lightclient 是一个基于 p2p 网络的应用,同时它也有持久化的需求,而目标是将 lightclient 跑在浏览器上。众所周知,浏览器对访问本地磁盘的限制是非常严格的,同时它的网络环境也比较受限,想要在上面重新实现完整的 p2p 网络是很困难的,存储也很受限,这些都需要重新调研方案,我们不可能因为需要在浏览器上执行,就将 Rocksdb wasm 化,这样工程太过浩大,不切实际。

调研 browser wasm rust 相关生态

browser

首先是存储,在浏览器上,能选的方案不多,加上有持久化和数据量需求,可选的就更少了,基本只有 opfsindexdb 两种方案,比较而言,虽然indexdb 是出了名的难用,但好歹还给了事务模型,opfs 是真的裸文件操作了,同时考虑到现在浏览器的支持程度,实际上 indexdb 的支持会更广一点(相对而言)。几乎属于没的选的选项。

wasm-rust

这里属于一言难尽的范畴,有关 wasm target 的讨论,延续了好几年,包括 WASI 支持,tokio 对 WASI 的支持,tokio 对 WASM on browser 的支持等等。rustc 最初的 target wasm32-unknown-unknown 默认实现是针对浏览器的,但并没有强调 web 端,而后续 wasm 发展出了 wasi 的 native 运行时,包括支持多线程等等操作,导致最初的 wasm32-unknown-unknown 目前处于一个尴尬的阶段,到底是单独开个 wasm-web target 还是让它继续这样,这个目前还没有定论,但毫无疑问,web 端的实现,目前只能使用这个 target 与 js/dom 交互。tokio 对 wasi 的支持,算是一种利好,至少部分东西在 wasm 全 target 通用,比如 sync mod 下的异步元语(channel/lock/permit)等等,在 rust 异步生态下,丢开 tokio 去单独实现一个 runtime 是很痛苦的一件事情。

同时,在早两年,tentacle 也已经实现了 web 端 websocket 的适配,网络通信上几乎已经是没有什么大问题了。剩下的就是 lightclient 自身的代码以及 ckb 相关依赖的 wasm 化问题。

验证

基于调研的情况,我们初步决定,从底层依赖开始,一点点向上将依赖库一步步进行 wasm 化,同时,由于处于项目验证初期,需要快速验证方案是否有可行性,我们并不打算在 demo 阶段引入持久化存储,而是使用 BtreeMap 作为替换方案进行 demo 验证,这样就能绕开一大部分问题,尽快验证可行性。

这个分支就是基于 BtreeMap 的 demo 实现,只有几个核心 api 实现,但已经完成了 lightclient 的绝大多数核心功能,有朋友想玩也可以去尝试一下,操作步骤和上面说的一样,就是代码比较 dirty,但 work。

最后

这一篇就先说这么多,下一篇应该是一些需要注意的地方,再下一篇就是 indexdb 爬坑日记了。

4 Likes

Hi Driftluo, can I just make a suggestion to you and also the Nervos devs in general.

I think it would be great if when posting these types of things that the first paragraph be devoted to explaining how this ultra technical stuff is going to benefit CKB and CKB holders.

I always read these things from start to finish, not because I understand it, but just because it usually reinforces my belief that the cryptape devs are most likely among the most talented devs in the crypto industry, but I still usually come away not knowing what the hell I’ve just read.

That whole 3 pages gave me absolutely no insight into why you are even spending the last month or so doing this work.

“After finishing the above tasks, I have been working hard on the ckb on wasm plan for nearly a month.”

I follow CKB pretty closely and didn’t even know there was a “ckb on wasm plan”. This has probably been discussed already and I’ve probably even read about it and just forgot, but I still think that it would be very beneficial to have at least a small part at the start of these updates aimed at the general CKB community, just so we can understand the general concept and how this is hopefully going to benefit CKB holders in the longrun.

Thanks for the suggestion, my article did not explain why we are trying to wasm-ify lightclient. Let me briefly talk about what we will get after this project is production-ready.

If we make ckb light client working on wasm, any web page can directly run a ckb light client node(Yes, this is a fully functional light node), making it more convenient to quickly query and track the required script dynamics on the web page. At the same time, the architecture of fiber is almost the same as that of light client, which means that fiber only needs to be simply adapted to achieve the same capabilities as light client, that is, any web page can run a fiber node. This will be more convenient for front-end developers to develop the web page functions they want.

1 Like

Thanks for the reply mate, that’s made things a bit clearer as far as what the general purpose of this is, but I have to admit I’m still a bit lost as far as what it all means at the end of the day.

I think there is a big gap between what people on the technical side of crypto think is just ‘basic’ knowledge and what the vast majority of CKB holders and just crypto holders in general actually understand.

I get it though, because it’s the same for nearly every type of job or sport or whatever, that when you get really good at something, it’s very easy to forget that everyone else is still in the beginner stage.

I don’t even think I’m after an explanation of the technical side so much, I just want an explanation of ‘how’ and ‘when’ this will eventually benefit me as an end-user of crypto.

But I can totally understand how painful it must be to try and dumb things like this down to a really basic level, but I just think it would be something that would be very much appreciated by the general community if the devs could keep this in mind when releasing this type of info.