ledger Hook APIs

This commit is contained in:
tequ
2025-09-23 14:53:50 +09:00
parent 22c71a9801
commit 3f65b57997
3 changed files with 91 additions and 34 deletions

View File

@@ -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<uint256, HookReturnCode>
ledger_nonce() const;
Expected<Keylet, HookReturnCode>
ledger_keylet(Keylet const& klLo, Keylet const& klHi) const;
/// state APIs
// state

View File

@@ -11,6 +11,7 @@
#include <ripple/protocol/STObject.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/tokens.h>
#include "ripple/basics/base_uint.h"
#include <cfenv>
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<uint256, HookReturnCode>
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<Keylet, HookReturnCode>
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<ripple::uint256> 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<std::shared_ptr<Transaction>, HookReturnCode>
HookAPI::emit(Slice const& txBlob) const
{

View File

@@ -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<std::chrono::seconds>(
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<ripple::uint256> 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();
}