Skip to content

refactor: Wasm vm redesign - #7952

Open
kuznetsss wants to merge 55 commits into
XRPLF:ripple/wasmi-host-functionsfrom
kuznetsss:Wasm-vm-redesign
Open

refactor: Wasm vm redesign#7952
kuznetsss wants to merge 55 commits into
XRPLF:ripple/wasmi-host-functionsfrom
kuznetsss:Wasm-vm-redesign

Conversation

@kuznetsss

@kuznetsss kuznetsss commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

High Level Overview of Change

This PR replaces the wasmi C-API integration with a Rust wasmi wrapper reached over a cxx
bridge.

What's here

crates/ — cargo workspace, built in via corrosion.

  • xrpl-host-functionsthe ABI's single declaration site. host_functions! { … }
    generates the HostFunctions trait and the spec enum (import name + gas per function).
    no_std, no allocator, zero runtime deps, builds for wasm32 — so the guest SDK can
    implement the same trait from the same declaration.
  • xrpl-wasm-vm — the engine: run, and check (compile / imports / entry point /
    declared memory, with no host, store or gas, because a transaction's preflight() has no
    ledger to serve a host call from).
  • xrpl-wasm-vm-ffi — the bridge. Three crossings: run_escrow in, host calls back out,
    check_escrow in.
  • xrpl-wasm-testkit — test-only compile_wat, a separate crate so no assembler can reach
    the shipped node.

C++HostContext.{h,cpp}, an ABI-shaped noexcept view of HostFunctions; and
WasmVM.{h,cpp} with runEscrowWasm / preflightEscrowWasm and both TER maps.

Not in this PR

  • 5 of ~65 host functions are registered (ldgr_index, home_le_field, sha512_half,
    trace, trace_num). The remaining HostFuncImpl*.cpp are untouched and still compile.
  • src/test/app/HostFuncImpl_test.cpp is commented out: its assertions ran through the
    deleted C lowering.

Base branches

The PR is based on 2 branches:

Context of Change

API Impact

  • Public API: New feature (new methods and/or new fields)
  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)
  • libxrpl change (any change that may affect libxrpl or dependents of libxrpl)
  • Peer protocol change (must be backward compatible or bump the peer protocol version)

@kuznetsss
kuznetsss marked this pull request as ready for review August 4, 2026 16:40
@kuznetsss
kuznetsss requested a review from a team as a code owner August 4, 2026 16:40
@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

}

/// A check's verdict. No cost, because nothing was executed.
struct CheckResult {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we need both a CheckResult and a RunResult? There seems to be a lot of overlap between the two of them.

/// A negative return is a `HostError` code.
#[namespace = "xrpl"]
#[cxx_name = "getLedgerSqn"]
fn get_ledger_sqn(self: &HostContext, out: &mut [u8]) -> i32;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While I get that it might be idiomatic for snake case with rust, I think there is a broader question here about do we want to allow this difference within this repo. The CPP code is camel case (which in itself is not necessarily idiomatic cpp either).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am fine with having a split, I just wanted to point it out in case in really matter to someone.

}

/// Every import must be one the linker defines. The first that is not ends the
/// check, so a module with several faults reports the earliest.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Curious if this is also how the original code operated? I think a question would be what a better developer experience would be vs how much overhead it would take to provide the full list of faults.

// is generated from the same table.
for &op in HostFunctionSpec::ALL {
match op {
HostFunctionSpec::GetLedgerSqn => linker.func_wrap(

@TimothyBanks TimothyBanks Aug 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This match is going to be somewhat large. What are the options in Rust to handle this? Could we use a traits based approach in rust as well?

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