diff --git a/BUILD.md b/BUILD.md index 895e14d54d..f39add176d 100644 --- a/BUILD.md +++ b/BUILD.md @@ -226,22 +226,6 @@ cmake --build build/codegen --target code_gen The regenerated files should be committed alongside your changes. CI verifies that they are up-to-date. -## Rust crates - -The build compiles the Rust workspace in `crates/` and generates the cxxbridge -bindings the C++ side includes, so it needs a Rust toolchain (`cargo`, `rustc`) -at the channel pinned in [`rust-toolchain.toml`](./rust-toolchain.toml). The -[Nix development shell](./docs/build/nix.md) provides one; otherwise install it -as described in [Rust](./docs/build/environment.md#rust). - -The crates also have their own Rust unit tests. Those are run with `cargo` and -need only the Rust toolchain, independently of CMake (CI runs them with -`cargo nextest`): - -```bash -cargo test --manifest-path crates/Cargo.toml --workspace -``` - ## Coverage report The coverage report is intended for developers using compilers GCC @@ -332,6 +316,22 @@ memory) since they concatenate sources into fewer translation units. Non-unity builds may be faster for incremental builds, and can be helpful for detecting `#include` omissions. +### Rust crates + +The build compiles the Rust workspace in `crates/` and generates the cxxbridge +bindings the C++ side includes, so it needs a Rust toolchain (`cargo`, `rustc`) +at the channel pinned in [`rust-toolchain.toml`](./rust-toolchain.toml). The +[Nix development shell](./docs/build/nix.md) provides one; otherwise install it +as described in [Rust](./docs/build/environment.md#rust). + +The crates also have their own Rust unit tests. Those are run with `cargo` and +need only the Rust toolchain, independently of CMake (CI runs them with +`cargo nextest`): + +```bash +cargo test --manifest-path crates/Cargo.toml --workspace +``` + ### Verifying headers The regular build only compiles `.cpp` files, so a header is only ever checked diff --git a/crates/xrpl-wasm-vm/src/vm.rs b/crates/xrpl-wasm-vm/src/vm.rs index 09db3a4ebb..c9a2592378 100644 --- a/crates/xrpl-wasm-vm/src/vm.rs +++ b/crates/xrpl-wasm-vm/src/vm.rs @@ -28,8 +28,13 @@ pub const MAX_MEMORY_BYTES: usize = (MAX_MEMORY_PAGES * WASM_PAGE_BYTES) as usiz /// entries, which a module asks for in five bytes of LEB128 and pays for in ~34 GiB. pub const MAX_TABLE_ELEMENTS: usize = 1024; -/// Total bytes that may cross the host/guest boundary in one [`run`], separate -/// from gas. +/// Total bytes the host may write into guest memory in one [`run`], separate from +/// gas. +/// +/// One direction only. What the guest passes in is not charged: it reaches the host +/// as a borrowed slice of guest memory, capped per value at [`MAX_FIELD_BYTES`] by +/// `Region::read` and in number by gas, and a host that keeps a copy (`update_data`) +/// bounds it on its own side. pub const TRANSFER_LIMIT_BYTES: u64 = 1 << 20; /// Size cap on any single value crossing the boundary, in either direction; over diff --git a/src/libxrpl/tx/wasm/WasmVM.cpp b/src/libxrpl/tx/wasm/WasmVM.cpp index e01493e52f..7f05eea138 100644 --- a/src/libxrpl/tx/wasm/WasmVM.cpp +++ b/src/libxrpl/tx/wasm/WasmVM.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace xrpl { @@ -23,8 +24,8 @@ namespace { using RunStatus = rs::wasm_vm::RunStatus; using CheckStatus = rs::wasm_vm::CheckStatus; -// The engine's outcome as the caller's: a value with its cost, or a TER with the cost to -// record beside it. +// The engine's outcome as the caller's: a value with its gas cost, or a TER with the gas cost +// to record beside it. // // A `tecINTERNAL` reports no cost. It says the fault is the node's, and charging a // transaction for a node's defect would write that defect into the ledger. @@ -123,6 +124,9 @@ runEscrowWasm( std::int64_t gasLimit, std::string_view funcName) noexcept { + XRPL_ASSERT( + gasLimit > 0, + "::xrpl::runEscrowWasm : gas limit is positive (should be checked in preflight)"); // A run needs a budget to spend. Refused here rather than in the engine because what a // non-positive limit means is a transaction-validity rule; the engine's own budget is // therefore an unsigned quantity with no invalid value to represent. @@ -135,10 +139,11 @@ runEscrowWasm( // The host caches the current ledger object, the slot table and the // contract's data for the length of one run, so a reused one would answer a // later contract out of an earlier contract's state. + XRPL_ASSERT( + hfs.checkSelf(), "::xrpl::runEscrowWasm : host functions not clean before the run"); if (!hfs.checkSelf()) { - JLOG(hfs.getJournal().error()) << "wasm: host functions not clean before the run"; - return nodeSideFault; + throw std::runtime_error("host functions not clean before the run"); } HostContext const ctx{hfs};