Compare commits

...

2 Commits

Author SHA1 Message Date
Richard Holland
0e0b9cc8aa fix for clang-16 builds 2026-10-11 17:21:47 +11:00
tequ
505c28768a Expose Hook API signatures, keylet types and return codes in server_definitions (#884) 2026-10-11 15:26:25 +10:00
6 changed files with 214 additions and 174 deletions

View File

@@ -22,29 +22,29 @@ APPLY_HOOK="$SCRIPT_DIR/../include/xrpl/hook/hook_api.macro"
return s;
}
{
line = $0;
# Skip block comments
if (line ~ /\/\*/) {
next;
}
# 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);
# Each entry is HOOK_API_DEFINITION(RET, NAME, (PARAMS), AMENDMENT),
# possibly spread over several lines. Collect until the parentheses
# balance, then split on the first two commas; the parameter tuple
# is the first parenthesised group.
function emit(s, i, ret, name, p, q, params) {
sub(/^[[:space:]]*HOOK_API_DEFINITION[[:space:]]*\(/, "", s);
gsub(/[[:space:]]+/, " ", s);
i = index(s, ","); ret = trim(substr(s, 1, i - 1)); s = substr(s, i + 1);
i = index(s, ","); name = trim(substr(s, 1, i - 1)); s = substr(s, i + 1);
p = index(s, "("); q = index(s, ")");
params = trim(substr(s, p + 1, q - p - 1));
if (name == "_g")
name = "__attribute__((noduplicate)) _g";
printf("extern %s %s(%s);\n\n", ret, name, params);
}
/^[[:space:]]*HOOK_API_DEFINITION[[:space:]]*\(/ { buf = ""; collecting = 1; }
collecting {
buf = buf " " $0;
if (gsub(/\(/, "(", buf) == gsub(/\)/, ")", buf)) {
collecting = 0;
emit(buf);
}
}
' "$APPLY_HOOK"

View File

@@ -404,6 +404,18 @@ const double fee_base_multiplier = 1.1f;
using APIWhitelist = std::map<std::string, std::vector<uint8_t>>;
namespace detail {
template <class T>
constexpr uint8_t wasmTypeCode = sizeof(T) == 8 ? 0x7EU : 0x7FU;
template <class R, class... Args>
std::vector<uint8_t>
wasmSignature(R (*)(Args...))
{
return {wasmTypeCode<R>, wasmTypeCode<Args>...};
}
} // namespace detail
// 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
@@ -415,25 +427,15 @@ getImportWhitelist(Rules const& rules)
#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__
#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};
whitelist[#FUNCTION_NAME] = \
detail::wasmSignature((RETURN_TYPE(*) PARAMS_TUPLE) nullptr);
#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;

View File

@@ -1,374 +1,301 @@
// int32_t _g(uint32_t guard_id, uint32_t maxiter);
// clang-format off
HOOK_API_DEFINITION(
int32_t, _g, (uint32_t, uint32_t),
int32_t, _g, (uint32_t guard_id, uint32_t maxiter),
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),
int64_t, accept, (uint32_t read_ptr, uint32_t read_len, int64_t error_code),
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),
int64_t, rollback, (uint32_t read_ptr, uint32_t read_len, int64_t error_code),
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),
int64_t, util_raddr, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
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),
int64_t, util_accid, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
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),
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),
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),
int64_t, util_sha512h, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
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),
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),
uint256{})
// int64_t sto_validate(uint32_t tread_ptr, uint32_t tread_len);
HOOK_API_DEFINITION(
int64_t, sto_validate, (uint32_t, uint32_t),
int64_t, sto_validate, (uint32_t tread_ptr, uint32_t tread_len),
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),
int64_t, sto_subfield, (uint32_t read_ptr, uint32_t read_len, uint32_t field_id),
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),
int64_t, sto_subarray, (uint32_t read_ptr, uint32_t read_len, uint32_t array_id),
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),
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),
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),
int64_t, sto_erase, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len, uint32_t field_id),
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),
int64_t, etxn_details, (uint32_t write_ptr, uint32_t write_len),
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),
int64_t, etxn_fee_base, (uint32_t read_ptr, uint32_t read_len),
uint256{})
// int64_t etxn_reserve(uint32_t count);
HOOK_API_DEFINITION(
int64_t, etxn_reserve, (uint32_t),
int64_t, etxn_reserve, (uint32_t count),
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),
int64_t, etxn_nonce, (uint32_t write_ptr, uint32_t write_len),
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),
int64_t, emit, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
uint256{})
// int64_t float_set(int32_t exponent, int64_t mantissa);
HOOK_API_DEFINITION(
int64_t, float_set, (int32_t, int64_t),
int64_t, float_set, (int32_t exponent, int64_t mantissa),
uint256{})
// int64_t float_multiply(int64_t float1, int64_t float2);
HOOK_API_DEFINITION(
int64_t, float_multiply, (int64_t, int64_t),
int64_t, float_multiply, (int64_t float1, int64_t float2),
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),
int64_t, float_mulratio, (int64_t float1, uint32_t round_up, uint32_t numerator, uint32_t denominator),
uint256{})
// int64_t float_negate(int64_t float1);
HOOK_API_DEFINITION(
int64_t, float_negate, (int64_t),
int64_t, float_negate, (int64_t float1),
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),
int64_t, float_compare, (int64_t float1, int64_t float2, uint32_t mode),
uint256{})
// int64_t float_sum(int64_t float1, int64_t float2);
HOOK_API_DEFINITION(
int64_t, float_sum, (int64_t, int64_t),
int64_t, float_sum, (int64_t float1, int64_t float2),
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),
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),
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),
int64_t, float_sto_set, (uint32_t read_ptr, uint32_t read_len),
uint256{})
// int64_t float_invert(int64_t float1);
HOOK_API_DEFINITION(
int64_t, float_invert, (int64_t),
int64_t, float_invert, (int64_t float1),
uint256{})
// int64_t float_divide(int64_t float1, int64_t float2);
HOOK_API_DEFINITION(
int64_t, float_divide, (int64_t, int64_t),
int64_t, float_divide, (int64_t float1, int64_t float2),
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),
int64_t, float_mantissa, (int64_t float1),
uint256{})
// int64_t float_sign(int64_t float1);
HOOK_API_DEFINITION(
int64_t, float_sign, (int64_t),
int64_t, float_sign, (int64_t float1),
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),
int64_t, float_int, (int64_t float1, uint32_t decimal_places, uint32_t abs),
uint256{})
// int64_t float_log(int64_t float1);
HOOK_API_DEFINITION(
int64_t, float_log, (int64_t),
int64_t, float_log, (int64_t float1),
uint256{})
// int64_t float_root(int64_t float1, uint32_t n);
HOOK_API_DEFINITION(
int64_t, float_root, (int64_t, uint32_t),
int64_t, float_root, (int64_t float1, uint32_t n),
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),
int64_t, ledger_last_hash, (uint32_t write_ptr, uint32_t write_len),
uint256{})
// int64_t ledger_nonce(uint32_t write_ptr, uint32_t write_len);
HOOK_API_DEFINITION(
int64_t, ledger_nonce, (uint32_t, uint32_t),
int64_t, ledger_nonce, (uint32_t write_ptr, uint32_t write_len),
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),
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),
uint256{})
// int64_t hook_account(uint32_t write_ptr, uint32_t write_len);
HOOK_API_DEFINITION(
int64_t, hook_account, (uint32_t, uint32_t),
int64_t, hook_account, (uint32_t write_ptr, uint32_t write_len),
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),
int64_t, hook_hash, (uint32_t write_ptr, uint32_t write_len, int32_t hook_no),
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),
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),
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),
int64_t, hook_param, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
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),
int64_t, hook_skip, (uint32_t read_ptr, uint32_t read_len, uint32_t flags),
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),
int64_t, slot, (uint32_t write_ptr, uint32_t write_len, uint32_t slot),
uint256{})
// int64_t slot_clear(uint32_t slot);
HOOK_API_DEFINITION(
int64_t, slot_clear, (uint32_t),
int64_t, slot_clear, (uint32_t slot),
uint256{})
// int64_t slot_count(uint32_t slot);
HOOK_API_DEFINITION(
int64_t, slot_count, (uint32_t),
int64_t, slot_count, (uint32_t slot),
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),
int64_t, slot_set, (uint32_t read_ptr, uint32_t read_len, uint32_t slot),
uint256{})
// int64_t slot_size(uint32_t slot);
HOOK_API_DEFINITION(
int64_t, slot_size, (uint32_t),
int64_t, slot_size, (uint32_t slot),
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),
int64_t, slot_subarray, (uint32_t parent_slot, uint32_t array_id, uint32_t new_slot),
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),
int64_t, slot_subfield, (uint32_t parent_slot, uint32_t field_id, uint32_t new_slot),
uint256{})
// int64_t slot_type(uint32_t slot_no, uint32_t flags);
HOOK_API_DEFINITION(
int64_t, slot_type, (uint32_t, uint32_t),
int64_t, slot_type, (uint32_t slot_no, uint32_t flags),
uint256{})
// int64_t slot_float(uint32_t slot_no);
HOOK_API_DEFINITION(
int64_t, slot_float, (uint32_t),
int64_t, slot_float, (uint32_t slot_no),
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),
int64_t, state_set, (uint32_t read_ptr, uint32_t read_len, uint32_t kread_ptr, uint32_t kread_len),
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),
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),
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),
int64_t, state, (uint32_t write_ptr, uint32_t write_len, uint32_t kread_ptr, uint32_t kread_len),
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),
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),
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),
int64_t, trace, (uint32_t mread_ptr, uint32_t mread_len, uint32_t dread_ptr, uint32_t dread_len, uint32_t as_hex),
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),
int64_t, trace_num, (uint32_t read_ptr, uint32_t read_len, int64_t number),
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),
int64_t, trace_float, (uint32_t read_ptr, uint32_t read_len, int64_t float1),
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),
int64_t, otxn_field, (uint32_t write_ptr, uint32_t write_len, uint32_t field_id),
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),
int64_t, otxn_id, (uint32_t write_ptr, uint32_t write_len, uint32_t flags),
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),
int64_t, otxn_slot, (uint32_t slot_no),
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),
int64_t, otxn_param, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
uint256{})
// int64_t meta_slot(uint32_t slot_no);
HOOK_API_DEFINITION(
int64_t, meta_slot, (uint32_t),
int64_t, meta_slot, (uint32_t slot_no),
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),
int64_t, xpop_slot, (uint32_t slot_no_tx, uint32_t slot_no_meta),
featureHooksUpdate1)
// int64_t prepare(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len);
HOOK_API_DEFINITION(
int64_t, prepare, (uint32_t, uint32_t, uint32_t, uint32_t),
int64_t, prepare, (uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len),
featureHooksUpdate2)
// clang-format on

View File

@@ -47,6 +47,7 @@ JSS(AL_hit_rate); // out: GetCounts
JSS(AcceptedCredentials); // out: AccountObjects
JSS(Account); // in: TransactionSign; field.
JSS(AMMID); // field
JSS(API); // out: RPC server_definitions (HOOK)
JSS(Amount); // in: TransactionSign; field.
JSS(Authorize); // field
JSS(Amount2); // in/out: AMM IOU/XRP pool, deposit, withdraw amount
@@ -68,6 +69,9 @@ JSS(Destination); // in: TransactionSign; field.
JSS(EPrice); // in: AMM Deposit option
JSS(Fee); // in/out: TransactionSign; field.
JSS(FIELDS); // out: RPC server_definitions
JSS(HOOK); // out: RPC server_definitions
JSS(KEYLET_TYPES); // out: RPC server_definitions (HOOK)
JSS(RETURN_CODES); // out: RPC server_definitions (HOOK)
JSS(Flags); // in/out: TransactionSign; field.
JSS(GenesisMints);
JSS(GovernanceMarks);

View File

@@ -103,6 +103,35 @@ public:
BEAST_EXPECT(fieldNames.insert(name).second);
}
}
// hook api, keylet types and return codes
{
auto const& hook = result[jss::result][jss::HOOK];
BEAST_EXPECT(hook.isMember(jss::API));
BEAST_EXPECT(hook.isMember(jss::KEYLET_TYPES));
BEAST_EXPECT(hook.isMember(jss::RETURN_CODES));
auto const& accept = hook[jss::API]["accept"];
BEAST_EXPECT(accept["return"] == "int64_t");
BEAST_EXPECT(accept["params"].size() == 3);
BEAST_EXPECT(accept["params"][0u][jss::type] == "uint32_t");
BEAST_EXPECT(accept["params"][0u][jss::name] == "read_ptr");
BEAST_EXPECT(accept["params"][2u][jss::type] == "int64_t");
BEAST_EXPECT(accept["params"][2u][jss::name] == "error_code");
BEAST_EXPECT(!accept.isMember("amendment"));
auto const& burden = hook[jss::API]["etxn_burden"];
BEAST_EXPECT(burden["params"].size() == 0);
auto const& xpop = hook[jss::API]["xpop_slot"];
BEAST_EXPECT(xpop["amendment"] == "HooksUpdate1");
BEAST_EXPECT(hook[jss::KEYLET_TYPES]["HOOK"] == 1);
BEAST_EXPECT(hook[jss::KEYLET_TYPES]["MANIFEST"] == 37);
BEAST_EXPECT(hook[jss::RETURN_CODES]["SUCCESS"] == 0);
BEAST_EXPECT(hook[jss::RETURN_CODES]["INVALID_FLOAT"] == -10024);
BEAST_EXPECT(hook[jss::RETURN_CODES]["TOO_MANY_NAMESPACES"] == -45);
}
}
void
@@ -132,6 +161,7 @@ public:
BEAST_EXPECT(
!result[jss::result].isMember(jss::TRANSACTION_FLAGS_INDICES));
BEAST_EXPECT(!result[jss::result].isMember(jss::TYPES));
BEAST_EXPECT(!result[jss::result].isMember(jss::HOOK));
BEAST_EXPECT(result[jss::result].isMember(jss::hash));
}
@@ -156,6 +186,7 @@ public:
BEAST_EXPECT(
result[jss::result].isMember(jss::TRANSACTION_FLAGS_INDICES));
BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::HOOK));
BEAST_EXPECT(result[jss::result].isMember(jss::hash));
}
}

View File

@@ -24,6 +24,7 @@
#include <xrpld/app/misc/NetworkOPs.h>
#include <xrpld/core/Config.h>
#include <xrpld/rpc/detail/TransactionSign.h>
#include <xrpl/hook/Enum.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/json_writer.h>
#include <xrpl/protocol/TxFlags.h>
@@ -60,6 +61,14 @@ MAGIC_ENUM_FLAG(ripple::NFTokenCreateOfferFlags);
MAGIC_ENUM_FLAG(ripple::ClaimRewardFlags);
MAGIC_ENUM_16(ripple::AccountFlags);
// hook_return_code spans [-10024, 0] because of INVALID_FLOAT
template <>
struct magic_enum::customize::enum_range<hook_api::hook_return_code>
{
static constexpr int min = -10024;
static constexpr int max = 0;
};
namespace ripple {
class Definitions
@@ -83,6 +92,50 @@ private:
}
}
template <typename EnumType>
void
addEnumToJson(Json::Value& json)
{
json = Json::objectValue;
// No structured binding: STR() is a lambda, and capturing a
// binding needs P1091 (Clang 16+).
for (auto const& entry : magic_enum::enum_entries<EnumType>())
{
auto const name = entry.second;
json[STR(name)] = static_cast<Json::Int>(entry.first);
}
}
// params is the stringified C parameter list, e.g.
// "(uint32_t read_ptr, uint32_t read_len)"
void
addHookApi(
Json::Value& json,
std::string const& returnType,
std::string const& name,
std::string params,
uint256 const& amendment)
{
Json::Value& fn = json[name];
fn["return"] = returnType;
fn["params"] = Json::arrayValue;
boost::trim_if(params, boost::is_any_of("() "));
std::vector<std::string> parts;
if (!params.empty())
boost::split(parts, params, boost::is_any_of(","));
for (auto& part : parts)
{
boost::trim(part);
auto const sp = part.rfind(' ');
Json::Value p = Json::objectValue;
p[jss::type] = part.substr(0, sp);
p[jss::name] = part.substr(sp + 1);
fn["params"].append(p);
}
if (amendment != uint256{})
fn["amendment"] = featureToName(amendment);
}
Json::Value
generate()
{
@@ -385,6 +438,29 @@ private:
ret[jss::native_currency_code] = systemCurrencyCode();
// Hook API: enough to regenerate hook/extern.h, hookapi.h keylet
// constants and error.h without the xahaud source tree.
Json::Value& hook = ret[jss::HOOK];
hook = Json::objectValue;
hook[jss::API] = Json::objectValue;
#pragma push_macro("HOOK_API_DEFINITION")
#undef HOOK_API_DEFINITION
#define HOOK_API_DEFINITION( \
RETURN_TYPE, FUNCTION_NAME, PARAMS_TUPLE, AMENDMENT) \
addHookApi( \
hook[jss::API], \
#RETURN_TYPE, \
#FUNCTION_NAME, \
#PARAMS_TUPLE, \
AMENDMENT);
#include <xrpl/hook/hook_api.macro>
#undef HOOK_API_DEFINITION
#pragma pop_macro("HOOK_API_DEFINITION")
addEnumToJson<hook_api::keylet_code::keylet_code>(
hook[jss::KEYLET_TYPES]);
addEnumToJson<hook_api::hook_return_code>(hook[jss::RETURN_CODES]);
// generate hash
{
const std::string out = Json::FastWriter().write(ret);