Nervos 底層公鏈 CKB 的虛擬機(CKB-VM)是基於 RISC-V 打造的區塊鏈虛擬機。在前兩期中,咱們介紹了 CKB 虛擬機的設計理念,以及基於 RISC-V 指令集打造的選擇邏輯。那麼再往前推一步,咱們爲何會選擇基於真實 CPU 指令集來構建 CKB-VM 呢?在本篇文章中,CKB-VM 設計者將和咱們繼續討論 CKB-VM 的設計靈感、設計以及基於真實 CPU 指令集來構建 CKB-VM 的額外優點。
祕猿科技區塊鏈小課堂第 24 期git
在設計 CKB-VM 以前,咱們發現不少區塊鏈項目並非用真實的 CPU 指令集來構造本身的虛擬機。咱們熟知的以太坊下一代虛擬機 EWASM、EOS 以及 Dfinity 等都選擇了 WASM(WebAssembly,一種編碼格式)來構造本身的虛擬機。咱們也徹底能夠設計出一個具備高級語言特性的 VM,好比能夠用於靜態驗證,或是能夠直接支持高級數據結構,或是支持各類加密算法的 VM。github
可是咱們發現,雖然帶有高級語言特性的虛擬機可以提供更多的便利,好比可以支持語法各異的編程語言,但同時也會出現其餘一些問題:任何複雜的、帶有高級語言功能的 VM,不管多麼靈活,都不可避免的會在設計層面引入一些語義約束,出於性能的緣由,不一樣的語言在底層幾乎須要共享相同的語義(帶有高級語言特性的虛擬機須要綁定密碼學原語,若將來現有的原語被攻破,或者須要更換一套密碼學原語時,須要經過分叉來實現)。這樣一來, VM 自身的靈活性就會受到限制,這和 CKB 做爲加密經濟底層基礎設施的願景並不相符。算法
與此同時,一個帶有高級語言功能的 VM 一般會包含某些高級的數據結構與算法,這樣任何在 VM 中嵌入的高級數據結構與算法均可能只適合於某一類應用的開發,卻不適用於其它應用程序的開發。而且,咱們沒法預設全部可能的使用方式,這些嵌入 VM 自己的數據結構或算法除了兼容性以外沒有任何做用,隨着時間的推移,甚至會成爲負擔。編程
另外咱們還發現,全部的區塊鏈項目都要在馮·諾伊曼 CPU 架構(x86,x86_64,ARM 等架構)下才能運行,而且全部高級的 VM 特性都必須映射到現代體系架構的 CPU 彙編指令。數據結構
舉個例子,雖然 V8 引擎(由 Google 開發的開源 JavaScript 引擎,用於 Google Chrome 及 Chromium 中)看上去能夠有無限量的內存,可是其內部實現依然須要依靠一個十分複雜的垃圾回收算法,才能在有限的內存空間中模擬出無限的內存空間。架構
相似的,Haskell (一種標準化的,通用的純函數編程語言)或是 Idris(一個通用的依賴類型純函數式編程語言) 可能具備先進的靜態類型檢查模式(在某種程度上)來證實軟件運行的正確性,但在完成類型檢查以後,仍是須要經過一個翻譯層把靜態驗證後的代碼轉換成未驗證的原生 x86_64 彙編指令。編程語言
這裏的關鍵在於不管咱們如何設計 VM,都沒有辦法太過偏離當前的體系結構。換句話說,在任何 VM 的最底層,都須要將操做轉變成原始的彙編指令來執行。函數式編程
因而咱們想: 爲何不使用符合 CKB 虛擬機當前系統架構的真實 CPU 指令集來構建本身的虛擬機?
這樣一來,咱們不會丟失任何添加靜態驗證、高級數據結構、或是加密算法的可能性,而且不管咱們在 VM 中提供怎樣的數據結構或算法,均可以 最大化 VM 的靈活性 。此外,經過真實的 CPU 指令集,咱們能夠最大限度的讓開發者寫出任何知足要求的合約。函數
除了 靈活性 以外,基於真實 CPU 指令集的 VM 還有其它額外的優點:性能
爲硬件設計的 CPU 指令集一旦最終肯定並在芯片中使用,就難以修改,因此與一般是軟件實現的 VM 指令集相比,硬件指令集顯得很是穩定。這個屬性與 Layer 1 區塊鏈 VM 的訴求很是契合,由於穩定的指令集意味着較少的硬分叉,且不會犧牲靈活性。
物理 CPU 在運行時僅須要依靠寄存器和一段內存,在使用堆棧的操做過程當中,一般內存中的空間是指定的。這樣一來,咱們能夠在程序執行期間根據 VM 中的堆棧指針來獲取堆棧空間的使用狀況,從而最大限度地提升運行時狀態的可見性。
CKB-VM 能夠調整堆棧指針、更改內存中的區域分配,甚至根據須要擴大或縮小堆棧區域大小,從而提升 VM 的靈活性。當前 CPU 指令集還能夠提供過去週期的計數,從而容許查詢 VM 的運行開銷狀態。
具備真實 CPU 指令集的 VM 能夠輕鬆管理運行期的開銷,每一個指令執行時所需的 cycle 數(不考慮流水線)是固定的。 咱們能夠根據真實 CPU 指令集的這個特性來設計 CKB-VM 運行時的開銷計算機制,這樣一來,當咱們應用新算法時,也能夠準確地計算出所需的開銷。
可是,與經過操做碼或本機 VM 指令集實現加密算法的 VM 相比,使用真實 CPU 指令集存在一個關鍵的缺點: 性能 。
不過,根據研究和測試結果,咱們能夠經過適當的優化和即時(Just-In-Time,JIT)編譯器實現來優化基於真實 CPU 指令集在 VM 上運行的加密算法,從而知足 CKB 應用程序的需求。在處理即時性時,咱們是基於底層指令集進行處理,而不是基於像 JavaScript 這樣的高級語言上處理,這樣會使得 VM 具有更低的工做負載和更好的性能。
也許有人會問:在區塊鏈社區對 WebAssembly 有着強烈興趣和普遍關注的狀況下, CKB 爲何不直接使用 WebAssembly 呢?
WebAssembly 是一個偉大的項目,而且咱們很是但願它最後可以成功。一個擁有普遍支持的沙盒環境,對於整個區塊鏈行業,甚至整個軟件業來講都是件求之不得的事。從長遠來看,WebAssembly 也有潛力實現 CKB 所需的大部分特性,可是它並不能提供咱們在《CKB-VM 誕生記(一) 1》中提到的 RISC-V 能爲 CKB-VM 帶來的全部好處,好比,目前 WebAssembly 還全都是 JIT 實現,缺乏一個合理的運行期開銷計算模型。
另外,RISC-V 從 2010 年開始設計,在 2011 年發佈初版規範,2012 年出現基於 RISC-V 構建的硬件;而 WebAssembly 出現於 2015 年,2017 年發佈 MVP,相對來講,RISC-V 會比 WebAssembly 更加的成熟,因此至少在目前階段,咱們以爲使用 WebAssembly 並非 CKB-VM 最好的選擇。
固然,咱們並非徹底放棄使用 WebAssembly,考慮到 WebAssembly 與 RISC-V 一樣是底層 VM 的實現方式,並且不少設計和指令集十分類似, 咱們徹底有可能提供一個從 WebAssembly 到 RISC-V 的二進制轉換器,從而確保 CKB 也能夠利用目前區塊鏈上基於 WebAssembly 的創新。 另外,CKB 上也可以支持僅能夠編譯爲 WebAssembly 的語言(好比 Forest:https://github.com/forest-lan... )。
經過 CKB-VM 的設計,咱們的目標是創建一個圍繞 CKB 的社區,該社區能夠自由地發展和適應新技術的進步,而且能夠最大限度地減小人工干預(例如硬分叉)。 咱們相信 CKB-VM 能夠實現這一願景。
注: CKB-VM 與 CKB 同樣爲開源項目,目前 CKB-VM 仍在開發過程當中,儘管 CKB-VM 的大部分設計已經敲定,但某些設計也可能會在未來,由於你的貢獻而有新的變更和推動。這篇文章是爲了讓咱們的社區更加了解 CKB-VM,這樣人人均可以在裏面更好的玩耍並作出貢獻啦!