started conversion to wasmedge, not finished, not compiling

This commit is contained in:
Richard Holland
2022-01-13 15:40:15 +00:00
parent 912b60bfce
commit 7cefb339e7
5 changed files with 155 additions and 107 deletions

View File

@@ -1,17 +0,0 @@
find_package (libssvm_src QUIET)
if (NOT TARGET libssvm_src)
FetchContent_Declare(
libssvm_src
GIT_REPOSITORY git@github.com:RichardAH/libssvm.git
GIT_TAG 382bd11497439d334b37c585f38cc003d7aef080
)
FetchContent_MakeAvailable(libssvm_src)
# FetchContent_GetProperties(libssvm_src)
#if(NOT libssvm_src_POPULATED)
# FetchContent_Populate(libssvm_src)
# add_subdirectory(${libssvm_src_SOURCE_DIR} ${libssvm_src_BINARY_DIR})
#endif()
#Message("libssvm: srcdir:")
#Message(${libssvm_src_SOURCE_DIR})
target_include_directories (libssvm SYSTEM INTERFACE ${libssvm_src_SOURCE_DIR}/include)
endif()

View File

@@ -12,12 +12,8 @@
#include <memory>
#include <vector>
#include <ripple/protocol/digest.h>
#include "common/value.h"
#include "vm/configure.h"
#include "vm/vm.h"
#include "common/errcode.h"
#include "runtime/hostfunc.h"
#include "runtime/importobj.h"
#include <wasmedge.h>
#include <ripple/app/tx/impl/applyHookMacro.h>
namespace hook {
struct HookContext;
@@ -125,73 +121,6 @@ namespace hook_api {
const int drops_per_byte = 31250; //RH TODO make these votable config option
const double fee_base_multiplier = 1.1f;
// RH TODO: consider replacing macros with templates, if SSVM compatible templates even exist
#define LPAREN (
#define RPAREN )
#define EXPAND(...) __VA_ARGS__
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define SPLIT_1(D) EXPAND(CAT(SPLIT_, D))
#define SPLIT_uint32_t
#define SPLIT_int32_t
#define SPLIT_uint64_t
#define SPLIT_int64_t
#define SPLIT_2(a, b) SPLIT_1(a), SPLIT_1(b)
#define SPLIT_3(a, ...) SPLIT_1(a), SPLIT_2(__VA_ARGS__)
#define SPLIT_4(a, ...) SPLIT_1(a), SPLIT_3(__VA_ARGS__)
#define SPLIT_5(a, ...) SPLIT_1(a), SPLIT_4(__VA_ARGS__)
#define SPLIT_6(a, ...) SPLIT_1(a), SPLIT_5(__VA_ARGS__)
#define SPLIT_7(a, ...) SPLIT_1(a), SPLIT_6(__VA_ARGS__)
#define SPLIT_8(a, ...) SPLIT_1(a), SPLIT_7(__VA_ARGS__)
#define SPLIT_9(a, ...) SPLIT_1(a), SPLIT_8(__VA_ARGS__)
#define SPLIT_10(a, ...) SPLIT_1(a), SPLIT_9(__VA_ARGS__)
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define VA_NARGS(__drop, ...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define STRIP_TYPES(...) DEFER(CAT(SPLIT_,VA_NARGS(NULL, __VA_ARGS__))CAT(LPAREN OBSTRUCT(__VA_ARGS__) RPAREN))
// The above macros allow types to be stripped off a pramater list, used below for proxying call through class
#define DECLARE_HOOK_FUNCTION(R, F, ...)\
R F(hook::HookContext& hookCtx, SSVM::Runtime::Instance::MemoryInstance& memoryCtx, __VA_ARGS__);\
class WasmFunction_##F : public SSVM::Runtime::HostFunction<WasmFunction_##F>\
{\
public:\
hook::HookContext& hookCtx;\
WasmFunction_##F(hook::HookContext& ctx) : hookCtx(ctx) {};\
SSVM::Expect<R> body(SSVM::Runtime::Instance::MemoryInstance* memoryCtx, __VA_ARGS__)\
{\
R return_code = hook_api::F(hookCtx, *memoryCtx, STRIP_TYPES(__VA_ARGS__));\
if (return_code == RC_ROLLBACK || return_code == RC_ACCEPT)\
return SSVM::Unexpect(SSVM::ErrCode::Terminated);\
return return_code;\
}\
};
#define DECLARE_HOOK_FUNCNARG(R, F)\
R F(hook::HookContext& hookCtx, SSVM::Runtime::Instance::MemoryInstance& memoryCtx);\
class WasmFunction_##F : public SSVM::Runtime::HostFunction<WasmFunction_##F>\
{\
public:\
hook::HookContext& hookCtx;\
WasmFunction_##F(hook::HookContext& ctx) : hookCtx(ctx) {};\
SSVM::Expect<R> body(SSVM::Runtime::Instance::MemoryInstance* memoryCtx)\
{\
R return_code = hook_api::F(hookCtx, *memoryCtx);\
if (return_code == RC_ROLLBACK || return_code == RC_ACCEPT)\
return SSVM::Unexpect(SSVM::ErrCode::Terminated);\
return return_code;\
}\
};
#define DEFINE_HOOK_FUNCTION(R, F, ...)\
R hook_api::F(hook::HookContext& hookCtx, SSVM::Runtime::Instance::MemoryInstance& memoryCtx, __VA_ARGS__)
#define DEFINE_HOOK_FUNCNARG(R, F)\
R hook_api::F(hook::HookContext& hookCtx, SSVM::Runtime::Instance::MemoryInstance& memoryCtx)
// RH NOTE: Find descriptions of api functions in ./impl/applyHook.cpp and hookapi.h (include for hooks)
@@ -443,10 +372,26 @@ namespace hook {
// finalize the changes the hook made to the ledger
void commitChangesToLedger( hook::HookResult& hookResult, ripple::ApplyContext&, uint8_t );
#define ADD_HOOK_FUNCTION(F, ctx)\
addHostFunc(#F, std::make_unique<hook_api::WasmFunction_##F>(ctx))
class HookModule : public SSVM::Runtime::ImportObject
// 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");
// RH TODO: call destruct for these on rippled shutdown
#define ADD_HOOK_FUNCTION(F, ctx)\
{\
WasmEdge_FunctionInstanceContext* hf = WasmEdge_FunctionInstanceCreate(\
WasmFunctionType##F, WasmFunction##F, (void*)(&ctx), 0);\
WasmEdge_ImportObjectAddFunction(importObj, WasmFunctionName##F, hf);\
}
class HookModule
{
//RH TODO UPTO put the hook-api functions here!
//then wrap/proxy them with the appropriate DECLARE_HOOK classes
@@ -454,10 +399,11 @@ namespace hook {
public:
HookContext hookCtx;
HookModule(HookContext& ctx) : SSVM::Runtime::ImportObject("env"), hookCtx(ctx)
HookModule(HookContext& ctx) : hookCtx(ctx)
{
ctx.module = this;
WasmEdge_ImportObjectContext* importObj = WasmEdge_ImportObjectCreate(exportName);
ADD_HOOK_FUNCTION(_g, ctx);
ADD_HOOK_FUNCTION(accept, ctx);
ADD_HOOK_FUNCTION(rollback, ctx);
@@ -543,11 +489,10 @@ namespace hook {
ADD_HOOK_FUNCTION(trace_num, ctx);
ADD_HOOK_FUNCTION(trace_float, ctx);
SSVM::AST::Limit TabLimit(10, 20);
addHostTable("table", std::make_unique<SSVM::Runtime::Instance::TableInstance>(
SSVM::ElemType::FuncRef, TabLimit));
SSVM::AST::Limit MemLimit(1, 1);
addHostMemory("memory", std::make_unique<SSVM::Runtime::Instance::MemoryInstance>(MemLimit));
WasmEdge_TableInstanceContext* hostTable = WasmEdge_TableInstanceCreate(tableType);
WasmEdge_ImportObjectAddTable(importObj, tableName, hostTable);
WasmEdge_MemoryInstanceContext* hostMem = WasmEdge_MemoryInstanceCreate(memType);
WasmEdge_ImportObjectAddMemory(importObj, memName, hostMem);
}
virtual ~HookModule() = default;
};

View File

@@ -0,0 +1,125 @@
/**
* RH NOTE:
* This file contains macros for converting the hook api definitions into the currently used wasm runtime.
* Web assembly runtimes are more or less fungible, and at time of writing hooks has moved to WasmEdge from SSVM
* and before that from wasmer.
* After the first move it was decided there should be a relatively static interface for the definition and
* programming of the hook api itself, with the runtime-specific behaviour hidden away by templates or macros.
* Macros are more expressive and can themselves include templates so macros were then used.
*/
#define LPAREN (
#define LPAREN (
#define RPAREN )
#define COMMA ,
#define EXPAND(...) __VA_ARGS__
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define CAT2(L, R) CAT2_(L, R)
#define CAT2_(L, R) L ## R
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define VA_NARGS(__drop, ...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define FIRST(a, b) a
#define SECOND(a, b) b
#define STRIP_TYPES(...) FOR_VARS(SECOND, 0, __VA_ARGS__)
#define DELIM_0 ,
#define DELIM_1
#define DELIM_2 ;
#define DELIM(S) DELIM_##S
#define FOR_VAR_1(T, D) SEP(T, D)
#define FOR_VAR_2(T, S, a, b) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_1(T, b)
#define FOR_VAR_3(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_2(T, S, __VA_ARGS__)
#define FOR_VAR_4(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_3(T, S, __VA_ARGS__)
#define FOR_VAR_5(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_4(T, S, __VA_ARGS__)
#define FOR_VAR_6(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_5(T, S, __VA_ARGS__)
#define FOR_VAR_7(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_6(T, S, __VA_ARGS__)
#define FOR_VAR_8(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_7(T, S, __VA_ARGS__)
#define FOR_VAR_9(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_8(T, S, __VA_ARGS__)
#define FOR_VAR_10(T, S, a, ...) FOR_VAR_1(T, a) DELIM(S) FOR_VAR_9(T, S, __VA_ARGS__)
#define FOR_VARS(T, S, ...)\
DEFER(CAT(FOR_VAR_,VA_NARGS(NULL, __VA_ARGS__))CAT(LPAREN T COMMA S COMMA OBSTRUCT(__VA_ARGS__) RPAREN))
#define SEP(OP, D) EXPAND(OP CAT2(SEP_, D) RPAREN)
#define SEP_uint32_t LPAREN uint32_t COMMA
#define SEP_int32_t LPAREN int32_t COMMA
#define SEP_uint64_t LPAREN uint64_t COMMA
#define SEP_int64_t LPAREN int64_t COMMA
#define VAL_uint32_t WasmEdge_ValueGetI32(in[_stack++])
#define VAL_int32_t WasmEdge_ValueGetI32(in[_stack++])
#define VAL_uint64_t WasmEdge_ValueGetI64(in[_stack++])
#define VAL_int64_t WasmEdge_ValueGetI64(in[_stack++])
#define VAR_ASSIGN(T, V)\
T V = CAT(VAL_ ##T)
#define RET_uint32_t(return_code) WasmEdge_ValueGenI32(return_code)
#define RET_int32_t(return_code) WasmEdge_ValueGenI32(return_code)
#define RET_uint64_t(return_code) WasmEdge_ValueGenI64(return_code)
#define RET_int64_t(return_code) WasmEdge_ValueGenI64(return_code)
#define RET_ASSIGN(T, return_code)\
CAT2(RET_,T(return_code))
#define TYP_uint32_t WasmEdge_ValType_I32
#define TYP_int32_t WasmEdge_ValType_I32
#define TYP_uint64_t WasmEdge_ValType_I64
#define TYP_int64_t WasmEdge_ValType_I64
#define WASM_VAL_TYPE(T, b)\
CAT2(TYP_,T)
#define DECLARE_HOOK_FUNCTION(R, F, ...)\
WasmEdge_Result WasmFunction##F(\
void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\
const WasmEdge_Value *in, WasmEdge_Value *out)\
{\
int _stack = 0;\
FOR_VARS(VAR_ASSIGN, 2, __VA_ARGS__);\
hook::HookContext* hookCtx = reinterpret_cast<hook::HookContext*>(data_ptr);\
R return_code = hook_api::F(*hookCtx, *memCtx, STRIP_TYPES(__VA_ARGS__));\
if (return_code == RC_ROLLBACK || return_code == RC_ACCEPT)\
return WasmEdge_Result_Terminate;\
out[0] = RET_ASSIGN(R, return_code);\
return WasmEdge_Result_Success;\
};\
WasmEdge_FunctionTypeContext* WasmFunctionType##F = NULL;\
{\
enum WasmEdge_ValType r = { WASM_VAL_TYPE(R, dummy) };\
enum WasmEdge_ValType p = { FOR_VARS(WASM_VAL_TYPE, 0, __VA_ARGS__) };\
WasmFunctionType##F = WasmEdge_FunctionTypeCreate(p, VA_NARGS(NULL, __VA_ARGS__), r, 1);\
};\
WasmEdge_String WasmFunctionName##F = WasmEdge_StringCreateByCString(#F);
#define DECLARE_HOOK_FUNCNARG(R, F)\
WasmEdge_Result WasmFunction_##F(\
void *data_ptr, WasmEdge_MemoryInstanceContext *memCtx,\
const WasmEdge_Value *in, WasmEdge_Value *out)\
{\
hook::HookContext* hookCtx = reinterpret_cast<hook::HookContext*>(data_ptr);\
R return_code = hook_api::F(*hookCtx, *memCtx);\
if (return_code == RC_ROLLBACK || return_code == RC_ACCEPT)\
return WasmEdge_Result_Terminate;\
Out[0] = CAT2(RET_,R(return_code));\
return WasmEdge_Result_Success;\
};\
WasmEdge_FunctionTypeContext* WasmFunctionType##F = NULL;\
{\
enum WasmEdge_ValType r = { WASM_VAL_TYPE(R, dummy) };\
enum WasmEdge_ValType p = { };\
WasmFunctionType##F = WasmEdge_FunctionTypeCreate(p, 0, r, 1);\
}\
WasmEdge_String WasmFunctionName##F = WasmEdge_StringCreateByCString(#F);
#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)

View File

@@ -38,12 +38,7 @@
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <functional>
#include "common/value.h"
#include "vm/configure.h"
#include "vm/vm.h"
#include "common/errcode.h"
#include "runtime/hostfunc.h"
#include "runtime/importobj.h"
#include <wasmedge.h>
#define HS_ACC() ctx.tx.getAccountID(sfAccount) << "-" << ctx.tx.getTransactionID()
namespace ripple {

View File

@@ -14,8 +14,8 @@
#include <any>
#include <vector>
#include <utility>
#include "support/span.h"
#include "ripple/protocol/tokens.h"
#include <wasmedge.h>
#include <ripple/protocol/tokens.h>
using namespace ripple;