This commit is contained in:
tequ
2025-09-29 16:48:19 +09:00
parent cf59180660
commit bf9765753f
3 changed files with 131 additions and 15 deletions

View File

@@ -2497,21 +2497,14 @@ public:
OpenView ov{*env.current()};
ApplyContext applyCtx = createApplyContext(env, ov, invokeTx);
hook::HookStateMap stateMap;
auto hookCtx = hook::HookContext{
.applyCtx = applyCtx,
.expected_etxn_count = 1,
.nonce_used = {{uint256(0), true}},
.result =
{
.account = alice.id(),
.accountKeylet = keylet::account(alice),
.hookKeylet = keylet::hook(alice),
.stateMap = stateMap,
.hookParams = {{}},
},
};
auto hookCtx = makeStubHookContext(
applyCtx,
alice.id(),
alice.id(),
{
.expected_etxn_count = 1,
.nonce_used = {{uint256(0), true}},
});
hook::HookAPI api(hookCtx);
STTx emitTx = STTx(ttINVOKE, [&](STObject& obj) {

View File

@@ -20,9 +20,13 @@
#ifndef RIPPLE_TEST_JTX_HOOK_H_INCLUDED
#define RIPPLE_TEST_JTX_HOOK_H_INCLUDED
#include <ripple/app/hook/applyHook.h>
#include <ripple/json/json_value.h>
#include <cstdint>
#include <map>
#include <optional>
#include <test/jtx/Account.h>
#include <vector>
namespace ripple {
namespace test {
@@ -43,6 +47,66 @@ hso(std::string const& wasmHex, void (*f)(Json::Value& jv) = 0);
Json::Value
hso_delete(void (*f)(Json::Value& jv) = 0);
struct StubHookResult
{
ripple::uint256 const hookSetTxnID = ripple::uint256();
ripple::uint256 const hookHash = ripple::uint256();
ripple::uint256 const hookCanEmit = ripple::uint256();
ripple::uint256 const hookNamespace = ripple::uint256();
std::queue<std::shared_ptr<ripple::Transaction>> emittedTxn{};
std::optional<hook::HookStateMap> stateMap = std::nullopt;
uint16_t changedStateCount = 0;
std::map<
ripple::uint256, // hook hash
std::map<
std::vector<uint8_t>, // hook param name
std::vector<uint8_t> // hook param value
>>
hookParamOverrides = {};
std::optional<std::map<std::vector<uint8_t>, std::vector<uint8_t>>>
hookParams = std::nullopt;
std::set<ripple::uint256> hookSkips = {};
hook_api::ExitType exitType = hook_api::ExitType::ROLLBACK;
std::string exitReason{""};
int64_t exitCode{-1};
uint64_t instructionCount{0};
bool hasCallback = false;
bool isCallback = false;
bool isStrong = false;
uint32_t wasmParam = 0;
uint32_t overrideCount = 0;
uint8_t hookChainPosition = 0;
bool foreignStateSetDisabled = false;
bool executeAgainAsWeak = false;
std::shared_ptr<STObject const> provisionalMeta = nullptr;
};
struct StubHookContext
{
std::map<uint32_t, hook::SlotEntry> slot{};
std::queue<uint32_t> slot_free{};
uint32_t slot_counter{0};
uint16_t emit_nonce_counter{0};
uint16_t ledger_nonce_counter{0};
int64_t expected_etxn_count{-1};
std::map<ripple::uint256, bool> nonce_used{};
uint32_t generation = 0;
uint64_t burden = 0;
std::map<uint32_t, uint32_t> guard_map{};
StubHookResult result;
std::optional<ripple::STObject> emitFailure = std::nullopt;
const hook::HookExecutor* module = 0;
};
hook::HookContext
makeStubHookContext(
ripple::ApplyContext& applyCtx,
ripple::AccountID const& hookAccount,
ripple::AccountID const& otxnAccount,
StubHookContext const& stubHookContext);
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -18,7 +18,9 @@
//==============================================================================
#include <ripple/app/hook/Enum.h>
#include <ripple/app/hook/applyHook.h>
#include <ripple/basics/contract.h>
#include <ripple/protocol/Keylet.h>
#include <ripple/protocol/jss.h>
#include <stdexcept>
#include <test/jtx/hook.h>
@@ -102,6 +104,63 @@ hso(std::string const& wasmHex, void (*f)(Json::Value& jv))
return jv;
}
hook::HookContext
makeStubHookContext(
ripple::ApplyContext& applyCtx,
ripple::AccountID const& hookAccount,
ripple::AccountID const& otxnAccount,
StubHookContext const& stubHookContext)
{
auto& result = stubHookContext.result;
auto stateMap = result.stateMap.value_or(hook::HookStateMap{});
auto hookParams = result.hookParams.value_or(
std::map<std::vector<uint8_t>, std::vector<uint8_t>>{});
return hook::HookContext{
.applyCtx = applyCtx,
.slot = stubHookContext.slot,
.slot_free = stubHookContext.slot_free,
.slot_counter = stubHookContext.slot_counter,
.emit_nonce_counter = stubHookContext.emit_nonce_counter,
.ledger_nonce_counter = stubHookContext.ledger_nonce_counter,
.expected_etxn_count = stubHookContext.expected_etxn_count,
.nonce_used = stubHookContext.nonce_used,
.generation = stubHookContext.generation,
.burden = stubHookContext.burden,
.guard_map = stubHookContext.guard_map,
.result =
{
.hookSetTxnID = result.hookSetTxnID,
.hookHash = result.hookHash,
.hookCanEmit = ripple::uint256(),
.accountKeylet = keylet::account(hookAccount),
.hookKeylet = keylet::hook(hookAccount),
.account = hookAccount,
.otxnAccount = otxnAccount,
.hookNamespace = result.hookNamespace,
.emittedTxn = result.emittedTxn,
.stateMap = stateMap,
.changedStateCount = result.changedStateCount,
.hookParamOverrides = result.hookParamOverrides,
.hookParams = hookParams,
.hookSkips = result.hookSkips,
.exitType = result.exitType,
.exitReason = result.exitReason,
.exitCode = result.exitCode,
.instructionCount = result.instructionCount,
.hasCallback = result.hasCallback,
.isCallback = result.isCallback,
.isStrong = result.isStrong,
.wasmParam = result.wasmParam,
.overrideCount = result.overrideCount,
.hookChainPosition = result.hookChainPosition,
.foreignStateSetDisabled = result.foreignStateSetDisabled,
.executeAgainAsWeak = result.executeAgainAsWeak,
.provisionalMeta = result.provisionalMeta,
},
.emitFailure = stubHookContext.emitFailure,
.module = nullptr};
}
} // namespace jtx
} // namespace test
} // namespace ripple