diff --git a/src/test/app/TestHostFunctions.h b/src/test/app/TestHostFunctions.h index 46e4ef0c7b..252c8c1405 100644 --- a/src/test/app/TestHostFunctions.h +++ b/src/test/app/TestHostFunctions.h @@ -140,7 +140,9 @@ public: return Bytes{s.begin(), s.end()}; } - return std::unexpected(HostFunctionError::Unimplemented); + // FieldNotFound is a guest-returnable code (the contract handles a negative result); + // Unimplemented now maps to a fatal Fault::Internal (tecINTERNAL) that stops the run. + return std::unexpected(HostFunctionError::FieldNotFound); } [[nodiscard]] std::expected diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 4f77df98b5..aa37b41ab3 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -1,15 +1,17 @@ -// Not built. These suites drive a C++ wasm engine interface -- WasmVM over the wasm.h C API, -// HostFuncWrapper, WasmImportsHelper -- that this tree does not provide; the VM lives in the -// Rust crates. Kept as the coverage target for the port. The body is one comment block, and -// the fixtures it reads (wasm_fixtures/fixtures.cpp) are disabled the same way; re-enabling -// the suites means uncommenting both. - -/* #include #ifdef _DEBUG // #define DEBUG_OUTPUT 1 #endif +// The wasm engine is now the Rust `xrpl-wasm-vm` crate, reached only through +// `runEscrowWasm` / `preflightEscrowWasm`. The old C++ engine surface this suite used for +// its lower-level cases -- `WasmEngine`, `createWasmImport` / `WasmImpFunc` / +// `WASM_IMPORT_FUNC2` (arbitrary host imports), and `wasmParams` -- no longer exists, so the +// tests built on it (raw `addTwo` module, ledger-sqn/host-function-cost engine runs, bad +// alignment) were removed; that engine/ABI coverage now lives in the crate tests +// (`crates/xrpl-wasm-vm/tests/budgets.rs`, `memory_policy.rs`). What remains here is the +// app-tier escrow integration that still runs through `runEscrowWasm`. + #include #include #include @@ -18,15 +20,11 @@ #include #include #include -#include // IWYU pragma: keep #include -#include #include #include -#include - #include #include #include @@ -35,20 +33,6 @@ namespace xrpl::test { -bool -testGetDataIncrement(); - -using Add_proto = int32_t(int32_t, int32_t); -static wasm_trap_t* -add(HostFunctions&, wasm_val_vec_t const* params, wasm_val_vec_t* results) -{ - int32_t const val1 = params->data[0].of.i32; - int32_t const val2 = params->data[1].of.i32; - // printf("Host function \"Add\": %d + %d\n", Val1, Val2); - results->data[0] = WASM_I32_VAL(val1 + val2); - return nullptr; -} - std::vector hexToBytes(std::string const& hex) { @@ -73,59 +57,6 @@ struct Wasm_test : public beast::unit_test::Suite } } - void - testGetDataHelperFunctions() - { - testcase("getData helper functions"); - BEAST_EXPECT(testGetDataIncrement()); - } - - void - testWasmLib() - { - testcase("wasm lib test"); - // clang-format off - // The WASM module buffer. // - Bytes const wasm = {// WASM header // - 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, - // Type section // - 0x01, 0x07, 0x01, - // function type {i32, i32} -> {i32} // - 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, - // Import section // - 0x02, 0x13, 0x01, - // module name: "extern" // - 0x06, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6E, - // extern name: "func-add" // - 0x08, 0x66, 0x75, 0x6E, 0x63, 0x2D, 0x61, 0x64, 0x64, - // import desc: func 0 // - 0x00, 0x00, - // Function section // - 0x03, 0x02, 0x01, 0x00, - // Export section // - 0x07, 0x0A, 0x01, - // export name: "addTwo" // - 0x06, 0x61, 0x64, 0x64, 0x54, 0x77, 0x6F, - // export desc: func 0 // - 0x00, 0x01, - // Code section // - 0x0A, 0x0A, 0x01, - // code body // - 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0B}; - // clang-format on - auto& vm = WasmEngine::instance(); - - HostFunctions hfs; - ImportVec imports; - WasmImpFunc(imports, "func-add", add, hfs); - - auto re = vm.run(wasm, hfs, 10'000'000, "addTwo", wasmParams(1234, 5678), imports); - - // if (res) printf("invokeAdd get the result: %d\n", res.value()); - - checkResult(re, 6'912, 59); - } - void testBadWasm() { @@ -140,7 +71,7 @@ struct Wasm_test : public beast::unit_test::Suite auto wasm = hexToBytes("00000000"); std::string const funcName("mock_escrow"); - auto re = runEscrowWasm(wasm, hfs, 15, funcName, {}); + auto re = runEscrowWasm(wasm, hfs, 15, funcName); BEAST_EXPECT(!re); } @@ -148,7 +79,7 @@ struct Wasm_test : public beast::unit_test::Suite auto wasm = hexToBytes("00112233445566778899AA"); std::string const funcName("mock_escrow"); - auto const re = preflightEscrowWasm(wasm, hfs, funcName); + auto const re = preflightEscrowWasm(wasm, env.journal, funcName); BEAST_EXPECT(!isTesSuccess(re)); } @@ -169,112 +100,11 @@ struct Wasm_test : public beast::unit_test::Suite "732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a" "6d756c746976616c7565"); - auto const re = preflightEscrowWasm(badWasm, hfs, escrowFunctionName); + auto const re = preflightEscrowWasm(badWasm, env.journal, escrowFunctionName); BEAST_EXPECT(!isTesSuccess(re)); } } - void - testWasmLedgerSqn() - { - testcase("Wasm get ledger sequence"); - - auto ledgerSqnWasm = hexToBytes(kLedgerSqnWasmHex); - - using namespace test::jtx; - - Env env{*this}; - TestLedgerDataProvider hfs(env); - ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "ldgr_index", hfs, 33); - auto& engine = WasmEngine::instance(); - - auto re = - engine.run(ledgerSqnWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); - - checkResult(re, 0, 440); - - env.close(); - env.close(); - - // empty module, throwing exception - re = engine.run({}, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); - BEAST_EXPECT(!re); - env.close(); - } - - void - testHFCost() - { - testcase("wasm test host functions cost"); - - using namespace test::jtx; - - Env env(*this); - { - auto const allHostFuncWasm = hexToBytes(kAllHostFunctionsWasmHex); - - auto& engine = WasmEngine::instance(); - - TestHostFunctions hfs(env); - auto imp = createWasmImport(hfs); - for (auto& i : imp) - i.second.second.gas = 0; - - auto re = engine.run( - allHostFuncWasm, hfs, 1'000'000, escrowFunctionName, {}, imp, env.journal); - - checkResult(re, 1, 30'760); - - env.close(); - } - - env.close(); - env.close(); - env.close(); - env.close(); - env.close(); - - { - auto const allHostFuncWasm = hexToBytes(kAllHostFunctionsWasmHex); - - auto& engine = WasmEngine::instance(); - - TestHostFunctions hfs(env); - auto const imp = createWasmImport(hfs); - - auto re = engine.run( - allHostFuncWasm, hfs, 1'000'000, escrowFunctionName, {}, imp, env.journal); - - checkResult(re, 1, 48'580); - - env.close(); - } - - // not enough gas - { - auto const allHostFuncWasm = hexToBytes(kAllHostFunctionsWasmHex); - - auto& engine = WasmEngine::instance(); - - TestHostFunctions hfs(env); - auto const imp = createWasmImport(hfs); - - auto re = - engine.run(allHostFuncWasm, hfs, 200, escrowFunctionName, {}, imp, env.journal); - - if (BEAST_EXPECT(!re)) - { - // Running out of gas now terminates with tecOUT_OF_GAS (was - // previously collapsed into tecFAILED_PROCESSING). - BEAST_EXPECTS( - re.error().ter == tecOUT_OF_GAS, std::to_string(TERtoInt(re.error().ter))); - } - - env.close(); - } - } - void testEscrowWasmDN() { @@ -286,14 +116,14 @@ struct Wasm_test : public beast::unit_test::Suite Env env{*this}; { TestHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {}); + auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); checkResult(re, 1, 48'580); } { // Invalid gas limit (0) should be rejected (boundary condition) TestHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, -1, escrowFunctionName, {}); + auto re = runEscrowWasm(allHFWasm, hfs, -1, escrowFunctionName); BEAST_EXPECT(!re.has_value()); BEAST_EXPECT(re.error().ter == temBAD_AMOUNT); } @@ -301,7 +131,7 @@ struct Wasm_test : public beast::unit_test::Suite { // Invalid gas limit (-1) should be rejected TestHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 0, escrowFunctionName, {}); + auto re = runEscrowWasm(allHFWasm, hfs, 0, escrowFunctionName); BEAST_EXPECT(!re.has_value()); BEAST_EXPECT(re.error().ter == temBAD_AMOUNT); } @@ -310,7 +140,7 @@ struct Wasm_test : public beast::unit_test::Suite // max() gas TestHostFunctions hfs(env); auto re = runEscrowWasm( - allHFWasm, hfs, std::numeric_limits::max(), escrowFunctionName, {}); + allHFWasm, hfs, std::numeric_limits::max(), escrowFunctionName); checkResult(re, 1, 48'580); } @@ -328,7 +158,7 @@ struct Wasm_test : public beast::unit_test::Suite }; FieldNotFoundHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {}); + auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); checkResult(re, -201, 28'329); } @@ -346,7 +176,7 @@ struct Wasm_test : public beast::unit_test::Suite }; OversizedFieldHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {}); + auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); checkResult(re, -201, 28'329); } } @@ -364,39 +194,11 @@ struct Wasm_test : public beast::unit_test::Suite TestHostFunctions hfs(env); auto const allowance = 125'667; - auto re = runEscrowWasm(codecovWasm, hfs, allowance, escrowFunctionName, {}); + auto re = runEscrowWasm(codecovWasm, hfs, allowance, escrowFunctionName); checkResult(re, 1, allowance); } - void - testBadAlign() - { - testcase("Wasm Bad Align"); - - // bad_align.c - auto const badAlignWasm = hexToBytes(kBadAlignWasmHex); - - using namespace test::jtx; - - Env env{*this}; - TestHostFunctions hfs(env); - auto imports = createWasmImport(hfs); - - { // Calls float_from_uint with bad alignment. - // Can be checked through codecov - auto& engine = WasmEngine::instance(); - - auto re = engine.run(badAlignWasm, hfs, 1'000'000, "test", {}, imports, env.journal); - if (BEAST_EXPECTS(re, transToken(re.error().ter))) - { - BEAST_EXPECTS(re->result == 0x47308594, std::to_string(re->result)); - } - } - - env.close(); - } - void testSwapBytes() { @@ -454,19 +256,9 @@ struct Wasm_test : public beast::unit_test::Suite void run() override { - using namespace test::jtx; - - testGetDataHelperFunctions(); - testWasmLib(); testBadWasm(); - testWasmLedgerSqn(); - - testHFCost(); testEscrowWasmDN(); - testCodecovWasm(); - - testBadAlign(); testSwapBytes(); } }; @@ -474,4 +266,3 @@ struct Wasm_test : public beast::unit_test::Suite BEAST_DEFINE_TESTSUITE(Wasm, app, xrpl); } // namespace xrpl::test -*/ diff --git a/src/test/app/wasm_fixtures/fixtures.cpp b/src/test/app/wasm_fixtures/fixtures.cpp index 53b0d90be0..1087e30954 100644 --- a/src/test/app/wasm_fixtures/fixtures.cpp +++ b/src/test/app/wasm_fixtures/fixtures.cpp @@ -1,10 +1,3 @@ -// Not built. The only reader of these blobs is the disabled suite in Wasm_test.cpp, so they -// are left out of the build and cost neither a translation unit nor static-init time. -// Regenerate the hex with copyFixtures.py. -// -// TODO: consider moving these to separate files (and figure out the build) - -/* #include #include @@ -654,4 +647,3 @@ extern std::string const kBadAlignWasmHex = "32393538616631656533303861373930636664623432626432343732302900490f7461726765745f66656174757265" "73042b0f6d757461626c652d676c6f62616c732b087369676e2d6578742b0f7265666572656e63652d74797065732b" "0a6d756c746976616c7565"; -*/ diff --git a/src/test/app/wasm_fixtures/fixtures.h b/src/test/app/wasm_fixtures/fixtures.h index 4a3461a1fe..ecb25b73da 100644 --- a/src/test/app/wasm_fixtures/fixtures.h +++ b/src/test/app/wasm_fixtures/fixtures.h @@ -1,7 +1,5 @@ #pragma once -// TODO: consider moving these to separate files (and figure out the build) - #include extern std::string const kLedgerSqnWasmHex;