Authors: David Fuelling, Oleksandr Pidskopnyi, Mayukha Vadari, Peng Wang
One primary aspect of the WebAssembly (WASM) integration with rippled is the runtime used. WASM runtime environments are low-level virtual stack machines, like JVM, and can be embedded into any host application (such as rippled). There are several different implementations, with various tradeoffs. When we did an initial analysis of different runtimes earlier this year, we chose to use WAMR, primarily due to its performance benefits.
Upon finishing the initial development of the Smart Escrows implementation and reaching the review and testing stage, the RippleX programmability team decided to revisit the decision on the initial selection of WAMR as our WebAssembly VM runtime, to ensure the chosen runtime is well-positioned for success in our XRPL usage context. The team now had better context on VM internals and a better understanding of WebAssembly in general, which enabled a deeper analysis now compared to when the initial decision was made. Based on some initial meetings with members of the WebAssembly community, the team investigated two alternative runtimes (Wasmi and Wasmtime).
The team spoke to each of the three VM runtime teams directly, did some deeper analysis of the codebases and the ecosystems around each of the runtimes, and spoke to other trusted parties in the broader WebAssembly community.
Initial Investigation
The three runtimes investigated were:
- WAMR (the VM currently integrated in the Smart Escrow implementation)
- WasmTime (highly recommended by several researchers in the WASM ecosystem)
- Wasmi (used by Stellar and Polkadot)
Security Postures
- WAMR was created to service embedded-systems use-cases where the code running in the VM is “first party”, meaning that it is assumed to be trusted.
- WASMTime was created to run untrusted code (such as in a browser).
- Wasmi was also created to run untrusted code (on a blockchain). Wasmi was originally created by Parity Technologies, the team behind Polkadot, for the explicit purpose of running programmability on the Polkadot blockchain.
Code Complexity
- WAMR: The code is quite simple and written in C, which the team has a lot of experience with.
- WasmTime: Rather complex code and architecture. This makes it cumbersome to use and the increased complexity increases chances of potential bugs and security issues. To prevent resource exhaustion attacks, we explored loading/running wasmtime (at least the components before execution) in the VM itself - a complexity not needed for other runtimes.
- Wasmi: A simpler architecture and easier to digest, which also makes it easier for the programmability team to build knowledge about VM internals.
History of Security/Bugs
- WAMR: See section 2.2 of this research paper for some historical examples of bugs or security issues in WAMR that (according to the paper’s author) seem to be caused by a posture of assuming “first party” code on the part of the WAMR team. There have been a handful of major CVEs reported. The project has not had any audits done.
- WasmTime: There are many security-minded researchers working on it (as evidenced by the number of small CVEs reported). The project has had audits done, but none of them are public.
- Wasmi: There are 2 public blockchain-focused audits. The runtime is live in two blockchains (Polkadot and Stellar) and has not had major issues. There has only been one major CVE reported.
Language Implementation
Wasmtime and Wasmi are written in Rust, and support C APIs. WAMR is written in C.
Rust brings to bear memory safety and other compile-time checks that help improve the robustness of any project as compared to projects implemented in C or C++. While not a firm requirement of the VM we choose, the advantage of a Rust-based VM is that bugs or vulnerabilities can more easily be caught at compile time. A disadvantage of a Rust-based VM is that our engineering team has less experience with Rust, so digging into it or customizing a Rust project might be more difficult. Potentially the use of AI tools and reliance on the WASMTime dev team to implement new features could be a mitigant here.
High-Level Comparison
| WAMR | WasmTime | Wasmi | |
|---|---|---|---|
| Code complexity | Simple | Complex - 10x the code of Wasmi, with a lot of advanced features we don’t need | Simple, easier to digest/understand |
| Prior blockchain usage | None | DFINITY’s Internet Computer, Polkadot | Polkadot, Stellar’s Soroban |
| Security | Intended for embedded use cases and first-party code, not third-party code | Security is first and foremost for the team | Security is very good |
| Audits | Has not been audited | Has been audited (not blockchain-focused), but the audits are not public | Multiple public audits, based on blockchain usage |
| Native Fuel support | Yes | Yes | Yes |
| Language | C | Rust | Rust |
Performance Analysis
This report details the results of a comparative baseline performance test between four WebAssembly (WASM) virtual machines: WAMR, WasmTime (Pulley1), Wasmi, and Wasmtime (Winch2).
The VMs were tested against a basic WASM module at load levels of 100 TPS and 300 TPS, with each test running for 30 minutes. Higher TPS thresholds were not tested for this initial set of tests, since 300 TPS was enough to differentiate the four VM configurations.
Note: these are just preliminary tests to differentiate the VM configurations, and should not be taken as an indication of final Smart Escrow/VM performance yet. These tests are also specific to integrating the runtimes into rippled, and are not reflective of the runtime performances in other contexts.
Bottom Line
Under the 300 TPS high-stress workload, Wasmi delivered the most balanced and consistent performance profile. It combined fast ledger validation times, high ledger-processing throughput, and stable operation with minimal overvalidations3 and no sync issues. WAMR performed well but had some minor stability issues, and WasmTime (both Pulley and Winch) were highly unstable and slow (possibly due to large amounts of time spent loading/parsing contract bytecode into intermediate representations).
Key Findings
- At 100 TPS: All four VMs performed comparably and were stable, with no significant issues observed
-
At 300 TPS: Significant performance differences emerged.
- Stability: Wasmi and WAMR showed the highest stability. Wasmi had the lowest overvalidations (1) and zero P2P sync issues. WAMR also had zero sync issues, with slightly higher overvalidations (18).
- Instability: WasmTime (Pulley) and Wasmtime (Winch) were highly unstable, with large overvalidations (217 and 149) and significant P2P sync problems (32 and 53).
- Ledger Processing: Wasmi processed the most ledgers (480), making it the most efficient VM under load. WAMR was second (441). WasmTime and Winch processed substantially fewer (266 and 230).
- Validation Time: Wasmi had the fastest mean validation time (3.872s) at 300 TPS, ahead of WAMR (4.212s). WasmTime and Winch were significantly slower (6.983s and 8.082s).
- Transaction Throughput: Wasmtime (Winch) showed a high mean TPS (492.66), but this is misleading; its slow validation, low ledger count, and instability suggest irregular batching rather than sustained throughput. Wasmi (294.04 TPS) and WAMR (286.31 TPS) delivered more consistent and realistic throughput aligned with their ledger processing.
Key Metrics @ 300 TPS (Averaged):
| Metric | WAMR (Avg) | WasmTime Pulley (Avg) | Wasmi (Avg) | Wasmtime Winch (Avg) |
|---|---|---|---|---|
| Mean Validation Time (s) | 4.212 | 6.983 | 3.872 | 8.082 |
| Mean TPS | 286.31 | 325.3 | 294.04 | 492.664 |
| Ledger Count (30 min) | 441 | 266 | 480 | 230 |
| Overvalidations | 18 | 217 | 1 | 149 |
| P2P Out of Sync | 0 | 32 | 0 | 53 |
Conclusion
Based on these results (best performance, excellent qualitative findings), the RX Programmability team decided to switch to Wasmi.
Next Steps
The RX Programmability team is almost done with migrating all the Smart Escrow code to use Wasmi instead of WAMR. This change will be included in the next Devnet release.
-
Pulley is Wasmtime's portable interpreter, it executes a custom, register-based bytecode format generated by the Cranelift compiler. ↩
-
Winch is wasmtime's Single-Pass Compiler. It does less optimization during compilation, so the compilation step takes less time than Cranelift, but execution times are longer. ↩
-
An overvalidation is when it takes a ledger over 5 seconds to validate. ↩
-
Do not be misled by Winch’s high “Mean TPS” (492.66). Combined with its long validation time and very low ledger count, this indicates inconsistent queuing and spiky batch processing, not smooth throughput. Wasmi’s throughput (294.04 TPS) was strong and consistent, aligning with its good validation time and highest ledger count. ↩
Top comments (0)