mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-03 16:56:48 +00:00
Cleanup and some refactoring (#7383)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/ParamsHelper.h>
|
||||
#include <xrpl/tx/wasm/WasmImportsHelper.h>
|
||||
|
||||
#include <wasm.h>
|
||||
|
||||
|
||||
160
include/xrpl/tx/wasm/WasmCommon.h
Normal file
160
include/xrpl/tx/wasm/WasmCommon.h
Normal 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
|
||||
@@ -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
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/HostFunc.h>
|
||||
#include <xrpl/tx/wasm/WasmImportsHelper.h>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user