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