compiling, untested

This commit is contained in:
Richard Holland
2022-01-17 12:45:26 +00:00
parent 6a3a6e68bf
commit 943b4acfee
7 changed files with 138 additions and 101 deletions

View File

@@ -983,8 +983,6 @@ target_link_libraries (rippled
Ripple::opts Ripple::opts
Ripple::libs Ripple::libs
Ripple::xrpl_core Ripple::xrpl_core
libssvm
# /usr/lib/libwasmer.a
) )
exclude_if_included (rippled) exclude_if_included (rippled)
# define a macro for tests that might need to # define a macro for tests that might need to

View File

@@ -11,7 +11,7 @@ if (is_root_project) # WasmEdge not needed in the case of xrpl_core inclusion bu
ExternalProject_Add (wasmedge_src ExternalProject_Add (wasmedge_src
PREFIX ${nih_cache_path} PREFIX ${nih_cache_path}
GIT_REPOSITORY https://github.com/WasmEdge/WasmEdge.git GIT_REPOSITORY https://github.com/WasmEdge/WasmEdge.git
GIT_TAG 0.8.2 GIT_TAG 0.9.0
CMAKE_ARGS CMAKE_ARGS
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}

View File

@@ -52,7 +52,6 @@ include(RippledInterface)
### ###
include(deps/libssvm)
include(deps/Boost) include(deps/Boost)
include(deps/OpenSSL) include(deps/OpenSSL)
include(deps/Secp256k1) include(deps/Secp256k1)

View File

@@ -1,5 +1,5 @@
#ifndef APPLY_HOOK_INCLUDED #ifndef APPLY_HOOK_INCLUDED
#define APPLY_HOOK_INCLUDED #define APPLY_HOOK_INCLUDED 1
#include <ripple/basics/Blob.h> #include <ripple/basics/Blob.h>
#include <ripple/protocol/TER.h> #include <ripple/protocol/TER.h>
#include <ripple/app/tx/impl/ApplyContext.h> #include <ripple/app/tx/impl/ApplyContext.h>
@@ -12,16 +12,19 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <ripple/protocol/digest.h> #include <ripple/protocol/digest.h>
#include <wasmedge.h> #include <wasmedge/wasmedge.h>
#include <ripple/app/tx/applyHookMacro.h> #include <ripple/app/tx/applyHookMacro.h>
namespace hook {
namespace hook
{
struct HookContext; struct HookContext;
struct HookResult; struct HookResult;
bool isEmittedTxn(ripple::STTx const& tx); bool isEmittedTxn(ripple::STTx const& tx);
} }
namespace hook_api { namespace hook_api
{
#define TER_TO_HOOK_RETURN_CODE(x)\ #define TER_TO_HOOK_RETURN_CODE(x)\
(((TERtoInt(x)) << 16)*-1) (((TERtoInt(x)) << 16)*-1)
@@ -31,42 +34,46 @@ namespace hook_api {
#define DBG_PRINTF if (0) printf #define DBG_PRINTF if (0) printf
#define DBG_FPRINTF if (0) fprintf #define DBG_FPRINTF if (0) fprintf
namespace keylet_code { namespace keylet_code
enum keylet_code : uint32_t { {
HOOK = 1, enum keylet_code : uint32_t
HOOK_STATE = 2, {
ACCOUNT = 3, HOOK = 1,
AMENDMENTS = 4, HOOK_STATE = 2,
CHILD = 5, ACCOUNT = 3,
SKIP = 6, AMENDMENTS = 4,
FEES = 7, CHILD = 5,
NEGATIVE_UNL = 8, SKIP = 6,
LINE = 9, FEES = 7,
OFFER = 10, NEGATIVE_UNL = 8,
QUALITY = 11, LINE = 9,
EMITTED_DIR = 12, OFFER = 10,
TICKET = 13, QUALITY = 11,
SIGNERS = 14, EMITTED_DIR = 12,
CHECK = 15, TICKET = 13,
DEPOSIT_PREAUTH = 16, SIGNERS = 14,
UNCHECKED = 17, CHECK = 15,
OWNER_DIR = 18, DEPOSIT_PREAUTH = 16,
PAGE = 19, UNCHECKED = 17,
ESCROW = 20, OWNER_DIR = 18,
PAYCHAN = 21, PAGE = 19,
EMITTED = 22 ESCROW = 20,
}; PAYCHAN = 21,
EMITTED = 22
};
} }
namespace compare_mode { namespace compare_mode {
enum compare_mode : uint32_t { enum compare_mode : uint32_t
EQUAL = 1, {
LESS = 2, EQUAL = 1,
GREATER = 4 LESS = 2,
}; GREATER = 4
};
} }
enum hook_return_code : int64_t { enum hook_return_code : int64_t
{
SUCCESS = 0, // return codes > 0 are reserved for hook apis to return "success" SUCCESS = 0, // return codes > 0 are reserved for hook apis to return "success"
OUT_OF_BOUNDS = -1, // could not read or write to a pointer to provided by hook OUT_OF_BOUNDS = -1, // could not read or write to a pointer to provided by hook
INTERNAL_ERROR = -2, // eg directory is corrupt INTERNAL_ERROR = -2, // eg directory is corrupt
@@ -106,7 +113,8 @@ namespace hook_api {
TOO_MANY_PARAMS = -36 TOO_MANY_PARAMS = -36
}; };
enum ExitType : uint8_t { enum ExitType : uint8_t
{
UNSET = 0, UNSET = 0,
WASM_ERROR = 1, WASM_ERROR = 1,
ROLLBACK = 2, ROLLBACK = 2,
@@ -241,13 +249,15 @@ namespace hook_api {
} /* end namespace hook_api */ } /* end namespace hook_api */
namespace hook { namespace hook
{
bool canHook(ripple::TxType txType, uint64_t hookOn); bool canHook(ripple::TxType txType, uint64_t hookOn);
struct HookResult; struct HookResult;
hook::apply( HookResult
apply(
ripple::uint256 const& hookSetTxnID, /* this is the txid of the sethook, used for caching (one day) */ ripple::uint256 const& hookSetTxnID, /* this is the txid of the sethook, used for caching (one day) */
ripple::uint256 const& hookHash, /* hash of the actual hook byte code, used for metadata */ ripple::uint256 const& hookHash, /* hash of the actual hook byte code, used for metadata */
ripple::uint256 const& hookNamespace, ripple::uint256 const& hookNamespace,
@@ -266,7 +276,8 @@ namespace hook {
ripple::AccountID const& account, /* the account the hook is INSTALLED ON not always the otxn account */ ripple::AccountID const& account, /* the account the hook is INSTALLED ON not always the otxn account */
bool callback = false, bool callback = false,
uint32_t wasmParam = 0, uint32_t wasmParam = 0,
int32_t hookChainPosition = -1); int32_t hookChainPosition = -1
);
struct HookContext; struct HookContext;
@@ -321,7 +332,7 @@ namespace hook {
bool foreignStateSetDisabled = false; bool foreignStateSetDisabled = false;
}; };
class HookModule; class HookExecutor;
struct SlotEntry struct SlotEntry
{ {
@@ -350,7 +361,7 @@ namespace hook {
std::optional<ripple::STObject> emitFailure; // if this is a callback from a failed std::optional<ripple::STObject> emitFailure; // if this is a callback from a failed
// emitted txn then this optional becomes // emitted txn then this optional becomes
// populated with the SLE // populated with the SLE
const HookModule* module = 0; const HookExecutor* module = 0;
}; };
@@ -373,30 +384,29 @@ namespace hook {
void commitChangesToLedger( hook::HookResult& hookResult, ripple::ApplyContext&, uint8_t ); void commitChangesToLedger( hook::HookResult& hookResult, ripple::ApplyContext&, uint8_t );
// create these once at boot and keep them
WasmEdge_String exportName = WasmEdge_StringCreateByCString("env");
WasmEdge_String tableName = WasmEdge_StringCreateByCString("table");
WasmEdge_TableTypeContext* tableType =
WasmEdge_TableTypeCreate(WasmEdge_RefType_FuncRef, {.HasMax = true, .Min = 10, .Max = 20});
WasmEdge_MemoryTypeContext* memType =
WasmEdge_MemoryTypeCreate({.HasMax = true, .Min = 1, .Max = 1});
WasmEdge_String memName = WasmEdge_StringCreateByCString("memory");
WasmEdge_String cbakFunctionName = WasmEdge_StringCreateByCString("cbak");
WasmEdge_String hookFunctionName = WasmEdge_StringCreateByCString("hook");
// RH TODO: call destruct for these on rippled shutdown // RH TODO: call destruct for these on rippled shutdown
#define ADD_HOOK_FUNCTION(F, ctx)\ #define ADD_HOOK_FUNCTION(F, ctx)\
{\ {\
WasmEdge_FunctionInstanceContext* hf = WasmEdge_FunctionInstanceCreate(\ WasmEdge_FunctionInstanceContext* hf = WasmEdge_FunctionInstanceCreate(\
WasmFunctionType##F, WasmFunction##F, (void*)(&ctx), 0);\ hook_api::WasmFunctionType##F,\
WasmEdge_ImportObjectAddFunction(importObj, WasmFunctionName##F, hf);\ hook_api::WasmFunction##F,\
(void*)(&ctx), 0);\
WasmEdge_ImportObjectAddFunction(importObj, hook_api::WasmFunctionName##F, hf);\
} }
#define HR_ACC() hookResult.account << "-" << hookResult.otxnAccount #define HR_ACC() hookResult.account << "-" << hookResult.otxnAccount
#define HC_ACC() hookCtx.result.account << "-" << hookCtx.result.otxnAccount #define HC_ACC() hookCtx.result.account << "-" << hookCtx.result.otxnAccount
// create these once at boot and keep them
static WasmEdge_String exportName = WasmEdge_StringCreateByCString("env");
static WasmEdge_String tableName = WasmEdge_StringCreateByCString("table");
static auto* tableType =
WasmEdge_TableTypeCreate(WasmEdge_RefType_FuncRef, {.HasMax = true, .Min = 10, .Max = 20});
static auto* memType = WasmEdge_MemoryTypeCreate({.HasMax = true, .Min = 1, .Max = 1});
static WasmEdge_String memName = WasmEdge_StringCreateByCString("memory");
static WasmEdge_String cbakFunctionName = WasmEdge_StringCreateByCString("cbak");
static WasmEdge_String hookFunctionName = WasmEdge_StringCreateByCString("hook");
/** /**
* HookExecutor is effectively a two-part function: * HookExecutor is effectively a two-part function:
@@ -412,17 +422,39 @@ namespace hook {
private: private:
bool spent = false; // a HookExecutor can only be used once bool spent = false; // a HookExecutor can only be used once
public: public:
HookContext hookCtx; HookContext hookCtx;
WasmEdge_ImportObjectContext* importObj; WasmEdge_ImportObjectContext* importObj;
/**
* Validate that a web assembly blob can be loaded by wasmedge
*/
static std::optional<std::string> validateWasm(const void* wasm, size_t len)
{
std::optional<std::string> ret;
WasmEdge_ConfigureContext* confCtx = WasmEdge_ConfigureCreate();
WasmEdge_VMContext* vmCtx = WasmEdge_VMCreate(confCtx, NULL);
WasmEdge_Result res = WasmEdge_VMLoadWasmFromBuffer(vmCtx, reinterpret_cast<const uint8_t*>(wasm), len);
if (!WasmEdge_ResultOK(res))
*ret = std::string {WasmEdge_ResultGetMessage(res)};
else
{
res = WasmEdge_VMValidate(vmCtx);
if (!WasmEdge_ResultOK(res))
*ret = std::string {WasmEdge_ResultGetMessage(res)};
}
WasmEdge_VMDelete(vmCtx);
WasmEdge_ConfigureDelete(confCtx);
return ret;
}
/** /**
* Execute web assembly byte code against the constructed Hook Context * Execute web assembly byte code against the constructed Hook Context
* Once execution has occured the exector is spent and cannot be used again and should be destructed * Once execution has occured the exector is spent and cannot be used again and should be destructed
* Information about the execution is populated into hookCtx * Information about the execution is populated into hookCtx
*/ */
void executeWasm(void* wasm, size_t len, bool callback, WasmEdge_Value wasmParam, beast::Journal const& j) void executeWasm(const void* wasm, size_t len, bool callback, uint64_t wasmParam, beast::Journal const& j)
{ {
// HookExecutor can only execute once // HookExecutor can only execute once
@@ -435,8 +467,7 @@ namespace hook {
WasmEdge_ConfigureContext* confCtx = WasmEdge_ConfigureCreate(); WasmEdge_ConfigureContext* confCtx = WasmEdge_ConfigureCreate();
WasmEdge_ConfigureStatisticsSetInstructionCounting(confCtx, true); WasmEdge_ConfigureStatisticsSetInstructionCounting(confCtx, true);
WasmEdge_VMContext vmCtx = WasmEdge_VMCreate(confCtx, NULL); WasmEdge_VMContext* vmCtx = WasmEdge_VMCreate(confCtx, NULL);
WasmEdge_Result res = WasmEdge_VMRegisterModuleFromImport(vmCtx, this->importObj); WasmEdge_Result res = WasmEdge_VMRegisterModuleFromImport(vmCtx, this->importObj);
if (!WasmEdge_ResultOK(res)) if (!WasmEdge_ResultOK(res))
@@ -449,11 +480,11 @@ namespace hook {
else else
{ {
WasmEdge_Value params[1] = {wasmParam}; WasmEdge_Value params[1] = { WasmEdge_ValueGenI64((int64_t)wasmParam) };
WasmEdge_Value results[1]; WasmEdge_Value returns[1];
res = res =
WasmEdge_VMRunWasmFromBuffer(vmCtx, wasm, len, WasmEdge_VMRunWasmFromBuffer(vmCtx, reinterpret_cast<const uint8_t*>(wasm), len,
callback ? cbakFunctionName : hookFunctionName, callback ? cbakFunctionName : hookFunctionName,
params, 1, returns, 1); params, 1, returns, 1);
@@ -484,7 +515,7 @@ namespace hook {
WasmEdge_VMDelete(vmCtx); WasmEdge_VMDelete(vmCtx);
} }
HookModule(HookContext& ctx) HookExecutor(HookContext& ctx)
: hookCtx(ctx) : hookCtx(ctx)
, importObj(WasmEdge_ImportObjectCreate(exportName)) , importObj(WasmEdge_ImportObjectCreate(exportName))
{ {
@@ -579,7 +610,7 @@ namespace hook {
WasmEdge_ImportObjectAddMemory(importObj, memName, hostMem); WasmEdge_ImportObjectAddMemory(importObj, memName, hostMem);
} }
~HookModule() ~HookExecutor()
{ {
WasmEdge_ImportObjectDelete(importObj); WasmEdge_ImportObjectDelete(importObj);
}; };

View File

@@ -76,7 +76,26 @@
#define DECLARE_HOOK_FUNCTION(R, F, ...)\ #define DECLARE_HOOK_FUNCTION(R, F, ...)\
R F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx, __VA_ARGS__);\ R F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx, __VA_ARGS__);\
WasmEdge_Result WasmFunction##F(\ extern WasmEdge_Result WasmFunction##F(\
void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\
const WasmEdge_Value *in, WasmEdge_Value *out);\
extern WasmEdge_ValType WasmFunctionParams##F[];\
extern WasmEdge_ValType WasmFunctionResult##F[];\
extern WasmEdge_FunctionTypeContext* WasmFunctionType##F;\
extern WasmEdge_String WasmFunctionName##F;
#define DECLARE_HOOK_FUNCNARG(R, F)\
R F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx);\
extern WasmEdge_Result WasmFunction##F(\
void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\
const WasmEdge_Value *in, WasmEdge_Value *out);\
extern WasmEdge_ValType WasmFunctionResult##F[];\
extern WasmEdge_FunctionTypeContext* WasmFunctionType##F;\
extern WasmEdge_String WasmFunctionName##F;
#define DEFINE_HOOK_FUNCTION(R, F, ...)\
WasmEdge_Result hook_api::WasmFunction##F(\
void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\ void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\
const WasmEdge_Value *in, WasmEdge_Value *out)\ const WasmEdge_Value *in, WasmEdge_Value *out)\
{\ {\
@@ -89,17 +108,16 @@
out[0] = RET_ASSIGN(R, return_code);\ out[0] = RET_ASSIGN(R, return_code);\
return WasmEdge_Result_Success;\ return WasmEdge_Result_Success;\
};\ };\
WasmEdge_ValType WasmFunctionParams##F[] = { FOR_VARS(WASM_VAL_TYPE, 0, __VA_ARGS__) };\ WasmEdge_ValType hook_api::WasmFunctionParams##F[] = { FOR_VARS(WASM_VAL_TYPE, 0, __VA_ARGS__) };\
WasmEdge_ValType WasmFunctionResult##F[1] = { WASM_VAL_TYPE(R, dummy) };\ WasmEdge_ValType hook_api::WasmFunctionResult##F[1] = { WASM_VAL_TYPE(R, dummy) };\
WasmEdge_FunctionTypeContext* WasmFunctionType##F = WasmEdge_FunctionTypeCreate(\ WasmEdge_FunctionTypeContext* hook_api::WasmFunctionType##F = WasmEdge_FunctionTypeCreate(\
WasmFunctionParams##F, VA_NARGS(NULL, __VA_ARGS__),\ WasmFunctionParams##F, VA_NARGS(NULL, __VA_ARGS__),\
WasmFunctionResult##F, 1);\ WasmFunctionResult##F, 1);\
WasmEdge_String WasmFunctionName##F = WasmEdge_StringCreateByCString(#F); WasmEdge_String hook_api::WasmFunctionName##F = WasmEdge_StringCreateByCString(#F);\
R hook_api::F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx, __VA_ARGS__)
#define DEFINE_HOOK_FUNCNARG(R, F)\
#define DECLARE_HOOK_FUNCNARG(R, F)\ WasmEdge_Result hook_api::WasmFunction##F(\
R F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx);\
WasmEdge_Result WasmFunction_##F(\
void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\ void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\
const WasmEdge_Value *in, WasmEdge_Value *out)\ const WasmEdge_Value *in, WasmEdge_Value *out)\
{\ {\
@@ -110,17 +128,11 @@
out[0] = CAT2(RET_,R(return_code));\ out[0] = CAT2(RET_,R(return_code));\
return WasmEdge_Result_Success;\ return WasmEdge_Result_Success;\
};\ };\
WasmEdge_ValType WasmFunctionResult##F[1] = { WASM_VAL_TYPE(R, dummy) };\ WasmEdge_ValType hook_api::WasmFunctionResult##F[1] = { WASM_VAL_TYPE(R, dummy) };\
WasmEdge_FunctionTypeContext* WasmFunctionType##F = \ WasmEdge_FunctionTypeContext* hook_api::WasmFunctionType##F = \
WasmEdge_FunctionTypeCreate({}, 0, WasmFunctionResult##F, 1);\ WasmEdge_FunctionTypeCreate({}, 0, WasmFunctionResult##F, 1);\
WasmEdge_String WasmFunctionName##F = WasmEdge_StringCreateByCString(#F); WasmEdge_String hook_api::WasmFunctionName##F = WasmEdge_StringCreateByCString(#F);\
R hook_api::F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx)
#define DEFINE_HOOK_FUNCTION(R, F, ...)\
R hook_api::F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx, __VA_ARGS__)
#define DEFINE_HOOK_FUNCNARG(R, F)\
R hook_api::F(hook::HookContext& hookCtx, WasmEdge_MemoryInstanceContext& memoryCtx)
@@ -132,8 +144,8 @@
[[maybe_unused]] ApplyContext& applyCtx = hookCtx.applyCtx;\ [[maybe_unused]] ApplyContext& applyCtx = hookCtx.applyCtx;\
[[maybe_unused]] auto& view = applyCtx.view();\ [[maybe_unused]] auto& view = applyCtx.view();\
[[maybe_unused]] auto j = applyCtx.app.journal("View");\ [[maybe_unused]] auto j = applyCtx.app.journal("View");\
[[maybe_unused]] unsigned char* memory = WasmEdge_MemoryInstanceGetPointer(memoryCtx, 0, 0);\ [[maybe_unused]] unsigned char* memory = WasmEdge_MemoryInstanceGetPointer(&memoryCtx, 0, 0);\
[[maybe_unused]] const uint64_t memory_length = WasmEdge_MemoryInstanceGetPageSize(memoryCtx); [[maybe_unused]] const uint64_t memory_length = WasmEdge_MemoryInstanceGetPageSize(&memoryCtx);
#define WRITE_WASM_MEMORY(bytes_written, guest_dst_ptr, guest_dst_len,\ #define WRITE_WASM_MEMORY(bytes_written, guest_dst_ptr, guest_dst_len,\
host_src_ptr, host_src_len, host_memory_ptr, guest_memory_length)\ host_src_ptr, host_src_len, host_memory_ptr, guest_memory_length)\
@@ -147,7 +159,8 @@
<< " bytes past end of wasm memory";\ << " bytes past end of wasm memory";\
return OUT_OF_BOUNDS;\ return OUT_OF_BOUNDS;\
}\ }\
WasmEdge_MemoryInstanceGetPointer(memoryCtx, host_src_ptr, guest_dst_ptr, bytes_to_write);\ WasmEdge_MemoryInstanceSetData(&memoryCtx, \
reinterpret_cast<const uint8_t*>(host_src_ptr), guest_dst_ptr, bytes_to_write);\
bytes_written += bytes_to_write;\ bytes_written += bytes_to_write;\
} }

View File

@@ -38,7 +38,7 @@
#include <ripple/app/ledger/LedgerMaster.h> #include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/OpenLedger.h> #include <ripple/app/ledger/OpenLedger.h>
#include <functional> #include <functional>
#include <wasmedge.h> #include <wasmedge/wasmedge.h>
#define HS_ACC() ctx.tx.getAccountID(sfAccount) << "-" << ctx.tx.getTransactionID() #define HS_ACC() ctx.tx.getAccountID(sfAccount) << "-" << ctx.tx.getTransactionID()
namespace ripple { namespace ripple {
@@ -990,18 +990,14 @@ validateHookSetEntry(SetHookCtx& ctx, STObject const& hookSetObj)
<< "HookSet[" << HS_ACC() << "]: Trying to wasm instantiate proposed hook " << "HookSet[" << HS_ACC() << "]: Trying to wasm instantiate proposed hook "
<< "size = " << hook.size(); << "size = " << hook.size();
// check if wasm can be run std::optional<std::string> result =
SSVM::VM::Configure cfg; hook::HookExecutor::validateWasm(hook.data(), (size_t)hook.size());
SSVM::VM::VM vm(cfg);
if (auto res = vm.loadWasm(SSVM::Span<const uint8_t>(hook.data(), hook.size()))) if (result)
{ {
// do nothing
} else
{
uint32_t ssvm_error = static_cast<uint32_t>(res.error());
JLOG(ctx.j.trace()) JLOG(ctx.j.trace())
<< "HookSet[" << HS_ACC() << "]: " << "HookSet[" << HS_ACC() << "]: "
<< "Tried to set a hook with invalid code. SSVM error: " << ssvm_error; << "Tried to set a hook with invalid code. VM error: " << *result;
return {false, 0}; return {false, 0};
} }

View File

@@ -14,7 +14,7 @@
#include <any> #include <any>
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <wasmedge.h> #include <wasmedge/wasmedge.h>
#include <ripple/protocol/tokens.h> #include <ripple/protocol/tokens.h>
using namespace ripple; using namespace ripple;
@@ -499,7 +499,7 @@ hook::apply(
HookExecutor executor { hookCtx } ; HookExecutor executor { hookCtx } ;
executor.executeWasm(wasm.data(), wasm.dize(), callback, wasmParam); executor.executeWasm(wasm.data(), (size_t)wasm.size(), callback, wasmParam, j);
JLOG(j.trace()) << JLOG(j.trace()) <<
"HookInfo[" << HC_ACC() << "]: " << "HookInfo[" << HC_ACC() << "]: " <<