Cleanup and some refactoring (#7383)

This commit is contained in:
Olek
2026-06-02 21:15:58 -04:00
committed by GitHub
parent 63fff4b518
commit 0dbe51c740
20 changed files with 850 additions and 1123 deletions

View File

@@ -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;

View File

@@ -8,43 +8,10 @@
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
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<int64_t, int32_t>;
inline int32_t
HfErrorToInt(HostFunctionError e)
{
return static_cast<int32_t>(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<std::uint32_t, HostFunctionError>
getLedgerSqn() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<std::uint32_t, HostFunctionError>
getParentLedgerTime() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Hash, HostFunctionError>
getParentLedgerHash() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<uint32_t, HostFunctionError>
getBaseFee() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
updateData(Slice const& data)
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
didKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
delegateKeylet(AccountID const& account, AccountID const& authorize) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
offerKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t docId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
signersKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
ticketKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
vaultKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<std::uint32_t, HostFunctionError>
getNFTSerial(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
trace(std::string_view const& msg, Slice const& data, bool asHex) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceNum(std::string_view const& msg, int64_t data) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceAccount(std::string_view const& msg, AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceFloat(std::string_view const& msg, Slice const& data) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceAmount(std::string_view const& msg, STAmount const& amount) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromInt(int64_t x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromUint(uint64_t x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromSTAmount(STAmount const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromSTNumber(STNumber const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int64_t, HostFunctionError>
floatToInt(Slice const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<FloatPair, HostFunctionError>
floatToMantExp(Slice const& x) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromMantExp(int64_t mantissa, int32_t exponent, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
floatCompare(Slice const& x, Slice const& y) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatAdd(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatDivide(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatRoot(Slice const& x, int32_t n, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
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<HostFunctions>;
} // namespace xrpl

View File

@@ -18,8 +18,7 @@ class WasmHostFunctionsImpl : public HostFunctions
std::optional<Bytes> data_;
void* rt_ = nullptr;
public:
Expected<std::shared_ptr<SLE const>, 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
{

View File

@@ -1,6 +1,6 @@
#pragma once
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <wasm.h>

View File

@@ -0,0 +1,160 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <functional>
#include <optional>
#include <stdexcept>
#include <vector>
namespace xrpl {
using Bytes = std::vector<std::uint8_t>;
using Hash = xrpl::uint256;
using FloatPair = std::pair<int64_t, int32_t>;
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<std::uint8_t*>(ptr)), s(size)
{
}
};
template <typename T>
struct WasmResult
{
T result;
int64_t cost;
};
using EscrowResult = WasmResult<int32_t>;
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<std::reference_wrapper<WasmRuntimeWrapper>>;
struct WasmParam
{
// We are not supporting float/double
WasmTypes type = WasmTypes::WtI32;
union
{
std::int32_t i32;
std::int64_t i64 = 0;
} of;
};
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
inline void
wasmParamsHlp(std::vector<WasmParam>& v)
{
return;
}
template <class... Types>
inline std::vector<WasmParam>
wasmParams(Types&&... args)
{
std::vector<WasmParam> v;
v.reserve(sizeof...(args));
wasmParamsHlp(v, std::forward<Types>(args)...);
return v;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianessHlp(T x)
{
static_assert(std::is_integral_v<T>, "Only integral types");
if constexpr (Size > 1)
{
using U = std::make_unsigned_t<T>;
U u = static_cast<U>(x);
U const low = (u & 0xFF) << ((Size - 1) << 3);
u = adjustWasmEndianessHlp<U, Size - 1>(u >> 8);
return static_cast<T>(low | u);
}
return x;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianess(T x)
{
// LCOV_EXCL_START
static_assert(std::is_integral_v<T>, "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<int32_t>(e);
}
} // namespace xrpl

View File

@@ -1,84 +1,33 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/vector.hpp>
#include <bit>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
#include <wasm.h>
namespace bft = boost::function_types;
namespace xrpl {
template <typename>
inline constexpr bool wasmDependentFalse = false;
using Bytes = std::vector<std::uint8_t>;
using Hash = xrpl::uint256;
struct Wmem
{
std::uint8_t* p = nullptr;
std::size_t s = 0;
};
template <typename T>
struct WasmResult
{
T result;
int64_t cost;
};
using EscrowResult = WasmResult<int32_t>;
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<WasmTypes> result;
std::vector<WasmTypes> params;
// void* udata = nullptr;
// wasm_func_callback_with_env_t
void* wrap = nullptr;
uint32_t gas = 0;
};
using WasmUserData = std::pair<void*, WasmImportFunc>;
using WasmUserData = std::pair<HFRef, WasmImportFunc>;
// string - import function name
using ImportVec = std::unordered_map<std::string_view, WasmUserData>;
#define WASM_IMPORT_FUNC(v, f, ...) \
WasmImpFunc<f##_proto>(v, #f, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
// n - string literal name, must have static lifetime
#define WASM_IMPORT_FUNC2(v, f, n, ...) \
WasmImpFunc<f##_proto>(v, n, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
template <int N, int C, typename Mpl>
void
WasmImpArgs(WasmImportFunc& e)
@@ -108,6 +57,9 @@ WasmImpArgs(WasmImportFunc& e)
return;
}
template <typename>
inline constexpr bool wasmDependentFalse = false;
template <typename Rt>
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<F>(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<f##_proto>(v, #f, reinterpret_cast<void*>(&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 <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
inline void
wasmParamsHlp(std::vector<WasmParam>& v)
{
return;
}
template <class... Types>
inline std::vector<WasmParam>
wasmParams(Types&&... args)
{
std::vector<WasmParam> v;
v.reserve(sizeof...(args));
wasmParamsHlp(v, std::forward<Types>(args)...);
return v;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianessHlp(T x)
{
static_assert(std::is_integral_v<T>, "Only integral types");
if constexpr (Size > 1)
{
using U = std::make_unsigned_t<T>;
U u = static_cast<U>(x);
U const low = (u & 0xFF) << ((Size - 1) << 3);
u = adjustWasmEndianessHlp<U, Size - 1>(u >> 8);
return static_cast<T>(low | u);
}
return x;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianess(T x)
{
// LCOV_EXCL_START
static_assert(std::is_integral_v<T>, "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<f##_proto>(v, n, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
} // namespace xrpl

View File

@@ -1,6 +1,7 @@
#pragma once
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <string_view>

View File

@@ -1,5 +1,6 @@
#pragma once
#include <xrpl/protocol/Protocol.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <wasm.h>
@@ -139,13 +140,13 @@ using StorePtr = std::unique_ptr<wasm_store_t, decltype(&wasm_store_delete)>;
using FuncInfo = std::pair<wasm_func_t const*, wasm_functype_t const*>;
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<bool>(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<std::runtime_error>("no module");
return moduleWrap_->getInstance(i);
}
[[nodiscard]] Wmem
getMem() const;
getMem() const
{
return moduleWrap_ ? moduleWrap_->getMem() : Wmem();
}
Expected<WasmResult<int32_t>, 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<wasm_val_t>
convertParams(std::vector<WasmParam> const& params);

View File

@@ -5,8 +5,7 @@
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
@@ -19,10 +18,9 @@ namespace xrpl {
Expected<int32_t, HostFunctionError>
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();
}

View File

@@ -6,7 +6,7 @@
#include <xrpl/protocol/Serializer.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <boost/algorithm/hex.hpp>

View File

@@ -10,9 +10,8 @@
#include <xrpl/protocol/STBitString.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
#include <cstring>
@@ -119,16 +118,12 @@ static Expected<Bytes, HostFunctionError>
getAnyFieldData(FieldValue const& variantObj)
{
if (STBase const* const* obj = std::get_if<STBase const*>(&variantObj))
{
return getAnyFieldData(*obj);
}
if (uint256 const* const* u = std::get_if<uint256 const*>(&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);

View File

@@ -6,9 +6,8 @@
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>

View File

@@ -1,9 +1,8 @@
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/ledger/AmendmentTable.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
#include <string>

View File

@@ -5,9 +5,8 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/wasm/HostFuncWrapper.h> // IWYU pragma: keep
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <cstdint>
#include <string>
@@ -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

View File

@@ -5,7 +5,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <wasmi/config.h>
@@ -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<std::runtime_error>("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<bool>(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<std::runtime_error>("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<std::runtime_error>("no export"); // LCOV_EXCL_LINE
if (exportTypes.size() != exports_.size())
Throw<std::runtime_error>("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<std::runtime_error>("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<std::runtime_error>("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<std::uint8_t*>(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<std::uint8_t*>(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<std::int64_t>(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<decltype(gas)>::max();
wasmi_error_t* err = wasm_store_set_fuel(store, static_cast<std::uint64_t>(gas));
wasmi_error_t* err = wasm_store_set_fuel(store_, static_cast<std::uint64_t>(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<std::runtime_error>("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<wasm_val_t>
WasmiEngine::convertParams(std::vector<WasmParam> const& params)
{
@@ -711,8 +625,8 @@ WasmiResult
WasmiEngine::call(FuncInfo const& f, std::vector<wasm_val_t>& 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<std::runtime_error>("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<HostFunctions, decltype(clear)> const clearGuard(&hfs, clear);
auto clearRT = [](HostFunctions* p) { p->resetRT(); };
std::unique_ptr<HostFunctions, decltype(clearRT)> 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::runtime_error>("<" + std::string(funcName) + "> failure");
if (res.r.empty())
{
throw std::runtime_error(
Throw<std::runtime_error>(
"<" + std::string(funcName) + "> return nothing"); // LCOV_EXCL_LINE
}
if (res.r[0].kind != WASM_I32)
{
throw std::runtime_error(
Throw<std::runtime_error>(
"<" + std::string(funcName) +
"> return type mismatch, ret: " + std::to_string(static_cast<int>(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

View File

@@ -44,7 +44,8 @@
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/HostFuncWrapper.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <xrpl/tx/wasm/WasmiVM.h>
@@ -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<std::runtime_error>("Out of bounds");
Throw<std::out_of_range>("Out of bounds");
if (params[i].kind != WASM_I32 || params[i + 1].kind != WASM_I32)
Throw<std::runtime_error>("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<std::runtime_error>("Out of bounds");
Throw<std::out_of_range>("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<Arg, Issue>)
{
auto const* udata = reinterpret_cast<WasmUserData*>(e);
HostFunctions const* hf = reinterpret_cast<HostFunctions*>(udata->first);
auto* vrt = reinterpret_cast<VirtualRuntime*>(hf->getRT());
HostFunctions const& hf = udata->first;
auto& vrt = *reinterpret_cast<VirtualRuntime*>(hf.getRT());
auto const data = toBytes(std::forward<Arg>(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<int32_t>(ptr));
params[idx++] = wasm_val_t WASM_I32_VAL(static_cast<int32_t>(data.size()));
}
else
{
auto const* udata = reinterpret_cast<WasmUserData*>(e);
HostFunctions const* hf = reinterpret_cast<HostFunctions*>(udata->first);
auto* vrt = reinterpret_cast<VirtualRuntime*>(hf->getRT());
HostFunctions const& hf = udata->first;
auto& vrt = *reinterpret_cast<VirtualRuntime*>(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<int32_t>(ptr));
params[idx++] = wasm_val_t WASM_I32_VAL(static_cast<int32_t>(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>(args)), ...); // NOLINT
return f(std::forward<E>(e), params.get(), result.get()); // NOLINT
(ww_hlp(idx, e, params, std::forward<Args>(args)), ...);
return f(std::forward<E>(e), params.get(), result.get());
}
constexpr int64_t min64 = std::numeric_limits<int64_t>::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<int32_t> 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<int32_t> 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<int32_t> 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<int32_t> 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<uint8_t>) to a keylet
auto compareKeylet = [](std::vector<uint8_t> 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<uint64_t>::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

View File

@@ -1,3 +1,5 @@
#pragma once
#include <test/app/wasm_fixtures/fixtures.h>
#include <test/jtx/Env.h>
#include <test/unit_test/SuiteJournal.h>
@@ -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<std::uint32_t, HostFunctionError>
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<std::uint32_t, HostFunctionError>
@@ -91,7 +66,7 @@ public:
Expected<Hash, HostFunctionError>
getParentLedgerHash() const override
{
return env.current()->header().parentHash;
return env_.current()->header().parentHash;
}
Expected<std::uint32_t, HostFunctionError>
@@ -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<uint8_t const*>(&x);
return Bytes{p, p + sizeof(x)};
}
if (fname == sfSequence)
{
auto const x = getLedgerSqn();
@@ -141,6 +116,7 @@ public:
auto const* e = reinterpret_cast<uint8_t const*>(&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<Bytes, HostFunctionError>
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<uint8_t const*>(&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<Bytes, HostFunctionError>
@@ -190,9 +162,7 @@ public:
int32_t const* l = reinterpret_cast<int32_t const*>(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<int32_t const*>(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<int32_t const*>(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<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) const override
{
return env.current()->header().parentHash;
return env_.current()->header().parentHash;
}
Expected<Bytes, HostFunctionError>
@@ -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<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) const override
{
return Bytes(accountID.begin(), accountID.end());
return Bytes(accountID_.begin(), accountID_.end());
}
Expected<std::uint32_t, HostFunctionError>
@@ -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_;
}
};

View File

@@ -7,7 +7,8 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncWrapper.h> // IWYU pragma: keep
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <boost/algorithm/hex.hpp>
@@ -218,7 +219,7 @@ struct Wasm_test : public beast::unit_test::Suite
HostFunctions hfs;
ImportVec imports;
WasmImpFunc<Add_proto>(imports, "func-add", reinterpret_cast<void*>(&add), &hfs);
WasmImpFunc<Add_proto>(imports, "func-add", reinterpret_cast<void*>(&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<int64_t>() gas
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(
allHFWasm, hfs, std::numeric_limits<int64_t>::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();