Appearance
Control APIs
This page documents the ten control Hook APIs: the functions that terminate hook execution, guard loops, and inspect or influence the hook's position and parameters within the hook chain.
All signatures are copied verbatim from hook/extern.h. Return codes reference the shared error table in ../../glossary.md; the values quoted below come from include/xrpl/hook/Enum.h and hook/error.h.
Execution-termination model
A hook is a WebAssembly function that returns control to the ledger in exactly one of two ways:
accept— the originating transaction is applied. Any state changes the hook wrote and any transactions it emitted are kept.rollback— the originating transaction is rejected. State changes and emitted transactions from this hook are discarded.
Both functions terminate the hook immediately: internally they set the hook's exit type and return the special sentinel codes RC_ACCEPT (-20) or RC_ROLLBACK (-19) to the VM, which stops execution. Code after an accept/rollback call in the same path never runs.
If a hook function returns normally (falls off the end of hook()) without calling either, the default exit type is ROLLBACK (see applyHook.cpp, where the result is initialised with exitType = ROLLBACK "unless the hook calls accept()"). Under the fixXahauV3 amendment the default becomes WASM_ERROR instead; either way, not calling accept rejects the transaction. Always call accept explicitly on the success path.
Each hook execution records a metadata entry (sfHookExecution) that captures the outcome (verified in applyHook.cpp):
sfHookResult— the exit type as auint8_t(ExitType:WASM_ERROR=1,ROLLBACK=2,ACCEPT=3;UNSET=0).sfHookReturnCode— theerror_codeyou passed toaccept/rollback, stored asuint64_t. Negative values are encoded by setting the most-significant bit (0x8000000000000000 + (-code)), so a returned-16appears as a large unsigned number.sfHookReturnString— the reason string you passed (see the per-function notes).sfHookInstructionCount,sfHookEmitCount,sfHookStateChangeCount,sfHookHash, etc.
This metadata is how off-ledger tooling learns why a hook accepted or rejected, so the error_code and reason string you pass are your primary debugging channel.
The guard system
WebAssembly on Xahau is metered by a guard mechanism rather than an open-ended gas counter (Guard-type hooks; HookApiVersion 0). Every loop must call _g at its very top, declaring the maximum number of iterations it will run. This makes worst-case execution cost statically computable, so the network can price a SetHook up front and guarantee that hooks halt.
Two enforcement points exist:
Install time (static validation). When a hook is set, the server runs the guard validator in
include/xrpl/hook/Guard.h(check_guard) over the WASM. It walks the code section and, for everyloopopcode (0x03), requires the immediately following instructions to be exactlyi32.const <guard_id>,i32.const <maxiter>,call _g. A loop that is missing this prologue, that specifiesmaxiter == 0, or that calls a function other than_gthere is rejected and theSetHookfails (log codes such asGUARD_MISSING). There is a hard limit of 1024 guard calls per hook.Run time (dynamic enforcement). During execution
_gcounts calls perguard_id. If a guarded loop exceeds its declaredmaxiter,_gsets the exit type toROLLBACKwith exit codeGUARD_VIOLATION(-16) and terminates the hook.GUARD_VIOLATIONin the metadata therefore means "a loop ran more times than it promised."
The developer-facing GUARD(maxiter) / GUARDM(maxiter, n) macros (in hook/macro.h) build the guard_id from the source line number so each loop gets a distinct id; see ../macros.md. You rarely call _g by hand except for the mandatory _g(1,1) at the top of hook().
Index
| Function | Purpose |
|---|---|
accept | Terminate the hook and let the originating transaction proceed. |
rollback | Terminate the hook and reject the originating transaction. |
_g | Loop/branch guard; required at the top of every loop. |
hook_account | Write the AccountID the hook is installed on. |
hook_hash | Write the WASM hash of a hook in the chain. |
hook_pos | Return this hook's position within the hook chain. |
hook_param | Read this hook's install-time parameter value by key. |
hook_param_set | Override a parameter for a later hook in the chain. |
hook_again | Request a weak (post-apply) re-execution of the hook. |
hook_skip | Skip (or un-skip) a named hook in the chain. |
Related documents
- ../../README.md — documentation index.
- ../../overview.md — hook execution model and lifecycle.
- ../../glossary.md — full error-code and term reference.
- ../../macros.md —
GUARD,ASSERT,NOPE,SBUF, and other helpers. - ../../best-practices.md — guarding loops and structuring accept/rollback.
- transaction.md — the
otxn_*originating-transaction APIs. - state.md — persistent state read/write.
- emit-and-etxn.md — emitting transactions from a hook.
- utility.md —
util_raddr,util_keylet, STO helpers.