diff --git a/src/ripple/app/hook/HookAPI.h b/src/ripple/app/hook/HookAPI.h index 4161ed8f8..3470d2c6e 100644 --- a/src/ripple/app/hook/HookAPI.h +++ b/src/ripple/app/hook/HookAPI.h @@ -164,12 +164,23 @@ public: hook_pos() const; /// ledger APIs - // fee_base - // ledger_seq - // ledger_last_hash - // ledger_last_time - // ledger_nonce - // ledger_keylet + uint64_t + fee_base() const; + + uint32_t + ledger_seq() const; + + uint256 + ledger_last_hash() const; + + uint64_t + ledger_last_time() const; + + Expected + ledger_nonce() const; + + Expected + ledger_keylet(Keylet const& klLo, Keylet const& klHi) const; /// state APIs // state diff --git a/src/ripple/app/hook/impl/HookAPI.cpp b/src/ripple/app/hook/impl/HookAPI.cpp index d47b59f94..84af7b3ca 100644 --- a/src/ripple/app/hook/impl/HookAPI.cpp +++ b/src/ripple/app/hook/impl/HookAPI.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "ripple/basics/base_uint.h" #include namespace hook { @@ -566,6 +567,61 @@ HookAPI::hook_pos() const return hookCtx.result.hookChainPosition; } +uint64_t +HookAPI::fee_base() const +{ + return hookCtx.applyCtx.view().fees().base.drops(); +} + +uint32_t +HookAPI::ledger_seq() const +{ + return hookCtx.applyCtx.view().info().seq; +} + +uint256 +HookAPI::ledger_last_hash() const +{ + return hookCtx.applyCtx.view().info().parentHash; +} + +Expected +HookAPI::ledger_nonce() const +{ + auto& view = hookCtx.applyCtx.view(); + if (hookCtx.ledger_nonce_counter > hook_api::max_nonce) + return Unexpected(TOO_MANY_NONCES); + + auto hash = ripple::sha512Half( + ripple::HashPrefix::hookNonce, + view.info().seq, + view.info().parentCloseTime.time_since_epoch().count(), + view.info().parentHash, + hookCtx.applyCtx.tx.getTransactionID(), + hookCtx.ledger_nonce_counter++, + hookCtx.result.account); + + return hash; +} + +Expected +HookAPI::ledger_keylet(Keylet const& klLo, Keylet const& klHi) const +{ + // keylets must be the same type! + if (klLo.type != klHi.type) + return Unexpected(DOES_NOT_MATCH); + + std::optional found = + hookCtx.applyCtx.view().succ(klLo.key, klHi.key.next()); + + if (!found) + return Unexpected(DOESNT_EXIST); + + Keylet kl_out{klLo.type, *found}; + + return kl_out; +} + Expected, HookReturnCode> HookAPI::emit(Slice const& txBlob) const { diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index 9d0680ff4..7d5d572cf 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -2302,7 +2302,8 @@ DEFINE_HOOK_FUNCNARG(int64_t, ledger_seq) { HOOK_SETUP(); - return view.info().seq; + hook::HookAPI api(hookCtx); + return api.ledger_seq(); HOOK_TEARDOWN(); } @@ -2320,7 +2321,8 @@ DEFINE_HOOK_FUNCTION( if (write_len < 32) return TOO_SMALL; - uint256 hash = view.info().parentHash; + hook::HookAPI api(hookCtx); + auto const hash = api.ledger_last_hash(); WRITE_WASM_MEMORY_AND_RETURN( write_ptr, write_len, hash.data(), 32, memory, memory_length); @@ -2332,9 +2334,8 @@ DEFINE_HOOK_FUNCNARG(int64_t, ledger_last_time) { HOOK_SETUP(); - return std::chrono::duration_cast( - view.info().parentCloseTime.time_since_epoch()) - .count(); + hook::HookAPI api(hookCtx); + return api.ledger_last_time(); HOOK_TEARDOWN(); } @@ -3342,17 +3343,11 @@ DEFINE_HOOK_FUNCTION( if (NOT_IN_BOUNDS(write_ptr, write_len, memory_length)) return OUT_OF_BOUNDS; - if (hookCtx.ledger_nonce_counter > hook_api::max_nonce) - return TOO_MANY_NONCES; - - auto hash = ripple::sha512Half( - ripple::HashPrefix::hookNonce, - view.info().seq, - view.info().parentCloseTime.time_since_epoch().count(), - view.info().parentHash, - applyCtx.tx.getTransactionID(), - hookCtx.ledger_nonce_counter++, - hookCtx.result.account); + hook::HookAPI api(hookCtx); + auto const result = api.ledger_nonce(); + if (!result) + return result.error(); + auto const& hash = result.value(); WRITE_WASM_MEMORY_AND_RETURN( write_ptr, 32, hash.data(), 32, memory, memory_length); @@ -3392,17 +3387,11 @@ DEFINE_HOOK_FUNCTION( if (!klHi) return INVALID_ARGUMENT; - // keylets must be the same type! - if ((*klLo).type != (*klHi).type) - return DOES_NOT_MATCH; - - std::optional found = - view.succ((*klLo).key, (*klHi).key.next()); - - if (!found) - return DOESNT_EXIST; - - Keylet kl_out{(*klLo).type, *found}; + hook::HookAPI api(hookCtx); + auto const result = api.ledger_keylet(*klLo, *klHi); + if (!result) + return result.error(); + auto kl_out = result.value(); return serialize_keylet(kl_out, memory, write_ptr, write_len); @@ -4203,7 +4192,8 @@ DEFINE_HOOK_FUNCNARG(int64_t, fee_base) HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx, // hookCtx on current stack - return view.fees().base.drops(); + hook::HookAPI api(hookCtx); + return api.fee_base(); HOOK_TEARDOWN(); }