mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
fix create->install fallthrough bug
This commit is contained in:
@@ -1590,6 +1590,9 @@ SetHook::setHook()
|
|||||||
std::optional<uint64_t> newHookOn;
|
std::optional<uint64_t> newHookOn;
|
||||||
std::optional<uint64_t> defHookOn;
|
std::optional<uint64_t> defHookOn;
|
||||||
|
|
||||||
|
// when hsoCREATE is invoked it populates this variable in case the hook definition already exists
|
||||||
|
// and the operation falls through into a hsoINSTALL operation instead
|
||||||
|
std::optional<ripple::uint256> createHookHash;
|
||||||
/**
|
/**
|
||||||
* This is the primary HookSet loop. We iterate the sfHooks array inside the txn
|
* This is the primary HookSet loop. We iterate the sfHooks array inside the txn
|
||||||
* each entry of this array is available as hookSetObj.
|
* each entry of this array is available as hookSetObj.
|
||||||
@@ -1606,16 +1609,23 @@ SetHook::setHook()
|
|||||||
{
|
{
|
||||||
oldDefKeylet = keylet::hookDefinition(oldHook->get().getFieldH256(sfHookHash));
|
oldDefKeylet = keylet::hookDefinition(oldHook->get().getFieldH256(sfHookHash));
|
||||||
oldDefSLE = view().peek(*oldDefKeylet);
|
oldDefSLE = view().peek(*oldDefKeylet);
|
||||||
|
if (oldDefSLE)
|
||||||
defNamespace = oldDefSLE->getFieldH256(sfHookNamespace);
|
defNamespace = oldDefSLE->getFieldH256(sfHookNamespace);
|
||||||
oldNamespace = oldHook->get().isFieldPresent(sfHookNamespace)
|
|
||||||
? oldHook->get().getFieldH256(sfHookNamespace)
|
if (oldHook->get().isFieldPresent(sfHookNamespace))
|
||||||
: *defNamespace;
|
oldNamespace = oldHook->get().getFieldH256(sfHookNamespace);
|
||||||
|
else if (defNamespace)
|
||||||
|
oldNamespace = *defNamespace;
|
||||||
|
|
||||||
oldDirKeylet = keylet::hookStateDir(account_, *oldNamespace);
|
oldDirKeylet = keylet::hookStateDir(account_, *oldNamespace);
|
||||||
oldDirSLE = view().peek(*oldDirKeylet);
|
oldDirSLE = view().peek(*oldDirKeylet);
|
||||||
|
if (oldDefSLE)
|
||||||
defHookOn = oldDefSLE->getFieldU64(sfHookOn);
|
defHookOn = oldDefSLE->getFieldU64(sfHookOn);
|
||||||
oldHookOn = oldHook->get().isFieldPresent(sfHookOn)
|
|
||||||
? oldHook->get().getFieldU64(sfHookOn)
|
if (oldHook->get().isFieldPresent(sfHookOn))
|
||||||
: *defHookOn;
|
oldHookOn = oldHook->get().getFieldU64(sfHookOn);
|
||||||
|
else if (defHookOn)
|
||||||
|
oldHookOn = *defHookOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1744,11 +1754,11 @@ SetHook::setHook()
|
|||||||
return tecINTERNAL;
|
return tecINTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hash = ripple::sha512Half_s(
|
createHookHash = ripple::sha512Half_s(
|
||||||
ripple::Slice(wasmBytes.data(), wasmBytes.size())
|
ripple::Slice(wasmBytes.data(), wasmBytes.size())
|
||||||
);
|
);
|
||||||
|
|
||||||
auto keylet = ripple::keylet::hookDefinition(hash);
|
auto keylet = ripple::keylet::hookDefinition(*createHookHash);
|
||||||
|
|
||||||
|
|
||||||
if (view().exists(keylet))
|
if (view().exists(keylet))
|
||||||
@@ -1787,7 +1797,7 @@ SetHook::setHook()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto newHookDef = std::make_shared<SLE>( keylet );
|
auto newHookDef = std::make_shared<SLE>( keylet );
|
||||||
newHookDef->setFieldH256(sfHookHash, hash);
|
newHookDef->setFieldH256(sfHookHash, *createHookHash);
|
||||||
newHookDef->setFieldU64( sfHookOn, *newHookOn);
|
newHookDef->setFieldU64( sfHookOn, *newHookOn);
|
||||||
newHookDef->setFieldH256( sfHookNamespace, *newNamespace);
|
newHookDef->setFieldH256( sfHookNamespace, *newNamespace);
|
||||||
newHookDef->setFieldArray( sfHookParameters,
|
newHookDef->setFieldArray( sfHookParameters,
|
||||||
@@ -1800,7 +1810,7 @@ SetHook::setHook()
|
|||||||
newHookDef->setFieldU64( sfReferenceCount, 1);
|
newHookDef->setFieldU64( sfReferenceCount, 1);
|
||||||
newHookDef->setFieldAmount(sfFee, XRPAmount {hook::computeExecutionFee(maxInstrCount)} );
|
newHookDef->setFieldAmount(sfFee, XRPAmount {hook::computeExecutionFee(maxInstrCount)} );
|
||||||
view().insert(newHookDef);
|
view().insert(newHookDef);
|
||||||
newHook.setFieldH256(sfHookHash, hash);
|
newHook.setFieldH256(sfHookHash, *createHookHash);
|
||||||
newHooks.push_back(std::move(newHook));
|
newHooks.push_back(std::move(newHook));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1832,9 +1842,11 @@ SetHook::setHook()
|
|||||||
if (oldHook && reduceReferenceCount(oldDefSLE))
|
if (oldHook && reduceReferenceCount(oldDefSLE))
|
||||||
defsToDestroy.emplace(*oldDefKeylet);
|
defsToDestroy.emplace(*oldDefKeylet);
|
||||||
|
|
||||||
// set the hookhash on the new hook
|
// set the hookhash on the new hook, and allow for a fall through event from hsoCREATE
|
||||||
uint256 const& hash = hookSetObj->getFieldH256(sfHookHash);
|
if (!createHookHash)
|
||||||
newHook.setFieldH256(sfHookHash, hash);
|
createHookHash = hookSetObj->getFieldH256(sfHookHash);
|
||||||
|
|
||||||
|
newHook.setFieldH256(sfHookHash, *createHookHash);
|
||||||
|
|
||||||
// increment reference count of target HookDefintion
|
// increment reference count of target HookDefintion
|
||||||
incrementReferenceCount(newDefSLE);
|
incrementReferenceCount(newDefSLE);
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ Transactor::calculateHookChainFee(ReadView const& view, STTx const& tx, Keylet c
|
|||||||
{
|
{
|
||||||
ripple::STObject const* hookObj = dynamic_cast<ripple::STObject const*>(&hook);
|
ripple::STObject const* hookObj = dynamic_cast<ripple::STObject const*>(&hook);
|
||||||
|
|
||||||
if (hookObj->getCount() == 0 || !hookObj->isFieldPresent(sfHookHash)) // skip blanks
|
if (!hookObj->isFieldPresent(sfHookHash)) // skip blanks
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint256 const& hash = hookObj->getFieldH256(sfHookHash);
|
uint256 const& hash = hookObj->getFieldH256(sfHookHash);
|
||||||
@@ -960,7 +960,7 @@ executeHookChain(
|
|||||||
{
|
{
|
||||||
ripple::STObject const* hookObj = dynamic_cast<ripple::STObject const*>(&hook);
|
ripple::STObject const* hookObj = dynamic_cast<ripple::STObject const*>(&hook);
|
||||||
|
|
||||||
if (hookObj->getCount() == 0 || !hookObj->isFieldPresent(sfHookHash)) // skip blanks
|
if (!hookObj->isFieldPresent(sfHookHash)) // skip blanks
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// lookup hook definition
|
// lookup hook definition
|
||||||
@@ -976,9 +976,10 @@ executeHookChain(
|
|||||||
auto const& hookDef = ctx.view().peek(keylet::hookDefinition(hookHash));
|
auto const& hookDef = ctx.view().peek(keylet::hookDefinition(hookHash));
|
||||||
if (!hookDef)
|
if (!hookDef)
|
||||||
{
|
{
|
||||||
JLOG(j_.fatal())
|
JLOG(j_.warn())
|
||||||
<< "HookError[]: Failure: hook def missing (send)";
|
<< "HookError[]: Failure: hook def missing (send)";
|
||||||
return true;
|
// return true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the hook can fire
|
// check if the hook can fire
|
||||||
@@ -1150,7 +1151,7 @@ Transactor::operator()()
|
|||||||
|
|
||||||
STObject const* hookObj = dynamic_cast<STObject const*>(&hook);
|
STObject const* hookObj = dynamic_cast<STObject const*>(&hook);
|
||||||
|
|
||||||
if (hookObj->getCount() == 0 || !hookObj->isFieldPresent(sfHookHash)) // skip blanks
|
if (!hookObj->isFieldPresent(sfHookHash)) // skip blanks
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hookObj->getFieldH256(sfHookHash) != callbackHookHash)
|
if (hookObj->getFieldH256(sfHookHash) != callbackHookHash)
|
||||||
|
|||||||
Reference in New Issue
Block a user