Skip to content

Conversation

@mvadari
Copy link
Collaborator

@mvadari mvadari commented Oct 28, 2025

No description provided.


There are only 4 native types in the [WASM spec](https://webassembly.github.io/spec/core/syntax/types.html): `i32` (a signed 32-bit integer), `i64` (a signed 64-bit integer), `f32` (a 32-bit floating point number), and `f64` (a 64-bit floating point number). However, the floating point numbers use a different encoding from what `rippled` uses.

So essentially, we only have `i32` and `i64` in terms of useful types. **Every parameter and return type must be represented as these two types.** This is manifested as [pointers](https://en.wikipedia.org/wiki/Pointer_%28computer_programming%29) and lengths. _Note that any language that has full support for extensions will have helper functions to abstract away most of the complexity (especially involving pointers and lengths)._
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
So essentially, we only have `i32` and `i64` in terms of useful types. **Every parameter and return type must be represented as these two types.** This is manifested as [pointers](https://en.wikipedia.org/wiki/Pointer_%28computer_programming%29) and lengths. _Note that any language that has full support for extensions will have helper functions to abstract away most of the complexity (especially involving pointers and lengths)._
So essentially, we only have `i32` and `i64` in terms of useful types. **Every parameter and return type must be represented as these two types.** This is manifested as [pointers](https://en.wikipedia.org/wiki/Pointer_%28computer_programming%29) and lengths. _Note that any language that has full support for XRPL extensions will have helper functions to abstract away most of the complexity (especially involving pointers and lengths)._

Correct me if I'm wrong, but I want to disambiguate between Smart features/extensions and WASM extensions.


While WebAssembly has a [core specification](https://webassembly.github.io/spec/), different runtimes have flexibility in how they implement certain features that are not a part of the formal specification. For example, not all WASM runtimes can easily be embedded in a C++ project (such as `rippled`).

The most relevant part for the purpose of consensus is the gas cost for any operation or function. Different implementations may have different gas costs for executing a given function, due to implementation differences - e.g. some calculate gas costs by inserting additional instructions, while others have a counter in the VM logic. For instance, one basic Smart Escrow function cost 110 gas to run with [WasmEdge](https://wasmedge.org/), while it only cost 4 gas with [WAMR](https://github.com/bytecodealliance/wasm-micro-runtime). This would cause consensus issues if the computation limit was set at 100, for example - one runtime would succeed, while the other would fail.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any objection to citing WASMi instead of WAMR?

(fine if that's too much work, but I would imagine the costs is similar).


### 2.1. Gas

Gas consumption is determined by the WASM runtime used for execution. Different implementations may use different metering strategies, which yields different gas costs for identical WASM code. For example, [this issue](https://github.com/bytecodealliance/wasm-micro-runtime/issues/3927) discusses how WAMR measures gas consumption.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adapting for Wasmi?


## 4. Memory Management Strategies

WebAssembly does not include built-in memory management - there is no garbage collector or automatic heap allocation. Instead, memory is a contiguous linear buffer that can only grow (in fixed 64 KiB pages) and never shrink. That means WASM code must allocate and manage its own memory, typically via a custom allocator or language runtime, and explicitly track when memory is no longer needed. While there is [progress](https://developer.chrome.com/blog/wasmgc) on this front with WasmGC, it does not have full-fledged tooling support yet, and is currently only really useful for browser applications of WASM.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WebAssembly does not include built-in memory management - there is no garbage collector or automatic heap allocation. Instead, memory is a contiguous linear buffer that can only grow (in fixed 64 KiB pages) and never shrink. That means WASM code must allocate and manage its own memory, typically via a custom allocator or language runtime, and explicitly track when memory is no longer needed. While there is [progress](https://developer.chrome.com/blog/wasmgc) on this front with WasmGC, it does not have full-fledged tooling support yet, and is currently only really useful for browser applications of WASM.
WebAssembly 1.0 (which is the WASM profile XRPL smart features will support) does not include built-in memory management - there is no garbage collector or automatic heap allocation. Instead, memory is a contiguous linear buffer that can only grow (in fixed 64 KiB pages) and never shrink. That means WASM code must allocate and manage its own memory, typically via a custom allocator or language runtime, and explicitly track when memory is no longer needed. While there is [progress](https://developer.chrome.com/blog/wasmgc) on this front with WasmGC, it does not have full-fledged tooling support yet, and is currently only really useful for browser applications of WASM.


This is a bit of a problem for host functions, since data has to go back and forth between the caller (WASM dev) and the engine (`rippled`). Some data (e.g. parameters) may be generated on the WASM side, while some data (e.g. the return data) may be generated on the rippled side.

Therefore, in this design, the caller is responsible for allocating memory in advance, and must reuse or deallocate memory manually. See Appendix B for alternative designs that were considered and rejected.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding something about how we'll just terminate the WASM VM after each execution (or zero-out memory allocated by rippled for the WASM VM) as a final memory cleanup mechanism that yields increased safety?

| `ticket_keylet(`<br/>&emsp;`account_ptr: i32,`<br/>&emsp;`account_len: i32,`<br/>&emsp;`sequence: i32,`<br/>&emsp;`out_buff_ptr: i32,`<br/>&emsp;`out_buff_len: i32`<br />`)` | Calculate a `Ticket`'s keylet from its pieces. | 350 |
| `vault_keylet(`<br/>&emsp;`account_ptr: i32,`<br/>&emsp;`account_len: i32,`<br/>&emsp;`sequence: i32,`<br/>&emsp;`out_buff_ptr: i32,`<br/>&emsp;`out_buff_len: i32`<br />`)` | Calculate a `Vault`’s keylet from its pieces. | 350 |

The singleton keylets (e.g. `Amendments`) are a bit unnecessary to include, as a dev can simply copy the keylet directly instead. They will be included as constants in `craft` as well.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The singleton keylets (e.g. `Amendments`) are a bit unnecessary to include, as a dev can simply copy the keylet directly instead. They will be included as constants in `craft` as well.
The singleton keylets (e.g. `Amendments`) are a bit unnecessary to include, as a dev can simply copy the keylet directly instead (these will be included as constants in `xrpl-wasm-stdlib` as well).


### 5.9. Trace

Output debug info to the `rippled` debug log.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should specify the caps for traced data.


<img width="768" height="381" alt="image" src="https://github.com/user-attachments/assets/c3e4255c-f956-41f2-941f-90b643b3d567" />

Based on these findings, we narrowed down the search to **WasmEdge** and **WAMR**, which we then did further performance testing and analysis on.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit?

1. Caller-Allocated: The contract developer (on the WASM side) allocates fixed size arrays for returning data. The user knows the pointer and the length.
- This is really easy to implement, but means that the WASM dev needs to do their own memory allocation.
2. Host-Allocated: The host (rippled) allocates WASM memory in host functions and passes the pointer and the length to the WASM program.
- This is super easy to use for devs, as they don’t need to worry about allocation and all of that. However, more research is needed to determine how possible it is, because currently the only way that we know how to do this involves allocating a new page every time (to ensure the host isn’t overwriting addresses in use).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- This is super easy to use for devs, as they don’t need to worry about allocation and all of that. However, more research is needed to determine how possible it is, because currently the only way that we know how to do this involves allocating a new page every time (to ensure the host isn’t overwriting addresses in use).
- This is super easy to use for devs, as they don’t need to worry about allocation. However, more research is needed to determine how possible it is, because currently the only way that we know how to do this involves allocating a new page every time (to ensure the host isn’t overwriting addresses in use).


These graphs clearly show that WAMR is much more performant.

## Appendix B: Other Memory Management Strategies Considered
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Appendix B: Other Memory Management Strategies Considered
## Appendix B: Memory Management Strategies Considered

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants