The open source developers from the WasmEdge community have just delivered the first two milestones of our Web3 Foundation grant. The result is a Substrate implementation that runs on the WasmEdge WebAssembly Runtime.
Why is an Alternative Runtime Needed?
In Sept 2016, a computational DDoS attack was launched against the nascent Ethereum blockchain while most Ethereum developers were attending Devcon2 in Shanghai. The attack exploited an issue with the GETH software and brought down Ethereum nodes running GETH. However, the Parity nodes, written independently from a different programming language, were not affected. The Ethereum foundation put out an urgent notice asking miners to switch to Parity, and weathered the attack without interruption of the blockchain services. The biggest lesson from this so-called Shanghai Attack is the importance of diversity in blockchain node software. That is why we are excited to announce that Substrate, a leading blockchain framework, now runs on an alternative runtime — the WasmEdge Runtime.
WebAssembly is an ideal runtime for blockchains
While native applications compiled from languages like C/C++, Rust, and Swift are fast and efficient, they can often be unsafe (could crash the whole system) and are not portable across OSes and CPUs. WebAssembly has emerged as a fast, safe, secure, and portable runtime for “native” applications. It is especially important for blockchain node software.
Blockchains already have a reputation for being slow. High performance is mandatory. Safety, reliability, and security are key value propositions for blockchain systems. Public blockchains require diverse node operators, OSes, and hardware in order to achieve decentralization. Cross platform portability is a key feature for blockchain node software.
Substrate has selected WebAssembly as its runtime from early on. Substrate blockchain node software is written in Rust and compiled into WebAssembly bytecode. It then runs on a WebAssembly runtime across diverse node software and hardware setups.
WebAssembly runtimes are not created equal
One of the great strengths of WebAssembly is that it is an open standard. There are multiple open source implementations of WebAssembly. Learning from the lessons of Shanghai Attacks, it is an easy win for Substrate to be adapted to multiple WebAssembly runtimes. It provides the runtime diversity that is proven critical for the safety and reliability of a blockchain system.
In this Web3 Foundation grant project, we worked on Substrate compatibility with the WasmEdge Runtime.
WasmEdge is a lightweight, high-performance, and extensible WebAssembly runtime. It is the fastest Wasm VM today. WasmEdge is an official sandbox project hosted by the CNCF. Its use cases include modern web application architectures (Isomorphic & Jamstack applications), microservices on the edge cloud, serverless SaaS APIs, embedded functions, smart contracts, and smart devices. And with this grant project, it is also a sandbox runtime for blockchain nodes!
The challenges of host functions
When we started the journey to port Substrate to WasmEdge, we anticipated a rather straightforward engineering challenge. After all, Substrate already runs on WebAssembly and WasmEdge is fully compatible with the WebAssembly spec.
Well, we were wrong. The problem is that the standard WebAssembly specification was originally designed for a VM embedded in the web browser. For running standalone applications, such as a Substrate blockchain node, it lacks basic features such as file system access. The WASI standard emerged in 2018 to provide WebAssembly apps access to the operation system via the libc interface. Yet, writing everything from scratch on libc is still too restrictive — think of the cryptography libraries required by a blockchain system, do we really re-invent the wheel on libc? The solution here is a WebAssembly feature known as host functions. The host function allows OS native functions to be called from a WebAssembly app to perform specific tasks. The Substrate framework makes extensive use of WebAssembly host functions.
Unfortunately, the interactions between the WebAssembly runtime and host functions are not standardized. The WasmEdge Rust SDK supports registering and calling Rust-based host functions in WasmEdge. But it is not entirely compatible with how Substrate does it.
For this project, we refactored and enhanced the WasmEdge Rust SDK to support several approaches of host functions. Throughout the work, we were very impressed by the Substrate team’s work. The Substrate Rust code is tested and supported by a comprehensive suite of unit tests and CI actions. Those tests provided us with a concrete framework to test and anticipate the behavior of our code. They are an invaluable resource to our work.
The substrate-wasmedge repository contains subtrees of the WasmEdge project and the Substrate project. We made changes in the Substrate subtree so that it can build on WasmEdge Rust SDK and run on the WasmEdge runtime. A CLI flag is also provided for the user to switch between alternative WebAssembly runtimes.
We aim to merge our changes back into the upstream Substrate project. That will turn Substrate into a multi-WebAssembly blockchain framework. We will also demonstrate performance characteristics and benchmarks of Substrate on WasmEdge against alternatives.
For the time being, however, you are very welcome to try out your Substrate applications in substrate-wasmedge and let us know your success (or failure so that we can fix!)