mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
fix txmeta issues
This commit is contained in:
@@ -2,6 +2,27 @@
|
||||
#include <string>
|
||||
#ifndef HOOKENUM_INCLUDED
|
||||
#define HOOKENUM_INCLUDED 1
|
||||
namespace ripple
|
||||
{
|
||||
enum HookSetOperation : int8_t
|
||||
{
|
||||
hsoINVALID = -1,
|
||||
hsoNOOP = 0,
|
||||
hsoCREATE = 1,
|
||||
hsoINSTALL = 2,
|
||||
hsoDELETE = 3,
|
||||
hsoNSDELETE = 4,
|
||||
hsoUPDATE = 5
|
||||
};
|
||||
|
||||
enum HookSetFlags : uint8_t
|
||||
{
|
||||
hsfOVERRIDE = 0b00000001U, // override or delete hook
|
||||
hsfNSDELETE = 0b00000010U, // delete namespace
|
||||
hsfCOLLECT = 0b00000100U, // allow collect calls on this hook
|
||||
};
|
||||
}
|
||||
|
||||
namespace hook
|
||||
{
|
||||
enum TSHFlags : uint8_t
|
||||
@@ -11,6 +32,7 @@ namespace hook
|
||||
tshCOLLECT = 0b010,
|
||||
};
|
||||
|
||||
|
||||
namespace log
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -247,7 +247,7 @@ validateHookSetEntry(SetHookCtx& ctx, STObject const& hookSetObj)
|
||||
}
|
||||
|
||||
|
||||
if (flags & ~(hsfOVERRIDE | hsfNSDELETE))
|
||||
if (flags & ~(hsfOVERRIDE | hsfNSDELETE | hsfCOLLECT))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "HookSet(" << hook::log::FLAGS_INVALID << ")[" << HS_ACC()
|
||||
@@ -994,7 +994,7 @@ SetHook::setHook()
|
||||
* so a degree of copying is required.
|
||||
*/
|
||||
|
||||
uint32_t flags = 0;
|
||||
std::optional<uint32_t> flags;
|
||||
|
||||
if (hookSetObj && hookSetObj->get().isFieldPresent(sfFlags))
|
||||
flags = hookSetObj->get().getFieldU32(sfFlags);
|
||||
@@ -1004,6 +1004,18 @@ SetHook::setHook()
|
||||
|
||||
if (hookSetObj)
|
||||
op = inferOperation(hookSetObj->get());
|
||||
|
||||
|
||||
// these flags are not able to be passed onto the ledger object
|
||||
if (flags)
|
||||
{
|
||||
if (*flags & hsfOVERRIDE)
|
||||
*flags -= hsfOVERRIDE;
|
||||
|
||||
if (*flags & hsfNSDELETE)
|
||||
*flags -= hsfNSDELETE;
|
||||
}
|
||||
|
||||
|
||||
printf("HookSet operation %d: %s\n", hookSetNumber,
|
||||
(op == hsoNSDELETE ? "hsoNSDELETE" :
|
||||
@@ -1057,7 +1069,7 @@ SetHook::setHook()
|
||||
}
|
||||
|
||||
// users may destroy a namespace in any operation except NOOP and INVALID
|
||||
if (flags & hsfNSDELETE)
|
||||
if (flags && (*flags & hsfNSDELETE))
|
||||
{
|
||||
if (op == hsoNOOP || op == hsoINVALID)
|
||||
{
|
||||
@@ -1109,7 +1121,7 @@ SetHook::setHook()
|
||||
case hsoDELETE:
|
||||
{
|
||||
|
||||
if (!(flags & hsfOVERRIDE))
|
||||
if (!flags || !(*flags & hsfOVERRIDE))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "HookSet(" << hook::log::DELETE_FLAG << ")[" << HS_ACC()
|
||||
@@ -1162,6 +1174,11 @@ SetHook::setHook()
|
||||
if (hookSetObj->get().isFieldPresent(sfHookGrants))
|
||||
newHook.setFieldArray(sfHookGrants, hookSetObj->get().getFieldArray(sfHookGrants));
|
||||
|
||||
|
||||
if (flags)
|
||||
newHook.setFieldU32(sfFlags, *flags);
|
||||
|
||||
|
||||
newHooks.push_back(std::move(newHook));
|
||||
continue;
|
||||
}
|
||||
@@ -1169,7 +1186,7 @@ SetHook::setHook()
|
||||
|
||||
case hsoCREATE:
|
||||
{
|
||||
if (oldHook && oldHook->get().isFieldPresent(sfHookHash) && !(flags & hsfOVERRIDE))
|
||||
if (oldHook && oldHook->get().isFieldPresent(sfHookHash) && (!flags || !(*flags & hsfOVERRIDE)))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "HookSet(" << hook::log::CREATE_FLAG << ")[" << HS_ACC()
|
||||
@@ -1267,6 +1284,12 @@ SetHook::setHook()
|
||||
if (maxInstrCountCbak > 0)
|
||||
newHookDef->setFieldAmount(sfHookCallbackFee,
|
||||
XRPAmount {hook::computeExecutionFee(maxInstrCountCbak)});
|
||||
|
||||
if (flags)
|
||||
newHookDef->setFieldU32(sfFlags, *flags);
|
||||
else
|
||||
newHookDef->setFieldU32(sfFlags, 0);
|
||||
|
||||
view().insert(newHookDef);
|
||||
newHook.setFieldH256(sfHookHash, *createHookHash);
|
||||
newHooks.push_back(std::move(newHook));
|
||||
@@ -1279,7 +1302,7 @@ SetHook::setHook()
|
||||
// otherwise be created already exists on the ledger
|
||||
case hsoINSTALL:
|
||||
{
|
||||
if (oldHook && oldHook->get().isFieldPresent(sfHookHash) && !(flags & hsfOVERRIDE))
|
||||
if (oldHook && oldHook->get().isFieldPresent(sfHookHash) && (!flags || !(*flags & hsfOVERRIDE)))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "HookSet(" << hook::log::INSTALL_FLAG << ")[" << HS_ACC()
|
||||
@@ -1337,6 +1360,9 @@ SetHook::setHook()
|
||||
if (hookSetObj->get().isFieldPresent(sfHookGrants))
|
||||
newHook.setFieldArray(sfHookGrants, hookSetObj->get().getFieldArray(sfHookGrants));
|
||||
|
||||
if (flags)
|
||||
newHook.setFieldU32(sfFlags, *flags);
|
||||
|
||||
newHooks.push_back(std::move(newHook));
|
||||
|
||||
view().update(newDefSLE);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <ripple/app/hook/Enum.h>
|
||||
#include <ripple/app/hook/applyHook.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -45,24 +46,6 @@ struct SetHookCtx
|
||||
Application& app;
|
||||
};
|
||||
|
||||
enum HookSetOperation : int8_t
|
||||
{
|
||||
hsoINVALID = -1,
|
||||
hsoNOOP = 0,
|
||||
hsoCREATE = 1,
|
||||
hsoINSTALL = 2,
|
||||
hsoDELETE = 3,
|
||||
hsoNSDELETE = 4,
|
||||
hsoUPDATE = 5
|
||||
};
|
||||
|
||||
enum HookSetFlags : uint8_t
|
||||
{
|
||||
hsfOVERRIDE = (1U << 0U), // override or delete hook
|
||||
hsfNSDELETE = (1U << 1U), // delete namespace
|
||||
};
|
||||
|
||||
|
||||
class SetHook : public Transactor
|
||||
{
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <ripple/ledger/PaymentSandbox.h>
|
||||
#include <ripple/ledger/detail/ApplyViewBase.h>
|
||||
#include <ripple/app/hook/Enum.h>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
|
||||
@@ -156,7 +157,8 @@ Transactor::
|
||||
calculateHookChainFee(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
Keylet const& hookKeylet)
|
||||
Keylet const& hookKeylet,
|
||||
bool collectCallsOnly)
|
||||
{
|
||||
|
||||
std::shared_ptr<SLE const> hookSLE = view.read(hookKeylet);
|
||||
@@ -191,11 +193,20 @@ calculateHookChainFee(
|
||||
? hookObj->getFieldU64(sfHookOn)
|
||||
: hookDef->getFieldU64(sfHookOn));
|
||||
|
||||
if (hook::canHook(tx.getTxnType(), hookOn))
|
||||
uint32_t flags = 0;
|
||||
if (hookObj->isFieldPresent(sfFlags))
|
||||
flags = hookObj->getFieldU32(sfFlags);
|
||||
else
|
||||
flags = hookDef->getFieldU32(sfFlags);
|
||||
|
||||
if (hook::canHook(tx.getTxnType(), hookOn) &&
|
||||
((collectCallsOnly && (flags & hook::hsfCOLLECT)) ||
|
||||
(!collectCallsOnly && !(flags & hook::hsfCOLLECT)))
|
||||
)
|
||||
{
|
||||
fee += FeeUnit64{
|
||||
(uint32_t)(hookDef->getFieldAmount(sfFee).xrp().drops())
|
||||
};
|
||||
fee += FeeUnit64{
|
||||
(uint32_t)(hookDef->getFieldAmount(sfFee).xrp().drops())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -948,6 +959,13 @@ executeHookChain(
|
||||
if (!hook::canHook(ctx_.tx.getTxnType(), hookOn))
|
||||
continue; // skip if it can't
|
||||
|
||||
uint32_t flags = (hookObj->isFieldPresent(sfFlags) ?
|
||||
hookObj->getFieldU32(sfFlags) : hookDef->getFieldU32(sfFlags));
|
||||
|
||||
// skip weakly executed hooks that lack a collect flag
|
||||
if (!strong && !(flags & hsfCOLLECT))
|
||||
continue;
|
||||
|
||||
// fetch the namespace either from the hook object of, if absent, the hook def
|
||||
uint256 const& ns =
|
||||
(hookObj->isFieldPresent(sfHookNamespace)
|
||||
@@ -1240,7 +1258,7 @@ doTSH(
|
||||
|
||||
// compute and deduct fees for the TSH if applicable
|
||||
FeeUnit64 tshFee =
|
||||
calculateHookChainFee(view, ctx_.tx, klTshHook);
|
||||
calculateHookChainFee(view, ctx_.tx, klTshHook, !canRollback);
|
||||
|
||||
// no hooks to execute, skip tsh
|
||||
if (tshFee == 0)
|
||||
@@ -1614,8 +1632,11 @@ Transactor::operator()()
|
||||
{
|
||||
// weakly executed hooks have access to a provisional TxMeta
|
||||
// for this tx application.
|
||||
TxMeta meta = ctx_.generateProvisionalMeta();
|
||||
meta.setResult(result, 0);
|
||||
|
||||
std::shared_ptr<STObject const>
|
||||
proMeta = std::make_shared<STObject const>(std::move(ctx_.generateProvisionalMeta().getAsObject()));
|
||||
proMeta = std::make_shared<STObject const>(std::move(meta.getAsObject()));
|
||||
|
||||
// perform callback logic if applicable
|
||||
if (ctx_.tx.isFieldPresent(sfEmitDetails))
|
||||
|
||||
@@ -186,7 +186,8 @@ public:
|
||||
// Hooks
|
||||
|
||||
static FeeUnit64
|
||||
calculateHookChainFee(ReadView const& view, STTx const& tx, Keylet const& hookKeylet);
|
||||
calculateHookChainFee(ReadView const& view, STTx const& tx, Keylet const& hookKeylet,
|
||||
bool collectCallsOnly = false);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -75,6 +75,9 @@ public:
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
void
|
||||
setResult(TER res, int index);
|
||||
|
||||
void
|
||||
setAffectedNode(uint256 const&, SField const& type, std::uint16_t nodeType);
|
||||
STObject&
|
||||
|
||||
@@ -207,6 +207,14 @@ TxMeta::getAffectedNode(uint256 const& node)
|
||||
return *(mNodes.begin()); // Silence compiler warning.
|
||||
}
|
||||
|
||||
// used for mock TxMeta objects
|
||||
void
|
||||
TxMeta::setResult(TER res, int index)
|
||||
{
|
||||
mResult = TERtoInt(res);
|
||||
mIndex = index;
|
||||
}
|
||||
|
||||
STObject
|
||||
TxMeta::getAsObject() const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user