diff --git a/.github/workflows/verify-generated-headers.yml b/.github/workflows/verify-generated-headers.yml index 4120f7b7f9..723e7181b9 100644 --- a/.github/workflows/verify-generated-headers.yml +++ b/.github/workflows/verify-generated-headers.yml @@ -18,12 +18,23 @@ jobs: generator: bash ./hook/generate_sfcodes.sh - target: hook/tts.h generator: ./hook/generate_tts.sh - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 + env: + CLANG_VERSION: 10 name: ${{ matrix.target }} steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Download and install clang-format + run: | + sudo apt-get update -y + sudo apt-get install -y libtinfo5 + curl -LO https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz + tar -xf clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz + sudo mv clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04 /opt/clang-10 + sudo ln -s /opt/clang-10/bin/clang-format /usr/local/bin/clang-format-10 + - name: Verify ${{ matrix.target }} run: | set -euo pipefail diff --git a/hook/extern.h b/hook/extern.h index ee34af6ff8..667cec2a4c 100644 --- a/hook/extern.h +++ b/hook/extern.h @@ -82,7 +82,7 @@ sto_erase( uint32_t field_id); extern int64_t -etxn_burden(void); +etxn_burden(); extern int64_t etxn_details(uint32_t write_ptr, uint32_t write_len); @@ -94,7 +94,7 @@ extern int64_t etxn_reserve(uint32_t count); extern int64_t -etxn_generation(void); +etxn_generation(); extern int64_t etxn_nonce(uint32_t write_ptr, uint32_t write_len); @@ -149,7 +149,7 @@ extern int64_t float_divide(int64_t float1, int64_t float2); extern int64_t -float_one(void); +float_one(); extern int64_t float_mantissa(int64_t float1); @@ -167,13 +167,13 @@ extern int64_t float_root(int64_t float1, uint32_t n); extern int64_t -fee_base(void); +fee_base(); extern int64_t -ledger_seq(void); +ledger_seq(); extern int64_t -ledger_last_time(void); +ledger_last_time(); extern int64_t ledger_last_hash(uint32_t write_ptr, uint32_t write_len); @@ -213,13 +213,13 @@ hook_param( uint32_t read_len); extern int64_t -hook_again(void); +hook_again(); extern int64_t hook_skip(uint32_t read_ptr, uint32_t read_len, uint32_t flags); extern int64_t -hook_pos(void); +hook_pos(); extern int64_t slot(uint32_t write_ptr, uint32_t write_len, uint32_t slot); @@ -299,19 +299,19 @@ extern int64_t trace_float(uint32_t read_ptr, uint32_t read_len, int64_t float1); extern int64_t -otxn_burden(void); +otxn_burden(); extern int64_t otxn_field(uint32_t write_ptr, uint32_t write_len, uint32_t field_id); extern int64_t -otxn_generation(void); +otxn_generation(); extern int64_t otxn_id(uint32_t write_ptr, uint32_t write_len, uint32_t flags); extern int64_t -otxn_type(void); +otxn_type(); extern int64_t otxn_slot(uint32_t slot_no); diff --git a/hook/generate_extern.sh b/hook/generate_extern.sh index 2e9598ad02..0f05dac523 100755 --- a/hook/generate_extern.sh +++ b/hook/generate_extern.sh @@ -4,7 +4,7 @@ set -eu SCRIPT_DIR=$(dirname "$0") SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd) -APPLY_HOOK="$SCRIPT_DIR/../src/ripple/app/hook/applyHook.h" +APPLY_HOOK="$SCRIPT_DIR/../src/ripple/app/hook/hook_api.macro" { echo '// For documentation please see: https://xrpl-hooks.readme.io/reference/' @@ -19,127 +19,36 @@ APPLY_HOOK="$SCRIPT_DIR/../src/ripple/app/hook/applyHook.h" return s; } - function emit(ret, name, argc, argt, argn) { - attr = (name == "_g") ? " __attribute__((noduplicate))" : ""; - if (!first) - printf("\n"); - first = 0; - printf("extern %s%s\n", ret, attr); - if (argc == 0) { - printf("%s(void);\n", name); - return; - } - if (argc <= 3) { - line = argt[1] " " argn[1]; - for (i = 2; i <= argc; ++i) - line = line ", " argt[i] " " argn[i]; - printf("%s(%s);\n", name, line); - return; - } - printf("%s(\n", name); - for (i = 1; i <= argc; ++i) { - sep = (i < argc) ? "," : ");"; - printf(" %s %s%s\n", argt[i], argn[i], sep); - } - } - - function process(buffer, kind, payload, parts, n, i, arg, tokens, argc, argt, argn) { - if (kind == "func") - sub(/^DECLARE_HOOK_FUNCTION[[:space:]]*\(/, "", buffer); - else - sub(/^DECLARE_HOOK_FUNCNARG[[:space:]]*\(/, "", buffer); - buffer = trim(buffer); - sub(/\)[[:space:]]*$/, "", buffer); - n = split(buffer, parts, ","); - for (i = 1; i <= n; ++i) - parts[i] = trim(parts[i]); - ret = parts[1]; - name = parts[2]; - argc = 0; - delete argt; - delete argn; - for (i = 3; i <= n; ++i) { - arg = parts[i]; - if (arg == "") - continue; - split(arg, tokens, /[[:space:]]+/); - if (length(tokens) < 2) - continue; - ++argc; - argt[argc] = tokens[1]; - argn[argc] = tokens[2]; - } - emit(ret, name, argc, argt, argn); - } - - BEGIN { - first = 1; - in_block = 0; - in_macro = 0; - } - { line = $0; - if (in_block) { - if (line ~ /\*\//) { - sub(/.*\*\//, "", line); - in_block = 0; - } - else - next; - } - while (line ~ /\/\*/) { - if (line ~ /\/\*.*\*\//) { - gsub(/\/\*.*\*\//, "", line); - } - else { - sub(/\/\*.*/, "", line); - in_block = 1; - break; - } - } - sub(/\/\/.*$/, "", line); - line = trim(line); - if (line == "") - next; - - if (!in_macro && line ~ /^DECLARE_HOOK_FUNCTION\(/) { - buffer = line; - kind = "func"; - if (line ~ /\);[[:space:]]*$/) { - sub(/\);[[:space:]]*$/, "", buffer); - process(buffer, kind); - } - else - in_macro = 1; + + # Skip block comments + if (line ~ /\/\*/) { next; } - if (!in_macro && line ~ /^DECLARE_HOOK_FUNCNARG\(/) { - buffer = line; - kind = "narg"; - if (line ~ /\);[[:space:]]*$/) { - sub(/\);[[:space:]]*$/, "", buffer); - process(buffer, kind); - } - else - in_macro = 1; - next; - } - if (in_macro) { - buffer = buffer " " line; - if (line ~ /\);[[:space:]]*$/) { - sub(/\);[[:space:]]*$/, "", buffer); - process(buffer, kind); - in_macro = 0; + + # Look for comment lines that start with // and contain function signature + if (line ~ /^[[:space:]]*\/\/[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]+[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*\(/) { + # Remove leading // and trim + sub(/^[[:space:]]*\/\/[[:space:]]*/, "", line); + line = trim(line); + + # Check if function name is "_g" to add attribute + if (line ~ /[[:space:]]+_g[[:space:]]*\(/) { + # Insert __attribute__((noduplicate)) before _g + sub(/[[:space:]]+_g/, " __attribute__((noduplicate)) _g", line); } + + # printf("\n"); + + printf("extern %s\n\n", line); } } - - END { - printf("\n"); - } ' "$APPLY_HOOK" echo '#define HOOK_EXTERN' echo '#endif // HOOK_EXTERN' -} +} | ( + cd "$SCRIPT_DIR/.." + clang-format --style=file - +) diff --git a/src/ripple/app/hook/Enum.h b/src/ripple/app/hook/Enum.h index 9728b10401..7c726f926a 100644 --- a/src/ripple/app/hook/Enum.h +++ b/src/ripple/app/hook/Enum.h @@ -1,3 +1,8 @@ +#ifndef GUARD_CHECKER_BUILD +#include +#include +#include +#endif #include #include #include @@ -241,8 +246,10 @@ enum hook_log_code : uint16_t { SECTIONS_OUT_OF_SEQUENCE = 85, // the wasm contained sections out of sequence CUSTOM_SECTION_DISALLOWED = - 86, // the wasm contained a custom section (id=0) - INTERNAL_ERROR = 87, // an internal error described by the log text + 86, // the wasm contained a custom section (id=0) + INTERNAL_ERROR = 87, // an internal error described by the log text + MEMORY_MISSING = 88, // hook did not establish any memory section + MEMORY_MAX_PAGES = 89, // hook memory section maximum pages is not allowed // RH NOTE: only HookSet msgs got log codes, possibly all Hook log lines // should get a code? }; @@ -367,110 +374,82 @@ const uint8_t max_emit = 255; const uint8_t max_params = 16; const double fee_base_multiplier = 1.1f; -#define I32 0x7FU -#define I64 0x7EU - -#define HOOK_WRAP_PARAMS(...) __VA_ARGS__ -#define HOOK_API_DEFINITION(RETURN_TYPE, FUNCTION_NAME, PARAMS_TUPLE) \ - { \ -#FUNCTION_NAME, \ - { \ - RETURN_TYPE, HOOK_WRAP_PARAMS PARAMS_TUPLE \ - } \ - } - using APIWhitelist = std::map>; // RH NOTE: Find descriptions of api functions in ./impl/applyHook.cpp and // hookapi.h (include for hooks) this is a map of the api name to its return // code (vec[0] and its parameters vec[>0]) as wasm type codes -static const APIWhitelist import_whitelist{ - // clang-format off - HOOK_API_DEFINITION(I32, _g, (I32, I32)), - HOOK_API_DEFINITION(I64, accept, (I32, I32, I64)), - HOOK_API_DEFINITION(I64, rollback, (I32, I32, I64)), - HOOK_API_DEFINITION(I64, util_raddr, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, util_accid, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, util_verify, (I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, util_sha512h, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, util_keylet, (I32, I32, I32, I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, sto_validate, (I32, I32)), - HOOK_API_DEFINITION(I64, sto_subfield, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, sto_subarray, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, sto_emplace, (I32, I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, sto_erase, (I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, etxn_burden, ()), - HOOK_API_DEFINITION(I64, etxn_details, (I32, I32)), - HOOK_API_DEFINITION(I64, etxn_fee_base, (I32, I32)), - HOOK_API_DEFINITION(I64, etxn_reserve, (I32)), - HOOK_API_DEFINITION(I64, etxn_generation, ()), - HOOK_API_DEFINITION(I64, etxn_nonce, (I32, I32)), - HOOK_API_DEFINITION(I64, emit, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, float_set, (I32, I64)), - HOOK_API_DEFINITION(I64, float_multiply, (I64, I64)), - HOOK_API_DEFINITION(I64, float_mulratio, (I64, I32, I32, I32)), - HOOK_API_DEFINITION(I64, float_negate, (I64)), - HOOK_API_DEFINITION(I64, float_compare, (I64, I64, I32)), - HOOK_API_DEFINITION(I64, float_sum, (I64, I64)), - HOOK_API_DEFINITION(I64, float_sto, (I32, I32, I32, I32, I32, I32, I64, I32)), - HOOK_API_DEFINITION(I64, float_sto_set, (I32, I32)), - HOOK_API_DEFINITION(I64, float_invert, (I64)), - HOOK_API_DEFINITION(I64, float_divide, (I64, I64)), - HOOK_API_DEFINITION(I64, float_one, ()), - HOOK_API_DEFINITION(I64, float_mantissa, (I64)), - HOOK_API_DEFINITION(I64, float_sign, (I64)), - HOOK_API_DEFINITION(I64, float_int, (I64, I32, I32)), - HOOK_API_DEFINITION(I64, float_log, (I64)), - HOOK_API_DEFINITION(I64, float_root, (I64, I32)), - HOOK_API_DEFINITION(I64, fee_base, ()), - HOOK_API_DEFINITION(I64, ledger_seq, ()), - HOOK_API_DEFINITION(I64, ledger_last_time, ()), - HOOK_API_DEFINITION(I64, ledger_last_hash, (I32, I32)), - HOOK_API_DEFINITION(I64, ledger_nonce, (I32, I32)), - HOOK_API_DEFINITION(I64, ledger_keylet, (I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, hook_account, (I32, I32)), - HOOK_API_DEFINITION(I64, hook_hash, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, hook_param_set, (I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, hook_param, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, hook_again, ()), - HOOK_API_DEFINITION(I64, hook_skip, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, hook_pos, ()), - HOOK_API_DEFINITION(I64, slot, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, slot_clear, (I32)), - HOOK_API_DEFINITION(I64, slot_count, (I32)), - HOOK_API_DEFINITION(I64, slot_set, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, slot_size, (I32)), - HOOK_API_DEFINITION(I64, slot_subarray, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, slot_subfield, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, slot_type, (I32, I32)), - HOOK_API_DEFINITION(I64, slot_float, (I32)), - HOOK_API_DEFINITION(I64, state_set, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, state_foreign_set, (I32, I32, I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, state, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, state_foreign, (I32, I32, I32, I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, trace, (I32, I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, trace_num, (I32, I32, I64)), - HOOK_API_DEFINITION(I64, trace_float, (I32, I32, I64)), - HOOK_API_DEFINITION(I64, otxn_burden, ()), - HOOK_API_DEFINITION(I64, otxn_field, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, otxn_generation, ()), - HOOK_API_DEFINITION(I64, otxn_id, (I32, I32, I32)), - HOOK_API_DEFINITION(I64, otxn_type, ()), - HOOK_API_DEFINITION(I64, otxn_slot, (I32)), - HOOK_API_DEFINITION(I64, otxn_param, (I32, I32, I32, I32)), - HOOK_API_DEFINITION(I64, meta_slot, (I32)), - // clang-format on -}; +inline APIWhitelist +getImportWhitelist( +#ifndef GUARD_CHECKER_BUILD + Rules const& rules +#endif +) +{ + APIWhitelist whitelist; +#ifndef GUARD_CHECKER_BUILD + std::map amendments = {}; +#endif -// featureHooks1 -static const APIWhitelist import_whitelist_1{ - // clang-format off - HOOK_API_DEFINITION(I64, xpop_slot, (I32, I32)), - // clang-format on -}; +#pragma push_macro("HOOK_API_DEFINITION") +#undef HOOK_API_DEFINITION + +#define int64_t 0x7EU +#define int32_t 0x7FU +#define uint32_t 0x7FU + +#define HOOK_WRAP_PARAMS(...) __VA_ARGS__ + +#ifdef GUARD_CHECKER_BUILD +#define HOOK_API_DEFINITION(RETURN_TYPE, FUNCTION_NAME, PARAMS_TUPLE, ...) \ + whitelist[#FUNCTION_NAME] = {RETURN_TYPE, HOOK_WRAP_PARAMS PARAMS_TUPLE}; +#else +#define HOOK_API_DEFINITION( \ + RETURN_TYPE, FUNCTION_NAME, PARAMS_TUPLE, AMENDMENT) \ + if (AMENDMENT == uint256{} || rules.enabled(AMENDMENT)) \ + whitelist[#FUNCTION_NAME] = { \ + RETURN_TYPE, HOOK_WRAP_PARAMS PARAMS_TUPLE}; +#endif + +#include "hook_api.macro" + +#undef HOOK_API_DEFINITION +#undef HOOK_WRAP_PARAMS +#undef int64_t +#undef int32_t +#undef uint32_t +#pragma pop_macro("HOOK_API_DEFINITION") + + return whitelist; +} #undef HOOK_API_DEFINITION #undef I32 #undef I64 + +enum GuardRulesVersion : uint64_t { + GuardRuleFix20250131 = 0x00000001, + GuardRuleFeatureHooksMemoryFillCopy = 0x00000002, +}; + +inline uint64_t +getGuardRulesVersion( +#ifndef GUARD_CHECKER_BUILD + Rules const& rules +#endif +) +{ + uint64_t version = 0; +#ifndef GUARD_CHECKER_BUILD + if (rules.enabled(fix20250131)) + version |= GuardRuleFix20250131; + if (rules.enabled(featureHooksMemoryFillCopy)) + version |= GuardRuleFeatureHooksMemoryFillCopy; +#else + version = -1; // all bits set for guard checker +#endif + return version; +} + }; // namespace hook_api #endif diff --git a/src/ripple/app/hook/Guard.h b/src/ripple/app/hook/Guard.h index f395af4481..d0cc646d7e 100644 --- a/src/ripple/app/hook/Guard.h +++ b/src/ripple/app/hook/Guard.h @@ -634,7 +634,9 @@ check_guard( } else if (fc_type == 10) // memory.copy { - if (rulesVersion & 0x02U) + if ((rulesVersion & hook_api::GuardRuleFix20250131) && + !(rulesVersion & + hook_api::GuardRuleFeatureHooksMemoryFillCopy)) GUARD_ERROR("Memory.copy instruction is not allowed."); REQUIRE(2); @@ -642,7 +644,9 @@ check_guard( } else if (fc_type == 11) // memory.fill { - if (rulesVersion & 0x02U) + if ((rulesVersion & hook_api::GuardRuleFix20250131) && + !(rulesVersion & + hook_api::GuardRuleFeatureHooksMemoryFillCopy)) GUARD_ERROR("Memory.fill instruction is not allowed."); ADVANCE(1); @@ -826,6 +830,7 @@ validateGuards( std::vector const& wasm, GuardLog guardLog, std::string guardLogAccStr, + hook_api::APIWhitelist const import_whitelist, /* RH NOTE: * rules version is a bit field, so rule update 1 is 0x01, update 2 is 0x02 * and update 3 is 0x04 ideally at rule version 3 all bits so far are set @@ -835,7 +840,7 @@ validateGuards( * might have unforeseen consequences, without also rolling back further * changes that are fine. */ - uint64_t rulesVersion = 0) + uint64_t rulesVersion = 0x00) { uint64_t byteCount = wasm.size(); @@ -1020,31 +1025,24 @@ validateGuards( int type_idx = parseLeb128(wasm, i, &i); CHECK_SHORT_HOOK(); + auto it = import_whitelist.find(import_name); + auto it_end = import_whitelist.end(); + bool found_in_whitelist = (it != it_end); + if (import_name == "_g") { guard_import_number = func_upto; } - else if ( - hook_api::import_whitelist.find(import_name) == - hook_api::import_whitelist.end()) + if (!found_in_whitelist) { - if (rulesVersion > 0 && - hook_api::import_whitelist_1.find(import_name) != - hook_api::import_whitelist_1.end()) - { - // PASS, this is a version 1 api - } - else - { - GUARDLOG(hook::log::IMPORT_ILLEGAL) - << "Malformed transaction. " - << "Hook attempted to import a function that does " - "not " - << "appear in the hook_api function set: `" - << import_name << "`" - << "\n"; - return {}; - } + GUARDLOG(hook::log::IMPORT_ILLEGAL) + << "Malformed transaction. " + << "Hook attempted to import a function that does " + "not " + << "appear in the hook_api function set: `" + << import_name << "`" + << "\n"; + return {}; } // add to import map @@ -1178,6 +1176,65 @@ validateGuards( func_type_map[j] = type_idx; } } + else if ( + section_type == 5 && + (rulesVersion & + hook_api::GuardRuleFeatureHooksMemoryFillCopy)) // memory section + { + int memory_count = parseLeb128(wasm, i, &i); + CHECK_SHORT_HOOK(); + if (memory_count <= 0) + { + GUARDLOG(hook::log::MEMORY_MISSING) + << "Malformed transaction. " + << "Hook did not establish any memory section." + << "\n"; + return {}; + } + + // check the initial number of pages for each memory + for (int j = 0; j < memory_count; ++j) + { + // read the limits flag (0x00 = no max, 0x01 = has max) + if (i >= wasm.size()) + { + GUARDLOG(hook::log::SHORT_HOOK) + << "Malformed transaction. " + << "Hook memory section ended abruptly." + << "\n"; + return {}; + } + uint8_t limits = wasm[i++]; + + // read the minimum number of pages + int min_pages = parseLeb128(wasm, i, &i); + CHECK_SHORT_HOOK(); + + // limit the initial number of pages to 2 or less + if (min_pages > 2) + { + GUARDLOG(hook::log::WASM_VALIDATION) + << "Malformed transaction. " + << "Hook memory initial pages (" << min_pages + << ") exceeds maximum allowed (2)." + << "\n"; + return {}; + } + + // if the maximum number of pages is specified, reject it + if (limits == 0x01) + { + int max_pages = parseLeb128(wasm, i, &i); + CHECK_SHORT_HOOK(); + GUARDLOG(hook::log::MEMORY_MAX_PAGES) + << "Malformed transaction. " + << "Hook memory maximum pages (" << max_pages + << ") is not allowed." + << "\n"; + return {}; + } + } + } i = next_section; continue; @@ -1259,11 +1316,7 @@ validateGuards( for (auto const& [import_idx, api_name] : usage->second) { auto const& api_signature = - hook_api::import_whitelist.find(api_name) != - hook_api::import_whitelist.end() - ? hook_api::import_whitelist.find(api_name)->second - : hook_api::import_whitelist_1.find(api_name) - ->second; + import_whitelist.find(api_name)->second; if (!first_signature) { diff --git a/src/ripple/app/hook/Macro.h b/src/ripple/app/hook/Macro.h index 5f309b2e31..153677d4b3 100644 --- a/src/ripple/app/hook/Macro.h +++ b/src/ripple/app/hook/Macro.h @@ -88,18 +88,18 @@ #define WASM_VAL_TYPE(T, b) CAT2(TYP_, T) -#define DECLARE_HOOK_FUNCTION(R, F, ...) \ - R F(hook::HookContext& hookCtx, \ - WasmEdge_CallingFrameContext const& frameCtx, \ - __VA_ARGS__); \ - extern WasmEdge_Result WasmFunction##F( \ - void* data_ptr, \ - const WasmEdge_CallingFrameContext* frameCtx, \ - const WasmEdge_Value* in, \ - WasmEdge_Value* out); \ - extern WasmEdge_ValType WasmFunctionParams##F[]; \ - extern WasmEdge_ValType WasmFunctionResult##F[]; \ - extern WasmEdge_FunctionTypeContext* WasmFunctionType##F; \ +#define DECLARE_HOOK_FUNCTION(R, F, ...) \ + R F(hook::HookContext& hookCtx, \ + WasmEdge_CallingFrameContext const& frameCtx __VA_OPT__( \ + , )##__VA_ARGS__); \ + extern WasmEdge_Result WasmFunction##F( \ + void* data_ptr, \ + const WasmEdge_CallingFrameContext* frameCtx, \ + 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) \ diff --git a/src/ripple/app/hook/applyHook.h b/src/ripple/app/hook/applyHook.h index 2c1f250bbf..3fa02cbe63 100644 --- a/src/ripple/app/hook/applyHook.h +++ b/src/ripple/app/hook/applyHook.h @@ -61,365 +61,20 @@ namespace hook_api { if (HOOK_DBG) \ fprintf -DECLARE_HOOK_FUNCTION(int32_t, _g, uint32_t guard_id, uint32_t maxiter); - -DECLARE_HOOK_FUNCTION( - int64_t, - accept, - uint32_t read_ptr, - uint32_t read_len, - int64_t error_code); -DECLARE_HOOK_FUNCTION( - int64_t, - rollback, - uint32_t read_ptr, - uint32_t read_len, - int64_t error_code); - -DECLARE_HOOK_FUNCTION( - int64_t, - util_raddr, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len); -DECLARE_HOOK_FUNCTION( - int64_t, - util_accid, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len); -DECLARE_HOOK_FUNCTION( - int64_t, - util_verify, - uint32_t dread_ptr, - uint32_t dread_len, - uint32_t sread_ptr, - uint32_t sread_len, - uint32_t kread_ptr, - uint32_t kread_len); -DECLARE_HOOK_FUNCTION( - int64_t, - util_sha512h, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len); -DECLARE_HOOK_FUNCTION( - int64_t, - util_keylet, - uint32_t write_ptr, - uint32_t write_len, - uint32_t keylet_type, - uint32_t a, - uint32_t b, - uint32_t c, - uint32_t d, - uint32_t e, - uint32_t f); - -DECLARE_HOOK_FUNCTION( - int64_t, - sto_validate, - uint32_t tread_ptr, - uint32_t tread_len); -DECLARE_HOOK_FUNCTION( - int64_t, - sto_subfield, - uint32_t read_ptr, - uint32_t read_len, - uint32_t field_id); -DECLARE_HOOK_FUNCTION( - int64_t, - sto_subarray, - uint32_t read_ptr, - uint32_t read_len, - uint32_t array_id); -DECLARE_HOOK_FUNCTION( - int64_t, - sto_emplace, - uint32_t write_ptr, - uint32_t write_len, - uint32_t sread_ptr, - uint32_t sread_len, - uint32_t fread_ptr, - uint32_t fread_len, - uint32_t field_id); -DECLARE_HOOK_FUNCTION( - int64_t, - sto_erase, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len, - uint32_t field_id); - -DECLARE_HOOK_FUNCNARG(int64_t, etxn_burden); -DECLARE_HOOK_FUNCTION( - int64_t, - etxn_details, - uint32_t write_ptr, - uint32_t write_len); -DECLARE_HOOK_FUNCTION( - int64_t, - etxn_fee_base, - uint32_t read_ptr, - uint32_t read_len); -DECLARE_HOOK_FUNCTION(int64_t, etxn_reserve, uint32_t count); -DECLARE_HOOK_FUNCNARG(int64_t, etxn_generation); -DECLARE_HOOK_FUNCTION( - int64_t, - etxn_nonce, - uint32_t write_ptr, - uint32_t write_len); -DECLARE_HOOK_FUNCTION( - int64_t, - emit, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len); - -DECLARE_HOOK_FUNCTION(int64_t, float_set, int32_t exponent, int64_t mantissa); -DECLARE_HOOK_FUNCTION(int64_t, float_multiply, int64_t float1, int64_t float2); -DECLARE_HOOK_FUNCTION( - int64_t, - float_mulratio, - int64_t float1, - uint32_t round_up, - uint32_t numerator, - uint32_t denominator); -DECLARE_HOOK_FUNCTION(int64_t, float_negate, int64_t float1); -DECLARE_HOOK_FUNCTION( - int64_t, - float_compare, - int64_t float1, - int64_t float2, - uint32_t mode); -DECLARE_HOOK_FUNCTION(int64_t, float_sum, int64_t float1, int64_t float2); -DECLARE_HOOK_FUNCTION( - int64_t, - float_sto, - uint32_t write_ptr, - uint32_t write_len, - uint32_t cread_ptr, - uint32_t cread_len, - uint32_t iread_ptr, - uint32_t iread_len, - int64_t float1, - uint32_t field_code); -DECLARE_HOOK_FUNCTION( - int64_t, - float_sto_set, - uint32_t read_ptr, - uint32_t read_len); -DECLARE_HOOK_FUNCTION(int64_t, float_invert, int64_t float1); -DECLARE_HOOK_FUNCTION(int64_t, float_divide, int64_t float1, int64_t float2); -DECLARE_HOOK_FUNCNARG(int64_t, float_one); -DECLARE_HOOK_FUNCTION(int64_t, float_mantissa, int64_t float1); -DECLARE_HOOK_FUNCTION(int64_t, float_sign, int64_t float1); -DECLARE_HOOK_FUNCTION( - int64_t, - float_int, - int64_t float1, - uint32_t decimal_places, - uint32_t abs); -DECLARE_HOOK_FUNCTION(int64_t, float_log, int64_t float1); -DECLARE_HOOK_FUNCTION(int64_t, float_root, int64_t float1, uint32_t n); - -DECLARE_HOOK_FUNCNARG(int64_t, fee_base); -DECLARE_HOOK_FUNCNARG(int64_t, ledger_seq); -DECLARE_HOOK_FUNCNARG(int64_t, ledger_last_time); -DECLARE_HOOK_FUNCTION( - int64_t, - ledger_last_hash, - uint32_t write_ptr, - uint32_t write_len); -DECLARE_HOOK_FUNCTION( - int64_t, - ledger_nonce, - uint32_t write_ptr, - uint32_t write_len); -DECLARE_HOOK_FUNCTION( - int64_t, - ledger_keylet, - uint32_t write_ptr, - uint32_t write_len, - uint32_t lread_ptr, - uint32_t lread_len, - uint32_t hread_ptr, - uint32_t hread_len); - -DECLARE_HOOK_FUNCTION( - int64_t, - hook_account, - uint32_t write_ptr, - uint32_t write_len); -DECLARE_HOOK_FUNCTION( - int64_t, - hook_hash, - uint32_t write_ptr, - uint32_t write_len, - int32_t hook_no); -DECLARE_HOOK_FUNCTION( - int64_t, - hook_param_set, - uint32_t read_ptr, - uint32_t read_len, - uint32_t kread_ptr, - uint32_t kread_len, - uint32_t hread_ptr, - uint32_t hread_len); -DECLARE_HOOK_FUNCTION( - int64_t, - hook_param, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len); -DECLARE_HOOK_FUNCNARG(int64_t, hook_again); -DECLARE_HOOK_FUNCTION( - int64_t, - hook_skip, - uint32_t read_ptr, - uint32_t read_len, - uint32_t flags); -DECLARE_HOOK_FUNCNARG(int64_t, hook_pos); - -DECLARE_HOOK_FUNCTION( - int64_t, - slot, - uint32_t write_ptr, - uint32_t write_len, - uint32_t slot); -DECLARE_HOOK_FUNCTION(int64_t, slot_clear, uint32_t slot); -DECLARE_HOOK_FUNCTION(int64_t, slot_count, uint32_t slot); -DECLARE_HOOK_FUNCTION( - int64_t, - slot_set, - uint32_t read_ptr, - uint32_t read_len, - uint32_t slot); -DECLARE_HOOK_FUNCTION(int64_t, slot_size, uint32_t slot); -DECLARE_HOOK_FUNCTION( - int64_t, - slot_subarray, - uint32_t parent_slot, - uint32_t array_id, - uint32_t new_slot); -DECLARE_HOOK_FUNCTION( - int64_t, - slot_subfield, - uint32_t parent_slot, - uint32_t field_id, - uint32_t new_slot); -DECLARE_HOOK_FUNCTION(int64_t, slot_type, uint32_t slot_no, uint32_t flags); -DECLARE_HOOK_FUNCTION(int64_t, slot_float, uint32_t slot_no); - -DECLARE_HOOK_FUNCTION( - int64_t, - state_set, - uint32_t read_ptr, - uint32_t read_len, - uint32_t kread_ptr, - uint32_t kread_len); -DECLARE_HOOK_FUNCTION( - int64_t, - state_foreign_set, - uint32_t read_ptr, - uint32_t read_len, - uint32_t kread_ptr, - uint32_t kread_len, - uint32_t nread_ptr, - uint32_t nread_len, - uint32_t aread_ptr, - uint32_t aread_len); -DECLARE_HOOK_FUNCTION( - int64_t, - state, - uint32_t write_ptr, - uint32_t write_len, - uint32_t kread_ptr, - uint32_t kread_len); -DECLARE_HOOK_FUNCTION( - int64_t, - state_foreign, - uint32_t write_ptr, - uint32_t write_len, - uint32_t kread_ptr, - uint32_t kread_len, - uint32_t nread_ptr, - uint32_t nread_len, - uint32_t aread_ptr, - uint32_t aread_len); - -DECLARE_HOOK_FUNCTION( - int64_t, - trace, - uint32_t mread_ptr, - uint32_t mread_len, - uint32_t dread_ptr, - uint32_t dread_len, - uint32_t as_hex); -DECLARE_HOOK_FUNCTION( - int64_t, - trace_num, - uint32_t read_ptr, - uint32_t read_len, - int64_t number); -DECLARE_HOOK_FUNCTION( - int64_t, - trace_float, - uint32_t read_ptr, - uint32_t read_len, - int64_t float1); - -DECLARE_HOOK_FUNCNARG(int64_t, otxn_burden); -DECLARE_HOOK_FUNCTION( - int64_t, - otxn_field, - uint32_t write_ptr, - uint32_t write_len, - uint32_t field_id); -DECLARE_HOOK_FUNCNARG(int64_t, otxn_generation); -DECLARE_HOOK_FUNCTION( - int64_t, - otxn_id, - uint32_t write_ptr, - uint32_t write_len, - uint32_t flags); -DECLARE_HOOK_FUNCNARG(int64_t, otxn_type); -DECLARE_HOOK_FUNCTION(int64_t, otxn_slot, uint32_t slot_no); -DECLARE_HOOK_FUNCTION( - int64_t, - otxn_param, - uint32_t write_ptr, - uint32_t write_len, - uint32_t read_ptr, - uint32_t read_len); - -DECLARE_HOOK_FUNCTION(int64_t, meta_slot, uint32_t slot_no); -DECLARE_HOOK_FUNCTION( - int64_t, - xpop_slot, - uint32_t slot_no_tx, - uint32_t slot_no_meta); - -/* - DECLARE_HOOK_FUNCTION(int64_t, str_find, uint32_t hread_ptr, - uint32_t hread_len, uint32_t nread_ptr, uint32_t nread_len, uint32_t mode, - uint32_t n); DECLARE_HOOK_FUNCTION(int64_t, str_replace, uint32_t - write_ptr, uint32_t write_len, uint32_t hread_ptr, uint32_t hread_len, - uint32_t nread_ptr, - uint32_t nread_len, uint32_t rread_ptr, uint32_t rread_len, uint32_t mode, - uint32_t n); DECLARE_HOOK_FUNCTION(int64_t, str_compare, uint32_t - fread_ptr, uint32_t fread_len, uint32_t sread_ptr, uint32_t sread_len, - uint32_t mode); - DECLARE_HOOK_FUNCTION(int64_t, str_concat, uint32_t write_ptr, - uint32_t write_len, uint32_t read_ptr, uint32_t read_len, uint64_t operand, - uint32_t operand_type); -*/ +#pragma push_macro("HOOK_API_DEFINITION") +#undef HOOK_API_DEFINITION + +#define HOOK_WRAP_PARAMS(...) __VA_ARGS__ +#define HOOK_API_DEFINITION(RETURN_TYPE, FUNCTION_NAME, PARAMS_TUPLE, ...) \ + DECLARE_HOOK_FUNCTION( \ + RETURN_TYPE, FUNCTION_NAME, HOOK_WRAP_PARAMS PARAMS_TUPLE); + +#include + +#undef HOOK_API_DEFINITION +#undef HOOK_WRAP_PARAMS +#pragma pop_macro("HOOK_API_DEFINITION") + } /* end namespace hook_api */ namespace hook { @@ -792,97 +447,18 @@ class HookExecutor WasmEdge_LogSetDebugLevel(); - ADD_HOOK_FUNCTION(_g, ctx); - ADD_HOOK_FUNCTION(accept, ctx); - ADD_HOOK_FUNCTION(rollback, ctx); - ADD_HOOK_FUNCTION(util_raddr, ctx); - ADD_HOOK_FUNCTION(util_accid, ctx); - ADD_HOOK_FUNCTION(util_verify, ctx); - ADD_HOOK_FUNCTION(util_sha512h, ctx); - ADD_HOOK_FUNCTION(sto_validate, ctx); - ADD_HOOK_FUNCTION(sto_subfield, ctx); - ADD_HOOK_FUNCTION(sto_subarray, ctx); - ADD_HOOK_FUNCTION(sto_emplace, ctx); - ADD_HOOK_FUNCTION(sto_erase, ctx); - ADD_HOOK_FUNCTION(util_keylet, ctx); - - ADD_HOOK_FUNCTION(emit, ctx); - ADD_HOOK_FUNCTION(etxn_burden, ctx); - ADD_HOOK_FUNCTION(etxn_fee_base, ctx); - ADD_HOOK_FUNCTION(etxn_details, ctx); - ADD_HOOK_FUNCTION(etxn_reserve, ctx); - ADD_HOOK_FUNCTION(etxn_generation, ctx); - ADD_HOOK_FUNCTION(etxn_nonce, ctx); - - ADD_HOOK_FUNCTION(float_set, ctx); - ADD_HOOK_FUNCTION(float_multiply, ctx); - ADD_HOOK_FUNCTION(float_mulratio, ctx); - ADD_HOOK_FUNCTION(float_negate, ctx); - ADD_HOOK_FUNCTION(float_compare, ctx); - ADD_HOOK_FUNCTION(float_sum, ctx); - ADD_HOOK_FUNCTION(float_sto, ctx); - ADD_HOOK_FUNCTION(float_sto_set, ctx); - ADD_HOOK_FUNCTION(float_invert, ctx); - - ADD_HOOK_FUNCTION(float_divide, ctx); - ADD_HOOK_FUNCTION(float_one, ctx); - ADD_HOOK_FUNCTION(float_mantissa, ctx); - ADD_HOOK_FUNCTION(float_sign, ctx); - ADD_HOOK_FUNCTION(float_int, ctx); - ADD_HOOK_FUNCTION(float_log, ctx); - ADD_HOOK_FUNCTION(float_root, ctx); - - ADD_HOOK_FUNCTION(otxn_burden, ctx); - ADD_HOOK_FUNCTION(otxn_generation, ctx); - ADD_HOOK_FUNCTION(otxn_field, ctx); - ADD_HOOK_FUNCTION(otxn_id, ctx); - ADD_HOOK_FUNCTION(otxn_type, ctx); - ADD_HOOK_FUNCTION(otxn_slot, ctx); - ADD_HOOK_FUNCTION(otxn_param, ctx); - - ADD_HOOK_FUNCTION(hook_account, ctx); - ADD_HOOK_FUNCTION(hook_hash, ctx); - ADD_HOOK_FUNCTION(hook_again, ctx); - ADD_HOOK_FUNCTION(fee_base, ctx); - ADD_HOOK_FUNCTION(ledger_seq, ctx); - ADD_HOOK_FUNCTION(ledger_last_hash, ctx); - ADD_HOOK_FUNCTION(ledger_last_time, ctx); - ADD_HOOK_FUNCTION(ledger_nonce, ctx); - ADD_HOOK_FUNCTION(ledger_keylet, ctx); - - ADD_HOOK_FUNCTION(hook_param, ctx); - ADD_HOOK_FUNCTION(hook_param_set, ctx); - ADD_HOOK_FUNCTION(hook_skip, ctx); - ADD_HOOK_FUNCTION(hook_pos, ctx); - - ADD_HOOK_FUNCTION(state, ctx); - ADD_HOOK_FUNCTION(state_foreign, ctx); - ADD_HOOK_FUNCTION(state_set, ctx); - ADD_HOOK_FUNCTION(state_foreign_set, ctx); - - ADD_HOOK_FUNCTION(slot, ctx); - ADD_HOOK_FUNCTION(slot_clear, ctx); - ADD_HOOK_FUNCTION(slot_count, ctx); - ADD_HOOK_FUNCTION(slot_set, ctx); - ADD_HOOK_FUNCTION(slot_size, ctx); - ADD_HOOK_FUNCTION(slot_subarray, ctx); - ADD_HOOK_FUNCTION(slot_subfield, ctx); - ADD_HOOK_FUNCTION(slot_type, ctx); - ADD_HOOK_FUNCTION(slot_float, ctx); - - ADD_HOOK_FUNCTION(trace, ctx); - ADD_HOOK_FUNCTION(trace_num, ctx); - ADD_HOOK_FUNCTION(trace_float, ctx); - - ADD_HOOK_FUNCTION(meta_slot, ctx); - ADD_HOOK_FUNCTION(xpop_slot, ctx); - - /* - ADD_HOOK_FUNCTION(str_find, ctx); - ADD_HOOK_FUNCTION(str_replace, ctx); - ADD_HOOK_FUNCTION(str_compare, ctx); - ADD_HOOK_FUNCTION(str_concat, ctx); - */ +#pragma push_macro("HOOK_API_DEFINITION") +#undef HOOK_API_DEFINITION + +#define HOOK_WRAP_PARAMS(...) __VA_ARGS__ +#define HOOK_API_DEFINITION(RETURN_TYPE, FUNCTION_NAME, PARAMS_TUPLE, ...) \ + ADD_HOOK_FUNCTION(FUNCTION_NAME, ctx); + +#include + +#undef HOOK_API_DEFINITION +#undef HOOK_WRAP_PARAMS +#pragma pop_macro("HOOK_API_DEFINITION") WasmEdge_TableInstanceContext* hostTable = WasmEdge_TableInstanceCreate(tableType); diff --git a/src/ripple/app/hook/guard_checker.cpp b/src/ripple/app/hook/guard_checker.cpp index f20d24617b..f40f4c7eaf 100644 --- a/src/ripple/app/hook/guard_checker.cpp +++ b/src/ripple/app/hook/guard_checker.cpp @@ -1,3 +1,5 @@ +#define GUARD_CHECKER_BUILD +#include "Enum.h" #include "Guard.h" #include #include @@ -79,7 +81,12 @@ main(int argc, char** argv) close(fd); - auto result = validateGuards(hook, std::cout, "", 3); + auto result = validateGuards( + hook, + std::cout, + "", + hook_api::getImportWhitelist(), + hook_api::getGuardRulesVersion()); if (!result) { diff --git a/src/ripple/app/hook/hook_api.macro b/src/ripple/app/hook/hook_api.macro new file mode 100644 index 0000000000..d0d479a547 --- /dev/null +++ b/src/ripple/app/hook/hook_api.macro @@ -0,0 +1,221 @@ +// int32_t _g(uint32_t guard_id, uint32_t maxiter); +HOOK_API_DEFINITION(int32_t, _g, (uint32_t, uint32_t), uint256{}) + +// int64_t accept(uint32_t read_ptr, uint32_t read_len, int64_t error_code); +HOOK_API_DEFINITION(int64_t, accept, (uint32_t, uint32_t, int64_t), uint256{}) + +// int64_t rollback(uint32_t read_ptr, uint32_t read_len, int64_t error_code); +HOOK_API_DEFINITION(int64_t, rollback, (uint32_t, uint32_t, int64_t), uint256{}) + +// int64_t util_raddr(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, util_raddr, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t util_accid(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, util_accid, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t util_verify(uint32_t dread_ptr, uint32_t dread_len, uint32_t sread_ptr, uint32_t sread_len, uint32_t kread_ptr, uint32_t kread_len); +HOOK_API_DEFINITION(int64_t, util_verify, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t util_sha512h(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, util_sha512h, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t util_keylet(uint32_t write_ptr, uint32_t write_len, uint32_t keylet_type, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f); +HOOK_API_DEFINITION(int64_t, util_keylet, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t sto_validate(uint32_t tread_ptr, uint32_t tread_len); +HOOK_API_DEFINITION(int64_t, sto_validate, (uint32_t, uint32_t), uint256{}) + +// int64_t sto_subfield(uint32_t read_ptr, uint32_t read_len, uint32_t field_id); +HOOK_API_DEFINITION(int64_t, sto_subfield, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t sto_subarray(uint32_t read_ptr, uint32_t read_len, uint32_t array_id); +HOOK_API_DEFINITION(int64_t, sto_subarray, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t sto_emplace(uint32_t write_ptr, uint32_t write_len, uint32_t sread_ptr, uint32_t sread_len, uint32_t fread_ptr, uint32_t fread_len, uint32_t field_id); +HOOK_API_DEFINITION(int64_t, sto_emplace, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t sto_erase(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len, uint32_t field_id); +HOOK_API_DEFINITION(int64_t, sto_erase, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t etxn_burden(); +HOOK_API_DEFINITION(int64_t, etxn_burden, (), uint256{}) + +// int64_t etxn_details(uint32_t write_ptr, uint32_t write_len); +HOOK_API_DEFINITION(int64_t, etxn_details, (uint32_t, uint32_t), uint256{}) + +// int64_t etxn_fee_base(uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, etxn_fee_base, (uint32_t, uint32_t), uint256{}) + +// int64_t etxn_reserve(uint32_t count); +HOOK_API_DEFINITION(int64_t, etxn_reserve, (uint32_t), uint256{}) + +// int64_t etxn_generation(); +HOOK_API_DEFINITION(int64_t, etxn_generation, (), uint256{}) + +// int64_t etxn_nonce(uint32_t write_ptr, uint32_t write_len); +HOOK_API_DEFINITION(int64_t, etxn_nonce, (uint32_t, uint32_t), uint256{}) + +// int64_t emit(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, emit, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t float_set(int32_t exponent, int64_t mantissa); +HOOK_API_DEFINITION(int64_t, float_set, (int32_t, int64_t), uint256{}) + +// int64_t float_multiply(int64_t float1, int64_t float2); +HOOK_API_DEFINITION(int64_t, float_multiply, (int64_t, int64_t), uint256{}) + +// int64_t float_mulratio(int64_t float1, uint32_t round_up, uint32_t numerator, uint32_t denominator); +HOOK_API_DEFINITION(int64_t, float_mulratio, (int64_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t float_negate(int64_t float1); +HOOK_API_DEFINITION(int64_t, float_negate, (int64_t), uint256{}) + +// int64_t float_compare(int64_t float1, int64_t float2, uint32_t mode); +HOOK_API_DEFINITION(int64_t, float_compare, (int64_t, int64_t, uint32_t), uint256{}) + +// int64_t float_sum(int64_t float1, int64_t float2); +HOOK_API_DEFINITION(int64_t, float_sum, (int64_t, int64_t), uint256{}) + +// int64_t float_sto(uint32_t write_ptr, uint32_t write_len, uint32_t cread_ptr, uint32_t cread_len, uint32_t iread_ptr, uint32_t iread_len, int64_t float1, uint32_t field_code); +HOOK_API_DEFINITION(int64_t, float_sto, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, int64_t, uint32_t), uint256{}) + +// int64_t float_sto_set(uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, float_sto_set, (uint32_t, uint32_t), uint256{}) + +// int64_t float_invert(int64_t float1); +HOOK_API_DEFINITION(int64_t, float_invert, (int64_t), uint256{}) + +// int64_t float_divide(int64_t float1, int64_t float2); +HOOK_API_DEFINITION(int64_t, float_divide, (int64_t, int64_t), uint256{}) + +// int64_t float_one(); +HOOK_API_DEFINITION(int64_t, float_one, (), uint256{}) + +// int64_t float_mantissa(int64_t float1); +HOOK_API_DEFINITION(int64_t, float_mantissa, (int64_t), uint256{}) + +// int64_t float_sign(int64_t float1); +HOOK_API_DEFINITION(int64_t, float_sign, (int64_t), uint256{}) + +// int64_t float_int(int64_t float1, uint32_t decimal_places, uint32_t abs); +HOOK_API_DEFINITION(int64_t, float_int, (int64_t, uint32_t, uint32_t), uint256{}) + +// int64_t float_log(int64_t float1); +HOOK_API_DEFINITION(int64_t, float_log, (int64_t), uint256{}) + +// int64_t float_root(int64_t float1, uint32_t n); +HOOK_API_DEFINITION(int64_t, float_root, (int64_t, uint32_t), uint256{}) + +// int64_t fee_base(); +HOOK_API_DEFINITION(int64_t, fee_base, (), uint256{}) + +// int64_t ledger_seq(); +HOOK_API_DEFINITION(int64_t, ledger_seq, (), uint256{}) + +// int64_t ledger_last_time(); +HOOK_API_DEFINITION(int64_t, ledger_last_time, (), uint256{}) + +// int64_t ledger_last_hash(uint32_t write_ptr, uint32_t write_len); +HOOK_API_DEFINITION(int64_t, ledger_last_hash, (uint32_t, uint32_t), uint256{}) + +// int64_t ledger_nonce(uint32_t write_ptr, uint32_t write_len); +HOOK_API_DEFINITION(int64_t, ledger_nonce, (uint32_t, uint32_t), uint256{}) + +// int64_t ledger_keylet(uint32_t write_ptr, uint32_t write_len, uint32_t lread_ptr, uint32_t lread_len, uint32_t hread_ptr, uint32_t hread_len); +HOOK_API_DEFINITION(int64_t, ledger_keylet, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t hook_account(uint32_t write_ptr, uint32_t write_len); +HOOK_API_DEFINITION(int64_t, hook_account, (uint32_t, uint32_t), uint256{}) + +// int64_t hook_hash(uint32_t write_ptr, uint32_t write_len, int32_t hook_no); +HOOK_API_DEFINITION(int64_t, hook_hash, (uint32_t, uint32_t, int32_t), uint256{}) + +// int64_t hook_param_set(uint32_t read_ptr, uint32_t read_len, uint32_t kread_ptr, uint32_t kread_len, uint32_t hread_ptr, uint32_t hread_len); +HOOK_API_DEFINITION(int64_t, hook_param_set, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t hook_param(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, hook_param, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t hook_again(); +HOOK_API_DEFINITION(int64_t, hook_again, (), uint256{}) + +// int64_t hook_skip(uint32_t read_ptr, uint32_t read_len, uint32_t flags); +HOOK_API_DEFINITION(int64_t, hook_skip, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t hook_pos(); +HOOK_API_DEFINITION(int64_t, hook_pos, (), uint256{}) + +// int64_t slot(uint32_t write_ptr, uint32_t write_len, uint32_t slot); +HOOK_API_DEFINITION(int64_t, slot, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t slot_clear(uint32_t slot); +HOOK_API_DEFINITION(int64_t, slot_clear, (uint32_t), uint256{}) + +// int64_t slot_count(uint32_t slot); +HOOK_API_DEFINITION(int64_t, slot_count, (uint32_t), uint256{}) + +// int64_t slot_set(uint32_t read_ptr, uint32_t read_len, uint32_t slot); +HOOK_API_DEFINITION(int64_t, slot_set, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t slot_size(uint32_t slot); +HOOK_API_DEFINITION(int64_t, slot_size, (uint32_t), uint256{}) + +// int64_t slot_subarray(uint32_t parent_slot, uint32_t array_id, uint32_t new_slot); +HOOK_API_DEFINITION(int64_t, slot_subarray, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t slot_subfield(uint32_t parent_slot, uint32_t field_id, uint32_t new_slot); +HOOK_API_DEFINITION(int64_t, slot_subfield, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t slot_type(uint32_t slot_no, uint32_t flags); +HOOK_API_DEFINITION(int64_t, slot_type, (uint32_t, uint32_t), uint256{}) + +// int64_t slot_float(uint32_t slot_no); +HOOK_API_DEFINITION(int64_t, slot_float, (uint32_t), uint256{}) + +// int64_t state_set(uint32_t read_ptr, uint32_t read_len, uint32_t kread_ptr, uint32_t kread_len); +HOOK_API_DEFINITION(int64_t, state_set, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t state_foreign_set(uint32_t read_ptr, uint32_t read_len, uint32_t kread_ptr, uint32_t kread_len, uint32_t nread_ptr, uint32_t nread_len, uint32_t aread_ptr, uint32_t aread_len); +HOOK_API_DEFINITION(int64_t, state_foreign_set, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t state(uint32_t write_ptr, uint32_t write_len, uint32_t kread_ptr, uint32_t kread_len); +HOOK_API_DEFINITION(int64_t, state, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t state_foreign(uint32_t write_ptr, uint32_t write_len, uint32_t kread_ptr, uint32_t kread_len, uint32_t nread_ptr, uint32_t nread_len, uint32_t aread_ptr, uint32_t aread_len); +HOOK_API_DEFINITION(int64_t, state_foreign, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t trace(uint32_t mread_ptr, uint32_t mread_len, uint32_t dread_ptr, uint32_t dread_len, uint32_t as_hex); +HOOK_API_DEFINITION(int64_t, trace, (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t trace_num(uint32_t read_ptr, uint32_t read_len, int64_t number); +HOOK_API_DEFINITION(int64_t, trace_num, (uint32_t, uint32_t, int64_t), uint256{}) + +// int64_t trace_float(uint32_t read_ptr, uint32_t read_len, int64_t float1); +HOOK_API_DEFINITION(int64_t, trace_float, (uint32_t, uint32_t, int64_t), uint256{}) + +// int64_t otxn_burden(); +HOOK_API_DEFINITION(int64_t, otxn_burden, (), uint256{}) + +// int64_t otxn_field(uint32_t write_ptr, uint32_t write_len, uint32_t field_id); +HOOK_API_DEFINITION(int64_t, otxn_field, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t otxn_generation(); +HOOK_API_DEFINITION(int64_t, otxn_generation, (), uint256{}) + +// int64_t otxn_id(uint32_t write_ptr, uint32_t write_len, uint32_t flags); +HOOK_API_DEFINITION(int64_t, otxn_id, (uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t otxn_type(); +HOOK_API_DEFINITION(int64_t, otxn_type, (), uint256{}) + +// int64_t otxn_slot(uint32_t slot_no); +HOOK_API_DEFINITION(int64_t, otxn_slot, (uint32_t), uint256{}) + +// int64_t otxn_param(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len); +HOOK_API_DEFINITION(int64_t, otxn_param, (uint32_t, uint32_t, uint32_t, uint32_t), uint256{}) + +// int64_t meta_slot(uint32_t slot_no); +HOOK_API_DEFINITION(int64_t, meta_slot, (uint32_t), uint256{}) + +// int64_t xpop_slot(uint32_t slot_no_tx, uint32_t slot_no_meta); +HOOK_API_DEFINITION(int64_t, xpop_slot, (uint32_t, uint32_t), featureHooksUpdate1) diff --git a/src/ripple/app/tx/impl/Change.cpp b/src/ripple/app/tx/impl/Change.cpp index 37a436feea..c2eb62793e 100644 --- a/src/ripple/app/tx/impl/Change.cpp +++ b/src/ripple/app/tx/impl/Change.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include #include #include #include @@ -601,12 +602,13 @@ Change::activateXahauGenesis() for (auto const& [hookOn, wasmBytes, params] : genesis_hooks) { std::ostringstream loggerStream; + auto result = validateGuards( wasmBytes, // wasm to verify loggerStream, "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", - (ctx_.view().rules().enabled(featureHooksUpdate1) ? 1 : 0) + - (ctx_.view().rules().enabled(fix20250131) ? 2 : 0)); + hook_api::getImportWhitelist(ctx_.view().rules()), + hook_api::getGuardRulesVersion(ctx_.view().rules())); if (!result) { diff --git a/src/ripple/app/tx/impl/SetHook.cpp b/src/ripple/app/tx/impl/SetHook.cpp index 9ca8295571..2b35f2a592 100644 --- a/src/ripple/app/tx/impl/SetHook.cpp +++ b/src/ripple/app/tx/impl/SetHook.cpp @@ -490,8 +490,8 @@ SetHook::validateHookSetEntry(SetHookCtx& ctx, STObject const& hookSetObj) hook, // wasm to verify logger, hsacc, - (ctx.rules.enabled(featureHooksUpdate1) ? 1 : 0) + - (ctx.rules.enabled(fix20250131) ? 2 : 0)); + hook_api::getImportWhitelist(ctx.rules), + hook_api::getGuardRulesVersion(ctx.rules)); if (ctx.j.trace()) { diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index 2766859dc7..5ea7e3b5ea 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -74,7 +74,7 @@ namespace detail { // Feature.cpp. Because it's only used to reserve storage, and determine how // large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than // the actual number of amendments. A LogicError on startup will verify this. -static constexpr std::size_t numFeatures = 90; +static constexpr std::size_t numFeatures = 91; /** Amendments that this server supports and the default voting behavior. Whether they are enabled depends on the Rules defined in the validated @@ -378,6 +378,8 @@ extern uint256 const fixInvalidTxFlags; extern uint256 const featureExtendedHookState; extern uint256 const fixCronStacking; extern uint256 const fixHookAPI20251128; +extern uint256 const featureHooksMemoryFillCopy; + } // namespace ripple #endif diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index 24383f896c..5ff9a70736 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -484,6 +484,7 @@ REGISTER_FIX (fixInvalidTxFlags, Supported::yes, VoteBehavior::De REGISTER_FEATURE(ExtendedHookState, Supported::yes, VoteBehavior::DefaultNo); REGISTER_FIX (fixCronStacking, Supported::yes, VoteBehavior::DefaultYes); REGISTER_FIX (fixHookAPI20251128, Supported::yes, VoteBehavior::DefaultYes); +REGISTER_FEATURE(HooksMemoryFillCopy, Supported::yes, VoteBehavior::DefaultNo); // The following amendments are obsolete, but must remain supported // because they could potentially get enabled. diff --git a/src/test/app/SetHook_test.cpp b/src/test/app/SetHook_test.cpp index 0c7be29e81..0b53d28515 100644 --- a/src/test/app/SetHook_test.cpp +++ b/src/test/app/SetHook_test.cpp @@ -1298,48 +1298,285 @@ class SetHook0_test : public beast::unit_test::suite testFillCopy(FeatureBitset features) { testcase("Test fill/copy"); + using namespace jtx; - // a hook containing memory.fill instruction - std::string hookFill = - "0061736d0100000001130360027f7f017f60037f7f7e017e60017f017e02" - "170203656e76025f67000003656e76066163636570740001030201020503" - "0100020621057f01418088040b7f004180080b7f004180080b7f00418088" - "040b7f004180080b07080104686f6f6b00020aa4800001a0800001017e23" - "01412a41e400fc0b004101410110001a41004100420010011a20010b"; - - // a hook containing memory.copy instruction - std::string hookCopy = - "0061736d0100000001130360027f7f017f60037f7f7e017e60017f017e02" - "170203656e76025f67000003656e76066163636570740001030201020503" - "0100020621057f01418088040b7f004180080b7f004180080b7f00418088" - "040b7f004180080b07080104686f6f6b00020aa5800001a1800001017e23" - "00230141e400fc0a00004101410110001a41004100420010011a20010b"; + auto const alice = Account{"alice"}; + auto const bob = Account{"bob"}; - using namespace jtx; + { + // memory page size: 2 + + // 64KiB * (2-1) - 1024 = 64512 + // memory.fill with len=64512 works, but len=64513 traps. + // (memory 2) = 2 pages × 64KiB = 128KiB total. + // Fill range: [1024, 1024 + len) + // len=64512 → ends at 65536 (exactly before page 1 boundary) → OK + // len=64513 → touches 65537 (first byte of page 2) → out-of-bounds + // trap. + // Many runtimes reserve the last 64KiB as a guard page for safety. + // guard page for safety. Effectively only 1 page is writable. + + // a hook containing memory.fill instruction + TestHook hookFill = wasm[R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 1 + i32.const 42 + i32.const 130047 + memory.fill + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]"]; + + // a hook containing memory.copy instruction + TestHook hookCopy = wasm[R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 0 + global.get 1 + i32.const 130047 + memory.copy + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 1024)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]"]; + + for (bool withFix : {true, false}) + for (bool withFillCopy : {true, false}) + { + auto f = features; + if (!withFix) + f = f - fix20250131; + if (!withFillCopy) + f = f - featureHooksMemoryFillCopy; + Env env{*this, f}; + env.fund(XRP(10000), alice, bob); + env.close(); + + auto expect = ter(tesSUCCESS); + if (withFix && !withFillCopy) + expect = ter(temMALFORMED); + if (withFillCopy) + expect = ter(tesSUCCESS); + + env(ripple::test::jtx::hook(alice, {{hso(hookFill)}}, 0), + M(withFix ? "hookFill - with fix" + : "hookFill - zonder fix"), + HSFEE, + expect); + env.close(); - for (int withFix = 0; withFix < 2; ++withFix) + if (withFillCopy) + { + env(pay(bob, alice, XRP(1)), + fee(XRP(1)), + ter(tesSUCCESS)); + env.close(); + } + + env(ripple::test::jtx::hook(bob, {{hso(hookCopy)}}, 0), + M(withFix ? "hookCopy - with fix" + : "hookCopy - zonder fix"), + HSFEE, + expect); + env.close(); + + if (withFillCopy) + { + env(pay(bob, alice, XRP(1)), + fee(XRP(1)), + ter(tesSUCCESS)); + env.close(); + } + } + } { - auto f = withFix ? features : features - fix20250131; - Env env{*this, f}; + // Check trap + TestHook hookFill = wasm[R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 1 + i32.const 42 + i32.const 130049 + memory.fill + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]"]; - auto const alice = Account{"alice"}; - env.fund(XRP(10000), alice); + // a hook containing memory.copy instruction + TestHook hookCopy = wasm[R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 0 + global.get 1 + i32.const 130049 + memory.copy + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 1024)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]"]; - auto const bob = Account{"bob"}; - env.fund(XRP(10000), bob); + Env env{*this, features | featureHooksMemoryFillCopy}; + env.fund(XRP(10000), alice, bob); + env.close(); env(ripple::test::jtx::hook(alice, {{hso(hookFill)}}, 0), - M(withFix ? "hookFill - with fix" : "hookFill - zonder fix"), HSFEE, - withFix ? ter(temMALFORMED) : ter(tesSUCCESS)); + ter(tesSUCCESS)); + env.close(); + + env(pay(bob, alice, XRP(1)), + fee(XRP(1)), + M("hookFill - page cap exceeded"), + ter(tecHOOK_REJECTED)); + env.close(); env(ripple::test::jtx::hook(bob, {{hso(hookCopy)}}, 0), - M(withFix ? "hookCopy - with fix" : "hookCopy - zonder fix"), HSFEE, - withFix ? ter(temMALFORMED) : ter(tesSUCCESS)); + ter(tesSUCCESS)); + env.close(); + env(pay(bob, alice, XRP(1)), + fee(XRP(1)), + M("hookCopy - page cap exceeded"), + ter(tecHOOK_REJECTED)); env.close(); } + + { + TestHook hook = wasm[R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 3) + (global (;0;) (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]"]; + + for (bool withFillCopy : {true, false}) + { + auto f = features; + if (!withFillCopy) + f = f - featureHooksMemoryFillCopy; + + Env env{*this, f}; + env.fund(XRP(10000), alice, bob); + env.close(); + + env(ripple::test::jtx::hook(alice, {{hso(hook)}}, 0), + HSFEE, + M("hookFill - page out of bounds"), + withFillCopy ? ter(temMALFORMED) : ter(tesSUCCESS)); + env.close(); + + if (!withFillCopy) + { + env(pay(bob, alice, XRP(1)), fee(XRP(1)), ter(tesSUCCESS)); + env.close(); + } + } + } } void @@ -6872,7 +7109,10 @@ class SetHook0_test : public beast::unit_test::suite std::vector const keys = { "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC" "1"}; - Env env{*this, network::makeNetworkVLConfig(21337, keys)}; + Env env{ + *this, + network::makeNetworkVLConfig(21337, keys), + features - featureHooksUpdate1}; auto const master = Account("masterpassphrase"); env(noop(master), fee(10'000'000'000), ter(tesSUCCESS)); @@ -6950,6 +7190,16 @@ class SetHook0_test : public beast::unit_test::suite } )[test.hook]"]; + // before featureHooksUpdate1 + env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), + M("set xpop_slot (disabled)"), + HSFEE, + ter(temMALFORMED)); + env.close(); + + env.enableFeature(featureHooksUpdate1); + env.close(); + // install the hook on alice env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), M("set xpop_slot"), diff --git a/src/test/app/SetHook_wasm.h b/src/test/app/SetHook_wasm.h index 73294c9fb0..4deb2c244b 100644 --- a/src/test/app/SetHook_wasm.h +++ b/src/test/app/SetHook_wasm.h @@ -191,6 +191,251 @@ std::map> wasm = { }}, /* ==== WASM: 1 ==== */ + {R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 1 + i32.const 42 + i32.const 130047 + memory.fill + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x13U, + 0x03U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, + 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, + 0x17U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, + 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, + 0x70U, 0x74U, 0x00U, 0x01U, 0x03U, 0x02U, 0x01U, 0x02U, 0x05U, 0x03U, + 0x01U, 0x00U, 0x02U, 0x06U, 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0x80U, + 0x88U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, + 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x88U, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, + 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x02U, 0x0AU, 0x23U, + 0x01U, 0x21U, 0x01U, 0x01U, 0x7EU, 0x23U, 0x01U, 0x41U, 0x2AU, 0x41U, + 0xFFU, 0xF7U, 0x07U, 0xFCU, 0x0BU, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, + 0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, + 0x01U, 0x1AU, 0x20U, 0x01U, 0x0BU, + }}, + + /* ==== WASM: 2 ==== */ + {R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 0 + global.get 1 + i32.const 130047 + memory.copy + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 1024)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x13U, + 0x03U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, + 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, + 0x17U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, + 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, + 0x70U, 0x74U, 0x00U, 0x01U, 0x03U, 0x02U, 0x01U, 0x02U, 0x05U, 0x03U, + 0x01U, 0x00U, 0x02U, 0x06U, 0x20U, 0x05U, 0x7FU, 0x01U, 0x41U, 0x80U, + 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x88U, 0x04U, + 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, + 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x02U, 0x0AU, 0x24U, 0x01U, + 0x22U, 0x01U, 0x01U, 0x7EU, 0x23U, 0x00U, 0x23U, 0x01U, 0x41U, 0xFFU, + 0xF7U, 0x07U, 0xFCU, 0x0AU, 0x00U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, + 0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, + 0x01U, 0x1AU, 0x20U, 0x01U, 0x0BU, + }}, + + /* ==== WASM: 3 ==== */ + {R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 1 + i32.const 42 + i32.const 130049 + memory.fill + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x13U, + 0x03U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, + 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, + 0x17U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, + 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, + 0x70U, 0x74U, 0x00U, 0x01U, 0x03U, 0x02U, 0x01U, 0x02U, 0x05U, 0x03U, + 0x01U, 0x00U, 0x02U, 0x06U, 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0x80U, + 0x88U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, + 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x88U, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, + 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x02U, 0x0AU, 0x23U, + 0x01U, 0x21U, 0x01U, 0x01U, 0x7EU, 0x23U, 0x01U, 0x41U, 0x2AU, 0x41U, + 0x81U, 0xF8U, 0x07U, 0xFCU, 0x0BU, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, + 0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, + 0x01U, 0x1AU, 0x20U, 0x01U, 0x0BU, + }}, + + /* ==== WASM: 4 ==== */ + {R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + global.get 0 + global.get 1 + i32.const 130049 + memory.copy + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 1024)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x13U, + 0x03U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, + 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, + 0x17U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, + 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, + 0x70U, 0x74U, 0x00U, 0x01U, 0x03U, 0x02U, 0x01U, 0x02U, 0x05U, 0x03U, + 0x01U, 0x00U, 0x02U, 0x06U, 0x20U, 0x05U, 0x7FU, 0x01U, 0x41U, 0x80U, + 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x88U, 0x04U, + 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, + 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x02U, 0x0AU, 0x24U, 0x01U, + 0x22U, 0x01U, 0x01U, 0x7EU, 0x23U, 0x00U, 0x23U, 0x01U, 0x41U, 0x81U, + 0xF8U, 0x07U, 0xFCU, 0x0AU, 0x00U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, + 0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, + 0x01U, 0x1AU, 0x20U, 0x01U, 0x0BU, + }}, + + /* ==== WASM: 5 ==== */ + {R"[test.hook]( + (module + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32 i64) (result i64))) + (type (;2;) (func (param i32) (result i64))) + (import "env" "_g" (func (;0;) (type 0))) + (import "env" "accept" (func (;1;) (type 1))) + (func (;2;) (type 2) (param i32) (result i64) + (local i64) + i32.const 1 + i32.const 1 + call 0 + drop + i32.const 0 + i32.const 0 + i64.const 0 + call 1 + drop + local.get 1) + (memory (;0;) 3) + (global (;0;) (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 66560)) + (global (;4;) i32 (i32.const 1024)) + (export "hook" (func 2))) + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x13U, + 0x03U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, + 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, + 0x17U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, + 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, + 0x70U, 0x74U, 0x00U, 0x01U, 0x03U, 0x02U, 0x01U, 0x02U, 0x05U, 0x03U, + 0x01U, 0x00U, 0x03U, 0x06U, 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0x80U, + 0x88U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, + 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x88U, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, + 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x02U, 0x0AU, 0x18U, + 0x01U, 0x16U, 0x01U, 0x01U, 0x7EU, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, + 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, 0x01U, + 0x1AU, 0x20U, 0x01U, 0x0BU, + }}, + + /* ==== WASM: 6 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i64))) @@ -240,7 +485,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 2 ==== */ + /* ==== WASM: 7 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i64))) @@ -294,7 +539,7 @@ std::map> wasm = { 0x14U, 0x10U, 0x00U, 0x1AU, 0x0CU, 0x00U, 0x0BU, 0x0BU, }}, - /* ==== WASM: 3 ==== */ + /* ==== WASM: 8 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -361,7 +606,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x20U, 0x02U, 0x0BU, }}, - /* ==== WASM: 4 ==== */ + /* ==== WASM: 9 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -467,7 +712,7 @@ std::map> wasm = { 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x03U, 0x0BU, }}, - /* ==== WASM: 5 ==== */ + /* ==== WASM: 10 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -542,7 +787,7 @@ std::map> wasm = { 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x05U, 0x0BU, }}, - /* ==== WASM: 6 ==== */ + /* ==== WASM: 11 ==== */ {R"[test.hook]( #include extern int32_t _g(uint32_t, uint32_t); @@ -1159,7 +1404,7 @@ std::map> wasm = { 0x78U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 7 ==== */ + /* ==== WASM: 12 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1264,7 +1509,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 8 ==== */ + /* ==== WASM: 13 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1386,7 +1631,7 @@ std::map> wasm = { 0x58U, 0x4EU, 0x00U, }}, - /* ==== WASM: 9 ==== */ + /* ==== WASM: 14 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1509,7 +1754,7 @@ std::map> wasm = { 0x4EU, 0x59U, 0x5FU, 0x4EU, 0x4FU, 0x4EU, 0x43U, 0x45U, 0x53U, 0x00U, }}, - /* ==== WASM: 10 ==== */ + /* ==== WASM: 15 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1589,7 +1834,7 @@ std::map> wasm = { 0x54U, 0x00U, }}, - /* ==== WASM: 11 ==== */ + /* ==== WASM: 16 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1634,7 +1879,7 @@ std::map> wasm = { 0x30U, 0x00U, }}, - /* ==== WASM: 12 ==== */ + /* ==== WASM: 17 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1953,7 +2198,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 13 ==== */ + /* ==== WASM: 18 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -2739,7 +2984,7 @@ std::map> wasm = { 0x37U, 0x36U, 0x33U, 0x4CU, 0x4CU, 0x20U, 0x29U, 0x00U, }}, - /* ==== WASM: 14 ==== */ + /* ==== WASM: 19 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3129,7 +3374,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 15 ==== */ + /* ==== WASM: 20 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3310,7 +3555,7 @@ std::map> wasm = { 0x38U, 0x4CU, 0x4CU, 0x29U, 0x00U, }}, - /* ==== WASM: 16 ==== */ + /* ==== WASM: 21 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3499,7 +3744,7 @@ std::map> wasm = { 0x29U, 0x00U, }}, - /* ==== WASM: 17 ==== */ + /* ==== WASM: 22 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3738,7 +3983,7 @@ std::map> wasm = { 0x00U, 0x42U, 0x00U, 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 18 ==== */ + /* ==== WASM: 23 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -4440,7 +4685,7 @@ std::map> wasm = { 0x38U, 0x35U, 0x35U, 0x32U, 0x55U, 0x29U, 0x00U, }}, - /* ==== WASM: 19 ==== */ + /* ==== WASM: 24 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5785,7 +6030,7 @@ std::map> wasm = { 0x20U, 0x29U, 0x00U, }}, - /* ==== WASM: 20 ==== */ + /* ==== WASM: 25 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5887,7 +6132,7 @@ std::map> wasm = { 0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 21 ==== */ + /* ==== WASM: 26 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5930,7 +6175,7 @@ std::map> wasm = { 0x00U, 0x0BU, }}, - /* ==== WASM: 22 ==== */ + /* ==== WASM: 27 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -6078,7 +6323,7 @@ std::map> wasm = { 0x34U, 0x34U, 0x4CU, 0x4CU, 0x2CU, 0x20U, 0x33U, 0x29U, 0x00U, }}, - /* ==== WASM: 23 ==== */ + /* ==== WASM: 28 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -6406,7 +6651,7 @@ std::map> wasm = { 0x38U, 0x34U, 0x39U, 0x30U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 24 ==== */ + /* ==== WASM: 29 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -6611,7 +6856,7 @@ std::map> wasm = { 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 25 ==== */ + /* ==== WASM: 30 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -7295,7 +7540,7 @@ std::map> wasm = { 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 26 ==== */ + /* ==== WASM: 31 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -7590,7 +7835,7 @@ std::map> wasm = { 0x32U, 0x34U, 0x31U, 0x36U, 0x55U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 27 ==== */ + /* ==== WASM: 32 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8303,7 +8548,7 @@ std::map> wasm = { 0x31U, 0x33U, 0x33U, 0x38U, 0x20U, 0x29U, 0x00U, }}, - /* ==== WASM: 28 ==== */ + /* ==== WASM: 33 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8388,7 +8633,7 @@ std::map> wasm = { 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x30U, 0x00U, }}, - /* ==== WASM: 29 ==== */ + /* ==== WASM: 34 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8450,7 +8695,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 30 ==== */ + /* ==== WASM: 35 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8527,7 +8772,7 @@ std::map> wasm = { 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 31 ==== */ + /* ==== WASM: 36 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8604,7 +8849,7 @@ std::map> wasm = { 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 32 ==== */ + /* ==== WASM: 37 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8861,7 +9106,7 @@ std::map> wasm = { 0x00U, 0x00U, }}, - /* ==== WASM: 33 ==== */ + /* ==== WASM: 38 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9019,7 +9264,7 @@ std::map> wasm = { 0x04U, 0x00U, 0x00U, }}, - /* ==== WASM: 34 ==== */ + /* ==== WASM: 39 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9372,7 +9617,7 @@ std::map> wasm = { 0x00U, 0x2AU, 0x04U, 0x00U, 0x00U, 0x31U, 0x04U, 0x00U, 0x00U, }}, - /* ==== WASM: 35 ==== */ + /* ==== WASM: 40 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9405,7 +9650,7 @@ std::map> wasm = { 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU, }}, - /* ==== WASM: 36 ==== */ + /* ==== WASM: 41 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9632,7 +9877,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 37 ==== */ + /* ==== WASM: 42 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9663,7 +9908,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU, }}, - /* ==== WASM: 38 ==== */ + /* ==== WASM: 43 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9974,7 +10219,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 39 ==== */ + /* ==== WASM: 44 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10051,7 +10296,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 40 ==== */ + /* ==== WASM: 45 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10085,7 +10330,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU, }}, - /* ==== WASM: 41 ==== */ + /* ==== WASM: 46 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10172,7 +10417,7 @@ std::map> wasm = { 0x32U, 0x00U, }}, - /* ==== WASM: 42 ==== */ + /* ==== WASM: 47 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10206,7 +10451,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 43 ==== */ + /* ==== WASM: 48 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10346,7 +10591,7 @@ std::map> wasm = { 0x54U, 0x5FU, 0x4DU, 0x45U, 0x54U, 0x00U, }}, - /* ==== WASM: 44 ==== */ + /* ==== WASM: 49 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10536,7 +10781,7 @@ std::map> wasm = { 0x31U, 0x34U, 0x00U, }}, - /* ==== WASM: 45 ==== */ + /* ==== WASM: 50 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10690,7 +10935,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 46 ==== */ + /* ==== WASM: 51 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10851,7 +11096,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 47 ==== */ + /* ==== WASM: 52 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11008,7 +11253,7 @@ std::map> wasm = { 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U, }}, - /* ==== WASM: 48 ==== */ + /* ==== WASM: 53 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11093,7 +11338,7 @@ std::map> wasm = { 0x74U, 0x79U, 0x70U, 0x65U, 0x28U, 0x29U, 0x00U, }}, - /* ==== WASM: 49 ==== */ + /* ==== WASM: 54 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11350,7 +11595,7 @@ std::map> wasm = { 0x00U, 0x00U, }}, - /* ==== WASM: 50 ==== */ + /* ==== WASM: 55 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11588,7 +11833,7 @@ std::map> wasm = { 0x3EU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 51 ==== */ + /* ==== WASM: 56 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11684,7 +11929,7 @@ std::map> wasm = { 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 52 ==== */ + /* ==== WASM: 57 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11794,7 +12039,7 @@ std::map> wasm = { 0x20U, 0x31U, 0x00U, }}, - /* ==== WASM: 53 ==== */ + /* ==== WASM: 58 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11924,7 +12169,7 @@ std::map> wasm = { 0x30U, 0x30U, 0x30U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 54 ==== */ + /* ==== WASM: 59 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12198,7 +12443,7 @@ std::map> wasm = { 0x30U, 0x00U, }}, - /* ==== WASM: 55 ==== */ + /* ==== WASM: 60 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12335,7 +12580,7 @@ std::map> wasm = { 0x2CU, 0x20U, 0x73U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x31U, 0x00U, }}, - /* ==== WASM: 56 ==== */ + /* ==== WASM: 61 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12629,7 +12874,7 @@ std::map> wasm = { 0x5FU, 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U, }}, - /* ==== WASM: 57 ==== */ + /* ==== WASM: 62 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12863,7 +13108,7 @@ std::map> wasm = { 0x5FU, 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U, }}, - /* ==== WASM: 58 ==== */ + /* ==== WASM: 63 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13159,7 +13404,7 @@ std::map> wasm = { 0x2CU, 0x20U, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 59 ==== */ + /* ==== WASM: 64 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13363,7 +13608,7 @@ std::map> wasm = { 0x6EU, 0x74U, 0x32U, 0x22U, 0x20U, 0x2BU, 0x20U, 0x69U, 0x29U, 0x00U, }}, - /* ==== WASM: 60 ==== */ + /* ==== WASM: 65 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13480,7 +13725,7 @@ std::map> wasm = { 0x69U, 0x29U, 0x00U, }}, - /* ==== WASM: 61 ==== */ + /* ==== WASM: 66 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13589,7 +13834,7 @@ std::map> wasm = { 0x6EU, 0x74U, 0x65U, 0x6EU, 0x74U, 0x32U, 0x22U, 0x29U, 0x00U, }}, - /* ==== WASM: 62 ==== */ + /* ==== WASM: 67 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13862,7 +14107,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 63 ==== */ + /* ==== WASM: 68 ==== */ {R"[test.hook]( #include #define sfInvoiceID ((5U << 16U) + 17U) @@ -14081,7 +14326,7 @@ std::map> wasm = { 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 64 ==== */ + /* ==== WASM: 69 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14193,7 +14438,7 @@ std::map> wasm = { 0x58U, 0x49U, 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 65 ==== */ + /* ==== WASM: 70 ==== */ {R"[test.hook]( #include #define sfInvoiceID ((5U << 16U) + 17U) @@ -14329,7 +14574,7 @@ std::map> wasm = { 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 66 ==== */ + /* ==== WASM: 71 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14465,7 +14710,7 @@ std::map> wasm = { 0x49U, 0x47U, 0x00U, }}, - /* ==== WASM: 67 ==== */ + /* ==== WASM: 72 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14604,7 +14849,7 @@ std::map> wasm = { 0x66U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x32U, 0x29U, 0x00U, }}, - /* ==== WASM: 68 ==== */ + /* ==== WASM: 73 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14716,7 +14961,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 69 ==== */ + /* ==== WASM: 74 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14810,7 +15055,7 @@ std::map> wasm = { 0x61U, 0x64U, 0x5BU, 0x69U, 0x5DU, 0x00U, }}, - /* ==== WASM: 70 ==== */ + /* ==== WASM: 75 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14943,7 +15188,7 @@ std::map> wasm = { 0x64U, 0x5BU, 0x69U, 0x5DU, 0x00U, }}, - /* ==== WASM: 71 ==== */ + /* ==== WASM: 76 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -15031,7 +15276,7 @@ std::map> wasm = { 0x61U, 0x74U, 0x61U, 0x29U, 0x00U, }}, - /* ==== WASM: 72 ==== */ + /* ==== WASM: 77 ==== */ {R"[test.hook]( #include #define sfInvoiceID ((5U << 16U) + 17U) @@ -15142,7 +15387,7 @@ std::map> wasm = { 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 73 ==== */ + /* ==== WASM: 78 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -15353,7 +15598,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 74 ==== */ + /* ==== WASM: 79 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -15461,7 +15706,7 @@ std::map> wasm = { 0x20U, 0x22U, 0x32U, 0x22U, 0x2CU, 0x20U, 0x31U, 0x29U, 0x00U, }}, - /* ==== WASM: 75 ==== */ + /* ==== WASM: 80 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16073,7 +16318,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 76 ==== */ + /* ==== WASM: 81 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16260,7 +16505,7 @@ std::map> wasm = { 0x63U, 0x65U, 0x29U, 0x20U, 0x3EU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 77 ==== */ + /* ==== WASM: 82 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16610,7 +16855,7 @@ std::map> wasm = { 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 78 ==== */ + /* ==== WASM: 83 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16746,7 +16991,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 79 ==== */ + /* ==== WASM: 84 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16805,7 +17050,7 @@ std::map> wasm = { 0x64U, 0xE1U, 0xF1U, }}, - /* ==== WASM: 79 ==== */ + /* ==== WASM: 85 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16978,7 +17223,7 @@ std::map> wasm = { 0x54U, 0x5FU, 0x45U, 0x58U, 0x49U, 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 80 ==== */ + /* ==== WASM: 86 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -17126,7 +17371,7 @@ std::map> wasm = { 0x30U, 0x00U, 0x22U, 0x00U, 0x00U, 0x00U, 0x00U, }}, - /* ==== WASM: 81 ==== */ + /* ==== WASM: 87 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -17223,7 +17468,7 @@ std::map> wasm = { 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 82 ==== */ + /* ==== WASM: 88 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -17282,7 +17527,7 @@ std::map> wasm = { 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, }}, - /* ==== WASM: 83 ==== */ + /* ==== WASM: 89 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -17341,7 +17586,7 @@ std::map> wasm = { 0x4EU, 0x44U, 0x53U, 0x00U, }}, - /* ==== WASM: 84 ==== */ + /* ==== WASM: 90 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -19170,7 +19415,7 @@ std::map> wasm = { 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 85 ==== */ + /* ==== WASM: 91 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -20512,7 +20757,7 @@ std::map> wasm = { 0x20U, 0x30U, 0x2CU, 0x20U, 0x30U, 0x29U, 0x29U, 0x00U, }}, - /* ==== WASM: 86 ==== */ + /* ==== WASM: 92 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -23445,7 +23690,7 @@ std::map> wasm = { 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 87 ==== */ + /* ==== WASM: 93 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -25410,7 +25655,7 @@ std::map> wasm = { 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 88 ==== */ + /* ==== WASM: 94 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -25695,7 +25940,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 89 ==== */ + /* ==== WASM: 95 ==== */ {R"[test.hook]( #include extern int32_t _g(uint32_t, uint32_t); @@ -26282,7 +26527,7 @@ std::map> wasm = { 0x4EU, 0x5FU, 0x46U, 0x41U, 0x49U, 0x4CU, 0x55U, 0x52U, 0x45U, 0x00U, }}, - /* ==== WASM: 90 ==== */ + /* ==== WASM: 96 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -26311,7 +26556,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 91 ==== */ + /* ==== WASM: 97 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -26343,7 +26588,7 @@ std::map> wasm = { 0x20U, 0x52U, 0x65U, 0x6AU, 0x65U, 0x63U, 0x74U, 0x65U, 0x64U, 0x00U, }}, - /* ==== WASM: 92 ==== */ + /* ==== WASM: 98 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32 i64) (result i64))) @@ -26370,7 +26615,7 @@ std::map> wasm = { 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, 0x00U, 0x0BU, }}, - /* ==== WASM: 93 ==== */ + /* ==== WASM: 99 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i32))) @@ -26423,7 +26668,7 @@ std::map> wasm = { 0x00U, 0x1AU, 0x0BU, }}, - /* ==== WASM: 94 ==== */ + /* ==== WASM: 100 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -33066,7 +33311,7 @@ std::map> wasm = { 0x39U, 0x30U, 0x31U, 0x32U, 0x33U, 0x00U, }}, - /* ==== WASM: 95 ==== */ + /* ==== WASM: 101 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -33112,7 +33357,7 @@ std::map> wasm = { 0x0BU, 0x06U, 0x76U, 0x61U, 0x6CU, 0x75U, 0x65U, 0x00U, }}, - /* ==== WASM: 96 ==== */ + /* ==== WASM: 102 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter);