From 0dbe51c740790a195dfb5dd70e1c0fcf4f5cb6aa Mon Sep 17 00:00:00 2001 From: Olek <115580134+oleks-rip@users.noreply.github.com> Date: Tue, 2 Jun 2026 21:15:58 -0400 Subject: [PATCH] Cleanup and some refactoring (#7383) --- include/xrpl/protocol/Protocol.h | 4 +- include/xrpl/tx/wasm/HostFunc.h | 200 +++-- include/xrpl/tx/wasm/HostFuncImpl.h | 15 +- include/xrpl/tx/wasm/HostFuncWrapper.h | 2 +- include/xrpl/tx/wasm/WasmCommon.h | 160 ++++ .../{ParamsHelper.h => WasmImportsHelper.h} | 146 +--- include/xrpl/tx/wasm/WasmVM.h | 1 + include/xrpl/tx/wasm/WasmiVM.h | 131 +++- src/libxrpl/tx/wasm/HostFuncImpl.cpp | 8 +- src/libxrpl/tx/wasm/HostFuncImplFloat.cpp | 2 +- src/libxrpl/tx/wasm/HostFuncImplGetter.cpp | 13 +- src/libxrpl/tx/wasm/HostFuncImplKeylet.cpp | 3 +- .../tx/wasm/HostFuncImplLedgerHeader.cpp | 3 +- src/libxrpl/tx/wasm/HostFuncImplNFT.cpp | 3 +- src/libxrpl/tx/wasm/HostFuncWrapper.cpp | 682 +++++++----------- src/libxrpl/tx/wasm/WasmVM.cpp | 11 +- src/libxrpl/tx/wasm/WasmiVM.cpp | 242 ++----- src/test/app/HostFuncImpl_test.cpp | 177 ++--- src/test/app/TestHostFunctions.h | 115 +-- src/test/app/Wasm_test.cpp | 55 +- 20 files changed, 850 insertions(+), 1123 deletions(-) create mode 100644 include/xrpl/tx/wasm/WasmCommon.h rename include/xrpl/tx/wasm/{ParamsHelper.h => WasmImportsHelper.h} (50%) diff --git a/include/xrpl/protocol/Protocol.h b/include/xrpl/protocol/Protocol.h index 72b3b8d570..512998081e 100644 --- a/include/xrpl/protocol/Protocol.h +++ b/include/xrpl/protocol/Protocol.h @@ -252,10 +252,10 @@ constexpr std::uint8_t kVaultMaximumIouScale = 18; constexpr std::uint8_t kMaxAssetCheckDepth = 5; /** Maximum length of a Data field in Escrow object that can be updated by WASM code. */ -std::size_t constexpr maxWasmDataLength = 4 * 1024; // 4KB +constexpr std::size_t kMaxWasmDataLength = 4 * 1024; // 4KB /** Maximum length of parameters passed from WASM code to host functions. */ -std::size_t constexpr maxWasmParamLength = 1024; // 1KB +constexpr std::size_t kMaxWasmParamLength = 1024; // 1KB /** A ledger index. */ using LedgerIndex = std::uint32_t; diff --git a/include/xrpl/tx/wasm/HostFunc.h b/include/xrpl/tx/wasm/HostFunc.h index 7c5eb18b0c..3fc974423c 100644 --- a/include/xrpl/tx/wasm/HostFunc.h +++ b/include/xrpl/tx/wasm/HostFunc.h @@ -8,43 +8,10 @@ #include #include #include -#include +#include namespace xrpl { -enum class HostFunctionError : int32_t { - INTERNAL = -1, - FieldNotFound = -2, - BufferTooSmall = -3, - NoArray = -4, - NotLeafField = -5, - LocatorMalformed = -6, - SlotOutRange = -7, - SlotsFull = -8, - EmptySlot = -9, - LedgerObjNotFound = -10, - DECODING = -11, - DataFieldTooLarge = -12, - PointerOutOfBounds = -13, - NoMemExported = -14, - InvalidParams = -15, - InvalidAccount = -16, - InvalidField = -17, - IndexOutOfBounds = -18, - FloatInputMalformed = -19, - FloatComputationError = -20, - NoRuntime = -21, - OutOfGas = -22, -}; - -using FloatPair = std::pair; - -inline int32_t -HfErrorToInt(HostFunctionError e) -{ - return static_cast(e); -} - namespace wasm_float { std::string @@ -95,32 +62,45 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode); } // namespace wasm_float // Intended to work only through wasm runtime. Don't call them directly, except with unit tests -struct HostFunctions +class HostFunctions { - beast::Journal j; +protected: + RTOptRef rt_; + beast::Journal j_; - HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j(j) +public: + HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j_(j) { } - // LCOV_EXCL_START - virtual void - setRT(void*) + void + setRT(WasmRuntimeWrapper& rt) { + rt_ = rt; } - [[nodiscard]] virtual void* + void + resetRT() + { + rt_ = std::nullopt; + } + + [[nodiscard]] WasmRuntimeWrapper* getRT() const { - return nullptr; + if (!rt_) + return nullptr; // LCOV_EXCL_LINE + return &rt_->get(); } [[nodiscard]] beast::Journal getJournal() const { - return j; + return j_; } + // LCOV_EXCL_START + [[nodiscard]] virtual bool checkSelf() const { @@ -130,402 +110,404 @@ struct HostFunctions virtual Expected getLedgerSqn() const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getParentLedgerTime() const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getParentLedgerHash() const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getBaseFee() const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected isAmendmentEnabled(uint256 const& amendmentId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected isAmendmentEnabled(std::string_view const& amendmentName) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getTxField(SField const& fname) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getCurrentLedgerObjField(SField const& fname) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getLedgerObjField(int32_t cacheIdx, SField const& fname) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getTxNestedField(Slice const& locator) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getCurrentLedgerObjNestedField(Slice const& locator) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getTxArrayLen(SField const& fname) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getCurrentLedgerObjArrayLen(SField const& fname) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getTxNestedArrayLen(Slice const& locator) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getCurrentLedgerObjNestedArrayLen(Slice const& locator) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected updateData(Slice const& data) { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected computeSha512HalfHash(Slice const& data) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected accountKeylet(AccountID const& account) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected ammKeylet(Asset const& issue1, Asset const& issue2) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected checkKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected didKeylet(AccountID const& account) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected delegateKeylet(AccountID const& account, AccountID const& authorize) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected escrowKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected mptokenKeylet(MPTID const& mptid, AccountID const& holder) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected nftOfferKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected offerKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected oracleKeylet(AccountID const& account, std::uint32_t docId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected signersKeylet(AccountID const& account) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected ticketKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected vaultKeylet(AccountID const& account, std::uint32_t seq) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getNFT(AccountID const& account, uint256 const& nftId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getNFTIssuer(uint256 const& nftId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getNFTTaxon(uint256 const& nftId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getNFTFlags(uint256 const& nftId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getNFTTransferFee(uint256 const& nftId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected getNFTSerial(uint256 const& nftId) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected trace(std::string_view const& msg, Slice const& data, bool asHex) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected traceNum(std::string_view const& msg, int64_t data) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected traceAccount(std::string_view const& msg, AccountID const& account) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected traceFloat(std::string_view const& msg, Slice const& data) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected traceAmount(std::string_view const& msg, STAmount const& amount) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatFromInt(int64_t x, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatFromUint(uint64_t x, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatFromSTAmount(STAmount const& x, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatFromSTNumber(STNumber const& x, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatToInt(Slice const& x, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatToMantExp(Slice const& x) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatFromMantExp(int64_t mantissa, int32_t exponent, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatCompare(Slice const& x, Slice const& y) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatAdd(Slice const& x, Slice const& y, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatSubtract(Slice const& x, Slice const& y, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatMultiply(Slice const& x, Slice const& y, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatDivide(Slice const& x, Slice const& y, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatRoot(Slice const& x, int32_t n, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual Expected floatPower(Slice const& x, int32_t n, int32_t mode) const { - return Unexpected(HostFunctionError::INTERNAL); + return Unexpected(HostFunctionError::Internal); } virtual ~HostFunctions() = default; // LCOV_EXCL_STOP }; +using HFRef = std::reference_wrapper; + } // namespace xrpl diff --git a/include/xrpl/tx/wasm/HostFuncImpl.h b/include/xrpl/tx/wasm/HostFuncImpl.h index 689ce85a59..6741246d08 100644 --- a/include/xrpl/tx/wasm/HostFuncImpl.h +++ b/include/xrpl/tx/wasm/HostFuncImpl.h @@ -18,8 +18,7 @@ class WasmHostFunctionsImpl : public HostFunctions std::optional data_; - void* rt_ = nullptr; - +public: Expected, HostFunctionError> getCurrentLedgerObj() const { @@ -65,18 +64,6 @@ public: { } - void - setRT(void* rt) override - { - rt_ = rt; - } - - void* - getRT() const override - { - return rt_; - } - bool checkSelf() const override { diff --git a/include/xrpl/tx/wasm/HostFuncWrapper.h b/include/xrpl/tx/wasm/HostFuncWrapper.h index 313fe0b27f..d917c56df9 100644 --- a/include/xrpl/tx/wasm/HostFuncWrapper.h +++ b/include/xrpl/tx/wasm/HostFuncWrapper.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/include/xrpl/tx/wasm/WasmCommon.h b/include/xrpl/tx/wasm/WasmCommon.h new file mode 100644 index 0000000000..5e1b47b982 --- /dev/null +++ b/include/xrpl/tx/wasm/WasmCommon.h @@ -0,0 +1,160 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace xrpl { + +using Bytes = std::vector; +using Hash = xrpl::uint256; +using FloatPair = std::pair; + +enum class HostFunctionError : int32_t { + Internal = -1, + FieldNotFound = -2, + BufferTooSmall = -3, + NoArray = -4, + NotLeafField = -5, + LocatorMalformed = -6, + SlotOutRange = -7, + SlotsFull = -8, + EmptySlot = -9, + LedgerObjNotFound = -10, + Decoding = -11, + DataFieldTooLarge = -12, + PointerOutOfBounds = -13, + NoMemExported = -14, + InvalidParams = -15, + InvalidAccount = -16, + InvalidField = -17, + IndexOutOfBounds = -18, + FloatInputMalformed = -19, + FloatComputationError = -20, + NoRuntime = -21, + OutOfGas = -22, + OutOfTransferLimit = -23, +}; + +enum class WasmTypes { WtI32, WtI64 }; + +struct Wmem +{ + std::uint8_t* p = nullptr; + std::size_t s = 0; + + Wmem() = default; + Wmem(void* ptr, std::size_t size) : p(reinterpret_cast(ptr)), s(size) + { + } +}; + +template +struct WasmResult +{ + T result; + int64_t cost; +}; +using EscrowResult = WasmResult; + +class WasmRuntimeWrapper +{ +public: + virtual ~WasmRuntimeWrapper() = default; + + virtual Wmem + getMem() = 0; + + virtual std::int64_t + getGas() = 0; + + virtual std::int64_t + setGas(std::int64_t gas) = 0; +}; +using RTOptRef = std::optional>; + +struct WasmParam +{ + // We are not supporting float/double + + WasmTypes type = WasmTypes::WtI32; + union + { + std::int32_t i32; + std::int64_t i64 = 0; + } of; +}; + +template +inline void +wasmParamsHlp(std::vector& v, std::int32_t p, Types&&... args) +{ + v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}}); + wasmParamsHlp(v, std::forward(args)...); +} + +template +inline void +wasmParamsHlp(std::vector& v, std::int64_t p, Types&&... args) +{ + v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}}); + wasmParamsHlp(v, std::forward(args)...); +} + +inline void +wasmParamsHlp(std::vector& v) +{ + return; +} + +template +inline std::vector +wasmParams(Types&&... args) +{ + std::vector v; + v.reserve(sizeof...(args)); + wasmParamsHlp(v, std::forward(args)...); + return v; +} + +template +constexpr T +adjustWasmEndianessHlp(T x) +{ + static_assert(std::is_integral_v, "Only integral types"); + if constexpr (Size > 1) + { + using U = std::make_unsigned_t; + U u = static_cast(x); + U const low = (u & 0xFF) << ((Size - 1) << 3); + u = adjustWasmEndianessHlp(u >> 8); + return static_cast(low | u); + } + + return x; +} + +template +constexpr T +adjustWasmEndianess(T x) +{ + // LCOV_EXCL_START + static_assert(std::is_integral_v, "Only integral types"); + if constexpr (std::endian::native == std::endian::big) + { + return adjustWasmEndianessHlp(x); + } + return x; + // LCOV_EXCL_STOP +} + +constexpr int32_t +hfErrorToInt(HostFunctionError e) +{ + return static_cast(e); +} + +} // namespace xrpl diff --git a/include/xrpl/tx/wasm/ParamsHelper.h b/include/xrpl/tx/wasm/WasmImportsHelper.h similarity index 50% rename from include/xrpl/tx/wasm/ParamsHelper.h rename to include/xrpl/tx/wasm/WasmImportsHelper.h index 266b1dd334..18ceb52973 100644 --- a/include/xrpl/tx/wasm/ParamsHelper.h +++ b/include/xrpl/tx/wasm/WasmImportsHelper.h @@ -1,84 +1,33 @@ #pragma once #include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace bft = boost::function_types; namespace xrpl { -template -inline constexpr bool wasmDependentFalse = false; - -using Bytes = std::vector; -using Hash = xrpl::uint256; - -struct Wmem -{ - std::uint8_t* p = nullptr; - std::size_t s = 0; -}; - -template -struct WasmResult -{ - T result; - int64_t cost; -}; -using EscrowResult = WasmResult; - -struct WasmRuntimeWrapper -{ - virtual ~WasmRuntimeWrapper() = default; - - virtual Wmem - getMem() = 0; - - virtual std::int64_t - getGas() = 0; - - virtual std::int64_t - setGas(std::int64_t gas) = 0; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -enum class WasmTypes { WtI32, WtI64 }; - struct WasmImportFunc { std::string_view name; std::optional result; std::vector params; - // void* udata = nullptr; // wasm_func_callback_with_env_t void* wrap = nullptr; uint32_t gas = 0; }; -using WasmUserData = std::pair; +using WasmUserData = std::pair; +// string - import function name using ImportVec = std::unordered_map; -#define WASM_IMPORT_FUNC(v, f, ...) \ - WasmImpFunc(v, #f, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) - -// n - string literal name, must have static lifetime -#define WASM_IMPORT_FUNC2(v, f, n, ...) \ - WasmImpFunc(v, n, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) - template void WasmImpArgs(WasmImportFunc& e) @@ -108,6 +57,9 @@ WasmImpArgs(WasmImportFunc& e) return; } +template +inline constexpr bool wasmDependentFalse = false; + template void WasmImpRet(WasmImportFunc& e) @@ -154,7 +106,7 @@ WasmImpFunc( ImportVec& v, std::string_view impName, void* fWrap, - void* data = nullptr, + HostFunctions& hf, uint32_t gas = 0) { WasmImportFunc e; @@ -162,84 +114,14 @@ WasmImpFunc( e.wrap = fWrap; e.gas = gas; WasmImpFuncHelper(e); - v.emplace(impName, std::make_pair(data, std::move(e))); + v.emplace(impName, std::make_pair(HFRef(hf), std::move(e))); } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define WASM_IMPORT_FUNC(v, f, ...) \ + WasmImpFunc(v, #f, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) -struct WasmParam -{ - // We are not supporting float/double - - WasmTypes type = WasmTypes::WtI32; - union - { - std::int32_t i32; - std::int64_t i64 = 0; - } of; -}; - -template -inline void -wasmParamsHlp(std::vector& v, std::int32_t p, Types&&... args) -{ - v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}}); - wasmParamsHlp(v, std::forward(args)...); -} - -template -inline void -wasmParamsHlp(std::vector& v, std::int64_t p, Types&&... args) -{ - v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}}); - wasmParamsHlp(v, std::forward(args)...); -} - -inline void -wasmParamsHlp(std::vector& v) -{ - return; -} - -template -inline std::vector -wasmParams(Types&&... args) -{ - std::vector v; - v.reserve(sizeof...(args)); - wasmParamsHlp(v, std::forward(args)...); - return v; -} - -template -constexpr T -adjustWasmEndianessHlp(T x) -{ - static_assert(std::is_integral_v, "Only integral types"); - if constexpr (Size > 1) - { - using U = std::make_unsigned_t; - U u = static_cast(x); - U const low = (u & 0xFF) << ((Size - 1) << 3); - u = adjustWasmEndianessHlp(u >> 8); - return static_cast(low | u); - } - - return x; -} - -template -constexpr T -adjustWasmEndianess(T x) -{ - // LCOV_EXCL_START - static_assert(std::is_integral_v, "Only integral types"); - if constexpr (std::endian::native == std::endian::big) - { - return adjustWasmEndianessHlp(x); - } - return x; - // LCOV_EXCL_STOP -} +// n - string literal name, must have static lifetime +#define WASM_IMPORT_FUNC2(v, f, n, ...) \ + WasmImpFunc(v, n, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) } // namespace xrpl diff --git a/include/xrpl/tx/wasm/WasmVM.h b/include/xrpl/tx/wasm/WasmVM.h index 761ed4c618..ac3d987d1d 100644 --- a/include/xrpl/tx/wasm/WasmVM.h +++ b/include/xrpl/tx/wasm/WasmVM.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include diff --git a/include/xrpl/tx/wasm/WasmiVM.h b/include/xrpl/tx/wasm/WasmiVM.h index ef3c33b164..d31c096b15 100644 --- a/include/xrpl/tx/wasm/WasmiVM.h +++ b/include/xrpl/tx/wasm/WasmiVM.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -139,13 +140,13 @@ using StorePtr = std::unique_ptr; using FuncInfo = std::pair; -struct InstanceWrapper +class InstanceWrapper { - wasm_store_t* store = nullptr; - WasmExternVec exports; - mutable int memIdx = -1; - InstancePtr instance; - beast::Journal j = beast::Journal(beast::Journal::getNullSink()); + wasm_store_t* store_ = nullptr; + WasmExternVec exports_; + mutable int memIdx_ = -1; + InstancePtr instance_; + beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); private: static InstancePtr @@ -157,13 +158,19 @@ private: beast::Journal j); public: - InstanceWrapper(); + InstanceWrapper() : instance_(nullptr, &wasm_instance_delete) {}; InstanceWrapper(InstanceWrapper const&) = delete; - InstanceWrapper(InstanceWrapper&& o); + InstanceWrapper(InstanceWrapper&& o) : instance_(nullptr, &wasm_instance_delete) + { + *this = std::move(o); // LCOV_EXCL_LINE + } - InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j); + InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j) + : store_(s.get()), instance_(init(s, m, exports_, imports, j)), j_(j) + { + } InstanceWrapper& operator=(InstanceWrapper&& o); @@ -171,7 +178,10 @@ public: InstanceWrapper& operator=(InstanceWrapper const&) = delete; - operator bool() const; + operator bool() const + { + return static_cast(instance_); + } FuncInfo getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const; @@ -186,20 +196,25 @@ public: setGas(std::int64_t) const; }; -struct ModuleWrapper +class ModuleWrapper { - ModulePtr module; - InstanceWrapper instanceWrap; - WasmExporttypeVec exportTypes; - beast::Journal j = beast::Journal(beast::Journal::getNullSink()); - -private: - static ModulePtr - init(StorePtr& s, Bytes const& wasmBin, beast::Journal j); + ModulePtr module_; + InstanceWrapper instanceWrap_; + WasmExporttypeVec exportTypes_; + beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); public: - ModuleWrapper(); - ModuleWrapper(ModuleWrapper&& o); + // LCOV_EXCL_START + ModuleWrapper() : module_(nullptr, &wasm_module_delete) + { + } + + ModuleWrapper(ModuleWrapper&& o) : module_(nullptr, &wasm_module_delete) + { + *this = std::move(o); + } + // LCOV_EXCL_STOP + ModuleWrapper& operator=(ModuleWrapper&& o); ModuleWrapper( @@ -210,27 +225,55 @@ public: beast::Journal j); ~ModuleWrapper() = default; - operator bool() const; + operator bool() const + { + return instanceWrap_; + } FuncInfo - getFunc(std::string_view funcName) const; + getFunc(std::string_view funcName) const + { + return instanceWrap_.getFunc(funcName, exportTypes_); + } wasm_functype_t* getFuncType(std::string_view funcName) const; Wmem - getMem() const; + getMem() const + { + return instanceWrap_.getMem(); + } InstanceWrapper& - getInstance(int i = 0); + getInstance(int i = 0) + { + return instanceWrap_; + } + + InstanceWrapper const& + getInstance(int i = 0) const + { + return instanceWrap_; + } int - addInstance(StorePtr& s, WasmExternVec const& imports); + addInstance(StorePtr& s, WasmExternVec const& imports) + { + instanceWrap_ = {s, module_, imports, j_}; + return 0; + } std::int64_t - getGas() const; + getGas() const + { + return instanceWrap_ ? instanceWrap_.getGas() : -1; + } private: + static ModulePtr + init(StorePtr& s, Bytes const& wasmBin, beast::Journal j); + WasmExternVec buildImports(StorePtr& s, ImportVec const& imports) const; }; @@ -245,7 +288,10 @@ class WasmiEngine std::mutex m_; // 1 instance mutex public: - WasmiEngine(); + WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete) + { + } + ~WasmiEngine() = default; static EnginePtr @@ -270,21 +316,37 @@ public: beast::Journal j); [[nodiscard]] std::int64_t - getGas() const; + getGas() const + { + return moduleWrap_ ? moduleWrap_->getGas() : -1; // LCOV_EXCL_LINE + } // Host functions helper functionality wasm_trap_t* newTrap(std::string const& msg); + // LCOV_EXCL_START [[nodiscard]] beast::Journal - getJournal() const; + getJournal() const + { + return j_; + } + // LCOV_EXCL_STOP private: [[nodiscard]] InstanceWrapper& - getRT(int m = 0, int i = 0) const; + getRT(int m = 0, int i = 0) const + { + if (!moduleWrap_) + Throw("no module"); + return moduleWrap_->getInstance(i); + } [[nodiscard]] Wmem - getMem() const; + getMem() const + { + return moduleWrap_ ? moduleWrap_->getMem() : Wmem(); + } Expected, TER> runHlp( @@ -319,7 +381,10 @@ private: makeModule(Bytes const& wasmCode, WasmExternVec const& imports = {}); [[nodiscard]] FuncInfo - getFunc(std::string_view funcName) const; + getFunc(std::string_view funcName) const + { + return moduleWrap_->getFunc(funcName); + } static std::vector convertParams(std::vector const& params); diff --git a/src/libxrpl/tx/wasm/HostFuncImpl.cpp b/src/libxrpl/tx/wasm/HostFuncImpl.cpp index dbcd9d8e78..15ffeba68b 100644 --- a/src/libxrpl/tx/wasm/HostFuncImpl.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImpl.cpp @@ -5,8 +5,7 @@ #include #include #include -#include -#include +#include #include @@ -19,10 +18,9 @@ namespace xrpl { Expected WasmHostFunctionsImpl::updateData(Slice const& data) { - if (data.size() > maxWasmDataLength) - { + if (data.size() > kMaxWasmDataLength) return Unexpected(HostFunctionError::DataFieldTooLarge); - } + data_ = Bytes(data.begin(), data.end()); return data_->size(); } diff --git a/src/libxrpl/tx/wasm/HostFuncImplFloat.cpp b/src/libxrpl/tx/wasm/HostFuncImplFloat.cpp index c950aed947..dda1a09296 100644 --- a/src/libxrpl/tx/wasm/HostFuncImplFloat.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImplFloat.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include diff --git a/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp b/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp index a9aefd885e..3f94587dc4 100644 --- a/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp @@ -10,9 +10,8 @@ #include #include #include -#include #include -#include +#include #include #include @@ -119,16 +118,12 @@ static Expected getAnyFieldData(FieldValue const& variantObj) { if (STBase const* const* obj = std::get_if(&variantObj)) - { return getAnyFieldData(*obj); - } if (uint256 const* const* u = std::get_if(&variantObj)) - { return Bytes((*u)->begin(), (*u)->end()); - } - return Unexpected(HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return Unexpected(HostFunctionError::Internal); // LCOV_EXCL_LINE } static inline bool @@ -144,8 +139,8 @@ locateField(STObject const& obj, Slice const& locator) if (locator.empty() || ((locator.size() & 3) != 0u)) // must be multiple of 4 return Unexpected(HostFunctionError::LocatorMalformed); - static_assert(maxWasmParamLength % sizeof(int32_t) == 0); - int32_t locBuf[maxWasmParamLength / sizeof(int32_t)]; + static_assert(kMaxWasmParamLength % sizeof(int32_t) == 0); + int32_t locBuf[kMaxWasmParamLength / sizeof(int32_t)]; int32_t const* locPtr = &locBuf[0]; int32_t const locSize = locator.size() / sizeof(int32_t); diff --git a/src/libxrpl/tx/wasm/HostFuncImplKeylet.cpp b/src/libxrpl/tx/wasm/HostFuncImplKeylet.cpp index 1c589dee09..5d1d14bfac 100644 --- a/src/libxrpl/tx/wasm/HostFuncImplKeylet.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImplKeylet.cpp @@ -6,9 +6,8 @@ #include #include #include -#include #include -#include +#include #include diff --git a/src/libxrpl/tx/wasm/HostFuncImplLedgerHeader.cpp b/src/libxrpl/tx/wasm/HostFuncImplLedgerHeader.cpp index 91092ba8d0..837112389a 100644 --- a/src/libxrpl/tx/wasm/HostFuncImplLedgerHeader.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImplLedgerHeader.cpp @@ -1,9 +1,8 @@ #include #include #include -#include #include -#include +#include #include #include diff --git a/src/libxrpl/tx/wasm/HostFuncImplNFT.cpp b/src/libxrpl/tx/wasm/HostFuncImplNFT.cpp index b312ab7098..30d6dd5eff 100644 --- a/src/libxrpl/tx/wasm/HostFuncImplNFT.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImplNFT.cpp @@ -5,9 +5,8 @@ #include #include #include -#include #include -#include +#include #include diff --git a/src/libxrpl/tx/wasm/HostFuncWrapper.cpp b/src/libxrpl/tx/wasm/HostFuncWrapper.cpp index 1b10608667..a8a35fb8d7 100644 --- a/src/libxrpl/tx/wasm/HostFuncWrapper.cpp +++ b/src/libxrpl/tx/wasm/HostFuncWrapper.cpp @@ -18,7 +18,8 @@ #include #include #include -#include +#include +#include #include #include @@ -38,6 +39,51 @@ namespace xrpl { using SFieldCRef = std::reference_wrapper; +static inline HostFunctions* +getHF(void* env) +{ + auto const* udata = reinterpret_cast(env); + HostFunctions* hf = &udata->first.get(); // NOLINT + return hf; +} + +static inline Expected +checkGas(void* env) +{ + auto const* udata = reinterpret_cast(env); + HostFunctions const* hf = &udata->first.get(); + auto* rt = hf->getRT(); + + if (rt == nullptr) + { + wasm_trap_t* trap = reinterpret_cast( // NOLINT + WasmEngine::instance().newTrap("hf no runtime")); // LCOV_EXCL_LINE + return Unexpected(trap); // LCOV_EXCL_LINE + } + + int64_t const gas = rt->getGas(); + WasmImportFunc const& impFunc = udata->second; + int64_t const x = gas >= impFunc.gas ? gas - impFunc.gas : 0; + + if (rt->setGas(x) < 0) + { + wasm_trap_t* trap = reinterpret_cast( // NOLINT + WasmEngine::instance().newTrap("can't set gas")); // LCOV_EXCL_LINE + return Unexpected(trap); // LCOV_EXCL_LINE + } + + if (gas < impFunc.gas) + { + wasm_trap_t* const trap = // NOLINT + reinterpret_cast(WasmEngine::instance().newTrap("hf out of gas")); + return Unexpected(trap); + } + + return x; +} + +//---------------------------------------------------------------------------------------------------------------------- + static int32_t setData( WasmRuntimeWrapper* runtime, @@ -50,48 +96,78 @@ setData( return 0; // LCOV_EXCL_LINE if (dst < 0 || dstSize < 0 || (src == nullptr) || srcSize < 0) - return HfErrorToInt(HostFunctionError::InvalidParams); + return hfErrorToInt(HostFunctionError::InvalidParams); - if (srcSize > maxWasmDataLength) - return HfErrorToInt(HostFunctionError::DataFieldTooLarge); + if (srcSize > kMaxWasmDataLength) + return hfErrorToInt(HostFunctionError::DataFieldTooLarge); auto const memory = (runtime != nullptr) ? runtime->getMem() : Wmem(); // LCOV_EXCL_START if (memory.s == 0u) - return HfErrorToInt(HostFunctionError::NoMemExported); + return hfErrorToInt(HostFunctionError::NoMemExported); // LCOV_EXCL_STOP - if ((int64_t)dst + dstSize > memory.s) - return HfErrorToInt(HostFunctionError::PointerOutOfBounds); + if (std::cmp_greater((int64_t)dst + dstSize, memory.s)) + return hfErrorToInt(HostFunctionError::PointerOutOfBounds); if (srcSize > dstSize) - return HfErrorToInt(HostFunctionError::BufferTooSmall); + return hfErrorToInt(HostFunctionError::BufferTooSmall); memcpy(memory.p + dst, src, srcSize); return srcSize; } -template +static Expected +getDataSlice( + WasmRuntimeWrapper* runtime, + wasm_val_vec_t const* params, + int32_t& i, + bool isUpdate = false) +{ + int64_t const ptr = params->data[i].of.i32; + int64_t const size = params->data[i + 1].of.i32; + i += 2; + if (ptr < 0 || size < 0) + return Unexpected(HostFunctionError::InvalidParams); + + if (size == 0) + return Slice(); + + if (size > (isUpdate ? kMaxWasmDataLength : kMaxWasmParamLength)) + return Unexpected(HostFunctionError::DataFieldTooLarge); + + auto const memory = runtime != nullptr ? runtime->getMem() : Wmem(); + // LCOV_EXCL_START + if (memory.s == 0u) + return Unexpected(HostFunctionError::NoMemExported); + // LCOV_EXCL_STOP + + if (std::cmp_greater(ptr + size, memory.s)) + return Unexpected(HostFunctionError::PointerOutOfBounds); + + Slice data(memory.p + ptr, size); + return data; +} + static Expected -getDataInt32(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataInt32(WasmRuntimeWrapper const*, wasm_val_vec_t const* params, int32_t& i) { auto const result = params->data[i].of.i32; i++; return result; } -template static Expected -getDataInt64(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataInt64(WasmRuntimeWrapper const*, wasm_val_vec_t const* params, int32_t& i) { auto const result = params->data[i].of.i64; i++; return result; } -template +template static Expected -getDataUnsigned(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataUnsigned(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { static_assert(std::is_unsigned_v); auto const r = getDataSlice(runtime, params, i); @@ -115,125 +191,75 @@ getDataUnsigned(IW* runtime, wasm_val_vec_t const* params, int32_t& i) return x; } -template static Expected -getDataUInt32(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataUInt32(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { return getDataUnsigned(runtime, params, i); } -template static Expected -getDataUInt64(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataUInt64(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { return getDataUnsigned(runtime, params, i); } -template static Expected -getDataSField(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataSField(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { auto const& m = SField::getKnownCodeToField(); auto const it = m.find(params->data[i].of.i32); i++; if (it == m.end()) - { return Unexpected(HostFunctionError::InvalidField); - } + return *it->second; } -template -static Expected -getDataSlice(IW* runtime, wasm_val_vec_t const* params, int32_t& i, bool isUpdate = false) -{ - int64_t const ptr = params->data[i].of.i32; - int64_t const size = params->data[i + 1].of.i32; - i += 2; - if (ptr < 0 || size < 0) - return Unexpected(HostFunctionError::InvalidParams); - - if (!size) - return Slice(); - - if (size > (isUpdate ? maxWasmDataLength : maxWasmParamLength)) - return Unexpected(HostFunctionError::DataFieldTooLarge); - - auto const memory = runtime ? runtime->getMem() : Wmem(); - // LCOV_EXCL_START - if (!memory.s) - return Unexpected(HostFunctionError::NoMemExported); - // LCOV_EXCL_STOP - - if (ptr + size > memory.s) - return Unexpected(HostFunctionError::PointerOutOfBounds); - - Slice data(memory.p + ptr, size); - return data; -} - -template static Expected -getDataUInt256(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataUInt256(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { auto const slice = getDataSlice(runtime, params, i); if (!slice) - { return Unexpected(slice.error()); - } if (slice->size() != uint256::size()) - { return Unexpected(HostFunctionError::InvalidParams); - } + return uint256::fromVoid(slice->data()); } -template static Expected -getDataAccountID(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataAccountID(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { auto const slice = getDataSlice(runtime, params, i); if (!slice) - { return Unexpected(slice.error()); - } if (slice->size() != AccountID::size()) - { return Unexpected(HostFunctionError::InvalidParams); - } return AccountID::fromVoid(slice->data()); } -template static Expected -getDataCurrency(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataCurrency(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { auto const slice = getDataSlice(runtime, params, i); if (!slice) - { return Unexpected(slice.error()); - } if (slice->size() != Currency::size()) - { return Unexpected(HostFunctionError::InvalidParams); - } return Currency::fromVoid(slice->data()); } -template static Expected -getDataAsset(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataAsset(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { auto const slice = getDataSlice(runtime, params, i); if (!slice) - { return Unexpected(slice.error()); - } if (slice->size() == MPTID::size()) { @@ -247,6 +273,7 @@ getDataAsset(IW* runtime, wasm_val_vec_t const* params, int32_t& i) auto const issue = Issue{currency, xrpAccount()}; if (!issue.native()) return Unexpected(HostFunctionError::InvalidParams); + return Asset{issue}; } @@ -258,23 +285,24 @@ getDataAsset(IW* runtime, wasm_val_vec_t const* params, int32_t& i) if (issue.native()) return Unexpected(HostFunctionError::InvalidParams); + return Asset{issue}; } return Unexpected(HostFunctionError::InvalidParams); } -template static Expected -getDataString(IW* runtime, wasm_val_vec_t const* params, int32_t& i) +getDataString(WasmRuntimeWrapper* runtime, wasm_val_vec_t const* params, int32_t& i) { auto const slice = getDataSlice(runtime, params, i); if (!slice) return Unexpected(slice.error()); + return std::string_view(reinterpret_cast(slice->data()), slice->size()); } -static std::nullptr_t +static inline std::nullptr_t hfResult(wasm_val_vec_t* results, int32_t value) { results->data[0] = WASM_I32_VAL(value); @@ -282,10 +310,10 @@ hfResult(wasm_val_vec_t* results, int32_t value) return nullptr; } -static std::nullptr_t +static inline std::nullptr_t hfResult(wasm_val_vec_t* results, HostFunctionError value) { - results->data[0] = WASM_I32_VAL(HfErrorToInt(value)); + results->data[0] = WASM_I32_VAL(hfErrorToInt(value)); // results->size = 1; return nullptr; } @@ -300,77 +328,70 @@ returnResult( int32_t index) { if (!res) - { return hfResult(results, res.error()); - } - using t = std::decay_t; - if constexpr (std::is_same_v) + if constexpr (std::is_same_v) { if (index < 0 || index + 1 >= params->size) - return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return hfResult(results, HostFunctionError::Internal); // LCOV_EXCL_LINE - return hfResult( - results, - setData( - runtime, - params->data[index].of.i32, - params->data[index + 1].of.i32, - res->data(), - res->size())); + auto const dataResult = setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + res->data(), + res->size()); + return hfResult(results, dataResult); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { if (index < 0 || index + 1 >= params->size) - return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return hfResult(results, HostFunctionError::Internal); // LCOV_EXCL_LINE - return hfResult( - results, - setData( - runtime, - params->data[index].of.i32, - params->data[index + 1].of.i32, - res->data(), - res->size())); + auto const dataResult = setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + res->data(), + res->size()); + return hfResult(results, dataResult); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { return hfResult(results, res.value()); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { if (index < 0 || index + 1 >= params->size) - return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return hfResult(results, HostFunctionError::Internal); // LCOV_EXCL_LINE auto const resultValue = adjustWasmEndianess(res.value()); - return hfResult( - results, - setData( - runtime, - params->data[index].of.i32, - params->data[index + 1].of.i32, - reinterpret_cast(&resultValue), - static_cast(sizeof(resultValue)))); + auto const dataResult = setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + reinterpret_cast(&resultValue), + static_cast(sizeof(resultValue))); + return hfResult(results, dataResult); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { if (index < 0 || index + 1 >= params->size) - return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return hfResult(results, HostFunctionError::Internal); // LCOV_EXCL_LINE auto const resultValue = adjustWasmEndianess(res.value()); - return hfResult( - results, - setData( - runtime, - params->data[index].of.i32, - params->data[index + 1].of.i32, - reinterpret_cast(&resultValue), - static_cast(sizeof(resultValue)))); + auto const dataResult = setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + reinterpret_cast(&resultValue), + static_cast(sizeof(resultValue))); + return hfResult(results, dataResult); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { if (index < 0 || index + 3 >= params->size) - return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return hfResult(results, HostFunctionError::Internal); // LCOV_EXCL_LINE auto const mantissa = adjustWasmEndianess(res->first); auto const r1 = setData( @@ -393,7 +414,7 @@ returnResult( if (r2 < 0) return hfResult(results, r2); - return hfResult(results, r1 + r2); // 12 + return hfResult(results, r1 + r2); // 12 bytes } else { @@ -401,49 +422,6 @@ returnResult( } } -static inline HostFunctions* -getHF(void* env) -{ - auto const* udata = reinterpret_cast(env); - HostFunctions* hf = reinterpret_cast(udata->first); // NOLINT - return hf; -} - -static inline Expected -checkGas(void* env) -{ - auto const* udata = reinterpret_cast(env); - HostFunctions const* hf = reinterpret_cast(udata->first); - - auto* runtime = reinterpret_cast(hf->getRT()); - if (runtime == nullptr) - { - wasm_trap_t* trap = reinterpret_cast( // NOLINT - WasmEngine::instance().newTrap("hf no runtime")); // LCOV_EXCL_LINE - return Unexpected(trap); // LCOV_EXCL_LINE - } - - int64_t const gas = runtime->getGas(); - WasmImportFunc const& impFunc = udata->second; - int64_t const x = gas >= impFunc.gas ? gas - impFunc.gas : 0; - - if (runtime->setGas(x) < 0) - { - wasm_trap_t* trap = reinterpret_cast( // NOLINT - WasmEngine::instance().newTrap("can't set gas")); // LCOV_EXCL_LINE - return Unexpected(trap); // LCOV_EXCL_LINE - } - - if (gas < impFunc.gas) - { - wasm_trap_t* const trap = // NOLINT - reinterpret_cast(WasmEngine::instance().newTrap("hf out of gas")); - return Unexpected(trap); - } - - return x; -} - //---------------------------------------------------------------------------------------------------------------------- wasm_trap_t* getLedgerSqn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) @@ -451,7 +429,7 @@ getLedgerSqn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int const index = 0; return returnResult(runtime, params, results, hf->getLedgerSqn(), index); @@ -463,7 +441,7 @@ getParentLedgerTime_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int const index = 0; return returnResult(runtime, params, results, hf->getParentLedgerTime(), index); @@ -475,7 +453,7 @@ getParentLedgerHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int const index = 0; return returnResult(runtime, params, results, hf->getParentLedgerHash(), index); @@ -487,7 +465,7 @@ getBaseFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int const index = 0; return returnResult(runtime, params, results, hf->getBaseFee(), index); @@ -499,14 +477,12 @@ isAmendmentEnabled_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const slice = getDataSlice(runtime, params, index); if (!slice) - { return hfResult(results, slice.error()); - } if (slice->size() == uint256::size()) { @@ -517,9 +493,7 @@ isAmendmentEnabled_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* } if (slice->size() > 64) - { return hfResult(results, HostFunctionError::DataFieldTooLarge); - } auto const str = std::string_view(reinterpret_cast(slice->data()), slice->size()); return returnResult(runtime, params, results, hf->isAmendmentEnabled(str), index); @@ -531,20 +505,16 @@ cacheLedgerObj_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* res if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const id = getDataUInt256(runtime, params, index); if (!id) - { return hfResult(results, id.error()); - } auto const cache = getDataInt32(runtime, params, index); if (!cache) - { return hfResult(results, cache.error()); // LCOV_EXCL_LINE - } return returnResult(runtime, params, results, hf->cacheLedgerObj(*id, *cache), index); } @@ -555,14 +525,13 @@ getTxField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const fname = getDataSField(runtime, params, index); if (!fname) - { return hfResult(results, fname.error()); - } + return returnResult(runtime, params, results, hf->getTxField(*fname), index); } @@ -572,14 +541,12 @@ getCurrentLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_ if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const fname = getDataSField(runtime, params, index); if (!fname) - { return hfResult(results, fname.error()); - } return returnResult(runtime, params, results, hf->getCurrentLedgerObjField(*fname), index); } @@ -590,20 +557,16 @@ getLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const cache = getDataInt32(runtime, params, index); if (!cache) - { return hfResult(results, cache.error()); // LCOV_EXCL_LINE - } auto const fname = getDataSField(runtime, params, index); if (!fname) - { return hfResult(results, fname.error()); - } return returnResult(runtime, params, results, hf->getLedgerObjField(*cache, *fname), index); } @@ -614,14 +577,12 @@ getTxNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* r if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } return returnResult(runtime, params, results, hf->getTxNestedField(*bytes), index); } @@ -635,14 +596,13 @@ getCurrentLedgerObjNestedField_wrap( if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } + return returnResult( runtime, params, results, hf->getCurrentLedgerObjNestedField(*bytes), index); } @@ -653,20 +613,16 @@ getLedgerObjNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_v if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const cache = getDataInt32(runtime, params, index); if (!cache) - { return hfResult(results, cache.error()); // LCOV_EXCL_LINE - } auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } return returnResult( runtime, params, results, hf->getLedgerObjNestedField(*cache, *bytes), index); @@ -678,14 +634,12 @@ getTxArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const fname = getDataSField(runtime, params, index); if (!fname) - { return hfResult(results, fname.error()); - } return returnResult(runtime, params, results, hf->getTxArrayLen(*fname), index); } @@ -696,14 +650,12 @@ getCurrentLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_v if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const fname = getDataSField(runtime, params, index); if (!fname) - { return hfResult(results, fname.error()); - } return returnResult(runtime, params, results, hf->getCurrentLedgerObjArrayLen(*fname), index); } @@ -714,20 +666,16 @@ getLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_ if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const cache = getDataInt32(runtime, params, index); if (!cache) - { return hfResult(results, cache.error()); // LCOV_EXCL_LINE - } auto const fname = getDataSField(runtime, params, index); if (!fname) - { return hfResult(results, fname.error()); - } return returnResult(runtime, params, results, hf->getLedgerObjArrayLen(*cache, *fname), index); } @@ -738,14 +686,12 @@ getTxNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } return returnResult(runtime, params, results, hf->getTxNestedArrayLen(*bytes), index); } @@ -759,14 +705,12 @@ getCurrentLedgerObjNestedArrayLen_wrap( if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } return returnResult( runtime, params, results, hf->getCurrentLedgerObjNestedArrayLen(*bytes), index); @@ -777,20 +721,17 @@ getLedgerObjNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_va if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const cache = getDataInt32(runtime, params, index); if (!cache) - { return hfResult(results, cache.error()); // LCOV_EXCL_LINE - } auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } + return returnResult( runtime, params, results, hf->getLedgerObjNestedArrayLen(*cache, *bytes), index); } @@ -801,14 +742,12 @@ updateData_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const bytes = getDataSlice(runtime, params, index, true); if (!bytes) - { return hfResult(results, bytes.error()); - } return returnResult(runtime, params, results, hf->updateData(*bytes), index); } @@ -819,26 +758,20 @@ checkSignature_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* res if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const message = getDataSlice(runtime, params, index); if (!message) - { return hfResult(results, message.error()); - } auto const signature = getDataSlice(runtime, params, index); if (!signature) - { return hfResult(results, signature.error()); - } auto const pubkey = getDataSlice(runtime, params, index); if (!pubkey) - { return hfResult(results, pubkey.error()); - } return returnResult( runtime, params, results, hf->checkSignature(*message, *signature, *pubkey), index); @@ -850,14 +783,13 @@ computeSha512HalfHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const bytes = getDataSlice(runtime, params, index); if (!bytes) - { return hfResult(results, bytes.error()); - } + return returnResult(runtime, params, results, hf->computeSha512HalfHash(*bytes), index); } @@ -867,14 +799,12 @@ accountKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } return returnResult(runtime, params, results, hf->accountKeylet(*acc), index); } @@ -885,20 +815,16 @@ ammKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const issue1 = getDataAsset(runtime, params, index); if (!issue1) - { return hfResult(results, issue1.error()); - } auto const issue2 = getDataAsset(runtime, params, index); if (!issue2) - { return hfResult(results, issue2.error()); - } return returnResult( runtime, params, results, hf->ammKeylet(issue1.value(), issue2.value()), index); @@ -910,20 +836,16 @@ checkKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult(runtime, params, results, hf->checkKeylet(acc.value(), *seq), index); } @@ -934,26 +856,20 @@ credentialKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* r if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const subj = getDataAccountID(runtime, params, index); if (!subj) - { return hfResult(results, subj.error()); - } auto const iss = getDataAccountID(runtime, params, index); if (!iss) - { return hfResult(results, iss.error()); - } auto const credType = getDataSlice(runtime, params, index); if (!credType) - { return hfResult(results, credType.error()); - } return returnResult( runtime, params, results, hf->credentialKeylet(*subj, *iss, *credType), index); @@ -965,20 +881,16 @@ delegateKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* res if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const authorize = getDataAccountID(runtime, params, index); if (!authorize) - { return hfResult(results, authorize.error()); - } return returnResult( runtime, params, results, hf->delegateKeylet(acc.value(), authorize.value()), index); @@ -990,20 +902,16 @@ depositPreauthKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_ if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const authorize = getDataAccountID(runtime, params, index); if (!authorize) - { return hfResult(results, authorize.error()); - } return returnResult( runtime, params, results, hf->depositPreauthKeylet(acc.value(), authorize.value()), index); @@ -1015,14 +923,12 @@ didKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } return returnResult(runtime, params, results, hf->didKeylet(acc.value()), index); } @@ -1033,20 +939,16 @@ escrowKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult(runtime, params, results, hf->escrowKeylet(*acc, *seq), index); } @@ -1057,26 +959,20 @@ lineKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc1 = getDataAccountID(runtime, params, index); if (!acc1) - { return hfResult(results, acc1.error()); - } auto const acc2 = getDataAccountID(runtime, params, index); if (!acc2) - { return hfResult(results, acc2.error()); - } auto const currency = getDataCurrency(runtime, params, index); if (!currency) - { return hfResult(results, currency.error()); - } return returnResult( runtime, @@ -1092,20 +988,16 @@ mptIssuanceKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult( runtime, params, results, hf->mptIssuanceKeylet(acc.value(), seq.value()), index); @@ -1117,26 +1009,20 @@ mptokenKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const slice = getDataSlice(runtime, params, index); if (!slice) - { return hfResult(results, slice.error()); - } if (slice->size() != MPTID::size()) - { return hfResult(results, HostFunctionError::InvalidParams); - } auto const mptid = MPTID::fromVoid(slice->data()); auto const holder = getDataAccountID(runtime, params, index); if (!holder) - { return hfResult(results, holder.error()); - } return returnResult(runtime, params, results, hf->mptokenKeylet(mptid, holder.value()), index); } @@ -1147,20 +1033,16 @@ nftOfferKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* res if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult( runtime, params, results, hf->nftOfferKeylet(acc.value(), seq.value()), index); @@ -1172,20 +1054,16 @@ offerKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult(runtime, params, results, hf->offerKeylet(acc.value(), seq.value()), index); } @@ -1196,20 +1074,17 @@ oracleKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const documentId = getDataUInt32(runtime, params, index); if (!documentId) - { return hfResult(results, documentId.error()); - } + return returnResult(runtime, params, results, hf->oracleKeylet(*acc, *documentId), index); } @@ -1219,26 +1094,20 @@ paychanKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const dest = getDataAccountID(runtime, params, index); if (!dest) - { return hfResult(results, dest.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult( runtime, params, results, hf->paychanKeylet(acc.value(), dest.value(), seq.value()), index); @@ -1250,20 +1119,16 @@ permissionedDomainKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_ if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult( runtime, params, results, hf->permissionedDomainKeylet(acc.value(), seq.value()), index); @@ -1275,14 +1140,12 @@ signersKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } return returnResult(runtime, params, results, hf->signersKeylet(acc.value()), index); } @@ -1293,20 +1156,16 @@ ticketKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult( runtime, params, results, hf->ticketKeylet(acc.value(), seq.value()), index); @@ -1318,20 +1177,16 @@ vaultKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const seq = getDataUInt32(runtime, params, index); if (!seq) - { return hfResult(results, seq.error()); - } return returnResult(runtime, params, results, hf->vaultKeylet(acc.value(), seq.value()), index); } @@ -1342,20 +1197,16 @@ getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const acc = getDataAccountID(runtime, params, index); if (!acc) - { return hfResult(results, acc.error()); - } auto const nftId = getDataUInt256(runtime, params, index); if (!nftId) - { return hfResult(results, nftId.error()); - } return returnResult(runtime, params, results, hf->getNFT(*acc, *nftId), index); } @@ -1366,14 +1217,12 @@ getNFTIssuer_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const nftId = getDataUInt256(runtime, params, index); if (!nftId) - { return hfResult(results, nftId.error()); - } return returnResult(runtime, params, results, hf->getNFTIssuer(*nftId), index); } @@ -1384,14 +1233,12 @@ getNFTTaxon_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const nftId = getDataUInt256(runtime, params, index); if (!nftId) - { return hfResult(results, nftId.error()); - } return returnResult(runtime, params, results, hf->getNFTTaxon(*nftId), index); } @@ -1402,14 +1249,12 @@ getNFTFlags_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const nftId = getDataUInt256(runtime, params, index); if (!nftId) - { return hfResult(results, nftId.error()); - } return returnResult(runtime, params, results, hf->getNFTFlags(*nftId), index); } @@ -1420,14 +1265,12 @@ getNFTTransferFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const nftId = getDataUInt256(runtime, params, index); if (!nftId) - { return hfResult(results, nftId.error()); - } return returnResult(runtime, params, results, hf->getNFTTransferFee(*nftId), index); } @@ -1438,14 +1281,12 @@ getNFTSerial_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; auto const nftId = getDataUInt256(runtime, params, index); if (!nftId) - { return hfResult(results, nftId.error()); - } return returnResult(runtime, params, results, hf->getNFTSerial(*nftId), index); } @@ -1456,42 +1297,30 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; int64_t const len = (int64_t)params->data[1].of.i32 + params->data[3].of.i32; if (len < 0) - { return hfResult(results, HostFunctionError::InvalidParams); - } - if (std::cmp_greater(len, maxWasmParamLength)) - { + if (std::cmp_greater(len, kMaxWasmParamLength)) return hfResult(results, HostFunctionError::DataFieldTooLarge); - } auto const msg = getDataString(runtime, params, index); if (!msg) - { return hfResult(results, msg.error()); - } auto const data = getDataSlice(runtime, params, index); if (!data) - { return hfResult(results, data.error()); - } auto const asHex = getDataInt32(runtime, params, index); if (!asHex) - { return hfResult(results, asHex.error()); // LCOV_EXCL_LINE - } if (*asHex != 0 && *asHex != 1) - { return hfResult(results, HostFunctionError::InvalidParams); - } return returnResult(runtime, params, results, hf->trace(*msg, *data, *asHex != 0), index); } @@ -1502,31 +1331,23 @@ traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int index = 0; int32_t const len = params->data[1].of.i32; if (len < 0) - { return hfResult(results, HostFunctionError::InvalidParams); - } - if (std::cmp_greater(len, maxWasmParamLength)) - { + if (std::cmp_greater(len, kMaxWasmParamLength)) return hfResult(results, HostFunctionError::DataFieldTooLarge); - } auto const msg = getDataString(runtime, params, index); if (!msg) - { return hfResult(results, msg.error()); - } auto const number = getDataInt64(runtime, params, index); if (!number) - { return hfResult(results, number.error()); // LCOV_EXCL_LINE - } return returnResult(runtime, params, results, hf->traceNum(*msg, *number), index); } @@ -1537,31 +1358,23 @@ traceAccount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int32_t const len = params->data[1].of.i32; if (len < 0) - { return hfResult(results, HostFunctionError::InvalidParams); - } - if (std::cmp_greater(len, maxWasmParamLength)) - { + if (std::cmp_greater(len, kMaxWasmParamLength)) return hfResult(results, HostFunctionError::DataFieldTooLarge); - } int i = 0; auto const msg = getDataString(runtime, params, i); if (!msg) - { return hfResult(results, msg.error()); - } auto const account = getDataAccountID(runtime, params, i); if (!account) - { return hfResult(results, account.error()); - } return returnResult(runtime, params, results, hf->traceAccount(*msg, *account), i); } @@ -1572,31 +1385,23 @@ traceFloat_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int32_t const len = params->data[1].of.i32; if (len < 0) - { return hfResult(results, HostFunctionError::InvalidParams); - } - if (std::cmp_greater(len, maxWasmParamLength)) - { + if (std::cmp_greater(len, kMaxWasmParamLength)) return hfResult(results, HostFunctionError::DataFieldTooLarge); - } int i = 0; auto const msg = getDataString(runtime, params, i); if (!msg) - { return hfResult(results, msg.error()); - } auto const number = getDataSlice(runtime, params, i); if (!number) - { return hfResult(results, number.error()); - } return returnResult(runtime, params, results, hf->traceFloat(*msg, *number), i); } @@ -1607,31 +1412,23 @@ traceAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int32_t const len = params->data[1].of.i32; if (len < 0) - { return hfResult(results, HostFunctionError::InvalidParams); - } - if (std::cmp_greater(len, maxWasmParamLength)) - { + if (std::cmp_greater(len, kMaxWasmParamLength)) return hfResult(results, HostFunctionError::DataFieldTooLarge); - } int i = 0; auto const msg = getDataString(runtime, params, i); if (!msg) - { return hfResult(results, msg.error()); - } auto const amountSliceOpt = getDataSlice(runtime, params, i); if (!amountSliceOpt) - { return hfResult(results, amountSliceOpt.error()); - } auto const amountSlice = amountSliceOpt.value(); auto serialIter = SerialIter(amountSlice); @@ -1660,7 +1457,7 @@ floatFromInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataInt64(runtime, params, i); @@ -1682,7 +1479,7 @@ floatFromUint_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataUInt64(runtime, params, i); @@ -1704,7 +1501,7 @@ floatFromSTAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1739,7 +1536,7 @@ floatFromSTNumber_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1774,7 +1571,7 @@ floatToInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1796,7 +1593,7 @@ floatToMantExp_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* res if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1813,7 +1610,7 @@ floatFromMantExp_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* r if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; @@ -1840,7 +1637,7 @@ floatCompare_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1860,7 +1657,7 @@ floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1886,7 +1683,7 @@ floatSubtract_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1912,7 +1709,7 @@ floatMultiply_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1938,7 +1735,7 @@ floatDivide_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* result if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1964,7 +1761,7 @@ floatRoot_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -1990,7 +1787,7 @@ floatPower_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results if (auto g = checkGas(env); !g) return g.error(); // LCOV_EXCL_LINE auto* hf = getHF(env); - auto* runtime = reinterpret_cast(hf->getRT()); + auto* runtime = hf->getRT(); int i = 0; auto const x = getDataSlice(runtime, params, i); @@ -2013,10 +1810,12 @@ floatPower_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results // LCOV_EXCL_START namespace test { -class MockWasmRuntimeWrapper +class MockWasmRuntimeWrapper : public WasmRuntimeWrapper { Wmem mem_; + std::int64_t gas_ = 1'000'000; + public: MockWasmRuntimeWrapper(Wmem memory) : mem_(memory) { @@ -2024,10 +1823,23 @@ public: // Mock methods to simulate the behavior of WasmRuntimeWrapper [[nodiscard]] Wmem - getMem() const + getMem() override { return mem_; } + + std::int64_t + getGas() override + { + return gas_; + } + + std::int64_t + setGas(std::int64_t gas) override + { + gas_ = gas; + return gas_; + } }; bool @@ -2036,11 +1848,11 @@ testGetDataIncrement() wasm_val_t values[4]; std::array buffer = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; - MockWasmRuntimeWrapper runtime(Wmem{.p = buffer.data(), .s = buffer.size()}); + MockWasmRuntimeWrapper runtime(Wmem(buffer.data(), buffer.size())); { // test int32_t - wasm_val_vec_t const params = {1, &values[0]}; + wasm_val_vec_t const params = {.size = 1, .data = &values[0]}; values[0] = WASM_I32_VAL(42); @@ -2052,7 +1864,7 @@ testGetDataIncrement() { // test int64_t - wasm_val_vec_t const params = {1, &values[0]}; + wasm_val_vec_t const params = {.size = 1, .data = &values[0]}; values[0] = WASM_I64_VAL(1234); @@ -2064,7 +1876,7 @@ testGetDataIncrement() { // test SFieldCRef - wasm_val_vec_t const params = {1, &values[0]}; + wasm_val_vec_t const params = {.size = 1, .data = &values[0]}; values[0] = WASM_I32_VAL(sfAccount.getCode()); @@ -2076,7 +1888,7 @@ testGetDataIncrement() { // test Slice - wasm_val_vec_t const params = {2, &values[0]}; + wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(3); @@ -2089,7 +1901,7 @@ testGetDataIncrement() { // test string - wasm_val_vec_t const params = {2, &values[0]}; + wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(5); @@ -2107,7 +1919,7 @@ testGetDataIncrement() AccountID const id( calcAccountID(generateKeyPair(KeyType::Secp256k1, generateSeed("alice")).first)); - wasm_val_vec_t const params = {2, &values[0]}; + wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(AccountID::size()); @@ -2123,7 +1935,7 @@ testGetDataIncrement() // test uint256 Hash h1 = sha512Half(Slice(buffer.data(), 8)); - wasm_val_vec_t const params = {2, &values[0]}; + wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(Hash::size()); @@ -2139,7 +1951,7 @@ testGetDataIncrement() // test Currency Currency const c = xrpCurrency(); - wasm_val_vec_t const params = {2, &values[0]}; + wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(Currency::size()); diff --git a/src/libxrpl/tx/wasm/WasmVM.cpp b/src/libxrpl/tx/wasm/WasmVM.cpp index c3c724cd43..0f7f947a0a 100644 --- a/src/libxrpl/tx/wasm/WasmVM.cpp +++ b/src/libxrpl/tx/wasm/WasmVM.cpp @@ -4,7 +4,8 @@ #include #include #include // IWYU pragma: keep -#include +#include +#include #include #include @@ -27,7 +28,7 @@ namespace xrpl { // See XLS-0102 ยง6.5 (Future-Proofing): // https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0102-wasm-vm#65-future-proofing static void -setCommonHostFunctions(HostFunctions* hfs, ImportVec& i) +setCommonHostFunctions(HostFunctions& hfs, ImportVec& i) { // clang-format off WASM_IMPORT_FUNC2(i, getLedgerSqn, "get_ledger_sqn", hfs, 60); @@ -108,8 +109,8 @@ createWasmImport(HostFunctions& hfs) { ImportVec i; - setCommonHostFunctions(&hfs, i); - WASM_IMPORT_FUNC2(i, updateData, "update_data", &hfs, 1000); + setCommonHostFunctions(hfs, i); + WASM_IMPORT_FUNC2(i, updateData, "update_data", hfs, 1000); return i; } @@ -140,7 +141,7 @@ runEscrowWasm( #ifdef DEBUG_OUTPUT std::cout << ", ret: " << ret->result << ", gas spent: " << ret->cost << std::endl; #endif - return EscrowResult{ret->result, ret->cost}; + return EscrowResult{.result = ret->result, .cost = ret->cost}; } NotTEC diff --git a/src/libxrpl/tx/wasm/WasmiVM.cpp b/src/libxrpl/tx/wasm/WasmiVM.cpp index e22380741b..007610fee2 100644 --- a/src/libxrpl/tx/wasm/WasmiVM.cpp +++ b/src/libxrpl/tx/wasm/WasmiVM.cpp @@ -5,7 +5,8 @@ #include #include #include -#include +#include +#include #include #include @@ -76,30 +77,31 @@ printWasmError(std::string_view msg, wasm_trap_t* trap, beast::Journal jlog) } // namespace -struct WasmiRuntimeWrapper : public WasmRuntimeWrapper +class WasmiRuntimeWrapper : public WasmRuntimeWrapper { - InstanceWrapper& iw; + InstanceWrapper& iw_; - WasmiRuntimeWrapper(InstanceWrapper& iw) : iw(iw) +public: + WasmiRuntimeWrapper(InstanceWrapper& iw) : iw_(iw) { } Wmem getMem() override { - return iw.getMem(); + return iw_.getMem(); } std::int64_t getGas() override { - return iw.getGas(); + return iw_.getGas(); } std::int64_t setGas(std::int64_t gas) override { - return iw.setGas(gas); + return iw_.setGas(gas); } }; @@ -118,69 +120,43 @@ InstanceWrapper::init( if (!mi || (trap != nullptr)) { printWasmError("can't create instance", trap, j); - throw std::runtime_error("can't create instance"); + Throw("can't create instance"); } wasm_instance_exports(mi.get(), expt.get()); return mi; } -InstanceWrapper::InstanceWrapper() : instance(nullptr, &wasm_instance_delete) -{ -} - -// LCOV_EXCL_START -InstanceWrapper::InstanceWrapper(InstanceWrapper&& o) : instance(nullptr, &wasm_instance_delete) -{ - *this = std::move(o); -} -// LCOV_EXCL_STOP - -InstanceWrapper::InstanceWrapper( - StorePtr& s, - ModulePtr& m, - WasmExternVec const& imports, - beast::Journal j) - : store(s.get()), instance(init(s, m, exports, imports, j)), j(j) -{ -} - InstanceWrapper& InstanceWrapper::operator=(InstanceWrapper&& o) { if (this == &o) return *this; // LCOV_EXCL_LINE - store = o.store; - o.store = nullptr; - exports = std::move(o.exports); - memIdx = o.memIdx; - o.memIdx = -1; - instance = std::move(o.instance); + store_ = o.store_; + o.store_ = nullptr; + exports_ = std::move(o.exports_); + memIdx_ = o.memIdx_; + o.memIdx_ = -1; + instance_ = std::move(o.instance_); - j = o.j; + j_ = o.j_; return *this; } -InstanceWrapper:: -operator bool() const -{ - return static_cast(instance); -} - FuncInfo InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const { wasm_func_t const* f = nullptr; wasm_functype_t const* ft = nullptr; - if (!instance) - throw std::runtime_error("no instance"); // LCOV_EXCL_LINE + if (!instance_) + Throw("no instance"); // LCOV_EXCL_LINE if (exportTypes.empty()) - throw std::runtime_error("no export"); // LCOV_EXCL_LINE - if (exportTypes.size() != exports.size()) - throw std::runtime_error("invalid export"); // LCOV_EXCL_LINE + Throw("no export"); // LCOV_EXCL_LINE + if (exportTypes.size() != exports_.size()) + Throw("invalid export"); // LCOV_EXCL_LINE for (unsigned i = 0; i < exportTypes.size(); ++i) { @@ -193,9 +169,9 @@ InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exp if (funcName != std::string_view(name->data, name->size)) continue; - auto const* exn(exports[i]); + auto const* exn(exports_[i]); if (wasm_extern_kind(exn) != WASM_EXTERN_FUNC) - throw std::runtime_error("invalid export"); // LCOV_EXCL_LINE + Throw("invalid export"); // LCOV_EXCL_LINE ft = wasm_externtype_as_functype_const(exnType); f = wasm_extern_as_func_const(exn); @@ -204,7 +180,7 @@ InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exp } if ((f == nullptr) || (ft == nullptr)) - throw std::runtime_error("can't find function <" + std::string(funcName) + ">"); + Throw("can't find function <" + std::string(funcName) + ">"); return {f, ft}; } @@ -212,22 +188,20 @@ InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exp Wmem InstanceWrapper::getMem() const { - if (memIdx >= 0) + if (memIdx_ >= 0) { - auto* e(exports[memIdx]); + auto* e(exports_[memIdx_]); wasm_memory_t* mem = wasm_extern_as_memory(e); - return { - .p = reinterpret_cast(wasm_memory_data(mem)), - .s = wasm_memory_data_size(mem)}; + return Wmem(wasm_memory_data(mem), wasm_memory_data_size(mem)); } wasm_memory_t* mem = nullptr; - for (int i = 0; i < exports.size(); ++i) + for (int i = 0; i < exports_.size(); ++i) { - auto* e(exports[i]); + auto* e(exports_[i]); if (wasm_extern_kind(e) == WASM_EXTERN_MEMORY) { - memIdx = i; + memIdx_ = i; mem = wasm_extern_as_memory(e); break; } @@ -236,34 +210,32 @@ InstanceWrapper::getMem() const if (mem == nullptr) return {}; // LCOV_EXCL_LINE - return { - .p = reinterpret_cast(wasm_memory_data(mem)), - .s = wasm_memory_data_size(mem)}; + return Wmem(wasm_memory_data(mem), wasm_memory_data_size(mem)); } std::int64_t InstanceWrapper::getGas() const { - if (store == nullptr) + if (store_ == nullptr) return -1; // LCOV_EXCL_LINE std::uint64_t gas = 0; - wasm_store_get_fuel(store, &gas); + wasm_store_get_fuel(store_, &gas); return static_cast(gas); } std::int64_t InstanceWrapper::setGas(std::int64_t gas) const { - if (store == nullptr) + if (store_ == nullptr) return -1; // LCOV_EXCL_LINE if (gas < 0) gas = std::numeric_limits::max(); - wasmi_error_t* err = wasm_store_set_fuel(store, static_cast(gas)); + wasmi_error_t* err = wasm_store_set_fuel(store_, static_cast(gas)); if (err != nullptr) { // LCOV_EXCL_START - printWasmError("Can't set instance gas", nullptr, j); + printWasmError("Can't set instance gas", nullptr, j_); wasmi_error_delete(err); return -1; // LCOV_EXCL_STOP @@ -277,7 +249,7 @@ InstanceWrapper::setGas(std::int64_t gas) const ModulePtr ModuleWrapper::init(StorePtr& s, Bytes const& wasmBin, beast::Journal j) { - wasm_byte_vec_t const code{wasmBin.size(), (char*)(wasmBin.data())}; + wasm_byte_vec_t const code{.size = wasmBin.size(), .data = (char*)(wasmBin.data())}; ModulePtr m = ModulePtr(wasm_module_new(s.get(), &code), &wasm_module_delete); if (!m) throw std::runtime_error("can't create module"); @@ -285,26 +257,15 @@ ModuleWrapper::init(StorePtr& s, Bytes const& wasmBin, beast::Journal j) return m; } -// LCOV_EXCL_START -ModuleWrapper::ModuleWrapper() : module(nullptr, &wasm_module_delete) -{ -} - -ModuleWrapper::ModuleWrapper(ModuleWrapper&& o) : module(nullptr, &wasm_module_delete) -{ - *this = std::move(o); -} -// LCOV_EXCL_STOP - ModuleWrapper::ModuleWrapper( StorePtr& s, Bytes const& wasmBin, bool instantiate, ImportVec const& imports, beast::Journal j) - : module(init(s, wasmBin, j)), j(j) + : module_(init(s, wasmBin, j)), j_(j) { - wasm_module_exports(module.get(), exportTypes.get()); + wasm_module_exports(module_.get(), exportTypes_.get()); auto wimports = buildImports(s, imports); if (instantiate) { @@ -319,20 +280,14 @@ ModuleWrapper::operator=(ModuleWrapper&& o) if (this == &o) return *this; - module = std::move(o.module); - instanceWrap = std::move(o.instanceWrap); - exportTypes = std::move(o.exportTypes); - j = o.j; + module_ = std::move(o.module_); + instanceWrap_ = std::move(o.instanceWrap_); + exportTypes_ = std::move(o.exportTypes_); + j_ = o.j_; return *this; } -ModuleWrapper:: -operator bool() const -{ - return instanceWrap; -} - // LCOV_EXCL_STOP static WasmValtypeVec @@ -391,7 +346,7 @@ WasmExternVec ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const { WasmImporttypeVec importTypes; - wasm_module_imports(module.get(), importTypes.get()); + wasm_module_imports(module_.get(), importTypes.get()); if (importTypes.empty()) return {}; @@ -424,12 +379,12 @@ ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const auto const it = imports.find(fieldName); if (it == imports.end()) { - printWasmError("Import not found: " + std::string(fieldName), nullptr, j); + printWasmError("Import not found: " + std::string(fieldName), nullptr, j_); continue; // print all missed import } - auto const& obj = it->second; - auto const& imp = obj.second; + WasmUserData const& obj = it->second; + WasmImportFunc const& imp = obj.second; WasmValtypeVec params(makeImpParams(imp)); WasmValtypeVec results(makeImpReturn(imp)); @@ -462,25 +417,19 @@ ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const std::string("Imports not finished: ") + std::to_string(impCnt) + "/" + std::to_string(importTypes.size()), nullptr, - j); + j_); Throw("Missing imports"); } return wimports; } -FuncInfo -ModuleWrapper::getFunc(std::string_view funcName) const -{ - return instanceWrap.getFunc(funcName, exportTypes); -} - wasm_functype_t* ModuleWrapper::getFuncType(std::string_view funcName) const { - for (size_t i = 0; i < exportTypes.size(); i++) + for (size_t i = 0; i < exportTypes_.size(); i++) { - auto const* expType(exportTypes[i]); + auto const* expType(exportTypes_[i]); wasm_name_t const* name = wasm_exporttype_name(expType); wasm_externtype_t const* exnType = wasm_exporttype_type(expType); if (wasm_externtype_kind(exnType) == WASM_EXTERN_FUNC && @@ -493,25 +442,6 @@ ModuleWrapper::getFuncType(std::string_view funcName) const throw std::runtime_error("can't find function <" + std::string(funcName) + ">"); } -Wmem -ModuleWrapper::getMem() const -{ - return instanceWrap.getMem(); -} - -InstanceWrapper& -ModuleWrapper::getInstance(int) -{ - return instanceWrap; -} - -int -ModuleWrapper::addInstance(StorePtr& s, WasmExternVec const& imports) -{ - instanceWrap = {s, module, imports, j}; - return 0; -} - // int // my_module_t::delInstance(int i) // { @@ -522,12 +452,6 @@ ModuleWrapper::addInstance(StorePtr& s, WasmExternVec const& imports) // return i; // } -std::int64_t -ModuleWrapper::getGas() const -{ - return instanceWrap ? instanceWrap.getGas() : -1; -} - ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // void @@ -567,10 +491,6 @@ WasmiEngine::init() wasm_engine_new_with_config(config), &wasm_engine_delete); } -WasmiEngine::WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete) -{ -} - int WasmiEngine::addModule( Bytes const& wasmCode, @@ -608,12 +528,6 @@ WasmiEngine::addModule( // return module->addInstance(store.get()); // } -FuncInfo -WasmiEngine::getFunc(std::string_view funcName) const -{ - return moduleWrap_->getFunc(funcName); -} - std::vector WasmiEngine::convertParams(std::vector const& params) { @@ -711,8 +625,8 @@ WasmiResult WasmiEngine::call(FuncInfo const& f, std::vector& in) { WasmiResult ret(NR); - wasm_val_vec_t const inv = - in.empty() ? wasm_val_vec_t WASM_EMPTY_VEC : wasm_val_vec_t{in.size(), in.data()}; + wasm_val_vec_t const inv = in.empty() ? wasm_val_vec_t WASM_EMPTY_VEC + : wasm_val_vec_t{.size = in.size(), .data = in.data()}; #ifdef SHOW_CALL_TIME auto const start = usecs(); @@ -763,7 +677,7 @@ checkImports(ImportVec const& imports, HostFunctions* hfs) { for (auto const& obj : imports) { - if (hfs != obj.second.first) + if (hfs != &obj.second.first.get()) Throw("Imports hf unsync"); } } @@ -821,13 +735,13 @@ WasmiEngine::runHlp( // Create and instantiate the module. [[maybe_unused]] int const m = addModule(wasmCode, true, imports, gas); - if (!moduleWrap_ || !moduleWrap_->instanceWrap) + if (!moduleWrap_ || !moduleWrap_->getInstance()) throw std::runtime_error("no instance"); // LCOV_EXCL_LINE - auto clear = [](HostFunctions* p) { p->setRT(nullptr); }; - std::unique_ptr const clearGuard(&hfs, clear); + auto clearRT = [](HostFunctions* p) { p->resetRT(); }; + std::unique_ptr const clearGuard(&hfs, clearRT); WasmiRuntimeWrapper iw(getRT()); - hfs.setRT(&iw); + hfs.setRT(iw); // Call main auto const f = getFunc(!funcName.empty() ? funcName : "_start"); @@ -843,19 +757,17 @@ WasmiEngine::runHlp( auto const res = call<1>(f, p); if (res.f) - { - throw std::runtime_error("<" + std::string(funcName) + "> failure"); - } + Throw("<" + std::string(funcName) + "> failure"); if (res.r.empty()) { - throw std::runtime_error( + Throw( "<" + std::string(funcName) + "> return nothing"); // LCOV_EXCL_LINE } if (res.r[0].kind != WASM_I32) { - throw std::runtime_error( + Throw( "<" + std::string(funcName) + "> return type mismatch, ret: " + std::to_string(static_cast(res.r[0].kind))); } @@ -934,33 +846,11 @@ WasmiEngine::checkHlp( return tesSUCCESS; } -// LCOV_EXCL_START -std::int64_t -WasmiEngine::getGas() const -{ - return moduleWrap_ ? moduleWrap_->getGas() : -1; -} -// LCOV_EXCL_STOP - -Wmem -WasmiEngine::getMem() const -{ - return moduleWrap_ ? moduleWrap_->getMem() : Wmem(); -} - -InstanceWrapper& -WasmiEngine::getRT(int m, int i) const -{ - if (!moduleWrap_) - throw std::runtime_error("no module"); - return moduleWrap_->getInstance(i); -} - wasm_trap_t* WasmiEngine::newTrap(std::string const& txt) { static char empty[1] = {0}; - wasm_message_t msg = {1, empty}; + wasm_message_t msg = {.size = 1, .data = empty}; if (!txt.empty()) wasm_name_new(&msg, txt.size() + 1, txt.c_str()); // include 0 @@ -973,12 +863,4 @@ WasmiEngine::newTrap(std::string const& txt) return trap; } -// LCOV_EXCL_START -beast::Journal -WasmiEngine::getJournal() const -{ - return j_; -} -// LCOV_EXCL_STOP - } // namespace xrpl diff --git a/src/test/app/HostFuncImpl_test.cpp b/src/test/app/HostFuncImpl_test.cpp index 7a6166fe4c..ab925cb432 100644 --- a/src/test/app/HostFuncImpl_test.cpp +++ b/src/test/app/HostFuncImpl_test.cpp @@ -44,7 +44,8 @@ #include #include #include -#include +#include +#include #include #include @@ -174,7 +175,7 @@ public: Wmem getMem() override { - return {.p = buffer_.data(), .s = buffer_.size()}; + return Wmem(buffer_.data(), buffer_.size()); } std::int64_t @@ -206,14 +207,14 @@ public: checkIdx(WasmValVec const& params, size_t i) const { if (i + 1 >= params.size()) - Throw("Out of bounds"); + Throw("Out of bounds"); if (params[i].kind != WASM_I32 || params[i + 1].kind != WASM_I32) Throw("Invalid params"); std::int32_t const ptr = params[i].of.i32; std::int32_t const size = params[i + 1].of.i32; std::int64_t const offset = (std::int64_t)ptr + size; if (ptr < 0 || size < 0 || std::cmp_greater_equal(offset, buffer_.size())) - Throw("Out of bounds"); + Throw("Out of bounds"); } [[nodiscard]] Slice @@ -292,24 +293,24 @@ ww_hlp(size_t& idx, E&& e, P&& params, Arg&& arg) else if constexpr (std::is_same_v) { auto const* udata = reinterpret_cast(e); - HostFunctions const* hf = reinterpret_cast(udata->first); - auto* vrt = reinterpret_cast(hf->getRT()); + HostFunctions const& hf = udata->first; + auto& vrt = *reinterpret_cast(hf.getRT()); auto const data = toBytes(std::forward(arg)); size_t const ptr = (idx << 10); - vrt->setBytes(ptr, data.data(), data.size()); + vrt.setBytes(ptr, data.data(), data.size()); params[idx++] = wasm_val_t WASM_I32_VAL(static_cast(ptr)); params[idx++] = wasm_val_t WASM_I32_VAL(static_cast(data.size())); } else { auto const* udata = reinterpret_cast(e); - HostFunctions const* hf = reinterpret_cast(udata->first); - auto* vrt = reinterpret_cast(hf->getRT()); + HostFunctions const& hf = udata->first; + auto& vrt = *reinterpret_cast(hf.getRT()); size_t const ptr = (idx << 10); - vrt->setBytes(ptr, arg.data(), arg.size()); + vrt.setBytes(ptr, arg.data(), arg.size()); params[idx++] = wasm_val_t WASM_I32_VAL(static_cast(ptr)); params[idx++] = wasm_val_t WASM_I32_VAL(static_cast(arg.size())); } @@ -321,8 +322,8 @@ wasm_trap_t* ww(F&& f, E&& e, P&& params, P&& result, Args... args) { size_t idx = 0; - (ww_hlp(idx, e, params, std::forward(args)), ...); // NOLINT - return f(std::forward(e), params.get(), result.get()); // NOLINT + (ww_hlp(idx, e, params, std::forward(args)), ...); + return f(std::forward(e), params.get(), result.get()); } constexpr int64_t min64 = std::numeric_limits::min(); @@ -345,7 +346,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.getLedgerSqn(); @@ -378,7 +379,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.getParentLedgerTime(); @@ -413,7 +414,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.getParentLedgerHash(); @@ -450,7 +451,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getBaseFee(); { @@ -483,7 +484,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Use featureTokenEscrow for testing auto const amendmentId = featureTokenEscrow; @@ -572,7 +573,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.cacheLedgerObj(accountKeylet.key, -1); { @@ -693,7 +694,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); vrt.setGas(2'000'000); for (int i = 1; i <= 256; ++i) @@ -768,7 +769,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getTxField(sfAccount); { @@ -943,7 +944,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac2, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getTxField(sfAsset); { @@ -998,7 +999,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac2, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getTxField(sfAsset); { @@ -1054,7 +1055,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac2, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getTxField(sfAssetScale); { @@ -1103,7 +1104,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, escrowKeylet); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getCurrentLedgerObjField(sfAccount); { @@ -1191,7 +1192,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs2(ac, dummyEscrow); auto import2 = xrpl::createWasmImport(hfs2); - hfs2.setRT(&vrt2); + hfs2.setRT(vrt2); // hfs2.getCurrentLedgerObjField(sfAccount); { @@ -1234,7 +1235,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, escrowKeylet); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.cacheLedgerObj(accountKeylet.key, 1); { @@ -1403,7 +1404,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getTxNestedField(locator); { @@ -1536,7 +1537,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32); BEAST_EXPECTS( - result[0].of.i32 == HfErrorToInt(expectedError), std::to_string(result[0].of.i32)); + result[0].of.i32 == hfErrorToInt(expectedError), std::to_string(result[0].of.i32)); }; // hfs.getTxNestedField(locator); @@ -1692,7 +1693,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, signerKeylet); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getCurrentLedgerObjNestedField(baseLocatorSlice); // Locator for base field @@ -1738,7 +1739,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32); BEAST_EXPECTS( - result[0].of.i32 == HfErrorToInt(expectedError), std::to_string(result[0].of.i32)); + result[0].of.i32 == hfErrorToInt(expectedError), std::to_string(result[0].of.i32)); }; // hfs.getCurrentLedgerObjNestedField(locator); // Locator for non-existent base field @@ -1804,7 +1805,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl dummyHfs(ac, dummyEscrow); auto import2 = xrpl::createWasmImport(dummyHfs); - dummyHfs.setRT(&vrt2); + dummyHfs.setRT(vrt2); std::vector const locatorVec = {sfAccount.getCode()}; vrt2.setBytes(0, locatorVec.data(), locatorVec.size() * sizeof(int32_t)); @@ -1848,7 +1849,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Cache the SignerList ledger object in slot 1 auto const signerListKeylet = keylet::signers(env.master.id()); @@ -1997,7 +1998,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite 256); BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32); BEAST_EXPECTS( - result[0].of.i32 == HfErrorToInt(expectedError), std::to_string(result[0].of.i32)); + result[0].of.i32 == hfErrorToInt(expectedError), std::to_string(result[0].of.i32)); }; // Error: base field not found @@ -2113,7 +2114,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Should return 2 for sfMemos // hfs.getTxArrayLen(sfMemos); @@ -2200,7 +2201,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, signerKeylet); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getCurrentLedgerObjArrayLen(sfSignerEntries); { @@ -2253,7 +2254,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl dummyHfs(ac, dummyEscrow); auto import2 = xrpl::createWasmImport(dummyHfs); - dummyHfs.setRT(&vrt2); + dummyHfs.setRT(vrt2); // auto const len = dummyHfs.getCurrentLedgerObjArrayLen(sfMemos); WasmValVec params(1), result(1); @@ -2291,7 +2292,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); auto const signerListKeylet = keylet::signers(env.master.id()); // hfs.cacheLedgerObj(signerListKeylet.key, 1); @@ -2416,7 +2417,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Helper for error checks auto expectError = [&](std::vector const& locatorVec, @@ -2434,7 +2435,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32); BEAST_EXPECTS( - result[0].of.i32 == HfErrorToInt(expectedError), std::to_string(result[0].of.i32)); + result[0].of.i32 == hfErrorToInt(expectedError), std::to_string(result[0].of.i32)); }; // Locator for sfMemos @@ -2483,7 +2484,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, signerKeylet); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Helper for error checks auto expectError = [&](std::vector const& locatorVec, @@ -2501,7 +2502,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32); BEAST_EXPECTS( - result[0].of.i32 == HfErrorToInt(expectedError), std::to_string(result[0].of.i32)); + result[0].of.i32 == hfErrorToInt(expectedError), std::to_string(result[0].of.i32)); }; // Locator for sfSignerEntries @@ -2534,7 +2535,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl dummyHfs(ac, dummyEscrow); auto import2 = xrpl::createWasmImport(dummyHfs); - dummyHfs.setRT(&vrt2); + dummyHfs.setRT(vrt2); std::vector locatorVec = {sfAccount.getCode()}; // auto const result = dummyHfs.getCurrentLedgerObjNestedArrayLen(locator); @@ -2575,7 +2576,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); auto const signerListKeylet = keylet::signers(env.master.id()); // hfs.cacheLedgerObj(signerListKeylet.key, 1); @@ -2632,7 +2633,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32); BEAST_EXPECTS( - result[0].of.i32 == HfErrorToInt(expectedError), std::to_string(result[0].of.i32)); + result[0].of.i32 == hfErrorToInt(expectedError), std::to_string(result[0].of.i32)); }; // Error: non-array field @@ -2695,7 +2696,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, escrowKeylet); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Should succeed for small data Bytes data(10, 0x42); @@ -2712,7 +2713,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite } // Should fail for too large data - Bytes bigData(maxWasmDataLength + 1, 0x42); + Bytes bigData(kMaxWasmDataLength + 1, 0x42); // hfs.updateData(Slice(bigData.data(), bigData.size())); { vrt.setBytes(0, bigData.data(), bigData.size()); @@ -2722,7 +2723,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32) && BEAST_EXPECT( - result[0].of.i32 == HfErrorToInt(HostFunctionError::DataFieldTooLarge)); + result[0].of.i32 == hfErrorToInt(HostFunctionError::DataFieldTooLarge)); } } @@ -2741,7 +2742,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Generate a keypair and sign a message auto const kp = generateKeyPair(KeyType::Secp256k1, randomSeed()); @@ -2827,7 +2828,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite badPk.size()); BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32) && - BEAST_EXPECT(result[0].of.i32 == HfErrorToInt(HostFunctionError::InvalidParams)); + BEAST_EXPECT(result[0].of.i32 == hfErrorToInt(HostFunctionError::InvalidParams)); } // Should fail for empty public key @@ -2852,7 +2853,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite 0); BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32) && - BEAST_EXPECT(result[0].of.i32 == HfErrorToInt(HostFunctionError::InvalidParams)); + BEAST_EXPECT(result[0].of.i32 == hfErrorToInt(HostFunctionError::InvalidParams)); } // Should fail for empty signature @@ -2919,7 +2920,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string data = "hello world"; // hfs.computeSha512HalfHash(Slice(data.data(), data.size())); @@ -2965,7 +2966,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite auto const baseMpt = makeMptID(1, masterID); auto imp = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Lambda to compare a Bytes (std::vector) to a keylet auto compareKeylet = [](std::vector const& bytes, Keylet const& kl) { @@ -3771,7 +3772,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Should succeed for valid NFT { @@ -3819,7 +3820,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite 256); if (BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32)) - BEAST_EXPECT(result[0].of.i32 == HfErrorToInt(HostFunctionError::InvalidAccount)); + BEAST_EXPECT(result[0].of.i32 == hfErrorToInt(HostFunctionError::InvalidAccount)); } // Should fail for invalid nftId @@ -3842,7 +3843,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite 256); if (BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32)) - BEAST_EXPECT(result[0].of.i32 == HfErrorToInt(HostFunctionError::InvalidParams)); + BEAST_EXPECT(result[0].of.i32 == hfErrorToInt(HostFunctionError::InvalidParams)); } // Should fail for invalid nftId @@ -3866,7 +3867,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32) && BEAST_EXPECT( - result[0].of.i32 == HfErrorToInt(HostFunctionError::LedgerObjNotFound)); + result[0].of.i32 == hfErrorToInt(HostFunctionError::LedgerObjNotFound)); } { @@ -3887,7 +3888,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite 256); if (BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32)) - BEAST_EXPECT(result[0].of.i32 == HfErrorToInt(HostFunctionError::FieldNotFound)); + BEAST_EXPECT(result[0].of.i32 == hfErrorToInt(HostFunctionError::FieldNotFound)); } } @@ -3912,7 +3913,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Should succeed for valid NFT id { @@ -3954,7 +3955,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite AccountID::size()); if (BEAST_EXPECT(!trap) && BEAST_EXPECT(result[0].kind == WASM_I32)) - BEAST_EXPECT(result[0].of.i32 == HfErrorToInt(HostFunctionError::InvalidParams)); + BEAST_EXPECT(result[0].of.i32 == hfErrorToInt(HostFunctionError::InvalidParams)); } } @@ -3979,7 +3980,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // hfs.getNFTTaxon(nftId); vrt.setBytes(0, nftId.data(), uint256::size()); @@ -4022,7 +4023,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.getNFTFlags(nftId); @@ -4070,7 +4071,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.getNFTTransferFee(nftId); @@ -4129,7 +4130,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.getNFTSerial(nftId); @@ -4194,7 +4195,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "test trace"; std::string data = "abc"; @@ -4266,7 +4267,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "test trace"; std::string data = "abc"; @@ -4312,7 +4313,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace number"; int64_t const num = 123456789; @@ -4345,7 +4346,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace number"; int64_t const num = 123456789; @@ -4381,7 +4382,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace account"; auto const& accountId = env.master.id(); @@ -4422,7 +4423,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string msg = "trace account"; auto const& accountId = env.master.id(); @@ -4466,7 +4467,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace amount"; STAmount const amount = XRP(12345); @@ -4559,7 +4560,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace amount"; STAmount const amount = XRP(12345); @@ -4688,7 +4689,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace float"; @@ -4744,7 +4745,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite VirtualRuntime vrt; auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); std::string const msg = "trace float"; @@ -4783,7 +4784,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatFromInt(min64, -1); @@ -4895,7 +4896,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatFromUint(std::numeric_limits::min(), -1); @@ -5001,7 +5002,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatFromMantExp(1, 0, -1); @@ -5238,7 +5239,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatCompare(Slice(), Slice()); @@ -5358,7 +5359,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatAdd(Slice(), Slice(), -1); @@ -5517,7 +5518,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatSubtract(Slice(), Slice(), -1); @@ -5674,7 +5675,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatMultiply(Slice(), Slice(), -1); @@ -5855,7 +5856,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatDivide(Slice(), Slice(), -1); @@ -6036,7 +6037,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatRoot(Slice(), 2, -1); WasmValVec params(6), result(1); @@ -6236,7 +6237,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatPower(Slice(), 2, -1); WasmValVec params(6), result(1); @@ -6476,7 +6477,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatFromSTAmount(amount, -1); @@ -6677,7 +6678,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); // Test with invalid rounding mode { @@ -6788,7 +6789,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatToInt(makeSlice(float1), -1); @@ -7113,7 +7114,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); { // hfs.floatToMantExp(makeSlice(invalid)); @@ -7397,7 +7398,7 @@ struct HostFuncImpl_test : public beast::unit_test::Suite WasmHostFunctionsImpl hfs(ac, dummyEscrow); auto import = xrpl::createWasmImport(hfs); - hfs.setRT(&vrt); + hfs.setRT(vrt); bool ex = false; try diff --git a/src/test/app/TestHostFunctions.h b/src/test/app/TestHostFunctions.h index 26d30dd53c..d0dc19d52d 100644 --- a/src/test/app/TestHostFunctions.h +++ b/src/test/app/TestHostFunctions.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -18,62 +20,35 @@ namespace xrpl::test { -struct TestLedgerDataProvider : public HostFunctions +class TestLedgerDataProvider : public HostFunctions { - jtx::Env& env; - void* rt = nullptr; + jtx::Env& env_; public: - TestLedgerDataProvider(jtx::Env& env) : HostFunctions(env.journal), env(env) + TestLedgerDataProvider(jtx::Env& env) : HostFunctions(env.journal), env_(env) { } - void - setRT(void* rt) override - { - this->rt = rt; - } - - [[nodiscard]] void* - getRT() const override - { - return rt; - } - Expected getLedgerSqn() const override { - return env.current()->seq(); + return env_.current()->seq(); } }; -struct TestHostFunctions : public HostFunctions +class TestHostFunctions : public HostFunctions { - test::jtx::Env& env; - AccountID accountID; - Bytes data; - int clock_drift = 0; - void* rt = nullptr; +protected: + test::jtx::Env& env_; + AccountID accountID_; + Bytes data_; public: - TestHostFunctions(test::jtx::Env& env, int cd = 0) - : HostFunctions(env.journal), env(env), clock_drift(cd) + TestHostFunctions(test::jtx::Env& env) : HostFunctions(env.journal), env_(env) { - accountID = env.master.id(); + accountID_ = env.master.id(); std::string t = "10000"; - data = Bytes{t.begin(), t.end()}; - } - - void - setRT(void* rt) override - { - this->rt = rt; - } - - [[nodiscard]] void* - getRT() const override - { - return rt; + data_ = Bytes{t.begin(), t.end()}; } Expected @@ -91,7 +66,7 @@ public: Expected getParentLedgerHash() const override { - return env.current()->header().parentHash; + return env_.current()->header().parentHash; } Expected @@ -122,15 +97,15 @@ public: getTxField(SField const& fname) const override { if (fname == sfAccount) - { - return Bytes(accountID.begin(), accountID.end()); - } + return Bytes(accountID_.begin(), accountID_.end()); + if (fname == sfFee) { int64_t x = 235; uint8_t const* p = reinterpret_cast(&x); return Bytes{p, p + sizeof(x)}; } + if (fname == sfSequence) { auto const x = getLedgerSqn(); @@ -141,6 +116,7 @@ public: auto const* e = reinterpret_cast(&data + 1); return Bytes{b, e}; } + return Bytes(); } @@ -149,25 +125,21 @@ public: { auto const& sn = fname.getName(); if (sn == "Destination" || sn == "Account") - { - return Bytes(accountID.begin(), accountID.end()); - } + return Bytes(accountID_.begin(), accountID_.end()); if (sn == "Data") - { - return data; - } + return data_; if (sn == "FinishAfter") { - auto t = env.current()->parentCloseTime().time_since_epoch().count(); + 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); + return Unexpected(HostFunctionError::Internal); } Expected - getLedgerObjField(int32_t cacheIdx, SField const& fname) const override + getLedgerObjField(int32_t, SField const& fname) const override { if (fname == sfBalance) { @@ -175,11 +147,11 @@ public: uint8_t const* p = reinterpret_cast(&x); return Bytes{p, p + sizeof(x)}; } + if (fname == sfAccount) - { - return Bytes(accountID.begin(), accountID.end()); - } - return data; + return Bytes(accountID_.begin(), accountID_.end()); + + return data_; } Expected @@ -190,9 +162,7 @@ public: int32_t const* l = reinterpret_cast(locator.data()); int32_t const sfield = l[0]; if (sfield == sfAccount.getCode()) - { - return Bytes(accountID.begin(), accountID.end()); - } + return Bytes(accountID_.begin(), accountID_.end()); } 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, @@ -208,9 +178,7 @@ public: int32_t const* l = reinterpret_cast(locator.data()); int32_t const sfield = l[0]; if (sfield == sfAccount.getCode()) - { - return Bytes(accountID.begin(), accountID.end()); - } + return Bytes(accountID_.begin(), accountID_.end()); } 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, @@ -226,9 +194,7 @@ public: int32_t const* l = reinterpret_cast(locator.data()); int32_t const sfield = l[0]; if (sfield == sfAccount.getCode()) - { - return Bytes(accountID.begin(), accountID.end()); - } + return Bytes(accountID_.begin(), accountID_.end()); } 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, @@ -287,7 +253,7 @@ public: Expected computeSha512HalfHash(Slice const& data) const override { - return env.current()->header().parentHash; + return env_.current()->header().parentHash; } Expected @@ -352,9 +318,7 @@ public: getNFT(AccountID const& account, uint256 const& nftId) const override { if (!account || !nftId) - { return Unexpected(HostFunctionError::InvalidParams); - } std::string s = "https://ripple.com"; return Bytes(s.begin(), s.end()); @@ -363,7 +327,7 @@ public: Expected getNFTIssuer(uint256 const& nftId) const override { - return Bytes(accountID.begin(), accountID.end()); + return Bytes(accountID_.begin(), accountID_.end()); } Expected @@ -543,22 +507,21 @@ public: } }; -struct TestHostFunctionsSink : public TestHostFunctions +class TestHostFunctionsSink : public TestHostFunctions { - test::StreamSink sink; - void const* rt = nullptr; + test::StreamSink sink_; public: - explicit TestHostFunctionsSink(test::jtx::Env& env, int cd = 0) - : TestHostFunctions(env, cd), sink(beast::Severity::Debug) + explicit TestHostFunctionsSink(test::jtx::Env& env) + : TestHostFunctions(env), sink_(beast::Severity::Debug) { - j = beast::Journal(sink); + j_ = beast::Journal(sink_); } test::StreamSink& getSink() { - return sink; + return sink_; } }; diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index c1879d1fe9..49a29f1563 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -7,7 +7,8 @@ #include #include #include // IWYU pragma: keep -#include +#include +#include #include #include @@ -218,7 +219,7 @@ struct Wasm_test : public beast::unit_test::Suite HostFunctions hfs; ImportVec imports; - WasmImpFunc(imports, "func-add", reinterpret_cast(&add), &hfs); + WasmImpFunc(imports, "func-add", reinterpret_cast(&add), hfs); auto re = vm.run(wasm, hfs, 10'000'000, "addTwo", wasmParams(1234, 5678), imports); @@ -287,7 +288,7 @@ struct Wasm_test : public beast::unit_test::Suite Env env{*this}; TestLedgerDataProvider hfs(env); ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs, 33); + WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs, 33); auto& engine = WasmEngine::instance(); auto re = @@ -316,8 +317,8 @@ struct Wasm_test : public beast::unit_test::Suite Env env{*this}; TestLedgerDataProvider hfs(env); ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs, 33); - WASM_IMPORT_FUNC2(imports, getParentLedgerHash, "get_parent_ledger_hash", &hfs, 60); + WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs, 33); + WASM_IMPORT_FUNC2(imports, getParentLedgerHash, "get_parent_ledger_hash", hfs, 60); auto& engine = WasmEngine::instance(); // Test exp_func1() - should return 1 @@ -396,7 +397,7 @@ struct Wasm_test : public beast::unit_test::Suite auto& engine = WasmEngine::instance(); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto imp = createWasmImport(hfs); for (auto& i : imp) i.second.second.gas = 0; @@ -420,7 +421,7 @@ struct Wasm_test : public beast::unit_test::Suite auto& engine = WasmEngine::instance(); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto const imp = createWasmImport(hfs); auto re = engine.run( @@ -437,7 +438,7 @@ struct Wasm_test : public beast::unit_test::Suite auto& engine = WasmEngine::instance(); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto const imp = createWasmImport(hfs); auto re = @@ -463,14 +464,14 @@ struct Wasm_test : public beast::unit_test::Suite using namespace test::jtx; Env env{*this}; { - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {}); checkResult(re, 1, 70'340); } { // Invalid gas limit (0) should be rejected (boundary condition) - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto re = runEscrowWasm(allHFWasm, hfs, -1, escrowFunctionName, {}); BEAST_EXPECT(!re.has_value()); BEAST_EXPECT(re.error() == temBAD_AMOUNT); @@ -478,7 +479,7 @@ struct Wasm_test : public beast::unit_test::Suite { // Invalid gas limit (-1) should be rejected - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto re = runEscrowWasm(allHFWasm, hfs, 0, escrowFunctionName, {}); BEAST_EXPECT(!re.has_value()); BEAST_EXPECT(re.error() == temBAD_AMOUNT); @@ -486,7 +487,7 @@ struct Wasm_test : public beast::unit_test::Suite { // max() gas - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto re = runEscrowWasm( allHFWasm, hfs, std::numeric_limits::max(), escrowFunctionName, {}); checkResult(re, 1, 70'340); @@ -562,7 +563,7 @@ struct Wasm_test : public beast::unit_test::Suite { // infinite loop auto const infiniteLoopWasm = hexToBytes(kInfiniteLoopWasmHex); std::string const funcName("loop"); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); // infinite loop should be caught and fail auto const re = runEscrowWasm(infiniteLoopWasm, hfs, 1'000'000, funcName, {}); @@ -577,7 +578,7 @@ struct Wasm_test : public beast::unit_test::Suite auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); TestLedgerDataProvider hfs(env); ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", &hfs); + WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", hfs); auto& engine = WasmEngine::instance(); @@ -588,12 +589,12 @@ struct Wasm_test : public beast::unit_test::Suite } { - // bad import format + // HF unsync between import and VM auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); TestLedgerDataProvider hfs(env); + TestLedgerDataProvider hfs2(env); ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs); - imports["get_ledger_sqn"].first = nullptr; + WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs2); auto& engine = WasmEngine::instance(); @@ -608,7 +609,7 @@ struct Wasm_test : public beast::unit_test::Suite auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); TestLedgerDataProvider hfs(env); ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs); + WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs); auto& engine = WasmEngine::instance(); auto re = engine.run(lgrSqnWasm, hfs, 1'000'000, "func1", {}, imports, env.journal); @@ -630,7 +631,7 @@ struct Wasm_test : public beast::unit_test::Suite { auto const floatTestWasm = hexToBytes(kFloatTestsWasmHex); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto re = runEscrowWasm(floatTestWasm, hfs, 200'000, funcName, {}); checkResult(re, 1, 134'938); env.close(); @@ -639,7 +640,7 @@ struct Wasm_test : public beast::unit_test::Suite { auto const float0Wasm = hexToBytes(kFloat0Hex); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto re = runEscrowWasm(float0Wasm, hfs, 100'000, funcName, {}); checkResult(re, 1, 4'309); env.close(); @@ -656,7 +657,7 @@ struct Wasm_test : public beast::unit_test::Suite Env env{*this}; auto const codecovWasm = hexToBytes(kCodecovTestsWasmHex); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto const allowance = 220'169; auto re = runEscrowWasm(codecovWasm, hfs, allowance, escrowFunctionName, {}); @@ -674,7 +675,7 @@ struct Wasm_test : public beast::unit_test::Suite auto disabledFloatWasm = hexToBytes(kDisabledFloatHex); std::string const funcName("finish"); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); { // f32 set constant, opcode disabled exception @@ -810,7 +811,7 @@ struct Wasm_test : public beast::unit_test::Suite using namespace test::jtx; Env env{*this}; - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto imports = createWasmImport(hfs); { // Calls float_from_uint with bad alignment. @@ -832,7 +833,7 @@ struct Wasm_test : public beast::unit_test::Suite { using namespace test::jtx; Env env(*this); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); testcase("Wasm invalid return type"); @@ -887,7 +888,7 @@ struct Wasm_test : public beast::unit_test::Suite { using namespace test::jtx; Env env(*this); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); testcase("Wasm invalid params"); @@ -999,7 +1000,7 @@ struct Wasm_test : public beast::unit_test::Suite using namespace test::jtx; Env env{*this}; - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto imports = createWasmImport(hfs); // add 1k parameter (max that wasmi support) @@ -1054,7 +1055,7 @@ struct Wasm_test : public beast::unit_test::Suite Env env{*this}; auto& engine = WasmEngine::instance(); - TestHostFunctions hfs(env, 0); + TestHostFunctions hfs(env); auto imports = createWasmImport(hfs); env.close();