diff --git a/conan.lock b/conan.lock index ea5e66149d..c6a4070c77 100644 --- a/conan.lock +++ b/conan.lock @@ -3,7 +3,6 @@ "requires": [ "zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708", "xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688", - "wasmi/1.0.9#1fecdab9b90c96698eb35ea99ca4f5cb%1782307153.343419", "sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447", "soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521", "snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168", diff --git a/conanfile.py b/conanfile.py index 09cb6deeae..f883761f0e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -34,7 +34,6 @@ class Xrpl(ConanFile): "nudb/2.0.9", "openssl/3.6.3", "soci/4.0.3", - "wasmi/1.0.9", "zlib/1.3.2", ] @@ -222,7 +221,6 @@ class Xrpl(ConanFile): "soci::soci", "secp256k1::secp256k1", "sqlite3::sqlite", - "wasmi::wasmi", "xxhash::xxhash", "zlib::zlib", ] diff --git a/include/xrpl/tx/wasm/WasmVM.h b/include/xrpl/tx/wasm/WasmVM.h deleted file mode 100644 index e20488de00..0000000000 --- a/include/xrpl/tx/wasm/WasmVM.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace xrpl { - -std::string_view inline constexpr wEnv = "env"; -std::string_view inline constexpr wHostLib = "host_lib"; -std::string_view inline constexpr wMem = "memory"; -std::string_view inline constexpr wStore = "store"; -std::string_view inline constexpr wLoad = "load"; -std::string_view inline constexpr wSize = "size"; -std::string_view inline constexpr wAlloc = "allocate"; -std::string_view inline constexpr wDealloc = "deallocate"; -std::string_view inline constexpr wProcExit = "proc_exit"; - -std::string_view inline constexpr escrowFunctionName = "escrow_finish"; - -uint32_t inline constexpr maxPages = 128; // 8MB = 64KB*128 - -class WasmiEngine; - -class WasmEngine -{ - std::unique_ptr const impl_; - - WasmEngine(); - -public: - WasmEngine(WasmEngine const&) = delete; - WasmEngine(WasmEngine&&) = delete; - WasmEngine& - operator=(WasmEngine const&) = delete; - WasmEngine& - operator=(WasmEngine&&) = delete; - - static WasmEngine& - instance(); - - std::expected, WasmTER> - run(Bytes const& wasmCode, - HostFunctions& hfs, - int64_t gasLimit, - std::string_view funcName = {}, - std::vector const& params = {}, - ImportVec const& imports = {}, - beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); - - NotTEC - check( - Bytes const& wasmCode, - HostFunctions& hfs, - std::string_view funcName, - std::vector const& params = {}, - ImportVec const& imports = {}, - beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); - - // Host functions helper functionality - void* - newTrap(std::string const& txt = std::string()); - - [[nodiscard]] beast::Journal - getJournal() const; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ImportVec -createWasmImport(HostFunctions& hfs); - -std::expected -runEscrowWasm( - Bytes const& wasmCode, - HostFunctions& hfs, - int64_t gasLimit, - std::string_view funcName = escrowFunctionName, - std::vector const& params = {}); - -NotTEC -preflightEscrowWasm( - Bytes const& wasmCode, - HostFunctions& hfs, - std::string_view funcName = escrowFunctionName, - std::vector const& params = {}); - -} // namespace xrpl diff --git a/include/xrpl/tx/wasm/WasmiVM.h b/include/xrpl/tx/wasm/WasmiVM.h deleted file mode 100644 index 5a72cd35f6..0000000000 --- a/include/xrpl/tx/wasm/WasmiVM.h +++ /dev/null @@ -1,462 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace xrpl { - -template -class WasmVec -{ - using TD = std::remove_pointer_t; - T vec_; - -public: - WasmVec(size_t s = 0) : vec_ WASM_EMPTY_VEC - { - if (s > 0) - Create(&vec_, s); // zeroes memory - } - - ~WasmVec() - { - clear(); - } - - WasmVec(WasmVec const&) = delete; - WasmVec& - operator=(WasmVec const&) = delete; - - WasmVec(WasmVec&& other) noexcept : vec_ WASM_EMPTY_VEC - { - *this = std::move(other); - } - - WasmVec& - operator=(WasmVec&& other) noexcept - { - if (this != &other) - { - clear(); - vec_ = other.vec_; - other.vec_ = WASM_EMPTY_VEC; - } - return *this; - } - - void - clear() - { - Destroy(&vec_); // call destructor for every elements too - vec_ = WASM_EMPTY_VEC; - } - - T - release() - { - T result = vec_; - vec_ = WASM_EMPTY_VEC; - return result; - } - - T* - get() - { - return &vec_; - } - - [[nodiscard]] T const* - get() const - { - return &vec_; - } - - TD& - operator[](size_t i) - { - if (i >= vec_.size) - Throw("Out of bound"); - return vec_.data[i]; - } - - TD const& - operator[](size_t i) const - { - if (i >= vec_.size) - Throw("Out of bound"); - return vec_.data[i]; - } - - [[nodiscard]] size_t - size() const - { - return vec_.size; - } - - [[nodiscard]] bool - empty() const - { - return vec_.size == 0u; - } -}; - -using WasmValtypeVec = - WasmVec; -using WasmValVec = WasmVec; -using WasmExternVec = - WasmVec; -using WasmExporttypeVec = WasmVec< - wasm_exporttype_vec_t, - &wasm_exporttype_vec_new_uninitialized, - &wasm_exporttype_vec_delete>; -using WasmImporttypeVec = WasmVec< - wasm_importtype_vec_t, - &wasm_importtype_vec_new_uninitialized, - &wasm_importtype_vec_delete>; - -struct WasmiResult -{ - WasmValVec r; - // Set iff the call trapped. Holds the TER the trap was classified into - // (tecINTERNAL / tecOUT_OF_GAS / tecFAILED_PROCESSING); see - // WasmiEngine::call. std::nullopt means the call returned normally. - std::optional ter; - - WasmiResult(unsigned n = 0) : r(n) - { - } - - WasmiResult() = delete; - ~WasmiResult() = default; - WasmiResult(WasmiResult&& o) = default; - WasmiResult& - operator=(WasmiResult&& o) = default; -}; - -using ModulePtr = std::unique_ptr; -using InstancePtr = std::unique_ptr; -using EnginePtr = std::unique_ptr; -using StorePtr = std::unique_ptr; - -using FuncInfo = std::pair; - -class InstanceWrapper -{ - wasm_store_t* store_ = nullptr; - WasmExternVec exports_; - mutable int memIdx_ = -1; - InstancePtr instance_; - beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); - std::int64_t transferLimit_ = kWasmTransferLimit; - -private: - static InstancePtr - init( - StorePtr& s, - ModulePtr& m, - WasmExternVec& expt, - WasmExternVec const& imports, - beast::Journal j); - -public: - InstanceWrapper() : instance_(nullptr, &wasm_instance_delete) {}; - - InstanceWrapper(InstanceWrapper const&) = delete; - - 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) - : store_(s.get()), instance_(init(s, m, exports_, imports, j)), j_(j) - { - } - - InstanceWrapper& - operator=(InstanceWrapper&& o); - - InstanceWrapper& - operator=(InstanceWrapper const&) = delete; - - operator bool() const - { - return static_cast(instance_); - } - - FuncInfo - getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const; - - Wmem - getMem() const; - - std::int64_t - getGas() const; - - std::int64_t - setGas(std::int64_t) const; - - std::int64_t - getTransferLimit() const; - - std::int64_t - setTransferLimit(std::int64_t); -}; - -class ModuleWrapper -{ - ModulePtr module_; - InstanceWrapper instanceWrap_; - WasmExporttypeVec exportTypes_; - beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); - -public: - // 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( - StorePtr& s, - Bytes const& wasmBin, - bool instantiate, - ImportVec const& imports, - beast::Journal j); - ~ModuleWrapper() = default; - - operator bool() const - { - return instanceWrap_; - } - - FuncInfo - getFunc(std::string_view funcName) const - { - return instanceWrap_.getFunc(funcName, exportTypes_); - } - - wasm_functype_t const* - getFuncType(std::string_view funcName) const; - - Wmem - getMem() const - { - return instanceWrap_.getMem(); - } - - InstanceWrapper& - getInstance(int i = 0) - { - return instanceWrap_; - } - - InstanceWrapper const& - getInstance(int i = 0) const - { - return instanceWrap_; - } - - int - addInstance(StorePtr& s, WasmExternVec const& imports) - { - instanceWrap_ = {s, module_, imports, j_}; - return 0; - } - - std::int64_t - 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; -}; - -class WasmiEngine -{ - EnginePtr engine_; - StorePtr store_; - std::unique_ptr moduleWrap_; - beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); - - std::mutex m_; // 1 instance mutex - -public: - WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete) - { - } - - ~WasmiEngine() = default; - - static EnginePtr - init(); - - std::expected, WasmTER> - run(Bytes const& wasmCode, - HostFunctions& hfs, - int64_t gas, - std::string_view funcName, - std::vector const& params, - ImportVec const& imports, - beast::Journal j); - - NotTEC - check( - Bytes const& wasmCode, - HostFunctions& hfs, - std::string_view funcName, - std::vector const& params, - ImportVec const& imports, - beast::Journal j); - - [[nodiscard]] std::int64_t - 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 - { - return j_; - } - // LCOV_EXCL_STOP - -private: - [[nodiscard]] InstanceWrapper& - getRT(int m = 0, int i = 0) const - { - if (!moduleWrap_) - Throw("no module"); - return moduleWrap_->getInstance(i); - } - - [[nodiscard]] Wmem - getMem() const - { - return moduleWrap_ ? moduleWrap_->getMem() : Wmem(); - } - - std::expected, WasmTER> - runHlp( - Bytes const& wasmCode, - HostFunctions& hfs, - int64_t gas, - std::string_view funcName, - std::vector const& params, - ImportVec const& imports, - beast::Journal j); - - NotTEC - checkHlp( - Bytes const& wasmCode, - HostFunctions& hfs, - std::string_view funcName, - std::vector const& params, - ImportVec const& imports, - beast::Journal j); - - int - addModule(Bytes const& wasmCode, bool instantiate, ImportVec const& imports, int64_t gas); - void - clearModules(); - - // int addInstance(); - - int32_t - runFunc(std::string_view const funcName, int32_t p); - - int32_t - makeModule(Bytes const& wasmCode, WasmExternVec const& imports = {}); - - [[nodiscard]] FuncInfo - getFunc(std::string_view funcName) const - { - return moduleWrap_->getFunc(funcName); - } - - static std::vector - convertParams(std::vector const& params); - - static int - compareParamTypes(wasm_valtype_vec_t const* ftp, std::vector const& p); - - static void - addParam(std::vector& in, int32_t p); - static void - addParam(std::vector& in, int64_t p); - - template - inline WasmiResult - call(std::string_view func, Types&&... args); - - template - inline WasmiResult - call(FuncInfo const& f, Types&&... args); - - template - inline WasmiResult - call(FuncInfo const& f, std::vector& in); - - template - inline WasmiResult - call(FuncInfo const& f, std::vector& in, std::int32_t p, Types&&... args); - - template - inline WasmiResult - call(FuncInfo const& f, std::vector& in, std::int64_t p, Types&&... args); - - template - inline WasmiResult - call( - FuncInfo const& f, - std::vector& in, - uint8_t const* d, - int32_t sz, - Types&&... args); - - template - inline WasmiResult - call(FuncInfo const& f, std::vector& in, Bytes const& p, Types&&... args); -}; - -} // namespace xrpl diff --git a/src/libxrpl/tx/wasm/HostFuncWrapper.cpp b/src/libxrpl/tx/wasm/HostFuncWrapper.cpp deleted file mode 100644 index ea5caec6cc..0000000000 --- a/src/libxrpl/tx/wasm/HostFuncWrapper.cpp +++ /dev/null @@ -1,1873 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace xrpl { - -using SFieldCRef = std::reference_wrapper; - -constexpr int64_t unalignedGas = 50; - -// Charge `delta` gas; returns the remaining gas. Out-of-gas throws hfErrOutOfGas -// (-> tecOUT_OF_GAS); a failed setGas is an xrpld bug, throws hfErrInternal -// (-> tecINTERNAL). HostFuncMain_wrap turns both into traps. -static inline std::int64_t -checkGas(WasmRuntimeWrapper& rt, int64_t delta) -{ - int64_t const gas = rt.getGas(); - if (delta == 0) - return gas; - - int64_t const x = gas >= delta ? gas - delta : 0; - - if (rt.setGas(x) < 0) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - if (gas < delta) - Throw(std::string(hfErrOutOfGas)); - - return x; -} - -// Transfer limit is a separate soft budget: exceeding it is a normal guest-facing -// return code, not a trap. Only a failed setTransferLimit (an xrpld bug) throws. -static inline std::expected -checkTransfer(WasmRuntimeWrapper& rt, int64_t delta) -{ - auto const transLimit = rt.getTransferLimit(); - int64_t const x = transLimit >= delta ? transLimit - delta : 0; - - if (rt.setTransferLimit(x) < 0) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - if (transLimit < delta) - return std::unexpected(HostFunctionError::OutOfTransferLimit); - - return x; -} - -// On any failure here a C++ exception is thrown; HostFuncMain_wrap's catch-all -// turns it into tecINTERNAL. These conditions are all xrpld-side invariants. -static std::tuple -mainCheck(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) -{ - if (env == nullptr) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - if (params == nullptr) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - if (results == nullptr) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - WasmUserData const* udata = reinterpret_cast(env); - HostFunctions& hf = udata->first; - WasmRuntimeWrapper& rt = hf.getRT(); - WasmImportFunc const& impFunc = udata->second; - - // Charge the per-call gas. Throws (and terminates) if out of gas. - checkGas(rt, impFunc.gas); - - return std::tie(hf, impFunc); -} - -//---------------------------------------------------------------------------------------------------------------------- - -static int32_t -setData( - WasmRuntimeWrapper& runtime, - int32_t dst, - int32_t dstSize, - uint8_t const* src, - int32_t srcSize) -{ - if (srcSize == 0) - return 0; // LCOV_EXCL_LINE - - if (dst < 0 || dstSize < 0 || (src == nullptr) || srcSize < 0) - return hfErrorToInt(HostFunctionError::InvalidParams); - - if (srcSize > kMaxWasmDataLength) - return hfErrorToInt(HostFunctionError::DataFieldTooLarge); - - auto const memory = runtime.getMem(); - - // LCOV_EXCL_START - if (memory.s == 0u) - return hfErrorToInt(HostFunctionError::NoMemExported); - // LCOV_EXCL_STOP - if (std::cmp_greater((int64_t)dst + dstSize, memory.s)) - return hfErrorToInt(HostFunctionError::PointerOutOfBounds); - if (srcSize > dstSize) - return hfErrorToInt(HostFunctionError::BufferTooSmall); - - if (auto t = checkTransfer(runtime, srcSize); !t) - return hfErrorToInt(t.error()); - - memcpy(memory.p + dst, src, srcSize); - - return srcSize; -} - -static std::expected -getDataSlice(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - 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 std::unexpected(HostFunctionError::InvalidParams); - - if (size == 0) - return Slice(); - - if (size > kMaxWasmDataLength) - return std::unexpected(HostFunctionError::DataFieldTooLarge); - - auto const memory = runtime.getMem(); - // LCOV_EXCL_START - if (memory.s == 0u) - return std::unexpected(HostFunctionError::NoMemExported); - // LCOV_EXCL_STOP - - if (std::cmp_greater(ptr + size, memory.s)) - return std::unexpected(HostFunctionError::PointerOutOfBounds); - - Slice const data(memory.p + ptr, size); - return data; -} - -static std::expected -getDataInt32(WasmRuntimeWrapper const&, wasm_val_vec_t const* params, int32_t& i) -{ - auto const result = params->data[i].of.i32; - i++; - return result; -} - -static std::expected -getDataInt64(WasmRuntimeWrapper const&, wasm_val_vec_t const* params, int32_t& i) -{ - auto const result = params->data[i].of.i64; - i++; - return result; -} - -template -static std::expected -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); - if (!r) - return std::unexpected(r.error()); - if (r->size() != sizeof(T)) - return std::unexpected(HostFunctionError::InvalidParams); - - T x; - auto const p = reinterpret_cast(r->data()); - if (p & (alignof(T) - 1)) // unaligned - { - memcpy(&x, r->data(), sizeof(T)); - } - else - { - x = *reinterpret_cast(r->data()); - } - x = adjustWasmEndianess(x); - - return x; -} - -static std::expected -getDataUInt32(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - return getDataUnsigned(runtime, params, i); -} - -static std::expected -getDataUInt64(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - return getDataUnsigned(runtime, params, i); -} - -static std::expected -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 std::unexpected(HostFunctionError::InvalidField); - - return *it->second; -} - -static std::expected -getDataUInt256(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - auto const slice = getDataSlice(runtime, params, i); - if (!slice) - return std::unexpected(slice.error()); - - if (slice->size() != uint256::size()) - return std::unexpected(HostFunctionError::InvalidParams); - - if (auto t = checkTransfer(runtime, uint256::size()); !t) - return std::unexpected(t.error()); - - return uint256::fromVoid(slice->data()); -} - -static std::expected -getDataAccountID(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - auto const slice = getDataSlice(runtime, params, i); - if (!slice) - return std::unexpected(slice.error()); - - if (slice->size() != AccountID::size()) - return std::unexpected(HostFunctionError::InvalidParams); - - if (auto t = checkTransfer(runtime, AccountID::size()); !t) - return std::unexpected(t.error()); - - return AccountID::fromVoid(slice->data()); -} - -static std::expected -getDataCurrency(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - auto const slice = getDataSlice(runtime, params, i); - if (!slice) - return std::unexpected(slice.error()); - - if (slice->size() != Currency::size()) - return std::unexpected(HostFunctionError::InvalidParams); - - if (auto t = checkTransfer(runtime, Currency::size()); !t) - return std::unexpected(t.error()); - - return Currency::fromVoid(slice->data()); -} - -static std::expected -getDataAsset(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - auto const slice = getDataSlice(runtime, params, i); - if (!slice) - return std::unexpected(slice.error()); - - if (slice->size() == MPTID::size()) - { - if (auto t = checkTransfer(runtime, slice->size()); !t) - return std::unexpected(t.error()); - - auto const mptid = MPTID::fromVoid(slice->data()); - return Asset{mptid}; - } - - if (slice->size() == Currency::size()) - { - if (auto t = checkTransfer(runtime, slice->size()); !t) - return std::unexpected(t.error()); - - auto const currency = Currency::fromVoid(slice->data()); - auto const issue = Issue{currency, xrpAccount()}; - if (!issue.native()) - return std::unexpected(HostFunctionError::InvalidParams); - - return Asset{issue}; - } - - if (slice->size() == (Currency::size() + AccountID::size())) - { - if (auto t = checkTransfer(runtime, slice->size()); !t) - return std::unexpected(t.error()); - - auto const issue = Issue( - Currency::fromVoid(slice->data()), - AccountID::fromVoid(slice->data() + Currency::size())); - - if (issue.native()) - return std::unexpected(HostFunctionError::InvalidParams); - - return Asset{issue}; - } - - return std::unexpected(HostFunctionError::InvalidParams); -} - -static std::expected -getDataString(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - auto const slice = getDataSlice(runtime, params, i); - if (!slice) - return std::unexpected(slice.error()); - - return std::string_view(reinterpret_cast(slice->data()), slice->size()); -} - -static std::expected -getDataLocator(WasmRuntimeWrapper& runtime, wasm_val_vec_t const* params, int32_t& i) -{ - static_assert(kMaxWasmDataLength % sizeof(int32_t) == 0); - - auto const slice = getDataSlice(runtime, params, i); - if (!slice) - return std::unexpected(slice.error()); - if (slice->empty() || ((slice->size() & 3) != 0u)) // must be multiple of 4 - return std::unexpected(HostFunctionError::LocatorMalformed); - - uint32_t const locSize = slice->size() / sizeof(int32_t); - auto const p = reinterpret_cast(slice->data()); - - if ((p & (alignof(int32_t) - 1)) != 0u) - { // unaligned - - // Use gas and transfer limit for copying. checkGas throws (and - // terminates execution) if out of gas; checkTransfer keeps returning a - // guest-facing code when the transfer limit is exceeded. - checkGas(runtime, unalignedGas); - if (auto t = checkTransfer(runtime, slice->size()); !t) - return std::unexpected(t.error()); - - std::vector locBuf(locSize); - memcpy(&locBuf[0], slice->data(), slice->size()); - FieldLocator locator(std::move(locBuf)); - - return locator; - } - - auto const* locPtr = reinterpret_cast(slice->data()); - return FieldLocator(locPtr, locSize); -} - -static inline std::nullptr_t -hfResult(wasm_val_vec_t* results, int32_t value) -{ - results->data[0] = WASM_I32_VAL(value); - // results->size = 1; - return nullptr; -} - -static inline std::nullptr_t -hfResult(wasm_val_vec_t* results, HostFunctionError value) -{ - results->data[0] = WASM_I32_VAL(hfErrorToInt(value)); - // results->size = 1; - return nullptr; -} - -template -static std::nullptr_t -returnResult( - WasmRuntimeWrapper& runtime, - wasm_val_vec_t const* params, - wasm_val_vec_t* results, - std::expected const& res, - int32_t index) -{ - if (!res) - return hfResult(results, res.error()); - - if constexpr (std::is_same_v) - { - if (index < 0 || index + 1 >= params->size) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - 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) - { - if (index < 0 || index + 1 >= params->size) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - 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) - { - return hfResult(results, res.value()); - } - else if constexpr (std::is_same_v) - { - if (index < 0 || index + 1 >= params->size) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - auto const resultValue = adjustWasmEndianess(res.value()); - 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) - { - if (index < 0 || index + 1 >= params->size) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - auto const resultValue = adjustWasmEndianess(res.value()); - 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) - { - if (index < 0 || index + 3 >= params->size) - Throw(std::string(hfErrInternal)); // LCOV_EXCL_LINE - - auto const mantissa = adjustWasmEndianess(res->first); - auto const r1 = setData( - runtime, - params->data[index].of.i32, - params->data[index + 1].of.i32, - reinterpret_cast(&mantissa), - static_cast(sizeof(mantissa))); - if (r1 < 0) - return hfResult(results, r1); - - index += 2; - auto const exponent = adjustWasmEndianess(res->second); - auto const r2 = setData( - runtime, - params->data[index].of.i32, - params->data[index + 1].of.i32, - reinterpret_cast(&exponent), - static_cast(sizeof(exponent))); - if (r2 < 0) - return hfResult(results, r2); - - return hfResult(results, r1 + r2); // 12 bytes - } - else - { - static_assert([] { return false; }(), "Unhandled return type in returnResult"); - } -} - -//---------------------------------------------------------------------------------------------------------------------- - -wasm_trap_t* -HostFuncMain_wrap(WASM_CB_PARAMS_LIST) -{ - [[maybe_unused]] std::string_view hfName; - - try - { - auto [hf, impFunc] = mainCheck(env, params, results); - hfName = impFunc.name; - auto* fWrap = reinterpret_cast(impFunc.wrap); - return fWrap(hf, params, results); - } - catch (std::exception const& e) - { -#ifdef DEBUG_OUTPUT - std::cerr << "Hostfunction " << hfName << " exception: " << e.what() << std::endl; -#endif - // Normalize to the two boundary signals: explicit out-of-gas, else any - // exception (including stray ones from helpers) is an internal fault. - bool const oog = std::string_view(e.what()) == hfErrOutOfGas; - wasm_trap_t* trap = reinterpret_cast( // NOLINT - WasmEngine::instance().newTrap(std::string(oog ? hfErrOutOfGas : hfErrInternal))); - return trap; - } - catch (...) - { -#ifdef DEBUG_OUTPUT - std::cerr << "Hostfunction " << hfName << " unknown exception." << std::endl; -#endif - wasm_trap_t* trap = reinterpret_cast( // NOLINT - WasmEngine::instance().newTrap(std::string(hfErrInternal))); // LCOV_EXCL_LINE - return trap; - } - - return nullptr; // LCOV_EXCL_LINE -} - -//---------------------------------------------------------------------------------------------------------------------- -wasm_trap_t* -getLedgerSqn_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int const index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - return returnResult(runtime, params, results, hf.getLedgerSqn(), index); -} - -wasm_trap_t* -getParentLedgerTime_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int const index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - return returnResult(runtime, params, results, hf.getParentLedgerTime(), index); -} - -wasm_trap_t* -getParentLedgerHash_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int const index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - return returnResult(runtime, params, results, hf.getParentLedgerHash(), index); -} - -wasm_trap_t* -getBaseFee_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int const index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - return returnResult(runtime, params, results, hf.getBaseFee(), index); -} - -wasm_trap_t* -isAmendmentEnabled_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const slice = getDataSlice(runtime, params, index); - if (!slice) - return hfResult(results, slice.error()); - - if (slice->size() == uint256::size()) - { - if (auto const ret = hf.isAmendmentEnabled(uint256::fromVoid(slice->data())); - ret && *ret == 1) - return returnResult(runtime, params, results, ret, index); - // Fall through to string lookup — the 32 bytes may be an amendment name - } - - 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); -} - -wasm_trap_t* -cacheLedgerObj_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -getTxField_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const fname = getDataSField(runtime, params, index); - if (!fname) - return hfResult(results, fname.error()); - - return returnResult(runtime, params, results, hf.getTxField(*fname), index); -} - -wasm_trap_t* -getCurrentLedgerObjField_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const fname = getDataSField(runtime, params, index); - if (!fname) - return hfResult(results, fname.error()); - - return returnResult(runtime, params, results, hf.getCurrentLedgerObjField(*fname), index); -} - -wasm_trap_t* -getLedgerObjField_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -getTxNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const locator = getDataLocator(runtime, params, index); - if (!locator) - return hfResult(results, locator.error()); - - return returnResult(runtime, params, results, hf.getTxNestedField(*locator), index); -} - -wasm_trap_t* -getCurrentLedgerObjNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const locator = getDataLocator(runtime, params, index); - if (!locator) - return hfResult(results, locator.error()); - - return returnResult( - runtime, params, results, hf.getCurrentLedgerObjNestedField(*locator), index); -} - -wasm_trap_t* -getLedgerObjNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const cache = getDataInt32(runtime, params, index); - if (!cache) - return hfResult(results, cache.error()); // LCOV_EXCL_LINE - - auto const locator = getDataLocator(runtime, params, index); - if (!locator) - return hfResult(results, locator.error()); - - return returnResult( - runtime, params, results, hf.getLedgerObjNestedField(*cache, *locator), index); -} - -wasm_trap_t* -getTxArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const fname = getDataSField(runtime, params, index); - if (!fname) - return hfResult(results, fname.error()); - - return returnResult(runtime, params, results, hf.getTxArrayLen(*fname), index); -} - -wasm_trap_t* -getCurrentLedgerObjArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const fname = getDataSField(runtime, params, index); - if (!fname) - return hfResult(results, fname.error()); - - return returnResult(runtime, params, results, hf.getCurrentLedgerObjArrayLen(*fname), index); -} - -wasm_trap_t* -getLedgerObjArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -getTxNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const locator = getDataLocator(runtime, params, index); - if (!locator) - return hfResult(results, locator.error()); - - return returnResult(runtime, params, results, hf.getTxNestedArrayLen(*locator), index); -} - -wasm_trap_t* -getCurrentLedgerObjNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const locator = getDataLocator(runtime, params, index); - if (!locator) - return hfResult(results, locator.error()); - - return returnResult( - runtime, params, results, hf.getCurrentLedgerObjNestedArrayLen(*locator), index); -} -wasm_trap_t* -getLedgerObjNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const cache = getDataInt32(runtime, params, index); - if (!cache) - return hfResult(results, cache.error()); // LCOV_EXCL_LINE - - auto const locator = getDataLocator(runtime, params, index); - if (!locator) - return hfResult(results, locator.error()); - - return returnResult( - runtime, params, results, hf.getLedgerObjNestedArrayLen(*cache, *locator), index); -} - -wasm_trap_t* -updateData_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const bytes = getDataSlice(runtime, params, index); - if (!bytes) - return hfResult(results, bytes.error()); - - return returnResult(runtime, params, results, hf.updateData(*bytes), index); -} - -wasm_trap_t* -checkSignature_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -computeSha512HalfHash_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const bytes = getDataSlice(runtime, params, index); - if (!bytes) - return hfResult(results, bytes.error()); - - return returnResult(runtime, params, results, hf.computeSha512HalfHash(*bytes), index); -} - -wasm_trap_t* -accountKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const acc = getDataAccountID(runtime, params, index); - if (!acc) - return hfResult(results, acc.error()); - - return returnResult(runtime, params, results, hf.accountKeylet(*acc), index); -} - -wasm_trap_t* -ammKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -checkKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -credentialKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -delegateKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -depositPreauthKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -didKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const acc = getDataAccountID(runtime, params, index); - if (!acc) - return hfResult(results, acc.error()); - - return returnResult(runtime, params, results, hf.didKeylet(acc.value()), index); -} - -wasm_trap_t* -escrowKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -trustLineKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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, - params, - results, - hf.trustLineKeylet(acc1.value(), acc2.value(), currency.value()), - index); -} - -wasm_trap_t* -mptokenIssuanceKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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.mptokenIssuanceKeylet(acc.value(), seq.value()), index); -} - -wasm_trap_t* -mptokenKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -nftokenOfferKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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.nftokenOfferKeylet(acc.value(), seq.value()), index); -} - -wasm_trap_t* -offerKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -oracleKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -paychannelKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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.paychannelKeylet(acc.value(), dest.value(), seq.value()), - index); -} - -wasm_trap_t* -permissionedDomainKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -signerListKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const acc = getDataAccountID(runtime, params, index); - if (!acc) - return hfResult(results, acc.error()); - - return returnResult(runtime, params, results, hf.signerListKeylet(acc.value()), index); -} - -wasm_trap_t* -ticketKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -vaultKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -getNFT_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -getNFTIssuer_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const nftId = getDataUInt256(runtime, params, index); - if (!nftId) - return hfResult(results, nftId.error()); - - return returnResult(runtime, params, results, hf.getNFTIssuer(*nftId), index); -} - -wasm_trap_t* -getNFTTaxon_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const nftId = getDataUInt256(runtime, params, index); - if (!nftId) - return hfResult(results, nftId.error()); - - return returnResult(runtime, params, results, hf.getNFTTaxon(*nftId), index); -} - -wasm_trap_t* -getNFTFlags_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const nftId = getDataUInt256(runtime, params, index); - if (!nftId) - return hfResult(results, nftId.error()); - - return returnResult(runtime, params, results, hf.getNFTFlags(*nftId), index); -} - -wasm_trap_t* -getNFTTransferFee_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const nftId = getDataUInt256(runtime, params, index); - if (!nftId) - return hfResult(results, nftId.error()); - - return returnResult(runtime, params, results, hf.getNFTTransferFee(*nftId), index); -} - -wasm_trap_t* -getNFTSequence_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const nftId = getDataUInt256(runtime, params, index); - if (!nftId) - return hfResult(results, nftId.error()); - - return returnResult(runtime, params, results, hf.getNFTSequence(*nftId), index); -} - -wasm_trap_t* -trace_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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()); - - if (msg->size() + data->size() > kMaxWasmDataLength) - return hfResult(results, HostFunctionError::DataFieldTooLarge); - - 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); -} - -wasm_trap_t* -traceNum_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int index = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -traceAccount_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -traceFloat_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); -} - -wasm_trap_t* -traceAmount_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - 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); - - std::optional amount; - try - { - amount = STAmount(serialIter, sfGeneric); - } - catch (std::exception const&) - { - amount = std::nullopt; - } - - if (!amount) - { - return hfResult(results, HostFunctionError::InvalidParams); - } - - return returnResult(runtime, params, results, hf.traceAmount(*msg, *amount), i); -} - -wasm_trap_t* -floatFromInt_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataInt64(runtime, params, i); - if (!x) - return hfResult(results, x.error()); // LCOV_EXCL_LINE - - i = 3; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 1; - return returnResult(runtime, params, results, hf.floatFromInt(*x, *rounding), i); -} - -wasm_trap_t* -floatFromUint_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataUInt64(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - i = 4; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 2; - return returnResult(runtime, params, results, hf.floatFromUint(*x, *rounding), i); -} - -wasm_trap_t* -floatFromSTAmount_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto serialIter = SerialIter(*x); - std::optional amount; - try - { - amount = STAmount(serialIter, sfGeneric); - } - catch (std::exception const&) - { - amount = std::nullopt; - } - if (!amount) - return hfResult(results, HostFunctionError::InvalidParams); - - i = 4; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 2; - return returnResult(runtime, params, results, hf.floatFromSTAmount(*amount, *rounding), i); -} - -wasm_trap_t* -floatFromSTNumber_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto serialIter = SerialIter(*x); - std::optional num; - try - { - num = STNumber(serialIter, sfGeneric); - } - catch (std::exception const&) - { - num = std::nullopt; - } - if (!num) - return hfResult(results, HostFunctionError::InvalidParams); - - i = 4; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 2; - return returnResult(runtime, params, results, hf.floatFromSTNumber(*num, *rounding), i); -} - -wasm_trap_t* -floatToInt_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - i = 4; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 2; - return returnResult(runtime, params, results, hf.floatToInt(*x, *rounding), i); -} - -wasm_trap_t* -floatToMantExp_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - i = 2; - return returnResult(runtime, params, results, hf.floatToMantExp(*x), i); -} - -wasm_trap_t* -floatFromMantExp_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const mant = getDataInt64(runtime, params, i); - if (!mant) - return hfResult(results, mant.error()); // LCOV_EXCL_LINE - - auto const exp = getDataInt32(runtime, params, i); - if (!exp) - return hfResult(results, exp.error()); // LCOV_EXCL_LINE - - i = 4; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 2; - return returnResult(runtime, params, results, hf.floatFromMantExp(*mant, *exp, *rounding), i); -} - -wasm_trap_t* -floatCompare_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const y = getDataSlice(runtime, params, i); - if (!y) - return hfResult(results, y.error()); - - return returnResult(runtime, params, results, hf.floatCompare(*x, *y), i); -} - -wasm_trap_t* -floatAdd_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const y = getDataSlice(runtime, params, i); - if (!y) - return hfResult(results, y.error()); - - i = 6; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 4; - return returnResult(runtime, params, results, hf.floatAdd(*x, *y, *rounding), i); -} - -wasm_trap_t* -floatSubtract_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const y = getDataSlice(runtime, params, i); - if (!y) - return hfResult(results, y.error()); - - i = 6; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 4; - return returnResult(runtime, params, results, hf.floatSubtract(*x, *y, *rounding), i); -} - -wasm_trap_t* -floatMultiply_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const y = getDataSlice(runtime, params, i); - if (!y) - return hfResult(results, y.error()); - - i = 6; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 4; - return returnResult(runtime, params, results, hf.floatMultiply(*x, *y, *rounding), i); -} - -wasm_trap_t* -floatDivide_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const y = getDataSlice(runtime, params, i); - if (!y) - return hfResult(results, y.error()); - - i = 6; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 4; - return returnResult(runtime, params, results, hf.floatDivide(*x, *y, *rounding), i); -} - -wasm_trap_t* -floatRoot_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const n = getDataInt32(runtime, params, i); - if (!n) - return hfResult(results, n.error()); // LCOV_EXCL_LINE - - i = 5; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 3; - return returnResult(runtime, params, results, hf.floatRoot(*x, *n, *rounding), i); -} - -wasm_trap_t* -floatPower_wrap(WASM_SECONDARY_CB_PARAMS_LIST) -{ - int i = 0; - WasmRuntimeWrapper& runtime = hf.getRT(); - - auto const x = getDataSlice(runtime, params, i); - if (!x) - return hfResult(results, x.error()); - - auto const n = getDataInt32(runtime, params, i); - if (!n) - return hfResult(results, n.error()); // LCOV_EXCL_LINE - - i = 5; - auto const rounding = getDataInt32(runtime, params, i); - if (!rounding) - return hfResult(results, rounding.error()); // LCOV_EXCL_LINE - - i = 3; - return returnResult(runtime, params, results, hf.floatPower(*x, *n, *rounding), i); -} - -// LCOV_EXCL_START -namespace test { - -class MockWasmRuntimeWrapper : public WasmRuntimeWrapper -{ - Wmem mem_; - - std::int64_t gas_ = 1'000'000; - std::int64_t transferLimit_ = kWasmTransferLimit; - -public: - MockWasmRuntimeWrapper(Wmem memory) : mem_(memory) - { - } - - // Mock methods to simulate the behavior of WasmRuntimeWrapper - [[nodiscard]] Wmem - getMem() override - { - return mem_; - } - - std::int64_t - getGas() override - { - return gas_; - } - - std::int64_t - setGas(std::int64_t gas) override - { - gas_ = gas; - return gas_; - } - - std::int64_t - getTransferLimit() override - { - return transferLimit_; - } - - std::int64_t - setTransferLimit(std::int64_t x) override - { - transferLimit_ = x; - return transferLimit_; - } -}; - -bool -testGetDataIncrement() -{ - wasm_val_t values[4]; - - std::array buffer = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; - MockWasmRuntimeWrapper runtime(Wmem(buffer.data(), buffer.size())); - - { - // test int32_t - wasm_val_vec_t const params = {.size = 1, .data = &values[0]}; - - values[0] = WASM_I32_VAL(42); - - int index = 0; - auto const result = getDataInt32(runtime, ¶ms, index); - if (!result || result.value() != 42 || index != 1) - return false; - } - - { - // test int64_t - wasm_val_vec_t const params = {.size = 1, .data = &values[0]}; - - values[0] = WASM_I64_VAL(1234); - - int index = 0; - auto const result = getDataInt64(runtime, ¶ms, index); - if (!result || result.value() != 1234 || index != 1) - return false; - } - - { - // test SFieldCRef - wasm_val_vec_t const params = {.size = 1, .data = &values[0]}; - - values[0] = WASM_I32_VAL(sfAccount.getCode()); - - int index = 0; - auto const result = getDataSField(runtime, ¶ms, index); - if (!result || result.value().get() != sfAccount || index != 1) - return false; - } - - { - // test Slice - wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; - - values[0] = WASM_I32_VAL(0); - values[1] = WASM_I32_VAL(3); - - int index = 0; - auto const result = getDataSlice(runtime, ¶ms, index); - if (!result || result.value() != Slice(buffer.data(), 3) || index != 2) - return false; - } - - { - // test string - wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; - - values[0] = WASM_I32_VAL(0); - values[1] = WASM_I32_VAL(5); - - int index = 0; - auto const result = getDataString(runtime, ¶ms, index); - if (!result || - result.value() != std::string_view(reinterpret_cast(buffer.data()), 5) || - index != 2) - return false; - } - - { - // test account - AccountID const id( - calcAccountID(generateKeyPair(KeyType::Secp256k1, generateSeed("alice")).first)); - - wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; - - values[0] = WASM_I32_VAL(0); - values[1] = WASM_I32_VAL(AccountID::size()); - memcpy(&buffer[0], id.data(), AccountID::size()); - - int index = 0; - auto const result = getDataAccountID(runtime, ¶ms, index); - if (!result || result.value() != id || index != 2) - return false; - } - - { - // test uint256 - - Hash h1 = sha512Half(Slice(buffer.data(), 8)); - wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; - - values[0] = WASM_I32_VAL(0); - values[1] = WASM_I32_VAL(Hash::size()); - memcpy(&buffer[0], h1.data(), Hash::size()); - - int index = 0; - auto const result = getDataUInt256(runtime, ¶ms, index); - if (!result || result.value() != h1 || index != 2) - return false; - } - - { - // test Currency - - Currency const c = xrpCurrency(); - wasm_val_vec_t const params = {.size = 2, .data = &values[0]}; - - values[0] = WASM_I32_VAL(0); - values[1] = WASM_I32_VAL(Currency::size()); - memcpy(&buffer[0], c.data(), Currency::size()); - - int index = 0; - auto const result = getDataCurrency(runtime, ¶ms, index); - if (!result || result.value() != c || index != 2) - return false; - } - - return true; -} - -} // namespace test -// LCOV_EXCL_STOP - -} // namespace xrpl diff --git a/src/libxrpl/tx/wasm/WasmVM.cpp b/src/libxrpl/tx/wasm/WasmVM.cpp deleted file mode 100644 index 7eda08f42b..0000000000 --- a/src/libxrpl/tx/wasm/WasmVM.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include - -#include -#include -#include // IWYU pragma: keep -#include -#include - -#include -#include -#include -#include -#ifdef _DEBUG -// #define DEBUG_OUTPUT 1 -#endif - -#include -#include - -#include - -namespace xrpl { -// WARNING: Per XLS-0102, the host functions registered here form a stable -// ABI. Their name, semantics, parameters, and return types must NEVER be -// changed, as there may always be a program that uses it. New host functions -// may be added and existing gas costs may be adjusted, but every such change -// must be gated by an amendment. -// 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) -{ - // clang-format off - WASM_IMPORT_FUNC2(i, getLedgerSqn, "ldgr_index", hfs, 60); - WASM_IMPORT_FUNC2(i, getParentLedgerTime, "parent_ldgr_time", hfs, 60); - WASM_IMPORT_FUNC2(i, getParentLedgerHash, "parent_ldgr_hash", hfs, 60); - WASM_IMPORT_FUNC2(i, getBaseFee, "base_fee", hfs, 60); - WASM_IMPORT_FUNC2(i, isAmendmentEnabled, "amendment_enabled", hfs, 100); - - WASM_IMPORT_FUNC2(i, cacheLedgerObj, "cache_le", hfs, 5'000); - WASM_IMPORT_FUNC2(i, getTxField, "tx_field", hfs, 70); - WASM_IMPORT_FUNC2(i, getCurrentLedgerObjField, "home_le_field", hfs, 70); - WASM_IMPORT_FUNC2(i, getLedgerObjField, "le_field", hfs, 70); - WASM_IMPORT_FUNC2(i, getTxNestedField, "tx_inner", hfs, 110); - WASM_IMPORT_FUNC2(i, getCurrentLedgerObjNestedField, "home_le_inner", hfs, 110); - WASM_IMPORT_FUNC2(i, getLedgerObjNestedField, "le_inner", hfs, 110); - WASM_IMPORT_FUNC2(i, getTxArrayLen, "tx_arr_len", hfs, 40); - WASM_IMPORT_FUNC2(i, getCurrentLedgerObjArrayLen, "home_le_arr_len", hfs, 40); - WASM_IMPORT_FUNC2(i, getLedgerObjArrayLen, "le_arr_len", hfs, 40); - WASM_IMPORT_FUNC2(i, getTxNestedArrayLen, "tx_inner_arr_len", hfs, 70); - WASM_IMPORT_FUNC2(i, getCurrentLedgerObjNestedArrayLen, "home_le_inner_arr_len", hfs, 70); - WASM_IMPORT_FUNC2(i, getLedgerObjNestedArrayLen, "le_inner_arr_len", hfs, 70); - - WASM_IMPORT_FUNC2(i, checkSignature, "check_sig", hfs, 300); - WASM_IMPORT_FUNC2(i, computeSha512HalfHash, "sha512_half", hfs, 2000); - - WASM_IMPORT_FUNC2(i, accountKeylet, "accountroot_id", hfs, 350); - WASM_IMPORT_FUNC2(i, ammKeylet, "amm_id", hfs, 450); - WASM_IMPORT_FUNC2(i, checkKeylet, "check_id", hfs, 350); - WASM_IMPORT_FUNC2(i, credentialKeylet, "credential_id", hfs, 350); - WASM_IMPORT_FUNC2(i, delegateKeylet, "delegate_id", hfs, 350); - WASM_IMPORT_FUNC2(i, depositPreauthKeylet, "deposit_preauth_id", hfs, 350); - WASM_IMPORT_FUNC2(i, didKeylet, "did_id", hfs, 350); - WASM_IMPORT_FUNC2(i, escrowKeylet, "escrow_id", hfs, 350); - WASM_IMPORT_FUNC2(i, trustLineKeylet, "trustline_id", hfs, 400); - WASM_IMPORT_FUNC2(i, mptokenIssuanceKeylet, "mpt_issuance_id", hfs, 350); - WASM_IMPORT_FUNC2(i, mptokenKeylet, "mptoken_id", hfs, 500); - WASM_IMPORT_FUNC2(i, nftokenOfferKeylet, "nft_offer_id", hfs, 350); - WASM_IMPORT_FUNC2(i, offerKeylet, "offer_id", hfs, 350); - WASM_IMPORT_FUNC2(i, oracleKeylet, "oracle_id", hfs, 350); - WASM_IMPORT_FUNC2(i, paychannelKeylet, "paychan_id", hfs, 350); - WASM_IMPORT_FUNC2(i, permissionedDomainKeylet, "permissioned_domain_id", hfs, 350); - WASM_IMPORT_FUNC2(i, signerListKeylet, "signers_id", hfs, 350); - WASM_IMPORT_FUNC2(i, ticketKeylet, "ticket_id", hfs, 350); - WASM_IMPORT_FUNC2(i, vaultKeylet, "vault_id", hfs, 350); - - WASM_IMPORT_FUNC2(i, getNFT, "nft_uri", hfs, 5'000); - WASM_IMPORT_FUNC2(i, getNFTIssuer, "nft_issuer", hfs, 70); - WASM_IMPORT_FUNC2(i, getNFTTaxon, "nft_taxon", hfs, 60); - WASM_IMPORT_FUNC2(i, getNFTFlags, "nft_flags", hfs, 60); - WASM_IMPORT_FUNC2(i, getNFTTransferFee, "nft_xfer_fee", hfs, 60); - WASM_IMPORT_FUNC2(i, getNFTSequence, "nft_serial", hfs, 60); - - WASM_IMPORT_FUNC (i, trace, hfs, 500); - WASM_IMPORT_FUNC2(i, traceNum, "trace_num", hfs, 500); - WASM_IMPORT_FUNC2(i, traceAccount, "trace_acct", hfs, 500); - WASM_IMPORT_FUNC2(i, traceFloat, "trace_xfloat", hfs, 500); - WASM_IMPORT_FUNC2(i, traceAmount, "trace_amt", hfs, 500); - - WASM_IMPORT_FUNC2(i, floatFromInt, "float_from_int", hfs, 100); - WASM_IMPORT_FUNC2(i, floatFromUint, "float_from_uint", hfs, 130); - WASM_IMPORT_FUNC2(i, floatFromSTAmount, "float_from_stamount", hfs, 150); - WASM_IMPORT_FUNC2(i, floatFromSTNumber, "float_from_stnumber", hfs, 150); - WASM_IMPORT_FUNC2(i, floatToInt, "float_to_int", hfs, 130); - WASM_IMPORT_FUNC2(i, floatToMantExp, "float_to_mant_exp", hfs, 130); - WASM_IMPORT_FUNC2(i, floatFromMantExp, "float_from_mant_exp", hfs, 100); - WASM_IMPORT_FUNC2(i, floatCompare, "float_cmp", hfs, 80); - WASM_IMPORT_FUNC2(i, floatAdd, "float_add", hfs, 160); - WASM_IMPORT_FUNC2(i, floatSubtract, "float_sub", hfs, 160); - WASM_IMPORT_FUNC2(i, floatMultiply, "float_mult", hfs, 300); - WASM_IMPORT_FUNC2(i, floatDivide, "float_div", hfs, 300); - WASM_IMPORT_FUNC2(i, floatRoot, "float_root", hfs, 5'500); - WASM_IMPORT_FUNC2(i, floatPower, "float_pow", hfs, 5'500); - // clang-format on -} - -ImportVec -createWasmImport(HostFunctions& hfs) -{ - ImportVec i; - - setCommonHostFunctions(hfs, i); - WASM_IMPORT_FUNC2(i, updateData, "set_data", hfs, 1000); - - return i; -} - -std::expected -runEscrowWasm( - Bytes const& wasmCode, - HostFunctions& hfs, - int64_t gasLimit, - std::string_view funcName, - std::vector const& params) -{ - // create VM and set cost limit - auto& vm = WasmEngine::instance(); - // vm.initMaxPages(MAX_PAGES); - - auto const ret = - vm.run(wasmCode, hfs, gasLimit, funcName, params, createWasmImport(hfs), hfs.getJournal()); - - if (!ret) - { -#ifdef DEBUG_OUTPUT - std::cout << ", error: " << ret.error().ter << std::endl; -#endif - // Carries the TER (tecOUT_OF_GAS / tecFAILED_PROCESSING / tecINTERNAL / - // temBAD_AMOUNT) and, when meaningful, the gas consumed. The caller is - // responsible for writing that gas to tx metadata. - return std::unexpected(ret.error()); - } - -#ifdef DEBUG_OUTPUT - std::cout << ", ret: " << ret->result << ", gas spent: " << ret->cost << std::endl; -#endif - return EscrowResult{.result = ret->result, .cost = ret->cost}; -} - -NotTEC -preflightEscrowWasm( - Bytes const& wasmCode, - HostFunctions& hfs, - std::string_view funcName, - std::vector const& params) -{ - // create VM and set cost limit - auto& vm = WasmEngine::instance(); - // vm.initMaxPages(MAX_PAGES); - - auto const ret = - vm.check(wasmCode, hfs, funcName, params, createWasmImport(hfs), hfs.getJournal()); - - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -WasmEngine::WasmEngine() : impl_(std::make_unique()) -{ -} - -WasmEngine& -WasmEngine::instance() -{ - static WasmEngine e; - return e; -} - -std::expected, WasmTER> -WasmEngine::run( - Bytes const& wasmCode, - HostFunctions& hfs, - int64_t gasLimit, - std::string_view funcName, - std::vector const& params, - ImportVec const& imports, - beast::Journal j) -{ - return impl_->run(wasmCode, hfs, gasLimit, funcName, params, imports, j); -} - -NotTEC -WasmEngine::check( - Bytes const& wasmCode, - HostFunctions& hfs, - std::string_view funcName, - std::vector const& params, - ImportVec const& imports, - beast::Journal j) -{ - return impl_->check(wasmCode, hfs, funcName, params, imports, j); -} - -void* -WasmEngine::newTrap(std::string const& msg) -{ - return impl_->newTrap(msg); -} - -// LCOV_EXCL_START -beast::Journal -WasmEngine::getJournal() const -{ - return impl_->getJournal(); -} -// LCOV_EXCL_STOP - -} // namespace xrpl diff --git a/src/libxrpl/tx/wasm/WasmiVM.cpp b/src/libxrpl/tx/wasm/WasmiVM.cpp index cfe54fccc2..b299506dd1 100644 --- a/src/libxrpl/tx/wasm/WasmiVM.cpp +++ b/src/libxrpl/tx/wasm/WasmiVM.cpp @@ -1,3 +1,4 @@ +/* #include #include @@ -956,3 +957,4 @@ WasmiEngine::newTrap(std::string const& txt) } } // namespace xrpl +*/ diff --git a/src/test/app/HostFuncImpl_test.cpp b/src/test/app/HostFuncImpl_test.cpp index 8311aae638..4fb4c12717 100644 --- a/src/test/app/HostFuncImpl_test.cpp +++ b/src/test/app/HostFuncImpl_test.cpp @@ -1,4 +1,4 @@ - +/* #include #include #include @@ -6250,3 +6250,4 @@ struct HostFuncImpl_test : public beast::unit_test::Suite BEAST_DEFINE_TESTSUITE(HostFuncImpl, app, xrpl); } // namespace xrpl::test +*/ diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 3a9f541153..d3a265ca14 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -1,3 +1,4 @@ +/* #include #ifdef _DEBUG // #define DEBUG_OUTPUT 1 @@ -78,32 +79,32 @@ struct Wasm_test : public beast::unit_test::Suite { testcase("wasm lib test"); // clang-format off - /* The WASM module buffer. */ - Bytes const wasm = {/* WASM header */ + // The WASM module buffer. // + Bytes const wasm = {// WASM header // 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, - /* Type section */ + // Type section // 0x01, 0x07, 0x01, - /* function type {i32, i32} -> {i32} */ + // function type {i32, i32} -> {i32} // 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, - /* Import section */ + // Import section // 0x02, 0x13, 0x01, - /* module name: "extern" */ + // module name: "extern" // 0x06, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6E, - /* extern name: "func-add" */ + // extern name: "func-add" // 0x08, 0x66, 0x75, 0x6E, 0x63, 0x2D, 0x61, 0x64, 0x64, - /* import desc: func 0 */ + // import desc: func 0 // 0x00, 0x00, - /* Function section */ + // Function section // 0x03, 0x02, 0x01, 0x00, - /* Export section */ + // Export section // 0x07, 0x0A, 0x01, - /* export name: "addTwo" */ + // export name: "addTwo" // 0x06, 0x61, 0x64, 0x64, 0x54, 0x77, 0x6F, - /* export desc: func 0 */ + // export desc: func 0 // 0x00, 0x01, - /* Code section */ + // Code section // 0x0A, 0x0A, 0x01, - /* code body */ + // code body // 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0B}; // clang-format on auto& vm = WasmEngine::instance(); @@ -467,3 +468,4 @@ struct Wasm_test : public beast::unit_test::Suite BEAST_DEFINE_TESTSUITE(Wasm, app, xrpl); } // namespace xrpl::test +*/