From c90f47881c1fc4304cc1d5ed35d7f5fdc81ba6c8 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 2 Jul 2025 23:43:30 +0530 Subject: [PATCH 01/25] enum for HF errors --- src/xrpld/app/misc/WasmHostFunc.h | 34 ++++++++++++---------- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 6 ++-- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index 1d1f4d011be..82a45f045dc 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -29,22 +29,24 @@ namespace ripple { -int32_t const HF_ERR_INTERNAL = -1; -int32_t const HF_ERR_FIELD_NOT_FOUND = -2; -int32_t const HF_ERR_BUFFER_TOO_SMALL = -3; -int32_t const HF_ERR_NO_ARRAY = -4; -int32_t const HF_ERR_NOT_LEAF_FIELD = -5; -int32_t const HF_ERR_LOCATOR_MALFORMED = -6; -int32_t const HF_ERR_SLOT_OUT_RANGE = -7; -int32_t const HF_ERR_SLOTS_FULL = -8; -int32_t const HF_ERR_INVALID_SLOT = -9; -int32_t const HF_ERR_LEDGER_OBJ_NOT_FOUND = -10; -int32_t const HF_ERR_DECODING = -11; -int32_t const HF_ERR_DATA_FIELD_TOO_LARGE = -12; -int32_t const HF_ERR_OUT_OF_BOUNDS = -13; -int32_t const HF_ERR_NO_MEM_EXPORTED = -14; -int32_t const HF_ERR_INVALID_PARAMS = -15; -int32_t const HF_ERR_INVALID_ACCOUNT = -16; +enum HostFuncError : int32_t { + HF_ERR_INTERNAL = -1, + HF_ERR_FIELD_NOT_FOUND = -2, + HF_ERR_BUFFER_TOO_SMALL = -3, + HF_ERR_NO_ARRAY = -4, + HF_ERR_NOT_LEAF_FIELD = -5, + HF_ERR_LOCATOR_MALFORMED = -6, + HF_ERR_SLOT_OUT_RANGE = -7, + HF_ERR_SLOTS_FULL = -8, + HF_ERR_INVALID_SLOT = -9, + HF_ERR_LEDGER_OBJ_NOT_FOUND = -10, + HF_ERR_DECODING = -11, + HF_ERR_DATA_FIELD_TOO_LARGE = -12, + HF_ERR_OUT_OF_BOUNDS = -13, + HF_ERR_NO_MEM_EXPORTED = -14, + HF_ERR_INVALID_PARAMS = -15, + HF_ERR_INVALID_ACCOUNT = -16 +}; struct HostFunctions { diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 9b5968c31d1..df7e7fb8380 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -51,7 +51,7 @@ setData( return ssz; } -static Expected +static Expected getData(InstanceWrapper const* rt, int32_t src, int32_t ssz) { if (!ssz) @@ -68,7 +68,7 @@ getData(InstanceWrapper const* rt, int32_t src, int32_t ssz) return data; } -static Expected +static Expected getDataAccount(InstanceWrapper const* rt, int32_t ptr, int32_t sz) { auto const r = getData(rt, ptr, sz); @@ -78,7 +78,7 @@ getDataAccount(InstanceWrapper const* rt, int32_t ptr, int32_t sz) return AccountID::fromVoid(r->data()); } -static Expected +static Expected getDataString(InstanceWrapper const* rt, int32_t src, int32_t ssz) { if (!ssz) From 9bb9a8c4b6bb6ac36ebaf15e945e6d70d9eacd60 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 00:01:26 +0530 Subject: [PATCH 02/25] switch getData functions to be templates --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 85 ++++++++++++---------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index df7e7fb8380..1e99a42a377 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -51,9 +51,19 @@ setData( return ssz; } -static Expected -getData(InstanceWrapper const* rt, int32_t src, int32_t ssz) +template +Expected +getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t src); + +template <> +Expected +getData( + InstanceWrapper const* rt, + wasm_val_vec_t const* params, + int32_t i) { + auto const src = params->data[i].of.i32; + auto const ssz = params->data[i + 1].of.i32; if (!ssz) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -68,19 +78,29 @@ getData(InstanceWrapper const* rt, int32_t src, int32_t ssz) return data; } -static Expected -getDataAccount(InstanceWrapper const* rt, int32_t ptr, int32_t sz) +template <> +Expected +getData( + InstanceWrapper const* rt, + wasm_val_vec_t const* params, + int32_t i) { - auto const r = getData(rt, ptr, sz); + auto const r = getData(rt, params, i); if (!r || (r->size() < AccountID::bytes)) return Unexpected(HF_ERR_INVALID_PARAMS); return AccountID::fromVoid(r->data()); } -static Expected -getDataString(InstanceWrapper const* rt, int32_t src, int32_t ssz) +template <> +Expected +getData( + InstanceWrapper const* rt, + wasm_val_vec_t const* params, + int32_t i) { + auto const src = params->data[i].of.i32; + auto const ssz = params->data[i + 1].of.i32; if (!ssz) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -173,7 +193,7 @@ cacheLedgerObj_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -292,7 +312,7 @@ getTxNestedField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -321,7 +341,7 @@ getCurrentLedgerObjNestedField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -350,7 +370,7 @@ getLedgerObjNestedField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[1].of.i32, params->data[2].of.i32); + auto const r = getData(rt, params, 1); if (!r) { RET(r.error()); @@ -443,7 +463,7 @@ getTxNestedArrayLen_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -462,7 +482,7 @@ getCurrentLedgerObjNestedArrayLen_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -481,7 +501,7 @@ getLedgerObjNestedArrayLen_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[1].of.i32, params->data[2].of.i32); + auto const r = getData(rt, params, 1); if (!r) { RET(r.error()); @@ -506,7 +526,7 @@ updateData_wrap( RET(HF_ERR_DATA_FIELD_TOO_LARGE) } - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -524,7 +544,7 @@ computeSha512HalfHash_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const r = getData(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const r = getData(rt, params, 0); if (!r) { RET(r.error()); @@ -548,8 +568,7 @@ accountKeylet_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const acc = - getDataAccount(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const acc = getData(rt, params, 0); if (!acc) { RET(acc.error()); @@ -578,22 +597,19 @@ credentialKeylet_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const subject = - getDataAccount(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const subject = getData(rt, params, 0); if (!subject) { RET(subject.error()); } - auto const issuer = - getDataAccount(rt, params->data[2].of.i32, params->data[3].of.i32); + auto const issuer = getData(rt, params, 2); if (!issuer) { RET(issuer.error()); } - auto const credType = - getData(rt, params->data[4].of.i32, params->data[5].of.i32); + auto const credType = getData(rt, params, 4); if (!credType) { RET(credType.error()); @@ -623,8 +639,7 @@ escrowKeylet_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const acc = - getDataAccount(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const acc = getData(rt, params, 0); if (!acc) { RET(acc.error()); @@ -653,8 +668,7 @@ oracleKeylet_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const acc = - getDataAccount(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const acc = getData(rt, params, 0); if (!acc) { RET(acc.error()); @@ -680,15 +694,13 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const acc = - getDataAccount(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const acc = getData(rt, params, 0); if (!acc) { RET(acc.error()); } - auto const nftRaw = - getData(rt, params->data[2].of.i32, params->data[3].of.i32); + auto const nftRaw = getData(rt, params, 2); if (!nftRaw) { RET(nftRaw.error()); @@ -723,15 +735,13 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const msg = - getDataString(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const msg = getData(rt, params, 0); if (!msg) { RET(msg.error()); } - auto const data = - getData(rt, params->data[2].of.i32, params->data[3].of.i32); + auto const data = getData(rt, params, 2); if (!data) { RET(data.error()); @@ -747,8 +757,7 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const msg = - getDataString(rt, params->data[0].of.i32, params->data[1].of.i32); + auto const msg = getData(rt, params, 0); if (!msg) { RET(msg.error()); From ef018f817727ca9abe4ae636d5b615f58ee71efd Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 01:37:34 +0530 Subject: [PATCH 03/25] getData working --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 86 ++++++++++++---------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 1e99a42a377..1e250eff20b 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -26,6 +26,8 @@ namespace ripple { +#define SFIELD_PARAM std::reference_wrapper + static int32_t setData( InstanceWrapper const* rt, @@ -55,6 +57,22 @@ template Expected getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t src); +template <> +Expected +getData( + InstanceWrapper const* _rt, + wasm_val_vec_t const* params, + int32_t i) +{ + auto const& m = SField::getKnownCodeToField(); + auto const it = m.find(params->data[i].of.i32); + if (it == m.end()) + { + return Unexpected(HF_ERR_FIELD_NOT_FOUND); + } + return *it->second; +} + template <> Expected getData( @@ -219,15 +237,13 @@ getTxField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const& m = SField::getKnownCodeToField(); - auto const it = m.find(params->data[0].of.i32); - if (it == m.end()) + auto const& fname = getData(rt, params, 0); + if (!fname) { - RET(HF_ERR_FIELD_NOT_FOUND); + RET(fname.error()); } - auto const& fname(*it->second); - auto fieldData = hf->getTxField(fname); + auto fieldData = hf->getTxField(fname.value()); if (!fieldData) { RET(fieldData.error()); @@ -250,15 +266,13 @@ getCurrentLedgerObjField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const& m = SField::getKnownCodeToField(); - auto const it = m.find(params->data[0].of.i32); - if (it == m.end()) + auto const& fname = getData(rt, params, 0); + if (!fname) { - RET(HF_ERR_FIELD_NOT_FOUND); + RET(fname.error()); } - auto const& fname(*it->second); - auto fieldData = hf->getCurrentLedgerObjField(fname); + auto fieldData = hf->getCurrentLedgerObjField(fname.value()); if (!fieldData) { RET(fieldData.error()); @@ -281,15 +295,14 @@ getLedgerObjField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const& m = SField::getKnownCodeToField(); - auto const it = m.find(params->data[1].of.i32); - if (it == m.end()) + auto const& fname = getData(rt, params, 1); + if (!fname) { - RET(HF_ERR_FIELD_NOT_FOUND); + RET(fname.error()); } - auto const& fname(*it->second); - auto fieldData = hf->getLedgerObjField(params->data[0].of.i32, fname); + auto fieldData = + hf->getLedgerObjField(params->data[0].of.i32, fname.value()); if (!fieldData) { RET(fieldData.error()); @@ -398,17 +411,15 @@ getTxArrayLen_wrap( wasm_val_vec_t* results) { auto* hf = reinterpret_cast(env); - // auto const* rt = reinterpret_cast(hf->getRT()); + auto const* rt = reinterpret_cast(hf->getRT()); - auto const& m = SField::getKnownCodeToField(); - auto const it = m.find(params->data[0].of.i32); - if (it == m.end()) + auto const& fname = getData(rt, params, 0); + if (!fname) { - RET(HF_ERR_FIELD_NOT_FOUND); + RET(fname.error()); } - auto const& fname(*it->second); - int32_t sz = hf->getTxArrayLen(fname); + int32_t sz = hf->getTxArrayLen(fname.value()); RET(sz); } @@ -419,17 +430,15 @@ getCurrentLedgerObjArrayLen_wrap( wasm_val_vec_t* results) { auto* hf = reinterpret_cast(env); - // auto const* rt = reinterpret_cast(hf->getRT()); + auto const* rt = reinterpret_cast(hf->getRT()); - auto const& m = SField::getKnownCodeToField(); - auto const it = m.find(params->data[0].of.i32); - if (it == m.end()) + auto const& fname = getData(rt, params, 0); + if (!fname) { - RET(HF_ERR_FIELD_NOT_FOUND); + RET(fname.error()); } - auto const& fname(*it->second); - int32_t sz = hf->getCurrentLedgerObjArrayLen(fname); + int32_t sz = hf->getCurrentLedgerObjArrayLen(fname.value()); RET(sz); } @@ -440,17 +449,16 @@ getLedgerObjArrayLen_wrap( wasm_val_vec_t* results) { auto* hf = reinterpret_cast(env); - // auto const* rt = reinterpret_cast(hf->getRT()); + auto const* rt = reinterpret_cast(hf->getRT()); - auto const& m = SField::getKnownCodeToField(); - auto const it = m.find(params->data[1].of.i32); - if (it == m.end()) + auto const& fname = getData(rt, params, 1); + if (!fname) { - RET(HF_ERR_FIELD_NOT_FOUND); + RET(fname.error()); } - auto const& fname(*it->second); - int32_t sz = hf->getLedgerObjArrayLen(params->data[0].of.i32, fname); + int32_t sz = + hf->getLedgerObjArrayLen(params->data[0].of.i32, fname.value()); RET(sz); } From aadf66e12bdb8e046790a5620d2aa4be8df5b821 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 01:43:25 +0530 Subject: [PATCH 04/25] Slice -> Bytes in host functions --- src/test/app/Wasm_test.cpp | 26 +++++++++++----------- src/xrpld/app/misc/WasmHostFunc.h | 12 +++++----- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 15 +++++++------ src/xrpld/app/misc/WasmHostFuncImpl.h | 12 +++++----- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 16 ++++++------- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 52d30835612..f8f83680559 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -188,7 +188,7 @@ struct TestHostFunctions : public HostFunctions } Expected - getTxNestedField(Slice const& locator) override + getTxNestedField(Bytes const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, @@ -198,7 +198,7 @@ struct TestHostFunctions : public HostFunctions } Expected - getCurrentLedgerObjNestedField(Slice const& locator) override + getCurrentLedgerObjNestedField(Bytes const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, @@ -208,7 +208,7 @@ struct TestHostFunctions : public HostFunctions } Expected - getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override + getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, @@ -236,19 +236,19 @@ struct TestHostFunctions : public HostFunctions } int32_t - getTxNestedArrayLen(Slice const& locator) override + getTxNestedArrayLen(Bytes const& locator) override { return 32; } int32_t - getCurrentLedgerObjNestedArrayLen(Slice const& locator) override + getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override { return 32; } int32_t - getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override + getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override { return 32; } @@ -579,7 +579,7 @@ struct PerfHostFunctions : public HostFunctions } static Expected - locateField(STObject const& obj, Slice const& loc) + locateField(STObject const& obj, Bytes const& loc) { if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 return Unexpected(HF_ERR_LOCATOR_MALFORMED); @@ -636,7 +636,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getTxNestedField(Slice const& locator) override + getTxNestedField(Bytes const& locator) override { // std::cout << tx_->getJson(JsonOptions::none).toStyledString() << // std::endl; @@ -653,7 +653,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getCurrentLedgerObjNestedField(Slice const& locator) override + getCurrentLedgerObjNestedField(Bytes const& locator) override { auto const sle = env_.le(leKey); if (!sle) @@ -672,7 +672,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override + getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) @@ -761,7 +761,7 @@ struct PerfHostFunctions : public HostFunctions } int32_t - getTxNestedArrayLen(Slice const& locator) override + getTxNestedArrayLen(Bytes const& locator) override { auto const r = locateField(*tx_, locator); if (!r) @@ -776,7 +776,7 @@ struct PerfHostFunctions : public HostFunctions } int32_t - getCurrentLedgerObjNestedArrayLen(Slice const& locator) override + getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override { auto const sle = env_.le(leKey); if (!sle) @@ -794,7 +794,7 @@ struct PerfHostFunctions : public HostFunctions } int32_t - getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override + getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index 82a45f045dc..b98f11251e8 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -110,19 +110,19 @@ struct HostFunctions } virtual Expected - getTxNestedField(Slice const& locator) + getTxNestedField(Bytes const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - getCurrentLedgerObjNestedField(Slice const& locator) + getCurrentLedgerObjNestedField(Bytes const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) + getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) { return Unexpected(HF_ERR_INTERNAL); } @@ -146,19 +146,19 @@ struct HostFunctions } virtual int32_t - getTxNestedArrayLen(Slice const& locator) + getTxNestedArrayLen(Bytes const& locator) { return HF_ERR_INTERNAL; } virtual int32_t - getCurrentLedgerObjNestedArrayLen(Slice const& locator) + getCurrentLedgerObjNestedArrayLen(Bytes const& locator) { return HF_ERR_INTERNAL; } virtual int32_t - getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) + getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) { return HF_ERR_INTERNAL; } diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index 71236034afc..36d97015691 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -174,8 +174,9 @@ WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname) } static Expected -locateField(STObject const& obj, Slice const& loc) +locateField(STObject const& obj, Bytes const& bytesLoc) { + Slice const& loc = makeSlice(bytesLoc); if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 return Unexpected(HF_ERR_LOCATOR_MALFORMED); @@ -231,7 +232,7 @@ locateField(STObject const& obj, Slice const& loc) } Expected -WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) +WasmHostFunctionsImpl::getTxNestedField(Bytes const& locator) { auto const r = locateField(ctx.tx, locator); if (!r) @@ -245,7 +246,7 @@ WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) } Expected -WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) +WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Bytes const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) @@ -265,7 +266,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) Expected WasmHostFunctionsImpl::getLedgerObjNestedField( int32_t cacheIdx, - Slice const& locator) + Bytes const& locator) { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) @@ -349,7 +350,7 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen( } int32_t -WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) +WasmHostFunctionsImpl::getTxNestedArrayLen(Bytes const& locator) { auto const r = locateField(ctx.tx, locator); if (!r) @@ -364,7 +365,7 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) } int32_t -WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) +WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Bytes const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) @@ -384,7 +385,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) int32_t WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( int32_t cacheIdx, - Slice const& locator) + Bytes const& locator) { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index 091ca249345..ec793ad8110 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -79,13 +79,13 @@ class WasmHostFunctionsImpl : public HostFunctions getLedgerObjField(int32_t cacheIdx, SField const& fname) override; Expected - getTxNestedField(Slice const& locator) override; + getTxNestedField(Bytes const& locator) override; Expected - getCurrentLedgerObjNestedField(Slice const& locator) override; + getCurrentLedgerObjNestedField(Bytes const& locator) override; Expected - getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override; + getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override; int32_t getTxArrayLen(SField const& fname) override; @@ -97,13 +97,13 @@ class WasmHostFunctionsImpl : public HostFunctions getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override; int32_t - getTxNestedArrayLen(Slice const& locator) override; + getTxNestedArrayLen(Bytes const& locator) override; int32_t - getCurrentLedgerObjNestedArrayLen(Slice const& locator) override; + getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override; int32_t - getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override; + getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override; int32_t updateData(Bytes const& data) override; diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 1e250eff20b..902356312e8 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -331,7 +331,7 @@ getTxNestedField_wrap( RET(r.error()); } - auto fieldData = hf->getTxNestedField(makeSlice(r.value())); + auto fieldData = hf->getTxNestedField(r.value()); if (!fieldData) { RET(fieldData.error()); @@ -360,7 +360,7 @@ getCurrentLedgerObjNestedField_wrap( RET(r.error()); } - auto fieldData = hf->getCurrentLedgerObjNestedField(makeSlice(r.value())); + auto fieldData = hf->getCurrentLedgerObjNestedField(r.value()); if (!fieldData) { RET(fieldData.error()); @@ -389,8 +389,8 @@ getLedgerObjNestedField_wrap( RET(r.error()); } - auto fieldData = hf->getLedgerObjNestedField( - params->data[0].of.i32, makeSlice(r.value())); + auto fieldData = + hf->getLedgerObjNestedField(params->data[0].of.i32, r.value()); if (!fieldData) { RET(fieldData.error()); @@ -477,7 +477,7 @@ getTxNestedArrayLen_wrap( RET(r.error()); } - int32_t sz = hf->getTxNestedArrayLen(makeSlice(r.value())); + int32_t sz = hf->getTxNestedArrayLen(r.value()); RET(sz); } @@ -496,7 +496,7 @@ getCurrentLedgerObjNestedArrayLen_wrap( RET(r.error()); } - int32_t sz = hf->getCurrentLedgerObjNestedArrayLen(makeSlice(r.value())); + int32_t sz = hf->getCurrentLedgerObjNestedArrayLen(r.value()); RET(sz); } @@ -515,8 +515,8 @@ getLedgerObjNestedArrayLen_wrap( RET(r.error()); } - int32_t sz = hf->getLedgerObjNestedArrayLen( - params->data[0].of.i32, makeSlice(r.value())); + int32_t sz = + hf->getLedgerObjNestedArrayLen(params->data[0].of.i32, r.value()); RET(sz); } From 253cbde3f2f6993592a230f2e5688eaf8aa24983 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 01:50:06 +0530 Subject: [PATCH 05/25] RET -> helper function instead of macro --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 325 ++++++++++++--------- 1 file changed, 180 insertions(+), 145 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 902356312e8..69fe1c9eac2 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -133,10 +133,14 @@ getData( return data; } -#define RET(x) \ - results->data[0] = WASM_I32_VAL(x); \ - results->num_elems = 1; \ +template +nullptr_t +hfResult(wasm_val_vec_t* results, T value) +{ + results->data[0] = WASM_I32_VAL(value); + results->num_elems = 1; return nullptr; +} wasm_trap_t* getLedgerSqnOld_wrap( @@ -147,7 +151,7 @@ getLedgerSqnOld_wrap( auto* hf = reinterpret_cast(env); // auto const* rt = reinterpret_cast(hf->getRT()); int32_t const sqn = hf->getLedgerSqn(); - RET(sqn); + return hfResult(results, sqn); } wasm_trap_t* @@ -160,12 +164,14 @@ getLedgerSqn_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int32_t const sqn = hf->getLedgerSqn(); - RET(setData( - rt, - params->data[0].of.i32, - params->data[1].of.i32, - reinterpret_cast(&sqn), - static_cast(sizeof(sqn)))); + return hfResult( + results, + setData( + rt, + params->data[0].of.i32, + params->data[1].of.i32, + reinterpret_cast(&sqn), + static_cast(sizeof(sqn)))); } wasm_trap_t* @@ -177,12 +183,14 @@ getParentLedgerTime_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); int32_t const ltime = hf->getParentLedgerTime(); - RET(setData( - rt, - params->data[0].of.i32, - params->data[1].of.i32, - reinterpret_cast(<ime), - static_cast(sizeof(ltime)))); + return hfResult( + results, + setData( + rt, + params->data[0].of.i32, + params->data[1].of.i32, + reinterpret_cast(<ime), + static_cast(sizeof(ltime)))); } wasm_trap_t* @@ -194,12 +202,14 @@ getParentLedgerHash_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); Hash const hash = hf->getParentLedgerHash(); - RET(setData( - rt, - params->data[0].of.i32, - params->data[1].of.i32, - hash.data(), - static_cast(hash.size()))); + return hfResult( + results, + setData( + rt, + params->data[0].of.i32, + params->data[1].of.i32, + hash.data(), + static_cast(hash.size()))); } wasm_trap_t* @@ -214,18 +224,18 @@ cacheLedgerObj_wrap( auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } if (r->size() < uint256::bytes) { - RET(HF_ERR_INVALID_PARAMS); + return hfResult(results, HF_ERR_INVALID_PARAMS); } uint256 const key(uint256::fromVoid(r->data())); int32_t const idx = hf->cacheLedgerObj(keylet::unchecked(key), params->data[2].of.i32); - RET(idx); + return hfResult(results, idx); } wasm_trap_t* @@ -240,21 +250,23 @@ getTxField_wrap( auto const& fname = getData(rt, params, 0); if (!fname) { - RET(fname.error()); + return hfResult(results, fname.error()); } auto fieldData = hf->getTxField(fname.value()); if (!fieldData) { - RET(fieldData.error()); + return hfResult(results, fieldData.error()); } - RET(setData( - rt, - params->data[1].of.i32, - params->data[2].of.i32, - fieldData->data(), - fieldData->size())); + return hfResult( + results, + setData( + rt, + params->data[1].of.i32, + params->data[2].of.i32, + fieldData->data(), + fieldData->size())); } wasm_trap_t* @@ -266,24 +278,27 @@ getCurrentLedgerObjField_wrap( auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); - auto const& fname = getData(rt, params, 0); + int i = 0; + auto const& fname = getData(rt, params, i++); if (!fname) { - RET(fname.error()); + return hfResult(results, fname.error()); } auto fieldData = hf->getCurrentLedgerObjField(fname.value()); if (!fieldData) { - RET(fieldData.error()); + return hfResult(results, fieldData.error()); } - RET(setData( - rt, - params->data[1].of.i32, - params->data[2].of.i32, - fieldData->data(), - fieldData->size())); + return hfResult( + results, + setData( + rt, + params->data[1].of.i32, + params->data[2].of.i32, + fieldData->data(), + fieldData->size())); } wasm_trap_t* @@ -298,22 +313,24 @@ getLedgerObjField_wrap( auto const& fname = getData(rt, params, 1); if (!fname) { - RET(fname.error()); + return hfResult(results, fname.error()); } auto fieldData = hf->getLedgerObjField(params->data[0].of.i32, fname.value()); if (!fieldData) { - RET(fieldData.error()); + return hfResult(results, fieldData.error()); } - RET(setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - fieldData->data(), - fieldData->size())); + return hfResult( + results, + setData( + rt, + params->data[2].of.i32, + params->data[3].of.i32, + fieldData->data(), + fieldData->size())); } wasm_trap_t* @@ -328,21 +345,23 @@ getTxNestedField_wrap( auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } auto fieldData = hf->getTxNestedField(r.value()); if (!fieldData) { - RET(fieldData.error()); + return hfResult(results, fieldData.error()); } - RET(setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - fieldData->data(), - fieldData->size())); + return hfResult( + results, + setData( + rt, + params->data[2].of.i32, + params->data[3].of.i32, + fieldData->data(), + fieldData->size())); } wasm_trap_t* @@ -357,21 +376,23 @@ getCurrentLedgerObjNestedField_wrap( auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } auto fieldData = hf->getCurrentLedgerObjNestedField(r.value()); if (!fieldData) { - RET(fieldData.error()); + return hfResult(results, fieldData.error()); } - RET(setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - fieldData->data(), - fieldData->size())); + return hfResult( + results, + setData( + rt, + params->data[2].of.i32, + params->data[3].of.i32, + fieldData->data(), + fieldData->size())); } wasm_trap_t* @@ -386,22 +407,24 @@ getLedgerObjNestedField_wrap( auto const r = getData(rt, params, 1); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } auto fieldData = hf->getLedgerObjNestedField(params->data[0].of.i32, r.value()); if (!fieldData) { - RET(fieldData.error()); + return hfResult(results, fieldData.error()); } - RET(setData( - rt, - params->data[3].of.i32, - params->data[4].of.i32, - fieldData->data(), - fieldData->size())); + return hfResult( + results, + setData( + rt, + params->data[3].of.i32, + params->data[4].of.i32, + fieldData->data(), + fieldData->size())); } wasm_trap_t* @@ -416,11 +439,11 @@ getTxArrayLen_wrap( auto const& fname = getData(rt, params, 0); if (!fname) { - RET(fname.error()); + return hfResult(results, fname.error()); } int32_t sz = hf->getTxArrayLen(fname.value()); - RET(sz); + return hfResult(results, sz); } wasm_trap_t* @@ -435,11 +458,11 @@ getCurrentLedgerObjArrayLen_wrap( auto const& fname = getData(rt, params, 0); if (!fname) { - RET(fname.error()); + return hfResult(results, fname.error()); } int32_t sz = hf->getCurrentLedgerObjArrayLen(fname.value()); - RET(sz); + return hfResult(results, sz); } wasm_trap_t* @@ -454,12 +477,12 @@ getLedgerObjArrayLen_wrap( auto const& fname = getData(rt, params, 1); if (!fname) { - RET(fname.error()); + return hfResult(results, fname.error()); } int32_t sz = hf->getLedgerObjArrayLen(params->data[0].of.i32, fname.value()); - RET(sz); + return hfResult(results, sz); } wasm_trap_t* @@ -474,11 +497,11 @@ getTxNestedArrayLen_wrap( auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } int32_t sz = hf->getTxNestedArrayLen(r.value()); - RET(sz); + return hfResult(results, sz); } wasm_trap_t* @@ -493,11 +516,11 @@ getCurrentLedgerObjNestedArrayLen_wrap( auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } int32_t sz = hf->getCurrentLedgerObjNestedArrayLen(r.value()); - RET(sz); + return hfResult(results, sz); } wasm_trap_t* @@ -512,12 +535,12 @@ getLedgerObjNestedArrayLen_wrap( auto const r = getData(rt, params, 1); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } int32_t sz = hf->getLedgerObjNestedArrayLen(params->data[0].of.i32, r.value()); - RET(sz); + return hfResult(results, sz); } wasm_trap_t* @@ -531,16 +554,16 @@ updateData_wrap( if (params->data[1].of.i32 > maxWasmDataLength) { - RET(HF_ERR_DATA_FIELD_TOO_LARGE) + return hfResult(results, HF_ERR_DATA_FIELD_TOO_LARGE); } auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } - RET(hf->updateData(r.value())); + return hfResult(results, hf->updateData(r.value())); } wasm_trap_t* @@ -555,16 +578,18 @@ computeSha512HalfHash_wrap( auto const r = getData(rt, params, 0); if (!r) { - RET(r.error()); + return hfResult(results, r.error()); } auto const hash = hf->computeSha512HalfHash(r.value()); - RET(setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - hash.data(), - hash.size())); + return hfResult( + results, + setData( + rt, + params->data[2].of.i32, + params->data[3].of.i32, + hash.data(), + hash.size())); } wasm_trap_t* @@ -579,21 +604,23 @@ accountKeylet_wrap( auto const acc = getData(rt, params, 0); if (!acc) { - RET(acc.error()); + return hfResult(results, acc.error()); } auto const k = hf->accountKeylet(acc.value()); if (!k) { - RET(k.error()); + return hfResult(results, k.error()); } - RET(setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - k->data(), - k->size())); + return hfResult( + results, + setData( + rt, + params->data[2].of.i32, + params->data[3].of.i32, + k->data(), + k->size())); } wasm_trap_t* @@ -608,34 +635,36 @@ credentialKeylet_wrap( auto const subject = getData(rt, params, 0); if (!subject) { - RET(subject.error()); + return hfResult(results, subject.error()); } auto const issuer = getData(rt, params, 2); if (!issuer) { - RET(issuer.error()); + return hfResult(results, issuer.error()); } auto const credType = getData(rt, params, 4); if (!credType) { - RET(credType.error()); + return hfResult(results, credType.error()); } auto const k = hf->credentialKeylet(subject.value(), issuer.value(), credType.value()); if (!k) { - RET(k.error()); + return hfResult(results, k.error()); } - RET(setData( - rt, - params->data[6].of.i32, - params->data[7].of.i32, - k->data(), - k->size())); + return hfResult( + results, + setData( + rt, + params->data[6].of.i32, + params->data[7].of.i32, + k->data(), + k->size())); } wasm_trap_t* @@ -650,21 +679,23 @@ escrowKeylet_wrap( auto const acc = getData(rt, params, 0); if (!acc) { - RET(acc.error()); + return hfResult(results, acc.error()); } auto const k = hf->escrowKeylet(acc.value(), params->data[2].of.i32); if (!k) { - RET(k.error()); + return hfResult(results, k.error()); } - RET(setData( - rt, - params->data[3].of.i32, - params->data[4].of.i32, - k->data(), - k->size())); + return hfResult( + results, + setData( + rt, + params->data[3].of.i32, + params->data[4].of.i32, + k->data(), + k->size())); } wasm_trap_t* @@ -679,21 +710,23 @@ oracleKeylet_wrap( auto const acc = getData(rt, params, 0); if (!acc) { - RET(acc.error()); + return hfResult(results, acc.error()); } auto const k = hf->oracleKeylet(acc.value(), params->data[2].of.i32); if (!k) { - RET(k.error()); + return hfResult(results, k.error()); } - RET(setData( - rt, - params->data[3].of.i32, - params->data[4].of.i32, - k->data(), - k->size())); + return hfResult( + results, + setData( + rt, + params->data[3].of.i32, + params->data[4].of.i32, + k->data(), + k->size())); } wasm_trap_t* @@ -705,13 +738,13 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const acc = getData(rt, params, 0); if (!acc) { - RET(acc.error()); + return hfResult(results, acc.error()); } auto const nftRaw = getData(rt, params, 2); if (!nftRaw) { - RET(nftRaw.error()); + return hfResult(results, nftRaw.error()); } if (nftRaw->size() != uint256::bytes) @@ -719,22 +752,24 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) hf->getJournal().trace() << "WAMR getNFT: Invalid NFT data size: " << nftRaw->size() << ", expected " << (uint256::bytes); - RET(HF_ERR_INVALID_PARAMS); + return hfResult(results, HF_ERR_INVALID_PARAMS); } uint256 const ntfId(uint256::fromVoid(nftRaw->data())); auto const nftURI = hf->getNFT(acc.value(), ntfId); if (!nftURI) { - RET(nftURI.error()); + return hfResult(results, nftURI.error()); } - RET(setData( - rt, - params->data[4].of.i32, - params->data[5].of.i32, - nftURI->data(), - nftURI->size())); + return hfResult( + results, + setData( + rt, + params->data[4].of.i32, + params->data[5].of.i32, + nftURI->data(), + nftURI->size())); } wasm_trap_t* @@ -746,17 +781,17 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const msg = getData(rt, params, 0); if (!msg) { - RET(msg.error()); + return hfResult(results, msg.error()); } auto const data = getData(rt, params, 2); if (!data) { - RET(data.error()); + return hfResult(results, data.error()); } auto const e = hf->trace(msg.value(), data.value(), params->data[4].of.i32); - RET(e); + return hfResult(results, e); } wasm_trap_t* @@ -768,11 +803,11 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const msg = getData(rt, params, 0); if (!msg) { - RET(msg.error()); + return hfResult(results, msg.error()); } auto const e = hf->traceNum(msg.value(), params->data[2].of.i64); - RET(e); + return hfResult(results, e); } } // namespace ripple From 5b020a984783a740094cfd574a6a01b74e4a622f Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 03:00:30 +0530 Subject: [PATCH 06/25] get template function working --- src/test/app/Wasm_test.cpp | 14 +- src/xrpld/app/misc/WasmHostFunc.h | 4 +- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 4 +- src/xrpld/app/misc/WasmHostFuncImpl.h | 4 +- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 460 ++++++++++++--------- 5 files changed, 282 insertions(+), 204 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index f8f83680559..8b51e4bd9e0 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -110,7 +110,7 @@ struct TestHostFunctions : public HostFunctions return env_.journal; } - int32_t + Expected getLedgerSqn() override { return static_cast(env_.current()->seq()); @@ -148,8 +148,10 @@ struct TestHostFunctions : public HostFunctions } else if (fname == sfSequence) { - int32_t x = getLedgerSqn(); - uint8_t const* p = reinterpret_cast(&x); + auto const x = getLedgerSqn(); + if (!x) + return Unexpected(x.error()); + uint8_t const* p = reinterpret_cast(&x.value()); return Bytes{p, p + sizeof(x)}; } return Bytes(); @@ -259,7 +261,7 @@ struct TestHostFunctions : public HostFunctions return 0; } - Hash + Expected computeSha512HalfHash(Bytes const& data) override { return env_.current()->info().parentHash; @@ -425,7 +427,7 @@ struct PerfHostFunctions : public HostFunctions return env_.journal; } - int32_t + Expected getLedgerSqn() override { return static_cast(env_.current()->seq()); @@ -835,7 +837,7 @@ struct PerfHostFunctions : public HostFunctions return data.size(); } - Hash + Expected computeSha512HalfHash(Bytes const& data) override { auto const hash = sha512Half(data); diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index b98f11251e8..d0066f7d782 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -67,7 +67,7 @@ struct HostFunctions return beast::Journal{beast::Journal::getNullSink()}; } - virtual int32_t + virtual Expected getLedgerSqn() { return 1; @@ -169,7 +169,7 @@ struct HostFunctions return HF_ERR_INTERNAL; } - virtual Hash + virtual Expected computeSha512HalfHash(Bytes const& data) { return Hash{}; diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index 36d97015691..043b9f8b942 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -30,7 +30,7 @@ namespace ripple { -int32_t +Expected WasmHostFunctionsImpl::getLedgerSqn() { return ctx.view().seq(); @@ -418,7 +418,7 @@ WasmHostFunctionsImpl::updateData(Bytes const& data) return 0; } -Hash +Expected WasmHostFunctionsImpl::computeSha512HalfHash(Bytes const& data) { auto const hash = sha512Half(data); diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index ec793ad8110..a6469e2defc 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -57,7 +57,7 @@ class WasmHostFunctionsImpl : public HostFunctions return ctx.journal; } - int32_t + Expected getLedgerSqn() override; int32_t @@ -108,7 +108,7 @@ class WasmHostFunctionsImpl : public HostFunctions int32_t updateData(Bytes const& data) override; - Hash + Expected computeSha512HalfHash(Bytes const& data) override; Expected diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 69fe1c9eac2..4d1867b1ee6 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -55,14 +55,38 @@ setData( template Expected -getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t src); +getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t& src); + +template <> +Expected +getData( + InstanceWrapper const* _rt, + wasm_val_vec_t const* params, + int32_t& i) +{ + auto const result = params->data[i].of.i32; + i++; + return result; +} + +template <> +Expected +getData( + InstanceWrapper const* _rt, + wasm_val_vec_t const* params, + int32_t& i) +{ + auto const result = params->data[i].of.i64; + i++; + return result; +} template <> Expected getData( InstanceWrapper const* _rt, wasm_val_vec_t const* params, - int32_t i) + int32_t& i) { auto const& m = SField::getKnownCodeToField(); auto const it = m.find(params->data[i].of.i32); @@ -70,6 +94,7 @@ getData( { return Unexpected(HF_ERR_FIELD_NOT_FOUND); } + i++; return *it->second; } @@ -78,10 +103,11 @@ Expected getData( InstanceWrapper const* rt, wasm_val_vec_t const* params, - int32_t i) + int32_t& i) { auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; + i += 2; if (!ssz) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -101,7 +127,7 @@ Expected getData( InstanceWrapper const* rt, wasm_val_vec_t const* params, - int32_t i) + int32_t& i) { auto const r = getData(rt, params, i); if (!r || (r->size() < AccountID::bytes)) @@ -115,10 +141,11 @@ Expected getData( InstanceWrapper const* rt, wasm_val_vec_t const* params, - int32_t i) + int32_t& i) { auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; + i += 2; if (!ssz) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -142,6 +169,86 @@ hfResult(wasm_val_vec_t* results, T value) return nullptr; } +template +std::optional +checkErrors(Tuple const& t, std::index_sequence) +{ + std::optional err; + ((err = err ? err + : (!std::get(t) ? std::optional{std::get(t).error()} + : std::nullopt)), + ...); + return err; +} + +template +wasm_trap_t* +invokeHostFunc( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results, + Func&& f) +{ + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto expectedArgs = std::make_tuple(getData(rt, params, index)...); + + constexpr auto N = sizeof...(Args); + auto err = checkErrors(expectedArgs, std::make_index_sequence{}); + + if (err) + return hfResult(results, *err); + + auto unwrappedArgs = + std::apply([](auto&&... e) { return std::tuple{*e...}; }, expectedArgs); + + auto result = std::apply(std::forward(f), unwrappedArgs); + + if (!result) + return hfResult(results, result.error()); + + if constexpr (std::is_same_v, Bytes>) + { + return hfResult( + results, + setData( + rt, + params->data[index].of.i32, + params->data[index + 1].of.i32, + result->data(), + result->size())); + } + else if constexpr (std::is_same_v, Hash>) + { + return hfResult( + results, + setData( + rt, + params->data[index].of.i32, + params->data[index + 1].of.i32, + result->data(), + result->size())); + } + else if constexpr (std::is_same_v, int32_t>) + { + return hfResult( + results, + setData( + rt, + params->data[0].of.i32, + params->data[1].of.i32, + reinterpret_cast(&result), + static_cast(sizeof(result)))); + } + else + { + static_assert( + [] { return false; }(), "Unhandled return type in invokeHostFunc"); + } +} + wasm_trap_t* getLedgerSqnOld_wrap( void* env, @@ -150,28 +257,33 @@ getLedgerSqnOld_wrap( { auto* hf = reinterpret_cast(env); // auto const* rt = reinterpret_cast(hf->getRT()); - int32_t const sqn = hf->getLedgerSqn(); - return hfResult(results, sqn); + auto const sqn = hf->getLedgerSqn(); + if (!sqn) + { + return hfResult(results, sqn.error()); + } + return hfResult(results, sqn.value()); } +#define HOST_FUNCTION(funcName, name, return, ...) \ + wasm_trap_t* funcName##_wrap( \ + void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) \ + { \ + auto* hf = reinterpret_cast(env); \ + auto const* rt = \ + reinterpret_cast(hf->getRT()); \ + } + wasm_trap_t* getLedgerSqn_wrap( void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int32_t const sqn = hf->getLedgerSqn(); - - return hfResult( - results, - setData( - rt, - params->data[0].of.i32, - params->data[1].of.i32, - reinterpret_cast(&sqn), - static_cast(sizeof(sqn)))); + return invokeHostFunc( + env, params, results, [hf = reinterpret_cast(env)]() { + return hf->getLedgerSqn(); + }); } wasm_trap_t* @@ -182,13 +294,14 @@ getParentLedgerTime_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; int32_t const ltime = hf->getParentLedgerTime(); return hfResult( results, setData( rt, - params->data[0].of.i32, - params->data[1].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, reinterpret_cast(<ime), static_cast(sizeof(ltime)))); } @@ -201,13 +314,14 @@ getParentLedgerHash_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; Hash const hash = hf->getParentLedgerHash(); return hfResult( results, setData( rt, - params->data[0].of.i32, - params->data[1].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, hash.data(), static_cast(hash.size()))); } @@ -220,8 +334,9 @@ cacheLedgerObj_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 0); + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); @@ -233,9 +348,9 @@ cacheLedgerObj_wrap( } uint256 const key(uint256::fromVoid(r->data())); - int32_t const idx = - hf->cacheLedgerObj(keylet::unchecked(key), params->data[2].of.i32); - return hfResult(results, idx); + int32_t const cacheIndex = + hf->cacheLedgerObj(keylet::unchecked(key), params->data[index].of.i32); + return hfResult(results, cacheIndex); } wasm_trap_t* @@ -246,8 +361,9 @@ getTxField_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const& fname = getData(rt, params, 0); + auto const& fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -263,8 +379,8 @@ getTxField_wrap( results, setData( rt, - params->data[1].of.i32, - params->data[2].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, fieldData->data(), fieldData->size())); } @@ -277,9 +393,9 @@ getCurrentLedgerObjField_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - int i = 0; - auto const& fname = getData(rt, params, i++); + auto const& fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -295,8 +411,8 @@ getCurrentLedgerObjField_wrap( results, setData( rt, - params->data[1].of.i32, - params->data[2].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, fieldData->data(), fieldData->size())); } @@ -309,15 +425,20 @@ getLedgerObjField_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const& fname = getData(rt, params, 1); + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + auto const& fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); } - auto fieldData = - hf->getLedgerObjField(params->data[0].of.i32, fname.value()); + auto fieldData = hf->getLedgerObjField(cache.value(), fname.value()); if (!fieldData) { return hfResult(results, fieldData.error()); @@ -327,8 +448,8 @@ getLedgerObjField_wrap( results, setData( rt, - params->data[2].of.i32, - params->data[3].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, fieldData->data(), fieldData->size())); } @@ -341,8 +462,9 @@ getTxNestedField_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 0); + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); @@ -358,8 +480,8 @@ getTxNestedField_wrap( results, setData( rt, - params->data[2].of.i32, - params->data[3].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, fieldData->data(), fieldData->size())); } @@ -372,8 +494,9 @@ getCurrentLedgerObjNestedField_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 0); + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); @@ -389,8 +512,8 @@ getCurrentLedgerObjNestedField_wrap( results, setData( rt, - params->data[2].of.i32, - params->data[3].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, fieldData->data(), fieldData->size())); } @@ -403,15 +526,20 @@ getLedgerObjNestedField_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 1); + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); } - auto fieldData = - hf->getLedgerObjNestedField(params->data[0].of.i32, r.value()); + auto fieldData = hf->getLedgerObjNestedField(cache.value(), r.value()); if (!fieldData) { return hfResult(results, fieldData.error()); @@ -421,8 +549,8 @@ getLedgerObjNestedField_wrap( results, setData( rt, - params->data[3].of.i32, - params->data[4].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, fieldData->data(), fieldData->size())); } @@ -435,8 +563,9 @@ getTxArrayLen_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const& fname = getData(rt, params, 0); + auto const& fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -454,8 +583,9 @@ getCurrentLedgerObjArrayLen_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const& fname = getData(rt, params, 0); + auto const& fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -473,15 +603,21 @@ getLedgerObjArrayLen_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const& fname = getData(rt, params, 1); + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + + auto const& fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); } - int32_t sz = - hf->getLedgerObjArrayLen(params->data[0].of.i32, fname.value()); + int32_t sz = hf->getLedgerObjArrayLen(cache.value(), fname.value()); return hfResult(results, sz); } @@ -493,8 +629,9 @@ getTxNestedArrayLen_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 0); + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); @@ -512,8 +649,9 @@ getCurrentLedgerObjNestedArrayLen_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 0); + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); @@ -531,15 +669,20 @@ getLedgerObjNestedArrayLen_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const r = getData(rt, params, 1); + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); } - int32_t sz = - hf->getLedgerObjNestedArrayLen(params->data[0].of.i32, r.value()); + int32_t sz = hf->getLedgerObjNestedArrayLen(cache.value(), r.value()); return hfResult(results, sz); } @@ -551,16 +694,17 @@ updateData_wrap( { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - if (params->data[1].of.i32 > maxWasmDataLength) + auto const r = getData(rt, params, index); + if (!r) { - return hfResult(results, HF_ERR_DATA_FIELD_TOO_LARGE); + return hfResult(results, r.error()); } - auto const r = getData(rt, params, 0); - if (!r) + if (r->size() > maxWasmDataLength) { - return hfResult(results, r.error()); + return hfResult(results, HF_ERR_DATA_FIELD_TOO_LARGE); } return hfResult(results, hf->updateData(r.value())); @@ -572,24 +716,13 @@ computeSha512HalfHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - - auto const r = getData(rt, params, 0); - if (!r) - { - return hfResult(results, r.error()); - } - - auto const hash = hf->computeSha512HalfHash(r.value()); - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - hash.data(), - hash.size())); + [hf = reinterpret_cast(env)](Bytes const& bytes) { + return hf->computeSha512HalfHash(bytes); + }); } wasm_trap_t* @@ -598,29 +731,13 @@ accountKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - - auto const acc = getData(rt, params, 0); - if (!acc) - { - return hfResult(results, acc.error()); - } - - auto const k = hf->accountKeylet(acc.value()); - if (!k) - { - return hfResult(results, k.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[2].of.i32, - params->data[3].of.i32, - k->data(), - k->size())); + [hf = reinterpret_cast(env)](AccountID const& acc) { + return hf->accountKeylet(acc); + }); } wasm_trap_t* @@ -629,42 +746,16 @@ credentialKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - - auto const subject = getData(rt, params, 0); - if (!subject) - { - return hfResult(results, subject.error()); - } - - auto const issuer = getData(rt, params, 2); - if (!issuer) - { - return hfResult(results, issuer.error()); - } - - auto const credType = getData(rt, params, 4); - if (!credType) - { - return hfResult(results, credType.error()); - } - - auto const k = - hf->credentialKeylet(subject.value(), issuer.value(), credType.value()); - if (!k) - { - return hfResult(results, k.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[6].of.i32, - params->data[7].of.i32, - k->data(), - k->size())); + [hf = reinterpret_cast(env)]( + AccountID const& subj, + AccountID const& iss, + Bytes const& credType) { + return hf->credentialKeylet(subj, iss, credType); + }); } wasm_trap_t* @@ -673,29 +764,14 @@ escrowKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - - auto const acc = getData(rt, params, 0); - if (!acc) - { - return hfResult(results, acc.error()); - } - - auto const k = hf->escrowKeylet(acc.value(), params->data[2].of.i32); - if (!k) - { - return hfResult(results, k.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[3].of.i32, - params->data[4].of.i32, - k->data(), - k->size())); + [hf = reinterpret_cast(env)]( + AccountID const& acc, int32_t seq) { + return hf->escrowKeylet(acc, seq); + }); } wasm_trap_t* @@ -704,29 +780,14 @@ oracleKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - - auto const acc = getData(rt, params, 0); - if (!acc) - { - return hfResult(results, acc.error()); - } - - auto const k = hf->oracleKeylet(acc.value(), params->data[2].of.i32); - if (!k) - { - return hfResult(results, k.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[3].of.i32, - params->data[4].of.i32, - k->data(), - k->size())); + [hf = reinterpret_cast(env)]( + AccountID const& acc, int32_t seq) { + return hf->oracleKeylet(acc, seq); + }); } wasm_trap_t* @@ -734,14 +795,15 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const acc = getData(rt, params, 0); + auto const acc = getData(rt, params, index); if (!acc) { return hfResult(results, acc.error()); } - auto const nftRaw = getData(rt, params, 2); + auto const nftRaw = getData(rt, params, index); if (!nftRaw) { return hfResult(results, nftRaw.error()); @@ -766,8 +828,8 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) results, setData( rt, - params->data[4].of.i32, - params->data[5].of.i32, + params->data[index].of.i32, + params->data[index + 1].of.i32, nftURI->data(), nftURI->size())); } @@ -777,20 +839,27 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const msg = getData(rt, params, 0); + auto const msg = getData(rt, params, index); if (!msg) { return hfResult(results, msg.error()); } - auto const data = getData(rt, params, 2); + auto const data = getData(rt, params, index); if (!data) { return hfResult(results, data.error()); } - auto const e = hf->trace(msg.value(), data.value(), params->data[4].of.i32); + auto const asHex = getData(rt, params, index); + if (!asHex) + { + return hfResult(results, asHex.error()); + } + + auto const e = hf->trace(msg.value(), data.value(), asHex.value()); return hfResult(results, e); } @@ -799,14 +868,21 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; - auto const msg = getData(rt, params, 0); + auto const msg = getData(rt, params, index); if (!msg) { return hfResult(results, msg.error()); } - auto const e = hf->traceNum(msg.value(), params->data[2].of.i64); + auto const number = getData(rt, params, index); + if (!number) + { + return hfResult(results, number.error()); + } + + auto const e = hf->traceNum(msg.value(), number.value()); return hfResult(results, e); } From 0f85e5882815a0e1a32c09160fe2c09a7eb6600d Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 03:36:27 +0530 Subject: [PATCH 07/25] more organization/cleanup --- src/test/app/Wasm_test.cpp | 104 +++++++-------- src/xrpld/app/misc/WasmHostFunc.h | 68 +++++----- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 48 +++---- src/xrpld/app/misc/WasmHostFuncImpl.h | 46 +++---- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 139 ++++++++++++++------- 5 files changed, 224 insertions(+), 181 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 8b51e4bd9e0..61118d801d2 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -54,7 +54,7 @@ struct TestLedgerDataProvider { } - int32_t + Expected get_ledger_sqn() { return (int32_t)env->current()->seq(); @@ -67,7 +67,7 @@ getLedgerSqn_wrap(void* env, wasm_val_vec_t const*, wasm_val_vec_t* results) { auto sqn = reinterpret_cast(env)->get_ledger_sqn(); - results->data[0] = WASM_I32_VAL(sqn); + results->data[0] = WASM_I32_VAL(sqn.value()); results->num_elems = 1; return nullptr; @@ -116,26 +116,26 @@ struct TestHostFunctions : public HostFunctions return static_cast(env_.current()->seq()); } - int32_t + Expected getParentLedgerTime() override { return env_.current()->parentCloseTime().time_since_epoch().count() + clock_drift_; } - Hash + Expected getParentLedgerHash() override { return env_.current()->info().parentHash; } - virtual int32_t + virtual Expected cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) override { return 1; } - Expected + Expected getTxField(SField const& fname) override { if (fname == sfAccount) @@ -157,7 +157,7 @@ struct TestHostFunctions : public HostFunctions return Bytes(); } - Expected + Expected getCurrentLedgerObjField(SField const& fname) override { auto const& sn = fname.getName(); @@ -173,10 +173,10 @@ struct TestHostFunctions : public HostFunctions return Bytes{s.begin(), s.end()}; } - return Unexpected(-1); + return Unexpected(HF_ERR_INTERNAL); } - Expected + Expected getLedgerObjField(int32_t cacheIdx, SField const& fname) override { // auto const& sn = fname.getName(); @@ -189,7 +189,7 @@ struct TestHostFunctions : public HostFunctions return data_; } - Expected + Expected getTxNestedField(Bytes const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, @@ -199,7 +199,7 @@ struct TestHostFunctions : public HostFunctions return Bytes(&a[0], &a[sizeof(a)]); } - Expected + Expected getCurrentLedgerObjNestedField(Bytes const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, @@ -209,7 +209,7 @@ struct TestHostFunctions : public HostFunctions return Bytes(&a[0], &a[sizeof(a)]); } - Expected + Expected getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, @@ -219,43 +219,43 @@ struct TestHostFunctions : public HostFunctions return Bytes(&a[0], &a[sizeof(a)]); } - int32_t + Expected getTxArrayLen(SField const& fname) override { return 32; } - int32_t + Expected getCurrentLedgerObjArrayLen(SField const& fname) override { return 32; } - int32_t + Expected getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override { return 32; } - int32_t + Expected getTxNestedArrayLen(Bytes const& locator) override { return 32; } - int32_t + Expected getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override { return 32; } - int32_t + Expected getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override { return 32; } - int32_t + Expected updateData(Bytes const& data) override { return 0; @@ -267,7 +267,7 @@ struct TestHostFunctions : public HostFunctions return env_.current()->info().parentHash; } - Expected + Expected accountKeylet(AccountID const& account) override { if (!account) @@ -276,7 +276,7 @@ struct TestHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected credentialKeylet( AccountID const& subject, AccountID const& issuer, @@ -289,7 +289,7 @@ struct TestHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected escrowKeylet(AccountID const& account, std::uint32_t seq) override { if (!account) @@ -298,7 +298,7 @@ struct TestHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected oracleKeylet(AccountID const& account, std::uint32_t documentId) override { if (!account) @@ -307,7 +307,7 @@ struct TestHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected getNFT(AccountID const& account, uint256 const& nftId) override { if (!account || !nftId) @@ -319,7 +319,7 @@ struct TestHostFunctions : public HostFunctions return Bytes(s.begin(), s.end()); } - int32_t + Expected trace(std::string const& msg, Bytes const& data, bool asHex) override { #ifdef DEBUG_OUTPUT @@ -345,7 +345,7 @@ struct TestHostFunctions : public HostFunctions return msg.size() + data.size() * (asHex ? 2 : 1); } - int32_t + Expected traceNum(std::string const& msg, int64_t data) override { #ifdef DEBUG_OUTPUT @@ -433,19 +433,19 @@ struct PerfHostFunctions : public HostFunctions return static_cast(env_.current()->seq()); } - int32_t + Expected getParentLedgerTime() override { return env_.current()->parentCloseTime().time_since_epoch().count(); } - Hash + Expected getParentLedgerHash() override { return env_.current()->info().parentHash; } - virtual int32_t + virtual Expected cacheLedgerObj(Keylet const&, int32_t cacheIdx) override { static int32_t intIdx = 0; @@ -527,7 +527,7 @@ struct PerfHostFunctions : public HostFunctions return msg.getData(); } - Expected + Expected getTxField(SField const& fname) override { auto const* field = tx_->peekAtPField(fname); @@ -540,7 +540,7 @@ struct PerfHostFunctions : public HostFunctions return getAnyFieldData(*field); } - Expected + Expected getCurrentLedgerObjField(SField const& fname) override { auto const sle = env_.le(leKey); @@ -557,7 +557,7 @@ struct PerfHostFunctions : public HostFunctions return getAnyFieldData(*field); } - Expected + Expected getLedgerObjField(int32_t cacheIdx, SField const& fname) override { --cacheIdx; @@ -580,7 +580,7 @@ struct PerfHostFunctions : public HostFunctions return getAnyFieldData(*field); } - static Expected + static Expected locateField(STObject const& obj, Bytes const& loc) { if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 @@ -637,7 +637,7 @@ struct PerfHostFunctions : public HostFunctions return field; } - Expected + Expected getTxNestedField(Bytes const& locator) override { // std::cout << tx_->getJson(JsonOptions::none).toStyledString() << @@ -654,7 +654,7 @@ struct PerfHostFunctions : public HostFunctions return getAnyFieldData(*field); } - Expected + Expected getCurrentLedgerObjNestedField(Bytes const& locator) override { auto const sle = env_.le(leKey); @@ -673,7 +673,7 @@ struct PerfHostFunctions : public HostFunctions return getAnyFieldData(*field); } - Expected + Expected getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override { --cacheIdx; @@ -698,7 +698,7 @@ struct PerfHostFunctions : public HostFunctions return getAnyFieldData(*field); } - int32_t + Expected getTxArrayLen(SField const& fname) override { if (fname.fieldType != STI_ARRAY) @@ -715,7 +715,7 @@ struct PerfHostFunctions : public HostFunctions return sz; } - int32_t + Expected getCurrentLedgerObjArrayLen(SField const& fname) override { if (fname.fieldType != STI_ARRAY) @@ -736,7 +736,7 @@ struct PerfHostFunctions : public HostFunctions return sz; } - int32_t + Expected getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override { if (fname.fieldType != STI_ARRAY) @@ -762,7 +762,7 @@ struct PerfHostFunctions : public HostFunctions return sz; } - int32_t + Expected getTxNestedArrayLen(Bytes const& locator) override { auto const r = locateField(*tx_, locator); @@ -777,7 +777,7 @@ struct PerfHostFunctions : public HostFunctions return sz; } - int32_t + Expected getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override { auto const sle = env_.le(leKey); @@ -795,7 +795,7 @@ struct PerfHostFunctions : public HostFunctions return sz; } - int32_t + Expected getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override { --cacheIdx; @@ -821,7 +821,7 @@ struct PerfHostFunctions : public HostFunctions return sz; } - int32_t + Expected updateData(Bytes const& data) override { ripple::detail::ApplyViewBase v( @@ -844,7 +844,7 @@ struct PerfHostFunctions : public HostFunctions return hash; } - Expected + Expected accountKeylet(AccountID const& account) override { if (!account) @@ -853,7 +853,7 @@ struct PerfHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected credentialKeylet( AccountID const& subject, AccountID const& issuer, @@ -869,7 +869,7 @@ struct PerfHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected escrowKeylet(AccountID const& account, std::uint32_t seq) override { if (!account) @@ -878,7 +878,7 @@ struct PerfHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected oracleKeylet(AccountID const& account, std::uint32_t documentId) override { if (!account) @@ -887,7 +887,7 @@ struct PerfHostFunctions : public HostFunctions return Bytes{keylet.key.begin(), keylet.key.end()}; } - Expected + Expected getNFT(AccountID const& account, uint256 const& nftId) override { if (!account || !nftId) @@ -911,7 +911,7 @@ struct PerfHostFunctions : public HostFunctions return Bytes(s.begin(), s.end()); } - int32_t + Expected trace(std::string const& msg, Bytes const& data, bool asHex) override { #ifdef DEBUG_OUTPUT @@ -937,7 +937,7 @@ struct PerfHostFunctions : public HostFunctions return msg.size() + data.size() * (asHex ? 2 : 1); } - int32_t + Expected traceNum(std::string const& msg, int64_t data) override { #ifdef DEBUG_OUTPUT @@ -1302,7 +1302,7 @@ struct Wasm_test : public beast::unit_test::suite explicit BadTestHostFunctions(Env& env) : TestHostFunctions(env) { } - Expected + Expected getTxField(SField const& fname) override { return Unexpected(HF_ERR_FIELD_NOT_FOUND); @@ -1322,7 +1322,7 @@ struct Wasm_test : public beast::unit_test::suite explicit BadTestHostFunctions(Env& env) : TestHostFunctions(env) { } - Expected + Expected getTxField(SField const& fname) override { return Bytes((MAX_PAGES + 1) * 64 * 1024, 1); diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index d0066f7d782..c51ae109995 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -73,100 +73,100 @@ struct HostFunctions return 1; } - virtual int32_t + virtual Expected getParentLedgerTime() { return 1; } - virtual Hash + virtual Expected getParentLedgerHash() { - return {}; + return Hash{}; } - virtual int32_t + virtual Expected cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getTxField(SField const& fname) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getCurrentLedgerObjField(SField const& fname) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getLedgerObjField(int32_t cacheIdx, SField const& fname) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getTxNestedField(Bytes const& locator) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getCurrentLedgerObjNestedField(Bytes const& locator) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) { return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected getTxArrayLen(SField const& fname) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected getCurrentLedgerObjArrayLen(SField const& fname) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected getTxNestedArrayLen(Bytes const& locator) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected getCurrentLedgerObjNestedArrayLen(Bytes const& locator) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected updateData(Bytes const& data) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } virtual Expected @@ -175,13 +175,13 @@ struct HostFunctions return Hash{}; } - virtual Expected + virtual Expected accountKeylet(AccountID const& account) { return Bytes{}; } - virtual Expected + virtual Expected credentialKeylet( AccountID const& subject, AccountID const& issuer, @@ -190,34 +190,34 @@ struct HostFunctions return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected escrowKeylet(AccountID const& account, std::uint32_t seq) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected oracleKeylet(AccountID const& account, std::uint32_t docId) { return Unexpected(HF_ERR_INTERNAL); } - virtual Expected + virtual Expected getNFT(AccountID const& account, uint256 const& nftId) { return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected trace(std::string const& msg, Bytes const& data, bool asHex) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } - virtual int32_t + virtual Expected traceNum(std::string const& msg, int64_t data) { - return HF_ERR_INTERNAL; + return Unexpected(HF_ERR_INTERNAL); } virtual ~HostFunctions() = default; diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index 043b9f8b942..db227eafa9f 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -36,19 +36,19 @@ WasmHostFunctionsImpl::getLedgerSqn() return ctx.view().seq(); } -int32_t +Expected WasmHostFunctionsImpl::getParentLedgerTime() { return ctx.view().parentCloseTime().time_since_epoch().count(); } -Hash +Expected WasmHostFunctionsImpl::getParentLedgerHash() { return ctx.view().info().parentHash; } -int32_t +Expected WasmHostFunctionsImpl::cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) { if (cacheIdx < 0 || cacheIdx > MAX_CACHE) @@ -126,7 +126,7 @@ getAnyFieldData(STBase const& obj) return msg.getData(); } -Expected +Expected WasmHostFunctionsImpl::getTxField(SField const& fname) { auto const* field = ctx.tx.peekAtPField(fname); @@ -138,7 +138,7 @@ WasmHostFunctionsImpl::getTxField(SField const& fname) return getAnyFieldData(*field); } -Expected +Expected WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname) { auto const sle = ctx.view().read(leKey); @@ -154,7 +154,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname) return getAnyFieldData(*field); } -Expected +Expected WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname) { --cacheIdx; @@ -173,7 +173,7 @@ WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname) return getAnyFieldData(*field); } -static Expected +static Expected locateField(STObject const& obj, Bytes const& bytesLoc) { Slice const& loc = makeSlice(bytesLoc); @@ -231,7 +231,7 @@ locateField(STObject const& obj, Bytes const& bytesLoc) return field; } -Expected +Expected WasmHostFunctionsImpl::getTxNestedField(Bytes const& locator) { auto const r = locateField(ctx.tx, locator); @@ -245,7 +245,7 @@ WasmHostFunctionsImpl::getTxNestedField(Bytes const& locator) return getAnyFieldData(*field); } -Expected +Expected WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Bytes const& locator) { auto const sle = ctx.view().read(leKey); @@ -263,7 +263,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Bytes const& locator) return getAnyFieldData(*field); } -Expected +Expected WasmHostFunctionsImpl::getLedgerObjNestedField( int32_t cacheIdx, Bytes const& locator) @@ -286,7 +286,7 @@ WasmHostFunctionsImpl::getLedgerObjNestedField( return getAnyFieldData(*field); } -int32_t +Expected WasmHostFunctionsImpl::getTxArrayLen(SField const& fname) { if (fname.fieldType != STI_ARRAY) @@ -303,7 +303,7 @@ WasmHostFunctionsImpl::getTxArrayLen(SField const& fname) return sz; } -int32_t +Expected WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname) { if (fname.fieldType != STI_ARRAY) @@ -324,7 +324,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname) return sz; } -int32_t +Expected WasmHostFunctionsImpl::getLedgerObjArrayLen( int32_t cacheIdx, SField const& fname) @@ -349,7 +349,7 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen( return sz; } -int32_t +Expected WasmHostFunctionsImpl::getTxNestedArrayLen(Bytes const& locator) { auto const r = locateField(ctx.tx, locator); @@ -364,7 +364,7 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Bytes const& locator) return sz; } -int32_t +Expected WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Bytes const& locator) { auto const sle = ctx.view().read(leKey); @@ -382,7 +382,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Bytes const& locator) return sz; } -int32_t +Expected WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( int32_t cacheIdx, Bytes const& locator) @@ -407,7 +407,7 @@ WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( return sz; } -int32_t +Expected WasmHostFunctionsImpl::updateData(Bytes const& data) { auto sle = ctx.view().peek(leKey); @@ -425,7 +425,7 @@ WasmHostFunctionsImpl::computeSha512HalfHash(Bytes const& data) return hash; } -Expected +Expected WasmHostFunctionsImpl::accountKeylet(AccountID const& account) { if (!account) @@ -434,7 +434,7 @@ WasmHostFunctionsImpl::accountKeylet(AccountID const& account) return Bytes{keylet.key.begin(), keylet.key.end()}; } -Expected +Expected WasmHostFunctionsImpl::credentialKeylet( AccountID const& subject, AccountID const& issuer, @@ -450,7 +450,7 @@ WasmHostFunctionsImpl::credentialKeylet( return Bytes{keylet.key.begin(), keylet.key.end()}; } -Expected +Expected WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq) { if (!account) @@ -459,7 +459,7 @@ WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq) return Bytes{keylet.key.begin(), keylet.key.end()}; } -Expected +Expected WasmHostFunctionsImpl::oracleKeylet( AccountID const& account, std::uint32_t documentId) @@ -470,7 +470,7 @@ WasmHostFunctionsImpl::oracleKeylet( return Bytes{keylet.key.begin(), keylet.key.end()}; } -Expected +Expected WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) { if (!account || !nftId) @@ -494,7 +494,7 @@ WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) return Bytes(s.begin(), s.end()); } -int32_t +Expected WasmHostFunctionsImpl::trace( std::string const& msg, Bytes const& data, @@ -519,7 +519,7 @@ WasmHostFunctionsImpl::trace( return msg.size() + data.size() * (asHex ? 2 : 1); } -int32_t +Expected WasmHostFunctionsImpl::traceNum(std::string const& msg, int64_t data) { #ifdef DEBUG_OUTPUT diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index a6469e2defc..44d20f93266 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -60,79 +60,79 @@ class WasmHostFunctionsImpl : public HostFunctions Expected getLedgerSqn() override; - int32_t + Expected getParentLedgerTime() override; - Hash + Expected getParentLedgerHash() override; - int32_t + Expected cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) override; - Expected + Expected getTxField(SField const& fname) override; - Expected + Expected getCurrentLedgerObjField(SField const& fname) override; - Expected + Expected getLedgerObjField(int32_t cacheIdx, SField const& fname) override; - Expected + Expected getTxNestedField(Bytes const& locator) override; - Expected + Expected getCurrentLedgerObjNestedField(Bytes const& locator) override; - Expected + Expected getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override; - int32_t + Expected getTxArrayLen(SField const& fname) override; - int32_t + Expected getCurrentLedgerObjArrayLen(SField const& fname) override; - int32_t + Expected getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override; - int32_t + Expected getTxNestedArrayLen(Bytes const& locator) override; - int32_t + Expected getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override; - int32_t + Expected getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override; - int32_t + Expected updateData(Bytes const& data) override; Expected computeSha512HalfHash(Bytes const& data) override; - Expected + Expected accountKeylet(AccountID const& account) override; - Expected + Expected credentialKeylet( AccountID const& subject, AccountID const& issuer, Bytes const& credentialType) override; - Expected + Expected escrowKeylet(AccountID const& account, std::uint32_t seq) override; - Expected + Expected oracleKeylet(AccountID const& account, std::uint32_t documentId) override; - Expected + Expected getNFT(AccountID const& account, uint256 const& nftId) override; - int32_t + Expected trace(std::string const& msg, Bytes const& data, bool asHex) override; - int32_t + Expected traceNum(std::string const& msg, int64_t data) override; }; diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 4d1867b1ee6..fca860524b7 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -122,6 +122,26 @@ getData( return data; } +template <> +Expected +getData( + InstanceWrapper const* rt, + wasm_val_vec_t const* params, + int32_t& i) +{ + auto const r = getData(rt, params, i); + if (!r) + { + return Unexpected(r.error()); + } + + if (r->size() != uint256::bytes) + { + return Unexpected(HF_ERR_INVALID_PARAMS); + } + return uint256::fromVoid(r->data()); +} + template <> Expected getData( @@ -292,18 +312,10 @@ getParentLedgerTime_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - int32_t const ltime = hf->getParentLedgerTime(); - return hfResult( - results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - reinterpret_cast(<ime), - static_cast(sizeof(ltime)))); + return invokeHostFunc( + env, params, results, [hf = reinterpret_cast(env)]() { + return hf->getParentLedgerTime(); + }); } wasm_trap_t* @@ -312,18 +324,10 @@ getParentLedgerHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - Hash const hash = hf->getParentLedgerHash(); - return hfResult( - results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - hash.data(), - static_cast(hash.size()))); + return invokeHostFunc( + env, params, results, [hf = reinterpret_cast(env)]() { + return hf->getParentLedgerHash(); + }); } wasm_trap_t* @@ -336,21 +340,23 @@ cacheLedgerObj_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const r = getData(rt, params, index); + auto const r = getData(rt, params, index); if (!r) { return hfResult(results, r.error()); } - - if (r->size() < uint256::bytes) + auto const cache = getData(rt, params, index); + if (!cache) { - return hfResult(results, HF_ERR_INVALID_PARAMS); + return hfResult(results, cache.error()); } - - uint256 const key(uint256::fromVoid(r->data())); - int32_t const cacheIndex = - hf->cacheLedgerObj(keylet::unchecked(key), params->data[index].of.i32); - return hfResult(results, cacheIndex); + auto const cacheIndex = + hf->cacheLedgerObj(keylet::unchecked(r.value()), cache.value()); + if (!cacheIndex) + { + return hfResult(results, cacheIndex.error()); + } + return hfResult(results, cacheIndex.value()); } wasm_trap_t* @@ -571,8 +577,12 @@ getTxArrayLen_wrap( return hfResult(results, fname.error()); } - int32_t sz = hf->getTxArrayLen(fname.value()); - return hfResult(results, sz); + auto const sz = hf->getTxArrayLen(fname.value()); + if (!sz) + { + return hfResult(results, sz.error()); + } + return hfResult(results, sz.value()); } wasm_trap_t* @@ -591,8 +601,12 @@ getCurrentLedgerObjArrayLen_wrap( return hfResult(results, fname.error()); } - int32_t sz = hf->getCurrentLedgerObjArrayLen(fname.value()); - return hfResult(results, sz); + auto const sz = hf->getCurrentLedgerObjArrayLen(fname.value()); + if (!sz) + { + return hfResult(results, sz.error()); + } + return hfResult(results, sz.value()); } wasm_trap_t* @@ -617,8 +631,12 @@ getLedgerObjArrayLen_wrap( return hfResult(results, fname.error()); } - int32_t sz = hf->getLedgerObjArrayLen(cache.value(), fname.value()); - return hfResult(results, sz); + auto const sz = hf->getLedgerObjArrayLen(cache.value(), fname.value()); + if (!sz) + { + return hfResult(results, sz.error()); + } + return hfResult(results, sz.value()); } wasm_trap_t* @@ -637,8 +655,12 @@ getTxNestedArrayLen_wrap( return hfResult(results, r.error()); } - int32_t sz = hf->getTxNestedArrayLen(r.value()); - return hfResult(results, sz); + auto const sz = hf->getTxNestedArrayLen(r.value()); + if (!sz) + { + return hfResult(results, sz.error()); + } + return hfResult(results, sz.value()); } wasm_trap_t* @@ -657,8 +679,12 @@ getCurrentLedgerObjNestedArrayLen_wrap( return hfResult(results, r.error()); } - int32_t sz = hf->getCurrentLedgerObjNestedArrayLen(r.value()); - return hfResult(results, sz); + auto const sz = hf->getCurrentLedgerObjNestedArrayLen(r.value()); + if (!sz) + { + return hfResult(results, sz.error()); + } + return hfResult(results, sz.value()); } wasm_trap_t* @@ -682,8 +708,12 @@ getLedgerObjNestedArrayLen_wrap( return hfResult(results, r.error()); } - int32_t sz = hf->getLedgerObjNestedArrayLen(cache.value(), r.value()); - return hfResult(results, sz); + auto const sz = hf->getLedgerObjNestedArrayLen(cache.value(), r.value()); + if (!sz) + { + return hfResult(results, sz.error()); + } + return hfResult(results, sz.value()); } wasm_trap_t* @@ -706,8 +736,13 @@ updateData_wrap( { return hfResult(results, HF_ERR_DATA_FIELD_TOO_LARGE); } + auto const result = hf->updateData(r.value()); + if (!result) + { + return hfResult(results, result.error()); + } - return hfResult(results, hf->updateData(r.value())); + return hfResult(results, result.value()); } wasm_trap_t* @@ -860,7 +895,11 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) } auto const e = hf->trace(msg.value(), data.value(), asHex.value()); - return hfResult(results, e); + if (!e) + { + return hfResult(results, e.error()); + } + return hfResult(results, e.value()); } wasm_trap_t* @@ -883,7 +922,11 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) } auto const e = hf->traceNum(msg.value(), number.value()); - return hfResult(results, e); + if (!e) + { + return hfResult(results, e.error()); + } + return hfResult(results, e.value()); } } // namespace ripple From 9021c6f9e5ca94d2ef43483175ec96e9f8e5f11b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 05:01:28 +0530 Subject: [PATCH 08/25] fix failures --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index fca860524b7..7f1da5580c2 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -130,6 +130,7 @@ getData( int32_t& i) { auto const r = getData(rt, params, i); + i++; if (!r) { return Unexpected(r.error()); @@ -257,10 +258,10 @@ invokeHostFunc( results, setData( rt, - params->data[0].of.i32, - params->data[1].of.i32, - reinterpret_cast(&result), - static_cast(sizeof(result)))); + params->data[index].of.i32, + params->data[index + 1].of.i32, + reinterpret_cast(&result.value()), + static_cast(sizeof(result.value())))); } else { From bbac8a7b87f8e67276d652b5a130c5754868426b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 3 Jul 2025 18:42:15 +0530 Subject: [PATCH 09/25] more cleanup --- src/test/app/Wasm_test.cpp | 4 +- src/xrpld/app/misc/WasmHostFunc.h | 2 +- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 53 +-- src/xrpld/app/misc/WasmHostFuncImpl.h | 2 +- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 426 ++++++--------------- 5 files changed, 143 insertions(+), 344 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 61118d801d2..b0c571007f9 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -130,7 +130,7 @@ struct TestHostFunctions : public HostFunctions } virtual Expected - cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) override + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override { return 1; } @@ -446,7 +446,7 @@ struct PerfHostFunctions : public HostFunctions } virtual Expected - cacheLedgerObj(Keylet const&, int32_t cacheIdx) override + cacheLedgerObj(uint256 const&, int32_t cacheIdx) override { static int32_t intIdx = 0; diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index c51ae109995..de5aff8d13d 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -86,7 +86,7 @@ struct HostFunctions } virtual Expected - cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) { return Unexpected(HF_ERR_INTERNAL); } diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index db227eafa9f..26b52329a88 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -49,10 +49,11 @@ WasmHostFunctionsImpl::getParentLedgerHash() } Expected -WasmHostFunctionsImpl::cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) +WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) { + auto const& keylet = keylet::unchecked(objId); if (cacheIdx < 0 || cacheIdx > MAX_CACHE) - return HF_ERR_SLOT_OUT_RANGE; + return Unexpected(HF_ERR_SLOT_OUT_RANGE); if (!cacheIdx) { @@ -64,10 +65,12 @@ WasmHostFunctionsImpl::cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) --cacheIdx; if (cacheIdx >= MAX_CACHE) - return HF_ERR_SLOTS_FULL; + return Unexpected(HF_ERR_SLOTS_FULL); cache[cacheIdx] = ctx.view().read(keylet); - return cache[cacheIdx] ? cacheIdx + 1 : HF_ERR_LEDGER_OBJ_NOT_FOUND; + if (!cache[cacheIdx]) + return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return cacheIdx + 1; } static Bytes @@ -290,14 +293,14 @@ Expected WasmHostFunctionsImpl::getTxArrayLen(SField const& fname) { if (fname.fieldType != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); auto const* field = ctx.tx.peekAtPField(fname); if (!field) - return HF_ERR_FIELD_NOT_FOUND; + return Unexpected(HF_ERR_FIELD_NOT_FOUND); if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -307,18 +310,18 @@ Expected WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname) { if (fname.fieldType != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); auto const sle = ctx.view().read(leKey); if (!sle) - return HF_ERR_LEDGER_OBJ_NOT_FOUND; + return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); auto const* field = sle->peekAtPField(fname); if (!field) - return HF_ERR_FIELD_NOT_FOUND; + return Unexpected(HF_ERR_FIELD_NOT_FOUND); if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -330,20 +333,20 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen( SField const& fname) { if (fname.fieldType != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return HF_ERR_SLOT_OUT_RANGE; + return Unexpected(HF_ERR_SLOT_OUT_RANGE); if (!cache[cacheIdx]) - return HF_ERR_INVALID_SLOT; + return Unexpected(HF_ERR_INVALID_SLOT); auto const* field = cache[cacheIdx]->peekAtPField(fname); if (!field) - return HF_ERR_FIELD_NOT_FOUND; + return Unexpected(HF_ERR_FIELD_NOT_FOUND); if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -358,7 +361,7 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Bytes const& locator) auto const* field = r.value(); if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -369,14 +372,14 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Bytes const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) - return HF_ERR_LEDGER_OBJ_NOT_FOUND; + return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); auto const r = locateField(*sle, locator); if (!r) return r.error(); auto const* field = r.value(); if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -389,10 +392,10 @@ WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return HF_ERR_SLOT_OUT_RANGE; + return Unexpected(HF_ERR_SLOT_OUT_RANGE); if (!cache[cacheIdx]) - return HF_ERR_INVALID_SLOT; + return Unexpected(HF_ERR_INVALID_SLOT); auto const r = locateField(*cache[cacheIdx], locator); if (!r) @@ -401,7 +404,7 @@ WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( auto const* field = r.value(); if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; + return Unexpected(HF_ERR_NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -410,9 +413,13 @@ WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( Expected WasmHostFunctionsImpl::updateData(Bytes const& data) { + if (data.size() > maxWasmDataLength) + { + return Unexpected(HF_ERR_DATA_FIELD_TOO_LARGE); + } auto sle = ctx.view().peek(leKey); if (!sle) - return HF_ERR_LEDGER_OBJ_NOT_FOUND; + return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); sle->setFieldVL(sfData, data); ctx.view().update(sle); return 0; diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index 44d20f93266..386972121a8 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -67,7 +67,7 @@ class WasmHostFunctionsImpl : public HostFunctions getParentLedgerHash() override; Expected - cacheLedgerObj(Keylet const& keylet, int32_t cacheIdx) override; + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override; Expected getTxField(SField const& fname) override; diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 7f1da5580c2..9463add4608 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -220,7 +220,9 @@ invokeHostFunc( auto err = checkErrors(expectedArgs, std::make_index_sequence{}); if (err) + { return hfResult(results, *err); + } auto unwrappedArgs = std::apply([](auto&&... e) { return std::tuple{*e...}; }, expectedArgs); @@ -228,7 +230,9 @@ invokeHostFunc( auto result = std::apply(std::forward(f), unwrappedArgs); if (!result) + { return hfResult(results, result.error()); + } if constexpr (std::is_same_v, Bytes>) { @@ -337,6 +341,14 @@ cacheLedgerObj_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { + // return invokeHostFunc( + // env, + // params, + // results, + // [hf = reinterpret_cast(env)](uint256 id, int32_t + // cache) { + // return hf->cacheLedgerObj(id, cache); + // }); auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; @@ -351,8 +363,7 @@ cacheLedgerObj_wrap( { return hfResult(results, cache.error()); } - auto const cacheIndex = - hf->cacheLedgerObj(keylet::unchecked(r.value()), cache.value()); + auto const cacheIndex = hf->cacheLedgerObj(r.value(), cache.value()); if (!cacheIndex) { return hfResult(results, cacheIndex.error()); @@ -366,30 +377,13 @@ getTxField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const& fname = getData(rt, params, index); - if (!fname) - { - return hfResult(results, fname.error()); - } - - auto fieldData = hf->getTxField(fname.value()); - if (!fieldData) - { - return hfResult(results, fieldData.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - fieldData->data(), - fieldData->size())); + [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + return hf->getTxField(fname); + }); } wasm_trap_t* @@ -398,30 +392,13 @@ getCurrentLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const& fname = getData(rt, params, index); - if (!fname) - { - return hfResult(results, fname.error()); - } - - auto fieldData = hf->getCurrentLedgerObjField(fname.value()); - if (!fieldData) - { - return hfResult(results, fieldData.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - fieldData->data(), - fieldData->size())); + [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + return hf->getCurrentLedgerObjField(fname); + }); } wasm_trap_t* @@ -430,35 +407,14 @@ getLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const cache = getData(rt, params, index); - if (!cache) - { - return hfResult(results, cache.error()); - } - auto const& fname = getData(rt, params, index); - if (!fname) - { - return hfResult(results, fname.error()); - } - - auto fieldData = hf->getLedgerObjField(cache.value(), fname.value()); - if (!fieldData) - { - return hfResult(results, fieldData.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - fieldData->data(), - fieldData->size())); + [hf = reinterpret_cast(env)]( + int32_t cache, SFIELD_PARAM fname) { + return hf->getLedgerObjField(cache, fname); + }); } wasm_trap_t* @@ -467,30 +423,13 @@ getTxNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - auto fieldData = hf->getTxNestedField(r.value()); - if (!fieldData) - { - return hfResult(results, fieldData.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - fieldData->data(), - fieldData->size())); + [hf = reinterpret_cast(env)](Bytes const& bytes) { + return hf->getTxNestedField(bytes); + }); } wasm_trap_t* @@ -499,30 +438,13 @@ getCurrentLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - auto fieldData = hf->getCurrentLedgerObjNestedField(r.value()); - if (!fieldData) - { - return hfResult(results, fieldData.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - fieldData->data(), - fieldData->size())); + [hf = reinterpret_cast(env)](Bytes const& bytes) { + return hf->getCurrentLedgerObjNestedField(bytes); + }); } wasm_trap_t* @@ -531,35 +453,14 @@ getLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const cache = getData(rt, params, index); - if (!cache) - { - return hfResult(results, cache.error()); - } - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - auto fieldData = hf->getLedgerObjNestedField(cache.value(), r.value()); - if (!fieldData) - { - return hfResult(results, fieldData.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - fieldData->data(), - fieldData->size())); + [hf = reinterpret_cast(env)]( + int32_t cache, Bytes const& bytes) { + return hf->getLedgerObjNestedField(cache, bytes); + }); } wasm_trap_t* @@ -568,22 +469,13 @@ getTxArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const& fname = getData(rt, params, index); - if (!fname) - { - return hfResult(results, fname.error()); - } - - auto const sz = hf->getTxArrayLen(fname.value()); - if (!sz) - { - return hfResult(results, sz.error()); - } - return hfResult(results, sz.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + return hf->getTxArrayLen(fname); + }); } wasm_trap_t* @@ -592,22 +484,13 @@ getCurrentLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const& fname = getData(rt, params, index); - if (!fname) - { - return hfResult(results, fname.error()); - } - - auto const sz = hf->getCurrentLedgerObjArrayLen(fname.value()); - if (!sz) - { - return hfResult(results, sz.error()); - } - return hfResult(results, sz.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + return hf->getCurrentLedgerObjArrayLen(fname); + }); } wasm_trap_t* @@ -616,28 +499,14 @@ getLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const cache = getData(rt, params, index); - if (!cache) - { - return hfResult(results, cache.error()); - } - - auto const& fname = getData(rt, params, index); - if (!fname) - { - return hfResult(results, fname.error()); - } - - auto const sz = hf->getLedgerObjArrayLen(cache.value(), fname.value()); - if (!sz) - { - return hfResult(results, sz.error()); - } - return hfResult(results, sz.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)]( + int32_t cache, SFIELD_PARAM fname) { + return hf->getLedgerObjArrayLen(cache, fname); + }); } wasm_trap_t* @@ -646,22 +515,13 @@ getTxNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - auto const sz = hf->getTxNestedArrayLen(r.value()); - if (!sz) - { - return hfResult(results, sz.error()); - } - return hfResult(results, sz.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)](Bytes const& bytes) { + return hf->getTxNestedArrayLen(bytes); + }); } wasm_trap_t* @@ -670,51 +530,28 @@ getCurrentLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - auto const sz = hf->getCurrentLedgerObjNestedArrayLen(r.value()); - if (!sz) - { - return hfResult(results, sz.error()); - } - return hfResult(results, sz.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)](Bytes const& bytes) { + return hf->getCurrentLedgerObjNestedArrayLen(bytes); + }); } - wasm_trap_t* getLedgerObjNestedArrayLen_wrap( void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const cache = getData(rt, params, index); - if (!cache) - { - return hfResult(results, cache.error()); - } - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - auto const sz = hf->getLedgerObjNestedArrayLen(cache.value(), r.value()); - if (!sz) - { - return hfResult(results, sz.error()); - } - return hfResult(results, sz.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)]( + int32_t cache, Bytes const& bytes) { + return hf->getLedgerObjNestedArrayLen(cache, bytes); + }); } wasm_trap_t* @@ -723,27 +560,13 @@ updateData_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - - if (r->size() > maxWasmDataLength) - { - return hfResult(results, HF_ERR_DATA_FIELD_TOO_LARGE); - } - auto const result = hf->updateData(r.value()); - if (!result) - { - return hfResult(results, result.error()); - } - - return hfResult(results, result.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)](Bytes const& bytes) { + return hf->updateData(bytes); + }); } wasm_trap_t* @@ -829,45 +652,14 @@ oracleKeylet_wrap( wasm_trap_t* getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const acc = getData(rt, params, index); - if (!acc) - { - return hfResult(results, acc.error()); - } - - auto const nftRaw = getData(rt, params, index); - if (!nftRaw) - { - return hfResult(results, nftRaw.error()); - } - - if (nftRaw->size() != uint256::bytes) - { - hf->getJournal().trace() - << "WAMR getNFT: Invalid NFT data size: " << nftRaw->size() - << ", expected " << (uint256::bytes); - return hfResult(results, HF_ERR_INVALID_PARAMS); - } - - uint256 const ntfId(uint256::fromVoid(nftRaw->data())); - auto const nftURI = hf->getNFT(acc.value(), ntfId); - if (!nftURI) - { - return hfResult(results, nftURI.error()); - } - - return hfResult( + return invokeHostFunc( + env, + params, results, - setData( - rt, - params->data[index].of.i32, - params->data[index + 1].of.i32, - nftURI->data(), - nftURI->size())); + [hf = reinterpret_cast(env)]( + AccountID const& acc, uint256 nftId) { + return hf->getNFT(acc, nftId); + }); } wasm_trap_t* From f0b7ee13cc9535cb2c05cf07a4e3b6aaa0e05244 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Sat, 5 Jul 2025 00:22:31 +0530 Subject: [PATCH 10/25] Bytes -> Slice --- src/test/app/Wasm_test.cpp | 48 +++++++++++----------- src/xrpld/app/misc/WasmHostFunc.h | 20 ++++----- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 26 ++++++------ src/xrpld/app/misc/WasmHostFuncImpl.h | 20 ++++----- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 48 +++++++++++----------- 5 files changed, 79 insertions(+), 83 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 6c2f4579fcb..1a65b4eccfd 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -190,7 +190,7 @@ struct TestHostFunctions : public HostFunctions } Expected - getTxNestedField(Bytes const& locator) override + getTxNestedField(Slice const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, @@ -200,7 +200,7 @@ struct TestHostFunctions : public HostFunctions } Expected - getCurrentLedgerObjNestedField(Bytes const& locator) override + getCurrentLedgerObjNestedField(Slice const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, @@ -210,7 +210,7 @@ struct TestHostFunctions : public HostFunctions } Expected - getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override { uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, @@ -238,31 +238,31 @@ struct TestHostFunctions : public HostFunctions } Expected - getTxNestedArrayLen(Bytes const& locator) override + getTxNestedArrayLen(Slice const& locator) override { return 32; } Expected - getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override { return 32; } Expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override { return 32; } Expected - updateData(Bytes const& data) override + updateData(Slice const& data) override { return 0; } Expected - computeSha512HalfHash(Bytes const& data) override + computeSha512HalfHash(Slice const& data) override { return env_.current()->info().parentHash; } @@ -280,12 +280,11 @@ struct TestHostFunctions : public HostFunctions credentialKeylet( AccountID const& subject, AccountID const& issuer, - Bytes const& credentialType) override + Slice const& credentialType) override { if (!subject || !issuer || credentialType.empty()) return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = - keylet::credential(subject, issuer, makeSlice(credentialType)); + auto const keylet = keylet::credential(subject, issuer, credentialType); return Bytes{keylet.key.begin(), keylet.key.end()}; } @@ -320,7 +319,7 @@ struct TestHostFunctions : public HostFunctions } Expected - trace(std::string const& msg, Bytes const& data, bool asHex) override + trace(std::string const& msg, Slice const& data, bool asHex) override { #ifdef DEBUG_OUTPUT auto& j = std::cerr; @@ -581,7 +580,7 @@ struct PerfHostFunctions : public HostFunctions } static Expected - locateField(STObject const& obj, Bytes const& loc) + locateField(STObject const& obj, Slice const& loc) { if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 return Unexpected(HF_ERR_LOCATOR_MALFORMED); @@ -638,7 +637,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getTxNestedField(Bytes const& locator) override + getTxNestedField(Slice const& locator) override { // std::cout << tx_->getJson(JsonOptions::none).toStyledString() << // std::endl; @@ -655,7 +654,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getCurrentLedgerObjNestedField(Bytes const& locator) override + getCurrentLedgerObjNestedField(Slice const& locator) override { auto const sle = env_.le(leKey); if (!sle) @@ -674,7 +673,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) @@ -763,7 +762,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getTxNestedArrayLen(Bytes const& locator) override + getTxNestedArrayLen(Slice const& locator) override { auto const r = locateField(*tx_, locator); if (!r) @@ -778,7 +777,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override { auto const sle = env_.le(leKey); if (!sle) @@ -796,7 +795,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) @@ -822,7 +821,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - updateData(Bytes const& data) override + updateData(Slice const& data) override { ripple::detail::ApplyViewBase v( env_.app().openLedger().current().get(), tapNONE); @@ -838,7 +837,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - computeSha512HalfHash(Bytes const& data) override + computeSha512HalfHash(Slice const& data) override { auto const hash = sha512Half(data); return hash; @@ -857,14 +856,13 @@ struct PerfHostFunctions : public HostFunctions credentialKeylet( AccountID const& subject, AccountID const& issuer, - Bytes const& credentialType) override + Slice const& credentialType) override { if (!subject || !issuer || credentialType.empty() || credentialType.size() > maxCredentialTypeLength) return Unexpected(HF_ERR_INVALID_PARAMS); - auto const keylet = - keylet::credential(subject, issuer, makeSlice(credentialType)); + auto const keylet = keylet::credential(subject, issuer, credentialType); return Bytes{keylet.key.begin(), keylet.key.end()}; } @@ -912,7 +910,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - trace(std::string const& msg, Bytes const& data, bool asHex) override + trace(std::string const& msg, Slice const& data, bool asHex) override { #ifdef DEBUG_OUTPUT auto& j = std::cerr; diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index 03c44b1d4a4..2b35c007297 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -112,19 +112,19 @@ struct HostFunctions } virtual Expected - getTxNestedField(Bytes const& locator) + getTxNestedField(Slice const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - getCurrentLedgerObjNestedField(Bytes const& locator) + getCurrentLedgerObjNestedField(Slice const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) { return Unexpected(HF_ERR_INTERNAL); } @@ -148,31 +148,31 @@ struct HostFunctions } virtual Expected - getTxNestedArrayLen(Bytes const& locator) + getTxNestedArrayLen(Slice const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - getCurrentLedgerObjNestedArrayLen(Bytes const& locator) + getCurrentLedgerObjNestedArrayLen(Slice const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - updateData(Bytes const& data) + updateData(Slice const& data) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - computeSha512HalfHash(Bytes const& data) + computeSha512HalfHash(Slice const& data) { return Hash{}; } @@ -187,7 +187,7 @@ struct HostFunctions credentialKeylet( AccountID const& subject, AccountID const& issuer, - Bytes const& credentialType) + Slice const& credentialType) { return Unexpected(HF_ERR_INTERNAL); } @@ -211,7 +211,7 @@ struct HostFunctions } virtual Expected - trace(std::string const& msg, Bytes const& data, bool asHex) + trace(std::string const& msg, Slice const& data, bool asHex) { return Unexpected(HF_ERR_INTERNAL); } diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index e02d0c98ad6..0d89360e564 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -170,9 +170,8 @@ noField(STBase const* field) } static Expected -locateField(STObject const& obj, Bytes const& bytesLoc) +locateField(STObject const& obj, Slice const& loc) { - Slice const& loc = makeSlice(bytesLoc); if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 return Unexpected(HF_ERR_LOCATOR_MALFORMED); @@ -228,7 +227,7 @@ locateField(STObject const& obj, Bytes const& bytesLoc) } Expected -WasmHostFunctionsImpl::getTxNestedField(Bytes const& locator) +WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) { auto const r = locateField(ctx.tx, locator); if (!r) @@ -238,7 +237,7 @@ WasmHostFunctionsImpl::getTxNestedField(Bytes const& locator) } Expected -WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Bytes const& locator) +WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) @@ -254,7 +253,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Bytes const& locator) Expected WasmHostFunctionsImpl::getLedgerObjNestedField( int32_t cacheIdx, - Bytes const& locator) + Slice const& locator) { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) @@ -334,7 +333,7 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen( } Expected -WasmHostFunctionsImpl::getTxNestedArrayLen(Bytes const& locator) +WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) { auto const r = locateField(ctx.tx, locator); if (!r) @@ -349,7 +348,7 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Bytes const& locator) } Expected -WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Bytes const& locator) +WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) @@ -369,7 +368,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Bytes const& locator) Expected WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( int32_t cacheIdx, - Bytes const& locator) + Slice const& locator) { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) @@ -391,7 +390,7 @@ WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( } Expected -WasmHostFunctionsImpl::updateData(Bytes const& data) +WasmHostFunctionsImpl::updateData(Slice const& data) { if (data.size() > maxWasmDataLength) { @@ -406,7 +405,7 @@ WasmHostFunctionsImpl::updateData(Bytes const& data) } Expected -WasmHostFunctionsImpl::computeSha512HalfHash(Bytes const& data) +WasmHostFunctionsImpl::computeSha512HalfHash(Slice const& data) { auto const hash = sha512Half(data); return hash; @@ -425,7 +424,7 @@ Expected WasmHostFunctionsImpl::credentialKeylet( AccountID const& subject, AccountID const& issuer, - Bytes const& credentialType) + Slice const& credentialType) { if (!subject || !issuer) return Unexpected(HF_ERR_INVALID_ACCOUNT); @@ -434,8 +433,7 @@ WasmHostFunctionsImpl::credentialKeylet( credentialType.size() > maxCredentialTypeLength) return Unexpected(HF_ERR_INVALID_PARAMS); - auto const keylet = - keylet::credential(subject, issuer, makeSlice(credentialType)); + auto const keylet = keylet::credential(subject, issuer, credentialType); return Bytes{keylet.key.begin(), keylet.key.end()}; } @@ -484,7 +482,7 @@ WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) Expected WasmHostFunctionsImpl::trace( std::string const& msg, - Bytes const& data, + Slice const& data, bool asHex) { #ifdef DEBUG_OUTPUT diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index 024207fb52b..f31258a76c8 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -79,13 +79,13 @@ class WasmHostFunctionsImpl : public HostFunctions getLedgerObjField(int32_t cacheIdx, SField const& fname) override; Expected - getTxNestedField(Bytes const& locator) override; + getTxNestedField(Slice const& locator) override; Expected - getCurrentLedgerObjNestedField(Bytes const& locator) override; + getCurrentLedgerObjNestedField(Slice const& locator) override; Expected - getLedgerObjNestedField(int32_t cacheIdx, Bytes const& locator) override; + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override; Expected getTxArrayLen(SField const& fname) override; @@ -97,19 +97,19 @@ class WasmHostFunctionsImpl : public HostFunctions getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override; Expected - getTxNestedArrayLen(Bytes const& locator) override; + getTxNestedArrayLen(Slice const& locator) override; Expected - getCurrentLedgerObjNestedArrayLen(Bytes const& locator) override; + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override; Expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, Bytes const& locator) override; + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override; Expected - updateData(Bytes const& data) override; + updateData(Slice const& data) override; Expected - computeSha512HalfHash(Bytes const& data) override; + computeSha512HalfHash(Slice const& data) override; Expected accountKeylet(AccountID const& account) override; @@ -118,7 +118,7 @@ class WasmHostFunctionsImpl : public HostFunctions credentialKeylet( AccountID const& subject, AccountID const& issuer, - Bytes const& credentialType) override; + Slice const& credentialType) override; Expected escrowKeylet(AccountID const& account, std::uint32_t seq) override; @@ -130,7 +130,7 @@ class WasmHostFunctionsImpl : public HostFunctions getNFT(AccountID const& account, uint256 const& nftId) override; Expected - trace(std::string const& msg, Bytes const& data, bool asHex) override; + trace(std::string const& msg, Slice const& data, bool asHex) override; Expected traceNum(std::string const& msg, int64_t data) override; diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index edcdbccfa9c..4443a53411e 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -102,8 +102,8 @@ getData( } template <> -Expected -getData( +Expected +getData( InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t& i) @@ -121,7 +121,7 @@ getData( if (src + ssz > mem.s) return Unexpected(HF_ERR_POINTER_OUT_OF_BOUNDS); - Bytes data(mem.p + src, mem.p + src + ssz); + Slice data(mem.p + src, ssz); return data; } @@ -132,7 +132,7 @@ getData( wasm_val_vec_t const* params, int32_t& i) { - auto const r = getData(rt, params, i); + auto const r = getData(rt, params, i); i++; if (!r) { @@ -153,7 +153,7 @@ getData( wasm_val_vec_t const* params, int32_t& i) { - auto const r = getData(rt, params, i); + auto const r = getData(rt, params, i); if (!r || (r->size() != AccountID::bytes)) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -426,11 +426,11 @@ getTxNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](Bytes const& bytes) { + [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getTxNestedField(bytes); }); } @@ -441,11 +441,11 @@ getCurrentLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](Bytes const& bytes) { + [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getCurrentLedgerObjNestedField(bytes); }); } @@ -456,12 +456,12 @@ getLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, [hf = reinterpret_cast(env)]( - int32_t cache, Bytes const& bytes) { + int32_t cache, Slice const& bytes) { return hf->getLedgerObjNestedField(cache, bytes); }); } @@ -518,11 +518,11 @@ getTxNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](Bytes const& bytes) { + [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getTxNestedArrayLen(bytes); }); } @@ -533,11 +533,11 @@ getCurrentLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](Bytes const& bytes) { + [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getCurrentLedgerObjNestedArrayLen(bytes); }); } @@ -547,12 +547,12 @@ getLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, [hf = reinterpret_cast(env)]( - int32_t cache, Bytes const& bytes) { + int32_t cache, Slice const& bytes) { return hf->getLedgerObjNestedArrayLen(cache, bytes); }); } @@ -563,11 +563,11 @@ updateData_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](Bytes const& bytes) { + [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->updateData(bytes); }); } @@ -578,11 +578,11 @@ computeSha512HalfHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](Bytes const& bytes) { + [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->computeSha512HalfHash(bytes); }); } @@ -608,14 +608,14 @@ credentialKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, [hf = reinterpret_cast(env)]( AccountID const& subj, AccountID const& iss, - Bytes const& credType) { + Slice const& credType) { return hf->credentialKeylet(subj, iss, credType); }); } @@ -678,7 +678,7 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) return hfResult(results, msg.error()); } - auto const data = getData(rt, params, index); + auto const data = getData(rt, params, index); if (!data) { return hfResult(results, data.error()); From e7a82981b50cd6a7f7fe827e284de0508fb0a7f7 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Sat, 5 Jul 2025 00:24:31 +0530 Subject: [PATCH 11/25] SFieldParam macro -> type alias --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 39 +++++++++------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 4443a53411e..e10aa354a0e 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -26,7 +26,7 @@ namespace ripple { -#define SFIELD_PARAM std::reference_wrapper +using SFieldParam = std::reference_wrapper; static int32_t setData( @@ -85,8 +85,8 @@ getData( } template <> -Expected -getData( +Expected +getData( InstanceWrapper const* _rt, wasm_val_vec_t const* params, int32_t& i) @@ -293,15 +293,6 @@ getLedgerSqnOld_wrap( return hfResult(results, sqn.value()); } -#define HOST_FUNCTION(funcName, name, return, ...) \ - wasm_trap_t* funcName##_wrap( \ - void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) \ - { \ - auto* hf = reinterpret_cast(env); \ - auto const* rt = \ - reinterpret_cast(hf->getRT()); \ - } - wasm_trap_t* getLedgerSqn_wrap( void* env, @@ -380,11 +371,11 @@ getTxField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getTxField(fname); }); } @@ -395,11 +386,11 @@ getCurrentLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getCurrentLedgerObjField(fname); }); } @@ -410,12 +401,12 @@ getLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, [hf = reinterpret_cast(env)]( - int32_t cache, SFIELD_PARAM fname) { + int32_t cache, SFieldParam fname) { return hf->getLedgerObjField(cache, fname); }); } @@ -472,11 +463,11 @@ getTxArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getTxArrayLen(fname); }); } @@ -487,11 +478,11 @@ getCurrentLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, - [hf = reinterpret_cast(env)](SFIELD_PARAM fname) { + [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getCurrentLedgerObjArrayLen(fname); }); } @@ -502,12 +493,12 @@ getLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( + return invokeHostFunc( env, params, results, [hf = reinterpret_cast(env)]( - int32_t cache, SFIELD_PARAM fname) { + int32_t cache, SFieldParam fname) { return hf->getLedgerObjArrayLen(cache, fname); }); } From b14124394e9d76e83e57d72d5a52bbbacc01f0f6 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 7 Jul 2025 19:30:43 +0530 Subject: [PATCH 12/25] fix return type --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index e10aa354a0e..6c4d2d47d4e 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -185,7 +185,7 @@ getData( } template -nullptr_t +std::nullptr_t hfResult(wasm_val_vec_t* results, T value) { results->data[0] = WASM_I32_VAL(value); From 2430d8366236263455e9e5e4bd3cac284cdf0f22 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 7 Jul 2025 22:35:59 +0530 Subject: [PATCH 13/25] fix bugs --- src/test/app/Wasm_test.cpp | 26 +-- src/xrpld/app/misc/WasmHostFunc.h | 4 +- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 25 ++- src/xrpld/app/misc/WasmHostFuncImpl.h | 4 +- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 206 ++++++++++----------- 5 files changed, 129 insertions(+), 136 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 1a65b4eccfd..ae231ce96b8 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -110,13 +110,13 @@ struct TestHostFunctions : public HostFunctions return env_.journal; } - Expected + Expected getLedgerSqn() override { - return static_cast(env_.current()->seq()); + return static_cast(env_.current()->seq()); } - Expected + Expected getParentLedgerTime() override { return env_.current()->parentCloseTime().time_since_epoch().count() + @@ -151,8 +151,10 @@ struct TestHostFunctions : public HostFunctions auto const x = getLedgerSqn(); if (!x) return Unexpected(x.error()); - uint8_t const* p = reinterpret_cast(&x.value()); - return Bytes{p, p + sizeof(x)}; + std::uint32_t const data = x.value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; } return Bytes(); } @@ -326,7 +328,7 @@ struct TestHostFunctions : public HostFunctions #else auto j = getJournal().trace(); #endif - j << msg; + j << "WASM TRACE: " << msg; if (!asHex) j << std::string_view( reinterpret_cast(data.data()), data.size()); @@ -352,7 +354,7 @@ struct TestHostFunctions : public HostFunctions #else auto j = getJournal().trace(); #endif - j << msg << data; + j << "WASM TRACE NUM: " << msg << data; #ifdef DEBUG_OUTPUT j << std::endl; @@ -426,13 +428,13 @@ struct PerfHostFunctions : public HostFunctions return env_.journal; } - Expected + Expected getLedgerSqn() override { - return static_cast(env_.current()->seq()); + return static_cast(env_.current()->seq()); } - Expected + Expected getParentLedgerTime() override { return env_.current()->parentCloseTime().time_since_epoch().count(); @@ -1387,7 +1389,7 @@ struct Wasm_test : public beast::unit_test::suite } void - testEscrowWasmDN2() + testEscrowWasmDN3() { testcase("wasm devnet 3 test"); @@ -1553,7 +1555,7 @@ struct Wasm_test : public beast::unit_test::suite // TODO: fix result testEscrowWasmDN1(); - testEscrowWasmDN2(); + testEscrowWasmDN3(); // perfTest(); } diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index 2b35c007297..ee113993ef4 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -69,13 +69,13 @@ struct HostFunctions return beast::Journal{beast::Journal::getNullSink()}; } - virtual Expected + virtual Expected getLedgerSqn() { return 1; } - virtual Expected + virtual Expected getParentLedgerTime() { return 1; diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index 0d89360e564..a330b6a8345 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -30,13 +30,13 @@ namespace ripple { -Expected +Expected WasmHostFunctionsImpl::getLedgerSqn() { return ctx.view().seq(); } -Expected +Expected WasmHostFunctionsImpl::getParentLedgerTime() { return ctx.view().parentCloseTime().time_since_epoch().count(); @@ -92,35 +92,34 @@ getAnyFieldData(STBase const* obj) return Unexpected(HF_ERR_NOT_LEAF_FIELD); break; case STI_ACCOUNT: { - auto const& super(static_cast(obj)); - auto const& data = super->value(); + auto const& account(static_cast(obj)); + auto const& data = account->value(); return Bytes{data.begin(), data.end()}; } break; case STI_AMOUNT: { - auto const& super(static_cast(obj)); - int64_t const data = super->xrp().drops(); + auto const& amount(static_cast(obj)); + int64_t const data = amount->xrp().drops(); auto const* b = reinterpret_cast(&data); auto const* e = reinterpret_cast(&data + 1); return Bytes{b, e}; } break; case STI_VL: { - auto const& super(static_cast(obj)); - auto const& data = super->value(); + auto const& vl(static_cast(obj)); + auto const& data = vl->value(); return Bytes{data.begin(), data.end()}; } break; case STI_UINT256: { - auto const& super(static_cast const*>(obj)); - auto const& data = super->value(); + auto const& num(static_cast const*>(obj)); + auto const& data = num->value(); return Bytes{data.begin(), data.end()}; } break; case STI_UINT32: { - auto const& super( - static_cast const*>(obj)); - std::uint32_t const data = super->value(); + auto const& num(static_cast const*>(obj)); + std::uint32_t const data = num->value(); auto const* b = reinterpret_cast(&data); auto const* e = reinterpret_cast(&data + 1); return Bytes{b, e}; diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index f31258a76c8..17bc5e7f994 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -57,10 +57,10 @@ class WasmHostFunctionsImpl : public HostFunctions return ctx.journal; } - Expected + Expected getLedgerSqn() override; - Expected + Expected getParentLedgerTime() override; Expected diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 6c4d2d47d4e..486deb2dd80 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -211,7 +211,8 @@ invokeHostFunc( void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results, - Func&& f) + Func&& f, + std::string const& funcName) { auto* hf = reinterpret_cast(env); auto const* rt = reinterpret_cast(hf->getRT()); @@ -224,6 +225,8 @@ invokeHostFunc( if (err) { + hf->getJournal().trace() + << "invokeHostFunc: param error: " << *err << std::endl; return hfResult(results, *err); } @@ -234,6 +237,8 @@ invokeHostFunc( if (!result) { + hf->getJournal().trace() + << "invokeHostFunc: returning error: " << result.error(); return hfResult(results, result.error()); } @@ -261,14 +266,21 @@ invokeHostFunc( } else if constexpr (std::is_same_v, int32_t>) { + return hfResult(results, result.value()); + } + else if constexpr (std::is_same_v< + std::decay_t, + std::uint32_t>) + { + auto const unwrappedResult = result.value(); return hfResult( results, setData( rt, params->data[index].of.i32, params->data[index + 1].of.i32, - reinterpret_cast(&result.value()), - static_cast(sizeof(result.value())))); + reinterpret_cast(&unwrappedResult), + static_cast(sizeof(unwrappedResult)))); } else { @@ -290,7 +302,7 @@ getLedgerSqnOld_wrap( { return hfResult(results, sqn.error()); } - return hfResult(results, sqn.value()); + return hfResult(results, static_cast(sqn.value())); } wasm_trap_t* @@ -300,9 +312,13 @@ getLedgerSqn_wrap( wasm_val_vec_t* results) { return invokeHostFunc( - env, params, results, [hf = reinterpret_cast(env)]() { + env, + params, + results, + [hf = reinterpret_cast(env)]() { return hf->getLedgerSqn(); - }); + }, + "getLedgerSqn"); } wasm_trap_t* @@ -312,9 +328,13 @@ getParentLedgerTime_wrap( wasm_val_vec_t* results) { return invokeHostFunc( - env, params, results, [hf = reinterpret_cast(env)]() { + env, + params, + results, + [hf = reinterpret_cast(env)]() { return hf->getParentLedgerTime(); - }); + }, + "getParentLedgerTime"); } wasm_trap_t* @@ -324,9 +344,13 @@ getParentLedgerHash_wrap( wasm_val_vec_t* results) { return invokeHostFunc( - env, params, results, [hf = reinterpret_cast(env)]() { + env, + params, + results, + [hf = reinterpret_cast(env)]() { return hf->getParentLedgerHash(); - }); + }, + "getParentLedgerHash"); } wasm_trap_t* @@ -335,34 +359,15 @@ cacheLedgerObj_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - // return invokeHostFunc( - // env, - // params, - // results, - // [hf = reinterpret_cast(env)](uint256 id, int32_t - // cache) { - // return hf->cacheLedgerObj(id, cache); - // }); - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const r = getData(rt, params, index); - if (!r) - { - return hfResult(results, r.error()); - } - auto const cache = getData(rt, params, index); - if (!cache) - { - return hfResult(results, cache.error()); - } - auto const cacheIndex = hf->cacheLedgerObj(r.value(), cache.value()); - if (!cacheIndex) - { - return hfResult(results, cacheIndex.error()); - } - return hfResult(results, cacheIndex.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)]( + uint256 id, int32_t cache) { + return hf->cacheLedgerObj(id, cache); + }, + "cacheLedgerObj"); } wasm_trap_t* @@ -377,7 +382,8 @@ getTxField_wrap( results, [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getTxField(fname); - }); + }, + "getTxField"); } wasm_trap_t* @@ -392,7 +398,8 @@ getCurrentLedgerObjField_wrap( results, [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getCurrentLedgerObjField(fname); - }); + }, + "getCurrentLedgerObj"); } wasm_trap_t* @@ -408,7 +415,8 @@ getLedgerObjField_wrap( [hf = reinterpret_cast(env)]( int32_t cache, SFieldParam fname) { return hf->getLedgerObjField(cache, fname); - }); + }, + "getLedgerObjField"); } wasm_trap_t* @@ -423,7 +431,8 @@ getTxNestedField_wrap( results, [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getTxNestedField(bytes); - }); + }, + "getTxNestedField"); } wasm_trap_t* @@ -438,7 +447,8 @@ getCurrentLedgerObjNestedField_wrap( results, [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getCurrentLedgerObjNestedField(bytes); - }); + }, + "getCurrentLedgerObjNestedField"); } wasm_trap_t* @@ -454,7 +464,8 @@ getLedgerObjNestedField_wrap( [hf = reinterpret_cast(env)]( int32_t cache, Slice const& bytes) { return hf->getLedgerObjNestedField(cache, bytes); - }); + }, + "getLedgerObjNestedField"); } wasm_trap_t* @@ -469,7 +480,8 @@ getTxArrayLen_wrap( results, [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getTxArrayLen(fname); - }); + }, + "getTxArrayLen"); } wasm_trap_t* @@ -484,7 +496,8 @@ getCurrentLedgerObjArrayLen_wrap( results, [hf = reinterpret_cast(env)](SFieldParam fname) { return hf->getCurrentLedgerObjArrayLen(fname); - }); + }, + "getCurrentLedgerObjArrayLen"); } wasm_trap_t* @@ -500,7 +513,8 @@ getLedgerObjArrayLen_wrap( [hf = reinterpret_cast(env)]( int32_t cache, SFieldParam fname) { return hf->getLedgerObjArrayLen(cache, fname); - }); + }, + "getLedgerObjArrayLen"); } wasm_trap_t* @@ -515,7 +529,8 @@ getTxNestedArrayLen_wrap( results, [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getTxNestedArrayLen(bytes); - }); + }, + "getTxNestedArrayLen"); } wasm_trap_t* @@ -530,7 +545,8 @@ getCurrentLedgerObjNestedArrayLen_wrap( results, [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->getCurrentLedgerObjNestedArrayLen(bytes); - }); + }, + "getCurrentLedgerObjNestedArrayLen"); } wasm_trap_t* getLedgerObjNestedArrayLen_wrap( @@ -545,7 +561,8 @@ getLedgerObjNestedArrayLen_wrap( [hf = reinterpret_cast(env)]( int32_t cache, Slice const& bytes) { return hf->getLedgerObjNestedArrayLen(cache, bytes); - }); + }, + "getLedgerObjNestedArrayLen"); } wasm_trap_t* @@ -560,7 +577,8 @@ updateData_wrap( results, [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->updateData(bytes); - }); + }, + "updateData"); } wasm_trap_t* @@ -575,7 +593,8 @@ computeSha512HalfHash_wrap( results, [hf = reinterpret_cast(env)](Slice const& bytes) { return hf->computeSha512HalfHash(bytes); - }); + }, + "computeSha512HalfHash"); } wasm_trap_t* @@ -590,7 +609,8 @@ accountKeylet_wrap( results, [hf = reinterpret_cast(env)](AccountID const& acc) { return hf->accountKeylet(acc); - }); + }, + "accountKeylet"); } wasm_trap_t* @@ -608,7 +628,8 @@ credentialKeylet_wrap( AccountID const& iss, Slice const& credType) { return hf->credentialKeylet(subj, iss, credType); - }); + }, + "credentialKeylet"); } wasm_trap_t* @@ -624,7 +645,8 @@ escrowKeylet_wrap( [hf = reinterpret_cast(env)]( AccountID const& acc, int32_t seq) { return hf->escrowKeylet(acc, seq); - }); + }, + "escrowKeylet"); } wasm_trap_t* @@ -640,7 +662,8 @@ oracleKeylet_wrap( [hf = reinterpret_cast(env)]( AccountID const& acc, int32_t seq) { return hf->oracleKeylet(acc, seq); - }); + }, + "oracleKeylet"); } wasm_trap_t* @@ -653,67 +676,36 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) [hf = reinterpret_cast(env)]( AccountID const& acc, uint256 nftId) { return hf->getNFT(acc, nftId); - }); + }, + "getNFT"); } wasm_trap_t* trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const msg = getData(rt, params, index); - if (!msg) - { - return hfResult(results, msg.error()); - } - - auto const data = getData(rt, params, index); - if (!data) - { - return hfResult(results, data.error()); - } - - auto const asHex = getData(rt, params, index); - if (!asHex) - { - return hfResult(results, asHex.error()); - } - - auto const e = hf->trace(msg.value(), data.value(), asHex.value()); - if (!e) - { - return hfResult(results, e.error()); - } - return hfResult(results, e.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)]( + std::string const& msg, Slice const& data, int32_t const& asHex) { + return hf->trace(msg, data, asHex); + }, + "trace"); } wasm_trap_t* traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto const msg = getData(rt, params, index); - if (!msg) - { - return hfResult(results, msg.error()); - } - - auto const number = getData(rt, params, index); - if (!number) - { - return hfResult(results, number.error()); - } - - auto const e = hf->traceNum(msg.value(), number.value()); - if (!e) - { - return hfResult(results, e.error()); - } - return hfResult(results, e.value()); + return invokeHostFunc( + env, + params, + results, + [hf = reinterpret_cast(env)]( + std::string const& msg, int64_t const& number) { + return hf->traceNum(msg, number); + }, + "trace"); } } // namespace ripple From 49836707f9fcfa1d5c80bcbc0c1c783a72ec3394 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 7 Jul 2025 22:41:08 +0530 Subject: [PATCH 14/25] replace std::make_index_sequence --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 486deb2dd80..987148c7360 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -193,15 +193,12 @@ hfResult(wasm_val_vec_t* results, T value) return nullptr; } -template +template std::optional -checkErrors(Tuple const& t, std::index_sequence) +checkErrors(Args const&... args) { std::optional err; - ((err = err ? err - : (!std::get(t) ? std::optional{std::get(t).error()} - : std::nullopt)), - ...); + ((err = !args ? args.error() : err), ...); // Fold expression return err; } @@ -220,8 +217,8 @@ invokeHostFunc( auto expectedArgs = std::make_tuple(getData(rt, params, index)...); - constexpr auto N = sizeof...(Args); - auto err = checkErrors(expectedArgs, std::make_index_sequence{}); + auto err = std::apply( + [](auto const&... args) { return checkErrors(args...); }, expectedArgs); if (err) { From 0c1f5874f7bf1782575207dbfa9098e13224a45e Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 7 Jul 2025 23:18:31 +0530 Subject: [PATCH 15/25] remove `failed` from output --- src/test/app/AMM_test.cpp | 2 +- src/test/app/Vault_test.cpp | 2 +- src/test/app/Wasm_test.cpp | 2 +- src/xrpld/app/misc/WamrVM.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index 2ee9e5f1f37..93bb57a0816 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -7480,7 +7480,7 @@ struct AMM_test : public jtx::AMMTest using namespace test::jtx; auto const testCase = [&](std::string suffix, FeatureBitset features) { - testcase("Failed pseudo-account allocation " + suffix); + testcase("Pseudo-account allocation failure " + suffix); std::string logs; Env env{*this, features, std::make_unique(&logs)}; env.fund(XRP(30'000), gw, alice); diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index ccac0e2819a..24a951c83c4 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -2638,7 +2638,7 @@ class Vault_test : public beast::unit_test::suite { using namespace test::jtx; - testcase("failed pseudo-account allocation"); + testcase("Pseudo-account allocation failure"); Env env{*this, supported_amendments() | featureSingleAssetVault}; Account const owner{"owner"}; Vault vault{env}; diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index ae231ce96b8..378b670e728 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -1363,7 +1363,7 @@ struct Wasm_test : public beast::unit_test::suite auto const s = sink.messages().str(); BEAST_EXPECT( - countSubstr(s, "WAMR Error: failed to call func") == 1); + countSubstr(s, "WAMR Error: failure to call func") == 1); BEAST_EXPECT( countSubstr(s, "Exception: wasm operand stack overflow") > 0); } diff --git a/src/xrpld/app/misc/WamrVM.cpp b/src/xrpld/app/misc/WamrVM.cpp index 9ad697b1c10..b712caef656 100644 --- a/src/xrpld/app/misc/WamrVM.cpp +++ b/src/xrpld/app/misc/WamrVM.cpp @@ -795,7 +795,7 @@ WamrEngine::call(FuncInfo const& f, std::vector& in) if (trap) { ret.f = true; - print_wasm_error("failed to call func", trap, j_); + print_wasm_error("failure to call func", trap, j_); } // assert(results[0].kind == WASM_I32); From d3a6097b8b8b813612b000706cd7ad41a6c6b18d Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 10 Jul 2025 01:25:30 +0530 Subject: [PATCH 16/25] remove complex function --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 598 +++++++++++++-------- 1 file changed, 362 insertions(+), 236 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 987148c7360..b1954a557a3 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -202,43 +202,19 @@ checkErrors(Args const&... args) return err; } -template -wasm_trap_t* -invokeHostFunc( - void* env, +template +std::nullptr_t +returnResult( + InstanceWrapper const* rt, wasm_val_vec_t const* params, wasm_val_vec_t* results, - Func&& f, - std::string const& funcName) + Expected result, + int32_t& index) { - auto* hf = reinterpret_cast(env); - auto const* rt = reinterpret_cast(hf->getRT()); - int index = 0; - - auto expectedArgs = std::make_tuple(getData(rt, params, index)...); - - auto err = std::apply( - [](auto const&... args) { return checkErrors(args...); }, expectedArgs); - - if (err) - { - hf->getJournal().trace() - << "invokeHostFunc: param error: " << *err << std::endl; - return hfResult(results, *err); - } - - auto unwrappedArgs = - std::apply([](auto&&... e) { return std::tuple{*e...}; }, expectedArgs); - - auto result = std::apply(std::forward(f), unwrappedArgs); - if (!result) { - hf->getJournal().trace() - << "invokeHostFunc: returning error: " << result.error(); return hfResult(results, result.error()); } - if constexpr (std::is_same_v, Bytes>) { return hfResult( @@ -282,7 +258,7 @@ invokeHostFunc( else { static_assert( - [] { return false; }(), "Unhandled return type in invokeHostFunc"); + [] { return false; }(), "Unhandled return type in returnResult"); } } @@ -308,14 +284,11 @@ getLedgerSqn_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]() { - return hf->getLedgerSqn(); - }, - "getLedgerSqn"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult(rt, params, results, hf->getLedgerSqn(), index); } wasm_trap_t* @@ -324,14 +297,11 @@ getParentLedgerTime_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]() { - return hf->getParentLedgerTime(); - }, - "getParentLedgerTime"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult(rt, params, results, hf->getParentLedgerTime(), index); } wasm_trap_t* @@ -340,14 +310,11 @@ getParentLedgerHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]() { - return hf->getParentLedgerHash(); - }, - "getParentLedgerHash"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult(rt, params, results, hf->getParentLedgerHash(), index); } wasm_trap_t* @@ -356,15 +323,24 @@ cacheLedgerObj_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - uint256 id, int32_t cache) { - return hf->cacheLedgerObj(id, cache); - }, - "cacheLedgerObj"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const id = getData(rt, params, index); + if (!id) + { + return hfResult(results, id.error()); + } + + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + + return returnResult( + rt, params, results, hf->cacheLedgerObj(*id, *cache), index); } wasm_trap_t* @@ -373,14 +349,16 @@ getTxField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](SFieldParam fname) { - return hf->getTxField(fname); - }, - "getTxField"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getData(rt, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + return returnResult(rt, params, results, hf->getTxField(*fname), index); } wasm_trap_t* @@ -389,14 +367,18 @@ getCurrentLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](SFieldParam fname) { - return hf->getCurrentLedgerObjField(fname); - }, - "getCurrentLedgerObj"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getData(rt, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + rt, params, results, hf->getCurrentLedgerObjField(*fname), index); } wasm_trap_t* @@ -405,15 +387,24 @@ getLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - int32_t cache, SFieldParam fname) { - return hf->getLedgerObjField(cache, fname); - }, - "getLedgerObjField"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + + auto const fname = getData(rt, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + rt, params, results, hf->getLedgerObjField(*cache, *fname), index); } wasm_trap_t* @@ -422,14 +413,18 @@ getTxNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](Slice const& bytes) { - return hf->getTxNestedField(bytes); - }, - "getTxNestedField"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + rt, params, results, hf->getTxNestedField(*bytes), index); } wasm_trap_t* @@ -438,14 +433,17 @@ getCurrentLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](Slice const& bytes) { - return hf->getCurrentLedgerObjNestedField(bytes); - }, - "getCurrentLedgerObjNestedField"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + return returnResult( + rt, params, results, hf->getCurrentLedgerObjNestedField(*bytes), index); } wasm_trap_t* @@ -454,15 +452,28 @@ getLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + rt, params, results, - [hf = reinterpret_cast(env)]( - int32_t cache, Slice const& bytes) { - return hf->getLedgerObjNestedField(cache, bytes); - }, - "getLedgerObjNestedField"); + hf->getLedgerObjNestedField(*cache, *bytes), + index); } wasm_trap_t* @@ -471,14 +482,17 @@ getTxArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](SFieldParam fname) { - return hf->getTxArrayLen(fname); - }, - "getTxArrayLen"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getData(rt, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult(rt, params, results, hf->getTxArrayLen(*fname), index); } wasm_trap_t* @@ -487,14 +501,18 @@ getCurrentLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](SFieldParam fname) { - return hf->getCurrentLedgerObjArrayLen(fname); - }, - "getCurrentLedgerObjArrayLen"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getData(rt, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + rt, params, results, hf->getCurrentLedgerObjArrayLen(*fname), index); } wasm_trap_t* @@ -503,15 +521,24 @@ getLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - int32_t cache, SFieldParam fname) { - return hf->getLedgerObjArrayLen(cache, fname); - }, - "getLedgerObjArrayLen"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + + auto const fname = getData(rt, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + rt, params, results, hf->getLedgerObjArrayLen(*cache, *fname), index); } wasm_trap_t* @@ -520,14 +547,18 @@ getTxNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](Slice const& bytes) { - return hf->getTxNestedArrayLen(bytes); - }, - "getTxNestedArrayLen"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + rt, params, results, hf->getTxNestedArrayLen(*bytes), index); } wasm_trap_t* @@ -536,14 +567,22 @@ getCurrentLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + rt, params, results, - [hf = reinterpret_cast(env)](Slice const& bytes) { - return hf->getCurrentLedgerObjNestedArrayLen(bytes); - }, - "getCurrentLedgerObjNestedArrayLen"); + hf->getCurrentLedgerObjNestedArrayLen(*bytes), + index); } wasm_trap_t* getLedgerObjNestedArrayLen_wrap( @@ -551,15 +590,27 @@ getLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getData(rt, params, index); + if (!cache) + { + return hfResult(results, cache.error()); + } + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + return returnResult( + rt, params, results, - [hf = reinterpret_cast(env)]( - int32_t cache, Slice const& bytes) { - return hf->getLedgerObjNestedArrayLen(cache, bytes); - }, - "getLedgerObjNestedArrayLen"); + hf->getLedgerObjNestedArrayLen(*cache, *bytes), + index); } wasm_trap_t* @@ -568,14 +619,17 @@ updateData_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](Slice const& bytes) { - return hf->updateData(bytes); - }, - "updateData"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult(rt, params, results, hf->updateData(*bytes), index); } wasm_trap_t* @@ -584,14 +638,17 @@ computeSha512HalfHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](Slice const& bytes) { - return hf->computeSha512HalfHash(bytes); - }, - "computeSha512HalfHash"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getData(rt, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + return returnResult( + rt, params, results, hf->computeSha512HalfHash(*bytes), index); } wasm_trap_t* @@ -600,14 +657,17 @@ accountKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)](AccountID const& acc) { - return hf->accountKeylet(acc); - }, - "accountKeylet"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getData(rt, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + return returnResult(rt, params, results, hf->accountKeylet(*acc), index); } wasm_trap_t* @@ -616,17 +676,34 @@ credentialKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const subj = getData(rt, params, index); + if (!subj) + { + return hfResult(results, subj.error()); + } + + auto const iss = getData(rt, params, index); + if (!iss) + { + return hfResult(results, iss.error()); + } + + auto const credType = getData(rt, params, index); + if (!credType) + { + return hfResult(results, credType.error()); + } + + return returnResult( + rt, params, results, - [hf = reinterpret_cast(env)]( - AccountID const& subj, - AccountID const& iss, - Slice const& credType) { - return hf->credentialKeylet(subj, iss, credType); - }, - "credentialKeylet"); + hf->credentialKeylet(*subj, *iss, *credType), + index); } wasm_trap_t* @@ -635,15 +712,24 @@ escrowKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - AccountID const& acc, int32_t seq) { - return hf->escrowKeylet(acc, seq); - }, - "escrowKeylet"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getData(rt, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getData(rt, params, index); + if (!seq) + { + return hfResult(results, seq.error()); + } + + return returnResult( + rt, params, results, hf->escrowKeylet(*acc, *seq), index); } wasm_trap_t* @@ -652,57 +738,97 @@ oracleKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - AccountID const& acc, int32_t seq) { - return hf->oracleKeylet(acc, seq); - }, - "oracleKeylet"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getData(rt, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getData(rt, params, index); + if (!seq) + { + return hfResult(results, seq.error()); + } + return returnResult( + rt, params, results, hf->oracleKeylet(*acc, *seq), index); } wasm_trap_t* getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - AccountID const& acc, uint256 nftId) { - return hf->getNFT(acc, nftId); - }, - "getNFT"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getData(rt, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const nftId = getData(rt, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult(rt, params, results, hf->getNFT(*acc, *nftId), index); } wasm_trap_t* trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - std::string const& msg, Slice const& data, int32_t const& asHex) { - return hf->trace(msg, data, asHex); - }, - "trace"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const msg = getData(rt, params, index); + if (!msg) + { + return hfResult(results, msg.error()); + } + + auto const data = getData(rt, params, index); + if (!data) + { + return hfResult(results, data.error()); + } + + auto const asHex = getData(rt, params, index); + if (!asHex) + { + return hfResult(results, asHex.error()); + } + + return returnResult( + rt, params, results, hf->trace(*msg, *data, *asHex), index); } wasm_trap_t* traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - return invokeHostFunc( - env, - params, - results, - [hf = reinterpret_cast(env)]( - std::string const& msg, int64_t const& number) { - return hf->traceNum(msg, number); - }, - "trace"); + auto* hf = reinterpret_cast(env); + auto const* rt = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const msg = getData(rt, params, index); + if (!msg) + { + return hfResult(results, msg.error()); + } + + auto const number = getData(rt, params, index); + if (!number) + { + return hfResult(results, number.error()); + } + + return returnResult( + rt, params, results, hf->traceNum(*msg, *number), index); } } // namespace ripple From e19d119dea012b57dc72c8e172055f089a3e1df6 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 10 Jul 2025 01:48:15 +0530 Subject: [PATCH 17/25] more uniformity --- src/xrpld/app/misc/WasmHostFunc.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index ee113993ef4..ff0aff76c56 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -72,19 +72,19 @@ struct HostFunctions virtual Expected getLedgerSqn() { - return 1; + return Unexpected(HF_ERR_INTERNAL); } virtual Expected getParentLedgerTime() { - return 1; + return Unexpected(HF_ERR_INTERNAL); } virtual Expected getParentLedgerHash() { - return Hash{}; + return Unexpected(HF_ERR_INTERNAL); } virtual Expected @@ -174,13 +174,13 @@ struct HostFunctions virtual Expected computeSha512HalfHash(Slice const& data) { - return Hash{}; + return Unexpected(HF_ERR_INTERNAL); } virtual Expected accountKeylet(AccountID const& account) { - return Bytes{}; + return Unexpected(HF_ERR_INTERNAL); } virtual Expected From 56b26e86885b7df04ca587360e04f325ef975301 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 11 Jul 2025 00:34:28 +0530 Subject: [PATCH 18/25] respond to comments --- src/test/app/Wasm_test.cpp | 8 ++-- src/xrpld/app/misc/WamrVM.cpp | 2 +- src/xrpld/app/misc/WasmHostFunc.h | 4 +- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 11 +++-- src/xrpld/app/misc/WasmHostFuncImpl.h | 4 +- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 51 +++++++++------------- 6 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 378b670e728..315a45e4616 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -321,7 +321,7 @@ struct TestHostFunctions : public HostFunctions } Expected - trace(std::string const& msg, Slice const& data, bool asHex) override + trace(std::string_view const& msg, Slice const& data, bool asHex) override { #ifdef DEBUG_OUTPUT auto& j = std::cerr; @@ -347,7 +347,7 @@ struct TestHostFunctions : public HostFunctions } Expected - traceNum(std::string const& msg, int64_t data) override + traceNum(std::string_view const& msg, int64_t data) override { #ifdef DEBUG_OUTPUT auto& j = std::cerr; @@ -912,7 +912,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - trace(std::string const& msg, Slice const& data, bool asHex) override + trace(std::string_view const& msg, Slice const& data, bool asHex) override { #ifdef DEBUG_OUTPUT auto& j = std::cerr; @@ -938,7 +938,7 @@ struct PerfHostFunctions : public HostFunctions } Expected - traceNum(std::string const& msg, int64_t data) override + traceNum(std::string_view const& msg, int64_t data) override { #ifdef DEBUG_OUTPUT auto& j = std::cerr; diff --git a/src/xrpld/app/misc/WamrVM.cpp b/src/xrpld/app/misc/WamrVM.cpp index b712caef656..64759ff8d07 100644 --- a/src/xrpld/app/misc/WamrVM.cpp +++ b/src/xrpld/app/misc/WamrVM.cpp @@ -924,7 +924,7 @@ WamrEngine::runHlp( auto const res = call<1>(f, p); if (res.f) - throw std::runtime_error("<" + std::string(funcName) + "> failed"); + throw std::runtime_error("<" + std::string(funcName) + "> failure"); else if (!res.r.num_elems) throw std::runtime_error( "<" + std::string(funcName) + "> return nothing"); diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index ff0aff76c56..c9da537ddb5 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -211,13 +211,13 @@ struct HostFunctions } virtual Expected - trace(std::string const& msg, Slice const& data, bool asHex) + trace(std::string_view const& msg, Slice const& data, bool asHex) { return Unexpected(HF_ERR_INTERNAL); } virtual Expected - traceNum(std::string const& msg, int64_t data) + traceNum(std::string_view const& msg, int64_t data) { return Unexpected(HF_ERR_INTERNAL); } diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index a330b6a8345..7c9027ea142 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -480,7 +480,7 @@ WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) Expected WasmHostFunctionsImpl::trace( - std::string const& msg, + std::string_view const& msg, Slice const& data, bool asHex) { @@ -490,13 +490,16 @@ WasmHostFunctionsImpl::trace( auto j = ctx.journal.trace(); #endif if (!asHex) + { j << "WAMR TRACE (" << leKey.key << "): " << msg << " - " << std::string_view( reinterpret_cast(data.data()), data.size()); + } else { - auto const hex = - boost::algorithm::hex(std::string(data.begin(), data.end())); + std::string hex; + hex.reserve(data.size() * 2); + boost::algorithm::hex(data.begin(), data.end(), hex.begin()); j << "WAMR DEV TRACE (" << leKey.key << "): " << msg << " - " << hex; } @@ -504,7 +507,7 @@ WasmHostFunctionsImpl::trace( } Expected -WasmHostFunctionsImpl::traceNum(std::string const& msg, int64_t data) +WasmHostFunctionsImpl::traceNum(std::string_view const& msg, int64_t data) { #ifdef DEBUG_OUTPUT auto j = ctx.journal.error(); diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.h b/src/xrpld/app/misc/WasmHostFuncImpl.h index 17bc5e7f994..58bf4c194a8 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.h +++ b/src/xrpld/app/misc/WasmHostFuncImpl.h @@ -130,10 +130,10 @@ class WasmHostFunctionsImpl : public HostFunctions getNFT(AccountID const& account, uint256 const& nftId) override; Expected - trace(std::string const& msg, Slice const& data, bool asHex) override; + trace(std::string_view const& msg, Slice const& data, bool asHex) override; Expected - traceNum(std::string const& msg, int64_t data) override; + traceNum(std::string_view const& msg, int64_t data) override; }; } // namespace ripple diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index b1954a557a3..59aa371cc28 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -26,7 +26,7 @@ namespace ripple { -using SFieldParam = std::reference_wrapper; +using SFieldCRef = std::reference_wrapper; static int32_t setData( @@ -85,8 +85,8 @@ getData( } template <> -Expected -getData( +Expected +getData( InstanceWrapper const* _rt, wasm_val_vec_t const* params, int32_t& i) @@ -110,7 +110,6 @@ getData( { auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; - i += 2; if (src < 0 || ssz <= 0) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -122,6 +121,7 @@ getData( return Unexpected(HF_ERR_POINTER_OUT_OF_BOUNDS); Slice data(mem.p + src, ssz); + i += 2; return data; } @@ -133,7 +133,6 @@ getData( int32_t& i) { auto const r = getData(rt, params, i); - i++; if (!r) { return Unexpected(r.error()); @@ -161,15 +160,14 @@ getData( } template <> -Expected -getData( +Expected +getData( InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t& i) { auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; - i += 2; if (src < 0 || ssz <= 0) return Unexpected(HF_ERR_INVALID_PARAMS); @@ -181,35 +179,26 @@ getData( return Unexpected(HF_ERR_POINTER_OUT_OF_BOUNDS); std::string data(mem.p + src, mem.p + src + ssz); - return data; + i += 2; + return std::string_view(data); } -template -std::nullptr_t -hfResult(wasm_val_vec_t* results, T value) +static std::nullptr_t +hfResult(wasm_val_vec_t* results, int32_t value) { results->data[0] = WASM_I32_VAL(value); results->num_elems = 1; return nullptr; } -template -std::optional -checkErrors(Args const&... args) -{ - std::optional err; - ((err = !args ? args.error() : err), ...); // Fold expression - return err; -} - template std::nullptr_t returnResult( InstanceWrapper const* rt, wasm_val_vec_t const* params, wasm_val_vec_t* results, - Expected result, - int32_t& index) + Expected const& result, + int32_t index) { if (!result) { @@ -353,7 +342,7 @@ getTxField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -371,7 +360,7 @@ getCurrentLedgerObjField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -397,7 +386,7 @@ getLedgerObjField_wrap( return hfResult(results, cache.error()); } - auto const fname = getData(rt, params, index); + auto const fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -486,7 +475,7 @@ getTxArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -505,7 +494,7 @@ getCurrentLedgerObjArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -531,7 +520,7 @@ getLedgerObjArrayLen_wrap( return hfResult(results, cache.error()); } - auto const fname = getData(rt, params, index); + auto const fname = getData(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -786,7 +775,7 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const msg = getData(rt, params, index); + auto const msg = getData(rt, params, index); if (!msg) { return hfResult(results, msg.error()); @@ -815,7 +804,7 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const msg = getData(rt, params, index); + auto const msg = getData(rt, params, index); if (!msg) { return hfResult(results, msg.error()); From a570b00ef10470c7c3ca125321b51e8ee6ff9e26 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 11 Jul 2025 01:07:36 +0530 Subject: [PATCH 19/25] enum class HostFunctionError --- src/test/app/TestHostFunctions.h | 797 ++++++++++++++++++ src/test/app/Wasm_test.cpp | 886 +-------------------- src/xrpld/app/misc/WasmHostFunc.h | 88 +- src/xrpld/app/misc/WasmHostFuncImpl.cpp | 102 +-- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 46 +- 5 files changed, 927 insertions(+), 992 deletions(-) create mode 100644 src/test/app/TestHostFunctions.h diff --git a/src/test/app/TestHostFunctions.h b/src/test/app/TestHostFunctions.h new file mode 100644 index 00000000000..680ec03896c --- /dev/null +++ b/src/test/app/TestHostFunctions.h @@ -0,0 +1,797 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include + +#include +#include +#include +#include + +#include + +namespace ripple { +namespace test { + +struct TestHostFunctions : public HostFunctions +{ + test::jtx::Env& env_; + AccountID accountID_; + Bytes data_; + int clock_drift_ = 0; + void const* rt_ = nullptr; + +public: + TestHostFunctions(test::jtx::Env& env, int cd = 0) + : env_(env), clock_drift_(cd) + { + auto opt = parseBase58("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"); + if (opt) + accountID_ = *opt; + std::string t = "10000"; + data_ = Bytes{t.begin(), t.end()}; + } + + virtual void + setRT(void const* rt) override + { + rt_ = rt; + } + + virtual void const* + getRT() const override + { + return rt_; + } + + beast::Journal + getJournal() override + { + return env_.journal; + } + + Expected + getLedgerSqn() override + { + return static_cast(env_.current()->seq()); + } + + Expected + getParentLedgerTime() override + { + return env_.current()->parentCloseTime().time_since_epoch().count() + + clock_drift_; + } + + Expected + getParentLedgerHash() override + { + return env_.current()->info().parentHash; + } + + virtual Expected + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override + { + return 1; + } + + Expected + getTxField(SField const& fname) override + { + if (fname == sfAccount) + return Bytes(accountID_.begin(), accountID_.end()); + else if (fname == sfFee) + { + int64_t x = 235; + uint8_t const* p = reinterpret_cast(&x); + return Bytes{p, p + sizeof(x)}; + } + else if (fname == sfSequence) + { + auto const x = getLedgerSqn(); + if (!x) + return Unexpected(x.error()); + std::uint32_t const data = x.value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; + } + return Bytes(); + } + + Expected + getCurrentLedgerObjField(SField const& fname) override + { + auto const& sn = fname.getName(); + if (sn == "Destination" || sn == "Account") + return Bytes(accountID_.begin(), accountID_.end()); + else if (sn == "Data") + return data_; + else if (sn == "FinishAfter") + { + auto t = + env_.current()->parentCloseTime().time_since_epoch().count(); + std::string s = std::to_string(t); + return Bytes{s.begin(), s.end()}; + } + + return Unexpected(HostFunctionError::INTERNAL); + } + + Expected + getLedgerObjField(int32_t cacheIdx, SField const& fname) override + { + // auto const& sn = fname.getName(); + if (fname == sfBalance) + { + int64_t x = 10'000; + uint8_t const* p = reinterpret_cast(&x); + return Bytes{p, p + sizeof(x)}; + } + return data_; + } + + Expected + getTxNestedField(Slice const& locator) override + { + uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, + 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, + 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, + 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; + return Bytes(&a[0], &a[sizeof(a)]); + } + + Expected + getCurrentLedgerObjNestedField(Slice const& locator) override + { + uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, + 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, + 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, + 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; + return Bytes(&a[0], &a[sizeof(a)]); + } + + Expected + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override + { + uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, + 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, + 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, + 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; + return Bytes(&a[0], &a[sizeof(a)]); + } + + Expected + getTxArrayLen(SField const& fname) override + { + return 32; + } + + Expected + getCurrentLedgerObjArrayLen(SField const& fname) override + { + return 32; + } + + Expected + getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override + { + return 32; + } + + Expected + getTxNestedArrayLen(Slice const& locator) override + { + return 32; + } + + Expected + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override + { + return 32; + } + + Expected + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override + { + return 32; + } + + Expected + updateData(Slice const& data) override + { + return 0; + } + + Expected + computeSha512HalfHash(Slice const& data) override + { + return env_.current()->info().parentHash; + } + + Expected + accountKeylet(AccountID const& account) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::account(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + credentialKeylet( + AccountID const& subject, + AccountID const& issuer, + Slice const& credentialType) override + { + if (!subject || !issuer || credentialType.empty() || + credentialType.size() > maxCredentialTypeLength) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::credential(subject, issuer, credentialType); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + escrowKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::escrow(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + oracleKeylet(AccountID const& account, std::uint32_t documentId) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::oracle(account, documentId); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + getNFT(AccountID const& account, uint256 const& nftId) override + { + if (!account || !nftId) + { + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + + std::string s = "https://ripple.com"; + return Bytes(s.begin(), s.end()); + } + + Expected + trace(std::string_view const& msg, Slice const& data, bool asHex) override + { +#ifdef DEBUG_OUTPUT + auto& j = std::cerr; +#else + auto j = getJournal().trace(); +#endif + j << "WASM TRACE: " << msg; + if (!asHex) + j << std::string_view( + reinterpret_cast(data.data()), data.size()); + else + { + std::string hex; + hex.reserve(data.size() * 2); + boost::algorithm::hex(data.begin(), data.end(), hex.begin()); + j << hex; + } + +#ifdef DEBUG_OUTPUT + j << std::endl; +#endif + + return msg.size() + data.size() * (asHex ? 2 : 1); + } + + Expected + traceNum(std::string_view const& msg, int64_t data) override + { +#ifdef DEBUG_OUTPUT + auto& j = std::cerr; +#else + auto j = getJournal().trace(); +#endif + j << "WASM TRACE NUM: " << msg << data; + +#ifdef DEBUG_OUTPUT + j << std::endl; +#endif + return msg.size() + sizeof(data); + } +}; + +struct TestHostFunctionsSink : public TestHostFunctions +{ + test::StreamSink sink_; + beast::Journal jlog_; + void const* rt_ = nullptr; + +public: + explicit TestHostFunctionsSink(test::jtx::Env& env, int cd = 0) + : TestHostFunctions(env, cd) + , sink_(beast::severities::kDebug) + , jlog_(sink_) + { + } + + test::StreamSink& + getSink() + { + return sink_; + } + + beast::Journal + getJournal() override + { + return jlog_; + } +}; + +struct PerfHostFunctions : public TestHostFunctions +{ + Keylet leKey; + static int constexpr MAX_CACHE = 256; + std::array, MAX_CACHE> cache; + std::shared_ptr tx_; + + void const* rt_ = nullptr; + +public: + PerfHostFunctions( + test::jtx::Env& env, + Keylet const& k, + std::shared_ptr&& tx) + : TestHostFunctions(env), leKey(k), tx_(std::move(tx)) + { + } + + virtual Expected + cacheLedgerObj(uint256 const&, int32_t cacheIdx) override + { + static int32_t intIdx = 0; + + if (cacheIdx < 0 || cacheIdx > MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cacheIdx) + { + for (cacheIdx = 0; cacheIdx < MAX_CACHE; ++cacheIdx) + if (!cache[cacheIdx]) + break; + if (cacheIdx >= MAX_CACHE) + cacheIdx = intIdx++ % MAX_CACHE; + } + else + --cacheIdx; + + if (cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOTS_FULL); + + cache[cacheIdx] = env_.le(leKey); + if (!cache[cacheIdx]) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + return cacheIdx + 1; + } + + static Bytes + getAnyFieldData(STBase const& obj) + { + // auto const& fname = obj.getFName(); + auto const stype = obj.getSType(); + switch (stype) + { + case STI_UNKNOWN: + case STI_NOTPRESENT: + return {}; + break; + case STI_ACCOUNT: { + auto const& super(static_cast(obj)); + auto const& data = super.value(); + return {data.begin(), data.end()}; + } + break; + case STI_AMOUNT: { + auto const& super(static_cast(obj)); + int64_t const data = super.xrp().drops(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return {b, e}; + } + break; + case STI_VL: { + auto const& super(static_cast(obj)); + auto const& data = super.value(); + return {data.begin(), data.end()}; + } + break; + case STI_UINT256: { + auto const& super(static_cast const&>(obj)); + auto const& data = super.value(); + return {data.begin(), data.end()}; + } + break; + case STI_UINT32: { + auto const& super( + static_cast const&>(obj)); + std::uint32_t const data = super.value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return {b, e}; + } + break; + default: + break; + } + + Serializer msg; + obj.add(msg); + + return msg.getData(); + } + + Expected + getTxField(SField const& fname) override + { + auto const* field = tx_->peekAtPField(fname); + if (!field) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + if ((STI_OBJECT == field->getSType()) || + (STI_ARRAY == field->getSType())) + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + + return getAnyFieldData(*field); + } + + Expected + getCurrentLedgerObjField(SField const& fname) override + { + auto const sle = env_.le(leKey); + if (!sle) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + + auto const* field = sle->peekAtPField(fname); + if (!field) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + if ((STI_OBJECT == field->getSType()) || + (STI_ARRAY == field->getSType())) + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + + return getAnyFieldData(*field); + } + + Expected + getLedgerObjField(int32_t cacheIdx, SField const& fname) override + { + --cacheIdx; + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cache[cacheIdx]) + { + // return Unexpected(HostFunctionError::INVALID_SLOT); + cache[cacheIdx] = env_.le(leKey); + } + + auto const* field = cache[cacheIdx]->peekAtPField(fname); + if (!field) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + if ((STI_OBJECT == field->getSType()) || + (STI_ARRAY == field->getSType())) + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + + return getAnyFieldData(*field); + } + + static Expected + locateField(STObject const& obj, Slice const& loc) + { + if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + + int32_t const* l = reinterpret_cast(loc.data()); + int32_t const sz = loc.size() / 4; + STBase const* field = nullptr; + auto const& m = SField::getKnownCodeToField(); + + { + int32_t const c = l[0]; + auto const it = m.find(c); + if (it == m.end()) + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + auto const& fname(*it->second); + + field = obj.peekAtPField(fname); + if (!field || (STI_NOTPRESENT == field->getSType())) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + + for (int i = 1; i < sz; ++i) + { + int32_t const c = l[i]; + + if (STI_ARRAY == field->getSType()) + { + auto const* arr = static_cast(field); + if (c >= arr->size()) + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + field = &(arr->operator[](c)); + } + else if (STI_OBJECT == field->getSType()) + { + auto const* o = static_cast(field); + + auto const it = m.find(c); + if (it == m.end()) + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + auto const& fname(*it->second); + + field = o->peekAtPField(fname); + } + else // simple field must be the last one + { + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + } + + if (!field || (STI_NOTPRESENT == field->getSType())) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + + return field; + } + + Expected + getTxNestedField(Slice const& locator) override + { + // std::cout << tx_->getJson(JsonOptions::none).toStyledString() << + // std::endl; + auto const r = locateField(*tx_, locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + if ((STI_OBJECT == field->getSType()) || + (STI_ARRAY == field->getSType())) + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + + return getAnyFieldData(*field); + } + + Expected + getCurrentLedgerObjNestedField(Slice const& locator) override + { + auto const sle = env_.le(leKey); + if (!sle) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + + auto const r = locateField(*sle, locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + if ((STI_OBJECT == field->getSType()) || + (STI_ARRAY == field->getSType())) + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + + return getAnyFieldData(*field); + } + + Expected + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override + { + --cacheIdx; + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cache[cacheIdx]) + { + // return Unexpected(HostFunctionError::INVALID_SLOT); + cache[cacheIdx] = env_.le(leKey); + } + + auto const r = locateField(*cache[cacheIdx], locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + if ((STI_OBJECT == field->getSType()) || + (STI_ARRAY == field->getSType())) + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + + return getAnyFieldData(*field); + } + + Expected + getTxArrayLen(SField const& fname) override + { + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const* field = tx_->peekAtPField(fname); + if (!field) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getCurrentLedgerObjArrayLen(SField const& fname) override + { + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const sle = env_.le(leKey); + if (!sle) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + + auto const* field = sle->peekAtPField(fname); + if (!field) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override + { + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cache[cacheIdx]) + { + // return Unexpected(HostFunctionError::INVALID_SLOT); + cache[cacheIdx] = env_.le(leKey); + } + + auto const* field = cache[cacheIdx]->peekAtPField(fname); + if (!field) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getTxNestedArrayLen(Slice const& locator) override + { + auto const r = locateField(*tx_, locator); + if (!r) + return Unexpected(r.error()); + auto const* field = r.value(); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override + { + auto const sle = env_.le(leKey); + if (!sle) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + auto const r = locateField(*sle, locator); + if (!r) + return Unexpected(r.error()); + auto const* field = r.value(); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override + { + --cacheIdx; + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cache[cacheIdx]) + { + // return Unexpected(HostFunctionError::INVALID_SLOT); + cache[cacheIdx] = env_.le(leKey); + } + + auto const r = locateField(*cache[cacheIdx], locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + updateData(Slice const& data) override + { + ripple::detail::ApplyViewBase v( + env_.app().openLedger().current().get(), tapNONE); + + auto sle = v.peek(leKey); + if (!sle) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + + sle->setFieldVL(sfData, data); + v.update(sle); + + return data.size(); + } + + Expected + computeSha512HalfHash(Slice const& data) override + { + auto const hash = sha512Half(data); + return hash; + } + + Expected + getNFT(AccountID const& account, uint256 const& nftId) override + { + if (!account || !nftId) + { + getJournal().trace() << "WAMR getNFT: Invalid account or NFT ID"; + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + + auto obj = nft::findToken(*env_.current(), account, nftId); + if (!obj) + { + getJournal().trace() << "WAMR getNFT: NFT not found"; + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + + auto ouri = obj->at(~sfURI); + if (!ouri) + return Bytes(); + + Slice const s = ouri->value(); + return Bytes(s.begin(), s.end()); + } +}; + +} // namespace test +} // namespace ripple diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 315a45e4616..c7071cc3595 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ /* This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. + Copyright (c) 2025 Ripple Labs Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,7 @@ */ //============================================================================== +#include #include #include @@ -73,887 +74,6 @@ getLedgerSqn_wrap(void* env, wasm_val_vec_t const*, wasm_val_vec_t* results) return nullptr; } -struct TestHostFunctions : public HostFunctions -{ - test::jtx::Env& env_; - AccountID accountID_; - Bytes data_; - int clock_drift_ = 0; - void const* rt_ = nullptr; - -public: - TestHostFunctions(test::jtx::Env& env, int cd = 0) - : env_(env), clock_drift_(cd) - { - auto opt = parseBase58("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"); - if (opt) - accountID_ = *opt; - std::string t = "10000"; - data_ = Bytes{t.begin(), t.end()}; - } - - virtual void - setRT(void const* rt) override - { - rt_ = rt; - } - - virtual void const* - getRT() const override - { - return rt_; - } - - beast::Journal - getJournal() override - { - return env_.journal; - } - - Expected - getLedgerSqn() override - { - return static_cast(env_.current()->seq()); - } - - Expected - getParentLedgerTime() override - { - return env_.current()->parentCloseTime().time_since_epoch().count() + - clock_drift_; - } - - Expected - getParentLedgerHash() override - { - return env_.current()->info().parentHash; - } - - virtual Expected - cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override - { - return 1; - } - - Expected - getTxField(SField const& fname) override - { - if (fname == sfAccount) - return Bytes(accountID_.begin(), accountID_.end()); - else if (fname == sfFee) - { - int64_t x = 235; - uint8_t const* p = reinterpret_cast(&x); - return Bytes{p, p + sizeof(x)}; - } - else if (fname == sfSequence) - { - auto const x = getLedgerSqn(); - if (!x) - return Unexpected(x.error()); - std::uint32_t const data = x.value(); - auto const* b = reinterpret_cast(&data); - auto const* e = reinterpret_cast(&data + 1); - return Bytes{b, e}; - } - return Bytes(); - } - - Expected - getCurrentLedgerObjField(SField const& fname) override - { - auto const& sn = fname.getName(); - if (sn == "Destination" || sn == "Account") - return Bytes(accountID_.begin(), accountID_.end()); - else if (sn == "Data") - return data_; - else if (sn == "FinishAfter") - { - auto t = - env_.current()->parentCloseTime().time_since_epoch().count(); - std::string s = std::to_string(t); - return Bytes{s.begin(), s.end()}; - } - - return Unexpected(HF_ERR_INTERNAL); - } - - Expected - getLedgerObjField(int32_t cacheIdx, SField const& fname) override - { - // auto const& sn = fname.getName(); - if (fname == sfBalance) - { - int64_t x = 10'000; - uint8_t const* p = reinterpret_cast(&x); - return Bytes{p, p + sizeof(x)}; - } - return data_; - } - - Expected - getTxNestedField(Slice const& locator) override - { - uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, - 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, - 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, - 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; - return Bytes(&a[0], &a[sizeof(a)]); - } - - Expected - getCurrentLedgerObjNestedField(Slice const& locator) override - { - uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, - 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, - 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, - 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; - return Bytes(&a[0], &a[sizeof(a)]); - } - - Expected - getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override - { - uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, - 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, - 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, - 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; - return Bytes(&a[0], &a[sizeof(a)]); - } - - Expected - getTxArrayLen(SField const& fname) override - { - return 32; - } - - Expected - getCurrentLedgerObjArrayLen(SField const& fname) override - { - return 32; - } - - Expected - getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override - { - return 32; - } - - Expected - getTxNestedArrayLen(Slice const& locator) override - { - return 32; - } - - Expected - getCurrentLedgerObjNestedArrayLen(Slice const& locator) override - { - return 32; - } - - Expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override - { - return 32; - } - - Expected - updateData(Slice const& data) override - { - return 0; - } - - Expected - computeSha512HalfHash(Slice const& data) override - { - return env_.current()->info().parentHash; - } - - Expected - accountKeylet(AccountID const& account) override - { - if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::account(account); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - credentialKeylet( - AccountID const& subject, - AccountID const& issuer, - Slice const& credentialType) override - { - if (!subject || !issuer || credentialType.empty()) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::credential(subject, issuer, credentialType); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - escrowKeylet(AccountID const& account, std::uint32_t seq) override - { - if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::escrow(account, seq); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - oracleKeylet(AccountID const& account, std::uint32_t documentId) override - { - if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::oracle(account, documentId); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - getNFT(AccountID const& account, uint256 const& nftId) override - { - if (!account || !nftId) - { - return Unexpected(HF_ERR_INVALID_PARAMS); - } - - std::string s = "https://ripple.com"; - return Bytes(s.begin(), s.end()); - } - - Expected - trace(std::string_view const& msg, Slice const& data, bool asHex) override - { -#ifdef DEBUG_OUTPUT - auto& j = std::cerr; -#else - auto j = getJournal().trace(); -#endif - j << "WASM TRACE: " << msg; - if (!asHex) - j << std::string_view( - reinterpret_cast(data.data()), data.size()); - else - { - auto const hex = - boost::algorithm::hex(std::string(data.begin(), data.end())); - j << hex; - } - -#ifdef DEBUG_OUTPUT - j << std::endl; -#endif - - return msg.size() + data.size() * (asHex ? 2 : 1); - } - - Expected - traceNum(std::string_view const& msg, int64_t data) override - { -#ifdef DEBUG_OUTPUT - auto& j = std::cerr; -#else - auto j = getJournal().trace(); -#endif - j << "WASM TRACE NUM: " << msg << data; - -#ifdef DEBUG_OUTPUT - j << std::endl; -#endif - return msg.size() + sizeof(data); - } -}; - -struct TestHostFunctionsSink : public TestHostFunctions -{ - test::StreamSink sink_; - beast::Journal jlog_; - void const* rt_ = nullptr; - -public: - explicit TestHostFunctionsSink(test::jtx::Env& env, int cd = 0) - : TestHostFunctions(env, cd) - , sink_(beast::severities::kDebug) - , jlog_(sink_) - { - } - - test::StreamSink& - getSink() - { - return sink_; - } - - beast::Journal - getJournal() override - { - return jlog_; - } -}; - -struct PerfHostFunctions : public HostFunctions -{ - test::jtx::Env& env_; - - Keylet leKey; - static int constexpr MAX_CACHE = 256; - std::array, MAX_CACHE> cache; - std::shared_ptr tx_; - - void const* rt_ = nullptr; - -public: - PerfHostFunctions( - test::jtx::Env& env, - Keylet const& k, - std::shared_ptr&& tx) - : env_(env), leKey(k), tx_(std::move(tx)) - { - } - - virtual void - setRT(void const* rt) override - { - rt_ = rt; - } - - virtual void const* - getRT() const override - { - return rt_; - } - - beast::Journal - getJournal() override - { - return env_.journal; - } - - Expected - getLedgerSqn() override - { - return static_cast(env_.current()->seq()); - } - - Expected - getParentLedgerTime() override - { - return env_.current()->parentCloseTime().time_since_epoch().count(); - } - - Expected - getParentLedgerHash() override - { - return env_.current()->info().parentHash; - } - - virtual Expected - cacheLedgerObj(uint256 const&, int32_t cacheIdx) override - { - static int32_t intIdx = 0; - - if (cacheIdx < 0 || cacheIdx > MAX_CACHE) - return HF_ERR_SLOT_OUT_RANGE; - - if (!cacheIdx) - { - for (cacheIdx = 0; cacheIdx < MAX_CACHE; ++cacheIdx) - if (!cache[cacheIdx]) - break; - if (cacheIdx >= MAX_CACHE) - cacheIdx = intIdx++ % MAX_CACHE; - } - else - --cacheIdx; - - if (cacheIdx >= MAX_CACHE) - return HF_ERR_SLOTS_FULL; - - cache[cacheIdx] = env_.le(leKey); - return cache[cacheIdx] ? cacheIdx + 1 : HF_ERR_LEDGER_OBJ_NOT_FOUND; - } - - static Bytes - getAnyFieldData(STBase const& obj) - { - // auto const& fname = obj.getFName(); - auto const stype = obj.getSType(); - switch (stype) - { - case STI_UNKNOWN: - case STI_NOTPRESENT: - return {}; - break; - case STI_ACCOUNT: { - auto const& super(static_cast(obj)); - auto const& data = super.value(); - return {data.begin(), data.end()}; - } - break; - case STI_AMOUNT: { - auto const& super(static_cast(obj)); - int64_t const data = super.xrp().drops(); - auto const* b = reinterpret_cast(&data); - auto const* e = reinterpret_cast(&data + 1); - return {b, e}; - } - break; - case STI_VL: { - auto const& super(static_cast(obj)); - auto const& data = super.value(); - return {data.begin(), data.end()}; - } - break; - case STI_UINT256: { - auto const& super(static_cast const&>(obj)); - auto const& data = super.value(); - return {data.begin(), data.end()}; - } - break; - case STI_UINT32: { - auto const& super( - static_cast const&>(obj)); - std::uint32_t const data = super.value(); - auto const* b = reinterpret_cast(&data); - auto const* e = reinterpret_cast(&data + 1); - return {b, e}; - } - break; - default: - break; - } - - Serializer msg; - obj.add(msg); - - return msg.getData(); - } - - Expected - getTxField(SField const& fname) override - { - auto const* field = tx_->peekAtPField(fname); - if (!field) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); - if ((STI_OBJECT == field->getSType()) || - (STI_ARRAY == field->getSType())) - return Unexpected(HF_ERR_NOT_LEAF_FIELD); - - return getAnyFieldData(*field); - } - - Expected - getCurrentLedgerObjField(SField const& fname) override - { - auto const sle = env_.le(leKey); - if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); - - auto const* field = sle->peekAtPField(fname); - if (!field) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); - if ((STI_OBJECT == field->getSType()) || - (STI_ARRAY == field->getSType())) - return Unexpected(HF_ERR_NOT_LEAF_FIELD); - - return getAnyFieldData(*field); - } - - Expected - getLedgerObjField(int32_t cacheIdx, SField const& fname) override - { - --cacheIdx; - if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); - - if (!cache[cacheIdx]) - { - // return Unexpected(HF_ERR_INVALID_SLOT); - cache[cacheIdx] = env_.le(leKey); - } - - auto const* field = cache[cacheIdx]->peekAtPField(fname); - if (!field) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); - if ((STI_OBJECT == field->getSType()) || - (STI_ARRAY == field->getSType())) - return Unexpected(HF_ERR_NOT_LEAF_FIELD); - - return getAnyFieldData(*field); - } - - static Expected - locateField(STObject const& obj, Slice const& loc) - { - if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 - return Unexpected(HF_ERR_LOCATOR_MALFORMED); - - int32_t const* l = reinterpret_cast(loc.data()); - int32_t const sz = loc.size() / 4; - STBase const* field = nullptr; - auto const& m = SField::getKnownCodeToField(); - - { - int32_t const c = l[0]; - auto const it = m.find(c); - if (it == m.end()) - return Unexpected(HF_ERR_LOCATOR_MALFORMED); - auto const& fname(*it->second); - - field = obj.peekAtPField(fname); - if (!field || (STI_NOTPRESENT == field->getSType())) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); - } - - for (int i = 1; i < sz; ++i) - { - int32_t const c = l[i]; - - if (STI_ARRAY == field->getSType()) - { - auto const* arr = static_cast(field); - if (c >= arr->size()) - return Unexpected(HF_ERR_LOCATOR_MALFORMED); - field = &(arr->operator[](c)); - } - else if (STI_OBJECT == field->getSType()) - { - auto const* o = static_cast(field); - - auto const it = m.find(c); - if (it == m.end()) - return Unexpected(HF_ERR_LOCATOR_MALFORMED); - auto const& fname(*it->second); - - field = o->peekAtPField(fname); - } - else // simple field must be the last one - { - return Unexpected(HF_ERR_LOCATOR_MALFORMED); - } - - if (!field || (STI_NOTPRESENT == field->getSType())) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); - } - - return field; - } - - Expected - getTxNestedField(Slice const& locator) override - { - // std::cout << tx_->getJson(JsonOptions::none).toStyledString() << - // std::endl; - auto const r = locateField(*tx_, locator); - if (!r) - return Unexpected(r.error()); - - auto const* field = r.value(); - if ((STI_OBJECT == field->getSType()) || - (STI_ARRAY == field->getSType())) - return Unexpected(HF_ERR_NOT_LEAF_FIELD); - - return getAnyFieldData(*field); - } - - Expected - getCurrentLedgerObjNestedField(Slice const& locator) override - { - auto const sle = env_.le(leKey); - if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); - - auto const r = locateField(*sle, locator); - if (!r) - return Unexpected(r.error()); - - auto const* field = r.value(); - if ((STI_OBJECT == field->getSType()) || - (STI_ARRAY == field->getSType())) - return Unexpected(HF_ERR_NOT_LEAF_FIELD); - - return getAnyFieldData(*field); - } - - Expected - getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override - { - --cacheIdx; - if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); - - if (!cache[cacheIdx]) - { - // return Unexpected(HF_ERR_INVALID_SLOT); - cache[cacheIdx] = env_.le(leKey); - } - - auto const r = locateField(*cache[cacheIdx], locator); - if (!r) - return Unexpected(r.error()); - - auto const* field = r.value(); - if ((STI_OBJECT == field->getSType()) || - (STI_ARRAY == field->getSType())) - return Unexpected(HF_ERR_NOT_LEAF_FIELD); - - return getAnyFieldData(*field); - } - - Expected - getTxArrayLen(SField const& fname) override - { - if (fname.fieldType != STI_ARRAY) - return HF_ERR_NO_ARRAY; - - auto const* field = tx_->peekAtPField(fname); - if (!field) - return HF_ERR_FIELD_NOT_FOUND; - - if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; - int32_t const sz = static_cast(field)->size(); - - return sz; - } - - Expected - getCurrentLedgerObjArrayLen(SField const& fname) override - { - if (fname.fieldType != STI_ARRAY) - return HF_ERR_NO_ARRAY; - - auto const sle = env_.le(leKey); - if (!sle) - return HF_ERR_LEDGER_OBJ_NOT_FOUND; - - auto const* field = sle->peekAtPField(fname); - if (!field) - return HF_ERR_FIELD_NOT_FOUND; - - if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; - int32_t const sz = static_cast(field)->size(); - - return sz; - } - - Expected - getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override - { - if (fname.fieldType != STI_ARRAY) - return HF_ERR_NO_ARRAY; - - if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return HF_ERR_SLOT_OUT_RANGE; - - if (!cache[cacheIdx]) - { - // return Unexpected(HF_ERR_INVALID_SLOT); - cache[cacheIdx] = env_.le(leKey); - } - - auto const* field = cache[cacheIdx]->peekAtPField(fname); - if (!field) - return HF_ERR_FIELD_NOT_FOUND; - - if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; - int32_t const sz = static_cast(field)->size(); - - return sz; - } - - Expected - getTxNestedArrayLen(Slice const& locator) override - { - auto const r = locateField(*tx_, locator); - if (!r) - return r.error(); - auto const* field = r.value(); - - if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; - int32_t const sz = static_cast(field)->size(); - - return sz; - } - - Expected - getCurrentLedgerObjNestedArrayLen(Slice const& locator) override - { - auto const sle = env_.le(leKey); - if (!sle) - return HF_ERR_LEDGER_OBJ_NOT_FOUND; - auto const r = locateField(*sle, locator); - if (!r) - return r.error(); - auto const* field = r.value(); - - if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; - int32_t const sz = static_cast(field)->size(); - - return sz; - } - - Expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override - { - --cacheIdx; - if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return HF_ERR_SLOT_OUT_RANGE; - - if (!cache[cacheIdx]) - { - // return Unexpected(HF_ERR_INVALID_SLOT); - cache[cacheIdx] = env_.le(leKey); - } - - auto const r = locateField(*cache[cacheIdx], locator); - if (!r) - return r.error(); - - auto const* field = r.value(); - - if (field->getSType() != STI_ARRAY) - return HF_ERR_NO_ARRAY; - int32_t const sz = static_cast(field)->size(); - - return sz; - } - - Expected - updateData(Slice const& data) override - { - ripple::detail::ApplyViewBase v( - env_.app().openLedger().current().get(), tapNONE); - - auto sle = v.peek(leKey); - if (!sle) - return HF_ERR_LEDGER_OBJ_NOT_FOUND; - - sle->setFieldVL(sfData, data); - v.update(sle); - - return data.size(); - } - - Expected - computeSha512HalfHash(Slice const& data) override - { - auto const hash = sha512Half(data); - return hash; - } - - Expected - accountKeylet(AccountID const& account) override - { - if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::account(account); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - credentialKeylet( - AccountID const& subject, - AccountID const& issuer, - Slice const& credentialType) override - { - if (!subject || !issuer || credentialType.empty() || - credentialType.size() > maxCredentialTypeLength) - return Unexpected(HF_ERR_INVALID_PARAMS); - - auto const keylet = keylet::credential(subject, issuer, credentialType); - - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - escrowKeylet(AccountID const& account, std::uint32_t seq) override - { - if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::escrow(account, seq); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - oracleKeylet(AccountID const& account, std::uint32_t documentId) override - { - if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); - auto const keylet = keylet::oracle(account, documentId); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - Expected - getNFT(AccountID const& account, uint256 const& nftId) override - { - if (!account || !nftId) - { - getJournal().trace() << "WAMR getNFT: Invalid account or NFT ID"; - return Unexpected(HF_ERR_INVALID_PARAMS); - } - - auto obj = nft::findToken(*env_.current(), account, nftId); - if (!obj) - { - getJournal().trace() << "WAMR getNFT: NFT not found"; - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); - } - - auto ouri = obj->at(~sfURI); - if (!ouri) - return Bytes(); - - Slice const s = ouri->value(); - return Bytes(s.begin(), s.end()); - } - - Expected - trace(std::string_view const& msg, Slice const& data, bool asHex) override - { -#ifdef DEBUG_OUTPUT - auto& j = std::cerr; -#else - auto j = getJournal().error(); -#endif - if (!asHex) - j << msg - << std::string_view( - reinterpret_cast(data.data()), data.size()); - else - { - auto const hex = - boost::algorithm::hex(std::string(data.begin(), data.end())); - j << msg << hex; - } - -#ifdef DEBUG_OUTPUT - j << std::endl; -#endif - - return msg.size() + data.size() * (asHex ? 2 : 1); - } - - Expected - traceNum(std::string_view const& msg, int64_t data) override - { -#ifdef DEBUG_OUTPUT - auto& j = std::cerr; -#else - auto j = getJournal().error(); -#endif - j << msg << data; - -#ifdef DEBUG_OUTPUT - j << std::endl; -#endif - return msg.size() + sizeof(data); - } -}; - struct Wasm_test : public beast::unit_test::suite { void @@ -1305,7 +425,7 @@ struct Wasm_test : public beast::unit_test::suite Expected getTxField(SField const& fname) override { - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); } }; BadTestHostFunctions nfs(env); diff --git a/src/xrpld/app/misc/WasmHostFunc.h b/src/xrpld/app/misc/WasmHostFunc.h index c9da537ddb5..b507d6fe696 100644 --- a/src/xrpld/app/misc/WasmHostFunc.h +++ b/src/xrpld/app/misc/WasmHostFunc.h @@ -29,25 +29,25 @@ namespace ripple { -enum HostFunctionError : int32_t { - HF_ERR_INTERNAL = -1, - HF_ERR_FIELD_NOT_FOUND = -2, - HF_ERR_BUFFER_TOO_SMALL = -3, - HF_ERR_NO_ARRAY = -4, - HF_ERR_NOT_LEAF_FIELD = -5, - HF_ERR_LOCATOR_MALFORMED = -6, - HF_ERR_SLOT_OUT_RANGE = -7, - HF_ERR_SLOTS_FULL = -8, - HF_ERR_EMPTY_SLOT = -9, - HF_ERR_LEDGER_OBJ_NOT_FOUND = -10, - HF_ERR_DECODING = -11, - HF_ERR_DATA_FIELD_TOO_LARGE = -12, - HF_ERR_POINTER_OUT_OF_BOUNDS = -13, - HF_ERR_NO_MEM_EXPORTED = -14, - HF_ERR_INVALID_PARAMS = -15, - HF_ERR_INVALID_ACCOUNT = -16, - HF_ERR_INVALID_FIELD = -17, - HF_ERR_INDEX_OUT_OF_BOUNDS = -18, +enum class HostFunctionError : int32_t { + INTERNAL = -1, + FIELD_NOT_FOUND = -2, + BUFFER_TOO_SMALL = -3, + NO_ARRAY = -4, + NOT_LEAF_FIELD = -5, + LOCATOR_MALFORMED = -6, + SLOT_OUT_RANGE = -7, + SLOTS_FULL = -8, + EMPTY_SLOT = -9, + LEDGER_OBJ_NOT_FOUND = -10, + DECODING = -11, + DATA_FIELD_TOO_LARGE = -12, + POINTER_OUT_OF_BOUNDS = -13, + NO_MEM_EXPORTED = -14, + INVALID_PARAMS = -15, + INVALID_ACCOUNT = -16, + INVALID_FIELD = -17, + INDEX_OUT_OF_BOUNDS = -18, }; struct HostFunctions @@ -72,115 +72,115 @@ struct HostFunctions virtual Expected getLedgerSqn() { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getParentLedgerTime() { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getParentLedgerHash() { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getTxField(SField const& fname) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getCurrentLedgerObjField(SField const& fname) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getLedgerObjField(int32_t cacheIdx, SField const& fname) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getTxNestedField(Slice const& locator) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getCurrentLedgerObjNestedField(Slice const& locator) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getTxArrayLen(SField const& fname) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getCurrentLedgerObjArrayLen(SField const& fname) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getTxNestedArrayLen(Slice const& locator) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getCurrentLedgerObjNestedArrayLen(Slice const& locator) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected updateData(Slice const& data) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected computeSha512HalfHash(Slice const& data) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected accountKeylet(AccountID const& account) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected @@ -189,37 +189,37 @@ struct HostFunctions AccountID const& issuer, Slice const& credentialType) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected escrowKeylet(AccountID const& account, std::uint32_t seq) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected oracleKeylet(AccountID const& account, std::uint32_t docId) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected getNFT(AccountID const& account, uint256 const& nftId) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected trace(std::string_view const& msg, Slice const& data, bool asHex) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual Expected traceNum(std::string_view const& msg, int64_t data) { - return Unexpected(HF_ERR_INTERNAL); + return Unexpected(HostFunctionError::INTERNAL); } virtual ~HostFunctions() = default; diff --git a/src/xrpld/app/misc/WasmHostFuncImpl.cpp b/src/xrpld/app/misc/WasmHostFuncImpl.cpp index 7c9027ea142..6c7ae43d91e 100644 --- a/src/xrpld/app/misc/WasmHostFuncImpl.cpp +++ b/src/xrpld/app/misc/WasmHostFuncImpl.cpp @@ -53,7 +53,7 @@ WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) { auto const& keylet = keylet::unchecked(objId); if (cacheIdx < 0 || cacheIdx > MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); if (!cacheIdx) { @@ -65,11 +65,11 @@ WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) --cacheIdx; if (cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOTS_FULL); + return Unexpected(HostFunctionError::SLOTS_FULL); cache[cacheIdx] = ctx.view().read(keylet); if (!cache[cacheIdx]) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); return cacheIdx + 1; } @@ -78,18 +78,18 @@ getAnyFieldData(STBase const* obj) { // auto const& fname = obj.getFName(); if (!obj) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); auto const stype = obj->getSType(); switch (stype) { case STI_UNKNOWN: case STI_NOTPRESENT: - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); break; case STI_OBJECT: case STI_ARRAY: - return Unexpected(HF_ERR_NOT_LEAF_FIELD); + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); break; case STI_ACCOUNT: { auto const& account(static_cast(obj)); @@ -146,7 +146,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname) { auto const sle = ctx.view().read(leKey); if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); return getAnyFieldData(sle->peekAtPField(fname)); } @@ -155,9 +155,9 @@ WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname) { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); if (!cache[cacheIdx]) - return Unexpected(HF_ERR_EMPTY_SLOT); + return Unexpected(HostFunctionError::EMPTY_SLOT); return getAnyFieldData(cache[cacheIdx]->peekAtPField(fname)); } @@ -172,7 +172,7 @@ static Expected locateField(STObject const& obj, Slice const& loc) { if (loc.empty() || (loc.size() & 3)) // must be multiple of 4 - return Unexpected(HF_ERR_LOCATOR_MALFORMED); + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); int32_t const* l = reinterpret_cast(loc.data()); int32_t const sz = loc.size() / 4; @@ -183,12 +183,12 @@ locateField(STObject const& obj, Slice const& loc) int32_t const c = l[0]; auto const it = m.find(c); if (it == m.end()) - return Unexpected(HF_ERR_INVALID_FIELD); + return Unexpected(HostFunctionError::INVALID_FIELD); auto const& fname(*it->second); field = obj.peekAtPField(fname); if (noField(field)) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); } for (int i = 1; i < sz; ++i) @@ -199,7 +199,7 @@ locateField(STObject const& obj, Slice const& loc) { auto const* arr = static_cast(field); if (c >= arr->size()) - return Unexpected(HF_ERR_INDEX_OUT_OF_BOUNDS); + return Unexpected(HostFunctionError::INDEX_OUT_OF_BOUNDS); field = &(arr->operator[](c)); } else if (STI_OBJECT == field->getSType()) @@ -208,18 +208,18 @@ locateField(STObject const& obj, Slice const& loc) auto const it = m.find(c); if (it == m.end()) - return Unexpected(HF_ERR_INVALID_FIELD); + return Unexpected(HostFunctionError::INVALID_FIELD); auto const& fname(*it->second); field = o->peekAtPField(fname); } else // simple field must be the last one { - return Unexpected(HF_ERR_LOCATOR_MALFORMED); + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); } if (noField(field)) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); } return field; @@ -240,7 +240,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); auto const r = locateField(*sle, locator); if (!r) @@ -256,10 +256,10 @@ WasmHostFunctionsImpl::getLedgerObjNestedField( { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); if (!cache[cacheIdx]) - return Unexpected(HF_ERR_EMPTY_SLOT); + return Unexpected(HostFunctionError::EMPTY_SLOT); auto const r = locateField(*cache[cacheIdx], locator); if (!r) @@ -272,14 +272,14 @@ Expected WasmHostFunctionsImpl::getTxArrayLen(SField const& fname) { if (fname.fieldType != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); auto const* field = ctx.tx.peekAtPField(fname); if (noField(field)) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); if (field->getSType() != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -289,18 +289,18 @@ Expected WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname) { if (fname.fieldType != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); auto const sle = ctx.view().read(leKey); if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); auto const* field = sle->peekAtPField(fname); if (noField(field)) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); if (field->getSType() != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -312,20 +312,20 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen( SField const& fname) { if (fname.fieldType != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); if (!cache[cacheIdx]) - return Unexpected(HF_ERR_EMPTY_SLOT); + return Unexpected(HostFunctionError::EMPTY_SLOT); auto const* field = cache[cacheIdx]->peekAtPField(fname); if (noField(field)) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); if (field->getSType() != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -336,11 +336,11 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) { auto const r = locateField(ctx.tx, locator); if (!r) - return r.error(); + return Unexpected(r.error()); auto const* field = r.value(); if (field->getSType() != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -351,14 +351,14 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) { auto const sle = ctx.view().read(leKey); if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); auto const r = locateField(*sle, locator); if (!r) - return r.error(); + return Unexpected(r.error()); auto const* field = r.value(); if (field->getSType() != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -371,18 +371,18 @@ WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( { --cacheIdx; if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) - return Unexpected(HF_ERR_SLOT_OUT_RANGE); + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); if (!cache[cacheIdx]) - return Unexpected(HF_ERR_EMPTY_SLOT); + return Unexpected(HostFunctionError::EMPTY_SLOT); auto const r = locateField(*cache[cacheIdx], locator); if (!r) - return r.error(); + return Unexpected(r.error()); auto const* field = r.value(); if (field->getSType() != STI_ARRAY) - return Unexpected(HF_ERR_NO_ARRAY); + return Unexpected(HostFunctionError::NO_ARRAY); int32_t const sz = static_cast(field)->size(); return sz; @@ -393,11 +393,11 @@ WasmHostFunctionsImpl::updateData(Slice const& data) { if (data.size() > maxWasmDataLength) { - return Unexpected(HF_ERR_DATA_FIELD_TOO_LARGE); + return Unexpected(HostFunctionError::DATA_FIELD_TOO_LARGE); } auto sle = ctx.view().peek(leKey); if (!sle) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); sle->setFieldVL(sfData, data); ctx.view().update(sle); return 0; @@ -414,7 +414,7 @@ Expected WasmHostFunctionsImpl::accountKeylet(AccountID const& account) { if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); + return Unexpected(HostFunctionError::INVALID_ACCOUNT); auto const keylet = keylet::account(account); return Bytes{keylet.key.begin(), keylet.key.end()}; } @@ -426,11 +426,11 @@ WasmHostFunctionsImpl::credentialKeylet( Slice const& credentialType) { if (!subject || !issuer) - return Unexpected(HF_ERR_INVALID_ACCOUNT); + return Unexpected(HostFunctionError::INVALID_ACCOUNT); if (credentialType.empty() || credentialType.size() > maxCredentialTypeLength) - return Unexpected(HF_ERR_INVALID_PARAMS); + return Unexpected(HostFunctionError::INVALID_PARAMS); auto const keylet = keylet::credential(subject, issuer, credentialType); @@ -441,7 +441,7 @@ Expected WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq) { if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); + return Unexpected(HostFunctionError::INVALID_ACCOUNT); auto const keylet = keylet::escrow(account, seq); return Bytes{keylet.key.begin(), keylet.key.end()}; } @@ -452,7 +452,7 @@ WasmHostFunctionsImpl::oracleKeylet( std::uint32_t documentId) { if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); + return Unexpected(HostFunctionError::INVALID_ACCOUNT); auto const keylet = keylet::oracle(account, documentId); return Bytes{keylet.key.begin(), keylet.key.end()}; } @@ -461,18 +461,18 @@ Expected WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) { if (!account) - return Unexpected(HF_ERR_INVALID_ACCOUNT); + return Unexpected(HostFunctionError::INVALID_ACCOUNT); if (!nftId) - return Unexpected(HF_ERR_INVALID_PARAMS); + return Unexpected(HostFunctionError::INVALID_PARAMS); auto obj = nft::findToken(ctx.view(), account, nftId); if (!obj) - return Unexpected(HF_ERR_LEDGER_OBJ_NOT_FOUND); + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); auto ouri = obj->at(~sfURI); if (!ouri) - return Unexpected(HF_ERR_FIELD_NOT_FOUND); + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); Slice const s = ouri->value(); return Bytes(s.begin(), s.end()); diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 59aa371cc28..1674d45b821 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -40,16 +40,20 @@ setData( return 0; if (dst < 0 || dsz < 0 || !src || ssz < 0) - return HF_ERR_INVALID_PARAMS; + return static_cast>( + HostFunctionError::INVALID_PARAMS); auto mem = rt ? rt->getMem() : wmem(); if (!mem.s) - return HF_ERR_NO_MEM_EXPORTED; + return static_cast>( + HostFunctionError::NO_MEM_EXPORTED); if (dst + dsz > mem.s) - return HF_ERR_POINTER_OUT_OF_BOUNDS; + return static_cast>( + HostFunctionError::POINTER_OUT_OF_BOUNDS); if (ssz > dsz) - return HF_ERR_BUFFER_TOO_SMALL; + return static_cast>( + HostFunctionError::BUFFER_TOO_SMALL); memcpy(mem.p + dst, src, ssz); @@ -95,7 +99,7 @@ getData( auto const it = m.find(params->data[i].of.i32); if (it == m.end()) { - return Unexpected(HF_ERR_INVALID_FIELD); + return Unexpected(HostFunctionError::INVALID_FIELD); } i++; return *it->second; @@ -111,14 +115,14 @@ getData( auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; if (src < 0 || ssz <= 0) - return Unexpected(HF_ERR_INVALID_PARAMS); + return Unexpected(HostFunctionError::INVALID_PARAMS); auto mem = rt ? rt->getMem() : wmem(); if (!mem.s) - return Unexpected(HF_ERR_NO_MEM_EXPORTED); + return Unexpected(HostFunctionError::NO_MEM_EXPORTED); if (src + ssz > mem.s) - return Unexpected(HF_ERR_POINTER_OUT_OF_BOUNDS); + return Unexpected(HostFunctionError::POINTER_OUT_OF_BOUNDS); Slice data(mem.p + src, ssz); i += 2; @@ -140,7 +144,7 @@ getData( if (r->size() != uint256::bytes) { - return Unexpected(HF_ERR_INVALID_PARAMS); + return Unexpected(HostFunctionError::INVALID_PARAMS); } return uint256::fromVoid(r->data()); } @@ -154,7 +158,7 @@ getData( { auto const r = getData(rt, params, i); if (!r || (r->size() != AccountID::bytes)) - return Unexpected(HF_ERR_INVALID_PARAMS); + return Unexpected(HostFunctionError::INVALID_PARAMS); return AccountID::fromVoid(r->data()); } @@ -169,27 +173,41 @@ getData( auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; if (src < 0 || ssz <= 0) - return Unexpected(HF_ERR_INVALID_PARAMS); + return Unexpected(HostFunctionError::INVALID_PARAMS); auto mem = rt ? rt->getMem() : wmem(); if (!mem.s) - return Unexpected(HF_ERR_NO_MEM_EXPORTED); + return Unexpected(HostFunctionError::NO_MEM_EXPORTED); if (src + ssz > mem.s) - return Unexpected(HF_ERR_POINTER_OUT_OF_BOUNDS); + return Unexpected(HostFunctionError::POINTER_OUT_OF_BOUNDS); std::string data(mem.p + src, mem.p + src + ssz); i += 2; return std::string_view(data); } -static std::nullptr_t +template +std::nullptr_t +hfResult(wasm_val_vec_t* results, T value); + +template <> +std::nullptr_t hfResult(wasm_val_vec_t* results, int32_t value) { results->data[0] = WASM_I32_VAL(value); results->num_elems = 1; return nullptr; } +template <> +std::nullptr_t +hfResult(wasm_val_vec_t* results, HostFunctionError value) +{ + results->data[0] = WASM_I32_VAL( + static_cast>(value)); + results->num_elems = 1; + return nullptr; +} template std::nullptr_t From 26db561e7f0814c48e0ac61edbca164c8f91c46b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 11 Jul 2025 01:45:52 +0530 Subject: [PATCH 20/25] rename variable --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 1674d45b821..81ff7e18d82 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -252,15 +252,15 @@ returnResult( std::decay_t, std::uint32_t>) { - auto const unwrappedResult = result.value(); + auto const resultValue = result.value(); return hfResult( results, setData( rt, params->data[index].of.i32, params->data[index + 1].of.i32, - reinterpret_cast(&unwrappedResult), - static_cast(sizeof(unwrappedResult)))); + reinterpret_cast(&resultValue), + static_cast(sizeof(resultValue)))); } else { From b6888335ea1a53d88f459e8cc4b1618ab7332ff4 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 11 Jul 2025 01:48:55 +0530 Subject: [PATCH 21/25] respond to comments --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 81ff7e18d82..310c813475a 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -170,21 +170,11 @@ getData( wasm_val_vec_t const* params, int32_t& i) { - auto const src = params->data[i].of.i32; - auto const ssz = params->data[i + 1].of.i32; - if (src < 0 || ssz <= 0) - return Unexpected(HostFunctionError::INVALID_PARAMS); - - auto mem = rt ? rt->getMem() : wmem(); - if (!mem.s) - return Unexpected(HostFunctionError::NO_MEM_EXPORTED); - - if (src + ssz > mem.s) - return Unexpected(HostFunctionError::POINTER_OUT_OF_BOUNDS); - - std::string data(mem.p + src, mem.p + src + ssz); - i += 2; - return std::string_view(data); + auto const r = getData(rt, params, i); + if (!r) + return Unexpected(r.error()); + return std::string_view( + reinterpret_cast(r->data()), r->size()); } template From 66da62f8fc3e5cd6334f2b5480e8d5cd5218c802 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 11 Jul 2025 02:12:53 +0530 Subject: [PATCH 22/25] remove templating --- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 310c813475a..98401c18f06 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -177,11 +177,6 @@ getData( reinterpret_cast(r->data()), r->size()); } -template -std::nullptr_t -hfResult(wasm_val_vec_t* results, T value); - -template <> std::nullptr_t hfResult(wasm_val_vec_t* results, int32_t value) { @@ -189,7 +184,7 @@ hfResult(wasm_val_vec_t* results, int32_t value) results->num_elems = 1; return nullptr; } -template <> + std::nullptr_t hfResult(wasm_val_vec_t* results, HostFunctionError value) { From 8fd0b28e29a0764f88d201d8f3d896cea34b328e Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 11 Jul 2025 23:49:44 +0530 Subject: [PATCH 23/25] [WIP] basic getData tests --- src/test/app/Wasm_test.cpp | 82 ++++++++++++++++++++++ src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 6 -- src/xrpld/app/misc/WasmHostFuncWrapper.h | 7 ++ 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index c7071cc3595..a19568d8a7b 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -21,7 +21,9 @@ #include #include +#include #include +#include #include #include #include @@ -76,6 +78,85 @@ getLedgerSqn_wrap(void* env, wasm_val_vec_t const*, wasm_val_vec_t* results) struct Wasm_test : public beast::unit_test::suite { + void + testGetDataHelperFunctions() + { + testcase("getData helper functions"); + + auto& engine = WasmEngine::instance(); + + { + // test int32_t + wasm_val_vec_t params; + wasm_val_t values[1]; + + values[0].kind = WASM_I32; + values[0].of.i32 = 42; + + wasm_val_vec_new(¶ms, 1, values); + InstanceWrapper const wrapper; + int index = 0; + auto const result = getData(&wrapper, ¶ms, index); + BEAST_EXPECT(result && result.value() == 42); + BEAST_EXPECT(index == 1); + } + + { + // test int64_t + wasm_val_vec_t params; + wasm_val_t values[1]; + + values[0].kind = WASM_I64; + values[0].of.i64 = 1234; + + wasm_val_vec_new(¶ms, 1, values); + InstanceWrapper const wrapper; + int index = 0; + auto const result = getData(&wrapper, ¶ms, index); + BEAST_EXPECT(result && result.value() == 1234); + BEAST_EXPECT(index == 1); + } + + { + // test SFieldCRef + wasm_val_vec_t params; + wasm_val_t values[1]; + + values[0].kind = WASM_I32; + values[0].of.i32 = sfAccount.fieldCode; + + wasm_val_vec_new(¶ms, 1, values); + InstanceWrapper const wrapper; + int index = 0; + auto const result = getData(&wrapper, ¶ms, index); + BEAST_EXPECT(result && result.value().get() == sfAccount); + BEAST_EXPECT(index == 1); + } + + { + // test Slice + wasm_val_vec_t params; + wasm_val_t values[2]; + + values[0].kind = WASM_I32; + values[0].of.i32 = 0; + + values[0].kind = WASM_I32; + values[0].of.i32 = 2; + + wasm_val_vec_new(¶ms, 2, values); + InstanceWrapper const wrapper; + + auto mem = wrapper.getMem(); + mem.s = 2; + + int index = 0; + auto const result = getData(&wrapper, ¶ms, index); + BEAST_EXPECT(result && result.value() == Slice{}); + BEAST_EXPECT(index == 2); + } + } + void testWasmFib() { @@ -659,6 +740,7 @@ struct Wasm_test : public beast::unit_test::suite { using namespace test::jtx; + testGetDataHelperFunctions(); testWasmLib(); testBadWasm(); testWasmCheckJson(); diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 98401c18f06..07896dceaf3 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -26,8 +26,6 @@ namespace ripple { -using SFieldCRef = std::reference_wrapper; - static int32_t setData( InstanceWrapper const* rt, @@ -60,10 +58,6 @@ setData( return ssz; } -template -Expected -getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t& src); - template <> Expected getData( diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.h b/src/xrpld/app/misc/WasmHostFuncWrapper.h index ac0cb88e497..53ec895efe7 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.h +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.h @@ -23,6 +23,13 @@ namespace ripple { +using SFieldCRef = std::reference_wrapper; + +// helper function, only in `.h` for testing purposes +template +Expected +getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t& src); + using getLedgerSqnOld_proto = int32_t(); wasm_trap_t* getLedgerSqnOld_wrap( From c3f769a142dbe13f6b67745dc42c67af9a722767 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Sat, 12 Jul 2025 01:25:36 +0530 Subject: [PATCH 24/25] weird linker error --- src/test/app/Wasm_test.cpp | 43 +++++-- src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 125 +++++++++------------ src/xrpld/app/misc/WasmHostFuncWrapper.h | 26 ++++- 3 files changed, 105 insertions(+), 89 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index a19568d8a7b..9a384c4f4f2 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -76,6 +76,23 @@ getLedgerSqn_wrap(void* env, wasm_val_vec_t const*, wasm_val_vec_t* results) return nullptr; } +class MockInstanceWrapper +{ + wmem mem_; + +public: + MockInstanceWrapper(wmem mem) : mem_(mem) + { + } + + // Mock methods to simulate the behavior of InstanceWrapper + wmem + getMem() const + { + return mem_; + } +}; + struct Wasm_test : public beast::unit_test::suite { void @@ -83,7 +100,9 @@ struct Wasm_test : public beast::unit_test::suite { testcase("getData helper functions"); - auto& engine = WasmEngine::instance(); + [[maybe_unused]] auto& engine = WasmEngine::instance(); + + InstanceWrapper const emptyWrapper; { // test int32_t @@ -94,9 +113,8 @@ struct Wasm_test : public beast::unit_test::suite values[0].of.i32 = 42; wasm_val_vec_new(¶ms, 1, values); - InstanceWrapper const wrapper; int index = 0; - auto const result = getData(&wrapper, ¶ms, index); + auto const result = getDataInt32(&emptyWrapper, ¶ms, index); BEAST_EXPECT(result && result.value() == 42); BEAST_EXPECT(index == 1); } @@ -110,9 +128,8 @@ struct Wasm_test : public beast::unit_test::suite values[0].of.i64 = 1234; wasm_val_vec_new(¶ms, 1, values); - InstanceWrapper const wrapper; int index = 0; - auto const result = getData(&wrapper, ¶ms, index); + auto const result = getDataInt64(&emptyWrapper, ¶ms, index); BEAST_EXPECT(result && result.value() == 1234); BEAST_EXPECT(index == 1); } @@ -126,9 +143,8 @@ struct Wasm_test : public beast::unit_test::suite values[0].of.i32 = sfAccount.fieldCode; wasm_val_vec_new(¶ms, 1, values); - InstanceWrapper const wrapper; int index = 0; - auto const result = getData(&wrapper, ¶ms, index); + auto const result = getDataSField(&emptyWrapper, ¶ms, index); BEAST_EXPECT(result && result.value().get() == sfAccount); BEAST_EXPECT(index == 1); } @@ -145,14 +161,17 @@ struct Wasm_test : public beast::unit_test::suite values[0].of.i32 = 2; wasm_val_vec_new(¶ms, 2, values); - InstanceWrapper const wrapper; - auto mem = wrapper.getMem(); - mem.s = 2; + std::vector buffer = {'a', 'b', 'c'}; + + wmem m; + m.p = buffer.data(); + m.s = buffer.size(); + MockInstanceWrapper const wrapper(m); int index = 0; - auto const result = getData(&wrapper, ¶ms, index); - BEAST_EXPECT(result && result.value() == Slice{}); + auto const result = getDataSlice(&wrapper, ¶ms, index); + BEAST_EXPECT(result && result.value() == Slice(buffer.data(), 3)); BEAST_EXPECT(index == 2); } } diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index 07896dceaf3..d86449f9ab3 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -58,36 +58,27 @@ setData( return ssz; } -template <> +template Expected -getData( - InstanceWrapper const* _rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataInt32(IW const* _rt, wasm_val_vec_t const* params, int32_t& i) { auto const result = params->data[i].of.i32; i++; return result; } -template <> +template Expected -getData( - InstanceWrapper const* _rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataInt64(IW const* _rt, wasm_val_vec_t const* params, int32_t& i) { auto const result = params->data[i].of.i64; i++; return result; } -template <> +template Expected -getData( - InstanceWrapper const* _rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataSField(IW const* _rt, wasm_val_vec_t const* params, int32_t& i) { auto const& m = SField::getKnownCodeToField(); auto const it = m.find(params->data[i].of.i32); @@ -99,12 +90,9 @@ getData( return *it->second; } -template <> +template Expected -getData( - InstanceWrapper const* rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataSlice(IW const* rt, wasm_val_vec_t const* params, int32_t& i) { auto const src = params->data[i].of.i32; auto const ssz = params->data[i + 1].of.i32; @@ -123,14 +111,11 @@ getData( return data; } -template <> +template Expected -getData( - InstanceWrapper const* rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataUInt256(IW const* rt, wasm_val_vec_t const* params, int32_t& i) { - auto const r = getData(rt, params, i); + auto const r = getDataSlice(rt, params, i); if (!r) { return Unexpected(r.error()); @@ -143,28 +128,22 @@ getData( return uint256::fromVoid(r->data()); } -template <> +template Expected -getData( - InstanceWrapper const* rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataAccountID(IW const* rt, wasm_val_vec_t const* params, int32_t& i) { - auto const r = getData(rt, params, i); + auto const r = getDataSlice(rt, params, i); if (!r || (r->size() != AccountID::bytes)) return Unexpected(HostFunctionError::INVALID_PARAMS); return AccountID::fromVoid(r->data()); } -template <> +template Expected -getData( - InstanceWrapper const* rt, - wasm_val_vec_t const* params, - int32_t& i) +getDataString(IW const* rt, wasm_val_vec_t const* params, int32_t& i) { - auto const r = getData(rt, params, i); + auto const r = getDataSlice(rt, params, i); if (!r) return Unexpected(r.error()); return std::string_view( @@ -313,13 +292,13 @@ cacheLedgerObj_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const id = getData(rt, params, index); + auto const id = getDataUInt256(rt, params, index); if (!id) { return hfResult(results, id.error()); } - auto const cache = getData(rt, params, index); + auto const cache = getDataInt32(rt, params, index); if (!cache) { return hfResult(results, cache.error()); @@ -339,7 +318,7 @@ getTxField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getDataSField(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -357,7 +336,7 @@ getCurrentLedgerObjField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getDataSField(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -377,13 +356,13 @@ getLedgerObjField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const cache = getData(rt, params, index); + auto const cache = getDataInt32(rt, params, index); if (!cache) { return hfResult(results, cache.error()); } - auto const fname = getData(rt, params, index); + auto const fname = getDataSField(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -403,7 +382,7 @@ getTxNestedField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -423,7 +402,7 @@ getCurrentLedgerObjNestedField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -442,13 +421,13 @@ getLedgerObjNestedField_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const cache = getData(rt, params, index); + auto const cache = getDataInt32(rt, params, index); if (!cache) { return hfResult(results, cache.error()); } - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -472,7 +451,7 @@ getTxArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getDataSField(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -491,7 +470,7 @@ getCurrentLedgerObjArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const fname = getData(rt, params, index); + auto const fname = getDataSField(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -511,13 +490,13 @@ getLedgerObjArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const cache = getData(rt, params, index); + auto const cache = getDataInt32(rt, params, index); if (!cache) { return hfResult(results, cache.error()); } - auto const fname = getData(rt, params, index); + auto const fname = getDataSField(rt, params, index); if (!fname) { return hfResult(results, fname.error()); @@ -537,7 +516,7 @@ getTxNestedArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -557,7 +536,7 @@ getCurrentLedgerObjNestedArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -580,13 +559,13 @@ getLedgerObjNestedArrayLen_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const cache = getData(rt, params, index); + auto const cache = getDataInt32(rt, params, index); if (!cache) { return hfResult(results, cache.error()); } - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -609,7 +588,7 @@ updateData_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -628,7 +607,7 @@ computeSha512HalfHash_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const bytes = getData(rt, params, index); + auto const bytes = getDataSlice(rt, params, index); if (!bytes) { return hfResult(results, bytes.error()); @@ -647,7 +626,7 @@ accountKeylet_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const acc = getData(rt, params, index); + auto const acc = getDataAccountID(rt, params, index); if (!acc) { return hfResult(results, acc.error()); @@ -666,19 +645,19 @@ credentialKeylet_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const subj = getData(rt, params, index); + auto const subj = getDataAccountID(rt, params, index); if (!subj) { return hfResult(results, subj.error()); } - auto const iss = getData(rt, params, index); + auto const iss = getDataAccountID(rt, params, index); if (!iss) { return hfResult(results, iss.error()); } - auto const credType = getData(rt, params, index); + auto const credType = getDataSlice(rt, params, index); if (!credType) { return hfResult(results, credType.error()); @@ -702,13 +681,13 @@ escrowKeylet_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const acc = getData(rt, params, index); + auto const acc = getDataAccountID(rt, params, index); if (!acc) { return hfResult(results, acc.error()); } - auto const seq = getData(rt, params, index); + auto const seq = getDataInt32(rt, params, index); if (!seq) { return hfResult(results, seq.error()); @@ -728,13 +707,13 @@ oracleKeylet_wrap( auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const acc = getData(rt, params, index); + auto const acc = getDataAccountID(rt, params, index); if (!acc) { return hfResult(results, acc.error()); } - auto const seq = getData(rt, params, index); + auto const seq = getDataInt32(rt, params, index); if (!seq) { return hfResult(results, seq.error()); @@ -750,13 +729,13 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const acc = getData(rt, params, index); + auto const acc = getDataAccountID(rt, params, index); if (!acc) { return hfResult(results, acc.error()); } - auto const nftId = getData(rt, params, index); + auto const nftId = getDataUInt256(rt, params, index); if (!nftId) { return hfResult(results, nftId.error()); @@ -772,19 +751,19 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const msg = getData(rt, params, index); + auto const msg = getDataString(rt, params, index); if (!msg) { return hfResult(results, msg.error()); } - auto const data = getData(rt, params, index); + auto const data = getDataSlice(rt, params, index); if (!data) { return hfResult(results, data.error()); } - auto const asHex = getData(rt, params, index); + auto const asHex = getDataInt32(rt, params, index); if (!asHex) { return hfResult(results, asHex.error()); @@ -801,13 +780,13 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) auto const* rt = reinterpret_cast(hf->getRT()); int index = 0; - auto const msg = getData(rt, params, index); + auto const msg = getDataString(rt, params, index); if (!msg) { return hfResult(results, msg.error()); } - auto const number = getData(rt, params, index); + auto const number = getDataInt64(rt, params, index); if (!number) { return hfResult(results, number.error()); diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.h b/src/xrpld/app/misc/WasmHostFuncWrapper.h index 53ec895efe7..e7fef3a12db 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.h +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.h @@ -25,10 +25,28 @@ namespace ripple { using SFieldCRef = std::reference_wrapper; -// helper function, only in `.h` for testing purposes -template -Expected -getData(InstanceWrapper const* rt, wasm_val_vec_t const* params, int32_t& src); +// helper functions, only in `.h` for testing purposes +template +Expected +getDataInt32(IW const* _rt, wasm_val_vec_t const* params, int32_t& i); +template +Expected +getDataInt64(IW const* _rt, wasm_val_vec_t const* params, int32_t& i); +template +Expected +getDataSField(IW const* _rt, wasm_val_vec_t const* params, int32_t& i); +template +Expected +getDataSlice(IW const* rt, wasm_val_vec_t const* params, int32_t& i); +template +Expected +getDataUInt256(IW const* rt, wasm_val_vec_t const* params, int32_t& i); +template +Expected +getDataAccountID(IW const* rt, wasm_val_vec_t const* params, int32_t& i); +template +Expected +getDataString(IW const* rt, wasm_val_vec_t const* params, int32_t& i); using getLedgerSqnOld_proto = int32_t(); wasm_trap_t* From 6f2e0857ae4c240a2ae01c17f75c99f7215cf996 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 14 Jul 2025 23:25:04 +0530 Subject: [PATCH 25/25] fix issue --- src/test/app/Wasm_test.cpp | 98 +------------ src/xrpld/app/misc/WasmHostFuncWrapper.cpp | 157 +++++++++++++++++++-- src/xrpld/app/misc/WasmHostFuncWrapper.h | 25 ---- 3 files changed, 148 insertions(+), 132 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 9a384c4f4f2..e4d92873dd0 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -21,9 +21,7 @@ #include #include -#include #include -#include #include #include #include @@ -37,6 +35,9 @@ namespace ripple { namespace test { +bool +testGetDataIncrement(); + using Add_proto = int32_t(int32_t, int32_t); static wasm_trap_t* Add(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) @@ -76,104 +77,13 @@ getLedgerSqn_wrap(void* env, wasm_val_vec_t const*, wasm_val_vec_t* results) return nullptr; } -class MockInstanceWrapper -{ - wmem mem_; - -public: - MockInstanceWrapper(wmem mem) : mem_(mem) - { - } - - // Mock methods to simulate the behavior of InstanceWrapper - wmem - getMem() const - { - return mem_; - } -}; - struct Wasm_test : public beast::unit_test::suite { void testGetDataHelperFunctions() { testcase("getData helper functions"); - - [[maybe_unused]] auto& engine = WasmEngine::instance(); - - InstanceWrapper const emptyWrapper; - - { - // test int32_t - wasm_val_vec_t params; - wasm_val_t values[1]; - - values[0].kind = WASM_I32; - values[0].of.i32 = 42; - - wasm_val_vec_new(¶ms, 1, values); - int index = 0; - auto const result = getDataInt32(&emptyWrapper, ¶ms, index); - BEAST_EXPECT(result && result.value() == 42); - BEAST_EXPECT(index == 1); - } - - { - // test int64_t - wasm_val_vec_t params; - wasm_val_t values[1]; - - values[0].kind = WASM_I64; - values[0].of.i64 = 1234; - - wasm_val_vec_new(¶ms, 1, values); - int index = 0; - auto const result = getDataInt64(&emptyWrapper, ¶ms, index); - BEAST_EXPECT(result && result.value() == 1234); - BEAST_EXPECT(index == 1); - } - - { - // test SFieldCRef - wasm_val_vec_t params; - wasm_val_t values[1]; - - values[0].kind = WASM_I32; - values[0].of.i32 = sfAccount.fieldCode; - - wasm_val_vec_new(¶ms, 1, values); - int index = 0; - auto const result = getDataSField(&emptyWrapper, ¶ms, index); - BEAST_EXPECT(result && result.value().get() == sfAccount); - BEAST_EXPECT(index == 1); - } - - { - // test Slice - wasm_val_vec_t params; - wasm_val_t values[2]; - - values[0].kind = WASM_I32; - values[0].of.i32 = 0; - - values[0].kind = WASM_I32; - values[0].of.i32 = 2; - - wasm_val_vec_new(¶ms, 2, values); - - std::vector buffer = {'a', 'b', 'c'}; - - wmem m; - m.p = buffer.data(); - m.s = buffer.size(); - MockInstanceWrapper const wrapper(m); - - int index = 0; - auto const result = getDataSlice(&wrapper, ¶ms, index); - BEAST_EXPECT(result && result.value() == Slice(buffer.data(), 3)); - BEAST_EXPECT(index == 2); - } + BEAST_EXPECT(testGetDataIncrement()); } void diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp index d86449f9ab3..c855638684a 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.cpp +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.cpp @@ -26,6 +26,8 @@ namespace ripple { +using SFieldCRef = std::reference_wrapper; + static int32_t setData( InstanceWrapper const* rt, @@ -173,14 +175,14 @@ returnResult( InstanceWrapper const* rt, wasm_val_vec_t const* params, wasm_val_vec_t* results, - Expected const& result, + Expected const& res, int32_t index) { - if (!result) + if (!res) { - return hfResult(results, result.error()); + return hfResult(results, res.error()); } - if constexpr (std::is_same_v, Bytes>) + if constexpr (std::is_same_v, Bytes>) { return hfResult( results, @@ -188,10 +190,10 @@ returnResult( rt, params->data[index].of.i32, params->data[index + 1].of.i32, - result->data(), - result->size())); + res->data(), + res->size())); } - else if constexpr (std::is_same_v, Hash>) + else if constexpr (std::is_same_v, Hash>) { return hfResult( results, @@ -199,18 +201,18 @@ returnResult( rt, params->data[index].of.i32, params->data[index + 1].of.i32, - result->data(), - result->size())); + res->data(), + res->size())); } - else if constexpr (std::is_same_v, int32_t>) + else if constexpr (std::is_same_v, int32_t>) { - return hfResult(results, result.value()); + return hfResult(results, res.value()); } else if constexpr (std::is_same_v< - std::decay_t, + std::decay_t, std::uint32_t>) { - auto const resultValue = result.value(); + auto const resultValue = res.value(); return hfResult( results, setData( @@ -796,4 +798,133 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) rt, params, results, hf->traceNum(*msg, *number), index); } +class MockInstanceWrapper +{ + wmem mem_; + +public: + MockInstanceWrapper(wmem mem) : mem_(mem) + { + } + + // Mock methods to simulate the behavior of InstanceWrapper + wmem + getMem() const + { + return mem_; + } +}; + +namespace test { +bool +testGetDataIncrement() +{ + wasm_val_t values[4]; + + std::array buffer = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; + MockInstanceWrapper rt(wmem{buffer.data(), buffer.size()}); + + { + // test int32_t + wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(42); + + int index = 0; + auto const result = getDataInt32(&rt, ¶ms, index); + if (!result || result.value() != 42 || index != 1) + return false; + } + + { + // test int64_t + wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I64_VAL(1234); + + int index = 0; + auto const result = getDataInt64(&rt, ¶ms, index); + if (!result || result.value() != 1234 || index != 1) + return false; + } + + { + // test SFieldCRef + wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(sfAccount.fieldCode); + + int index = 0; + auto const result = getDataSField(&rt, ¶ms, index); + if (!result || result.value().get() != sfAccount || index != 1) + return false; + } + + { + // test Slice + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(3); + + int index = 0; + auto const result = getDataSlice(&rt, ¶ms, index); + if (!result || result.value() != Slice(buffer.data(), 3)) + return false; + } + + { + // test string + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(5); + + int index = 0; + auto const result = getDataString(&rt, ¶ms, index); + if (!result || + result.value() != + std::string_view( + reinterpret_cast(buffer.data()), 5)) + return false; + } + + { + // test account + AccountID const id(calcAccountID( + generateKeyPair(KeyType::secp256k1, generateSeed("alice")).first)); + + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(id.bytes); + memcpy(&buffer[0], id.data(), id.bytes); + + int index = 0; + auto const result = getDataAccountID(&rt, ¶ms, index); + if (!result || result.value() != id) + return false; + } + + { + // test uint256 + + Hash h1 = sha512Half(Slice(buffer.data(), 8)); + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(h1.bytes); + memcpy(&buffer[0], h1.data(), h1.bytes); + + int index = 0; + auto const result = getDataUInt256(&rt, ¶ms, index); + if (!result || result.value() != h1) + return false; + } + + return true; +} + +} // namespace test } // namespace ripple diff --git a/src/xrpld/app/misc/WasmHostFuncWrapper.h b/src/xrpld/app/misc/WasmHostFuncWrapper.h index e7fef3a12db..ac0cb88e497 100644 --- a/src/xrpld/app/misc/WasmHostFuncWrapper.h +++ b/src/xrpld/app/misc/WasmHostFuncWrapper.h @@ -23,31 +23,6 @@ namespace ripple { -using SFieldCRef = std::reference_wrapper; - -// helper functions, only in `.h` for testing purposes -template -Expected -getDataInt32(IW const* _rt, wasm_val_vec_t const* params, int32_t& i); -template -Expected -getDataInt64(IW const* _rt, wasm_val_vec_t const* params, int32_t& i); -template -Expected -getDataSField(IW const* _rt, wasm_val_vec_t const* params, int32_t& i); -template -Expected -getDataSlice(IW const* rt, wasm_val_vec_t const* params, int32_t& i); -template -Expected -getDataUInt256(IW const* rt, wasm_val_vec_t const* params, int32_t& i); -template -Expected -getDataAccountID(IW const* rt, wasm_val_vec_t const* params, int32_t& i); -template -Expected -getDataString(IW const* rt, wasm_val_vec_t const* params, int32_t& i); - using getLedgerSqnOld_proto = int32_t(); wasm_trap_t* getLedgerSqnOld_wrap(