diff --git a/src/ripple/app/hook/Enum.h b/src/ripple/app/hook/Enum.h index 67f3d0e36..72dffc6e1 100644 --- a/src/ripple/app/hook/Enum.h +++ b/src/ripple/app/hook/Enum.h @@ -324,13 +324,13 @@ namespace hook_api {"otxn_type",{0x7EU}}, {"otxn_slot",{0x7EU,0x7FU}}, {"otxn_param",{0x7EU,0x7FU,0x7FU,0x7FU,0x7FU}}, - {"meta_slot",{0x7EU,0x7FU}} + {"meta_slot",{0x7EU,0x7FU}} }; // featureHooks1 static const std::map> import_whitelist_1 { - + {"xpop_slot",{0x7EU,0x7FU,0x7FU}} }; }; #endif diff --git a/src/ripple/app/hook/applyHook.h b/src/ripple/app/hook/applyHook.h index 41f6285fd..04129650a 100644 --- a/src/ripple/app/hook/applyHook.h +++ b/src/ripple/app/hook/applyHook.h @@ -212,6 +212,7 @@ namespace hook_api uint32_t read_ptr, uint32_t read_len); DECLARE_HOOK_FUNCTION(int64_t, meta_slot, uint32_t slot_no ); + DECLARE_HOOK_FUNCTION(int64_t, xpop_slot, uint32_t slot_no_tx, uint32_t slot_no_meta ); /* DECLARE_HOOK_FUNCTION(int64_t, str_find, uint32_t hread_ptr, uint32_t hread_len, @@ -661,6 +662,7 @@ namespace hook ADD_HOOK_FUNCTION(trace_float, ctx); ADD_HOOK_FUNCTION(meta_slot, ctx); + ADD_HOOK_FUNCTION(xpop_slot, ctx); /* ADD_HOOK_FUNCTION(str_find, ctx); diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index 003af180a..dfbbb23cc 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -5508,6 +5508,69 @@ DEFINE_HOOK_FUNCTION( HOOK_TEARDOWN(); } +DEFINE_HOOK_FUNCTION( + int64_t, + xpop_slot, + uint32_t slot_into_tx, uint32_t slot_into_meta ) +{ + HOOK_SETUP(); + + if (applyCtx.tx.getFieldU16(sfTransactionType) != ttIMPORT) + return PREREQUISITE_NOT_MET; + + if (slot_into_tx > hook_api::max_slots || slot_into_meta > hook_api::max_slots) + return INVALID_ARGUMENT; + + size_t free_count = hookCtx.slot_free.size(); + + size_t needed_count = + slot_into_tx == 0 && slot_into_meta == 0 ? 2 : slot_into_tx != 0 && slot_into_meta != 0 ? 0 : 1; + + if (free_count < needed_count) + return NO_FREE_SLOTS; + + if (slot_into_tx == 0) + { + if (no_free_slots(hookCtx)) + return NO_FREE_SLOTS; + + if (auto found = get_free_slot(hookCtx); found) + slot_into_tx = *found; + else + return NO_FREE_SLOTS; + } + + if (slot_into_meta == 0) + { + if (no_free_slots(hookCtx)) + return NO_FREE_SLOTS; + + if (auto found = get_free_slot(hookCtx); found) + slot_into_meta = *found; + else + return NO_FREE_SLOTS; + } + + auto [tx, meta] = Import::getInnerTxn(applyCtx.tx, j); + + hookCtx.slot.emplace( std::pair { slot_into_tx, hook::SlotEntry { + .storage = std::move(tx), + .entry = 0 + }}); + + hookCtx.slot[slot_into_tx].entry = &(*hookCtx.slot[slot_into_tx].storage); + + hookCtx.slot.emplace( std::pair { slot_into_meta, hook::SlotEntry { + .storage = std::move(meta), + .entry = 0 + }}); + + hookCtx.slot[slot_into_meta].entry = &(*hookCtx.slot[slot_into_meta].storage); + + return (slot_into_tx << 16U) + slot_into_meta; + + HOOK_TEARDOWN(); +} /* DEFINE_HOOK_FUNCTION(