add sfHookNamespaces array to account root

This commit is contained in:
Richard Holland
2022-03-11 13:02:10 +00:00
parent 918472fa47
commit 46130fe14f
6 changed files with 96 additions and 39 deletions

View File

@@ -1467,11 +1467,13 @@ SetHook::destroyNamespace(
SetHookCtx& ctx,
ApplyView& view,
const AccountID& account,
const Keylet & dirKeylet // the keylet of the namespace directory
uint256 ns
) {
JLOG(ctx.j.trace())
<< "HookSet[" << HS_ACC() << "]: DeleteState "
<< "Destroying Hook Namespace for " << account << " namespace keylet " << dirKeylet.key;
<< "Destroying Hook Namespace for " << account << " namespace " << ns;
Keylet dirKeylet = keylet::hookStateDir(account, ns);
std::shared_ptr<SLE const> sleDirNode{};
unsigned int uDirEntry{0};
@@ -1506,7 +1508,7 @@ SetHook::destroyNamespace(
uint32_t stateCount =sleAccount->getFieldU32(sfHookStateCount);
uint32_t oldStateCount = stateCount;
std::vector<std::optional<uint256>> toDelete {sleDir->getFieldV256(sfIndexes).size()};
std::vector<uint256> toDelete {sleDir->getFieldV256(sfIndexes).size()};
do
{
// Make sure any directory node types that we find are the kind
@@ -1535,7 +1537,8 @@ SetHook::destroyNamespace(
return tefBAD_LEDGER;
}
toDelete.push_back(uint256::fromVoidChecked(itemKeylet.key));
toDelete.push_back(uint256::fromVoid(itemKeylet.key.data()));
} while (cdirNext(view, dirKeylet.key, sleDirNode, uDirEntry, dirEntry));
@@ -1543,30 +1546,20 @@ SetHook::destroyNamespace(
// delete it!
for (auto const& itemKey: toDelete)
{
// should never happen
if (!itemKey)
{
JLOG(ctx.j.fatal())
<< "HookSet[" << HS_ACC() << "]: DeleteState "
<< "directory entry in ledger " << view.seq() << " "
<< "was invalid key fromVoidChecked.";
return tefBAD_LEDGER;
}
auto const& sleItem = view.peek({ltHOOK_STATE, *itemKey});
auto const& sleItem = view.peek({ltHOOK_STATE, itemKey});
if (!sleItem)
{
JLOG(ctx.j.warn())
<< "HookSet[" << HS_ACC() << "]: DeleteState "
<< "Namespace ltHOOK_STATE entry was not found in ledger: "
<< *itemKey;
<< itemKey;
continue;
}
auto const hint = (*sleItem)[sfOwnerNode];
if (!itemKey || !view.dirRemove(dirKeylet, hint, *itemKey, false))
if (!view.dirRemove(dirKeylet, hint, itemKey, false))
{
JLOG(ctx.j.fatal())
<< "HookSet[" << HS_ACC() << "]: DeleteState "
@@ -1589,6 +1582,24 @@ SetHook::destroyNamespace(
sleAccount->setFieldU32(sfHookStateCount, stateCount);
STVector256 const& vec = sleAccount->getFieldV256(sfHookNamespaces);
if (vec.size() - 1 == 0)
{
sleAccount->makeFieldAbsent(sfHookNamespaces);
}
else
{
std::vector<uint256> nv { vec.size() - 1 };
for (uint256 u : vec.value())
if (u != ns)
nv.push_back(u);
sleAccount->setFieldV256(sfHookNamespaces, STVector256 { std::move(nv) } );
}
view.update(sleAccount);
return tesSUCCESS;
}
@@ -1648,7 +1659,7 @@ createOrReuseNamespace(ripple::Keylet& newDirKeylet)
return tesSUSCCESS;
}
//if (oldDirSLE)
// reduceReferenceCount(oldDirSLE, (flag & hsoNSDELETE) ? dirsToDestroy : std::nullopt);
// reduceReferenceCount(oldDirSLE, (flag & hsoNSDELETE) ? namespacesToDestroy : std::nullopt);
*/
TER
@@ -1768,7 +1779,7 @@ SetHook::setHook()
}
std::set<ripple::Keylet, KeyletComparator> defsToDestroy {};
std::set<ripple::Keylet, KeyletComparator> dirsToDestroy {};
std::set<uint256> namespacesToDestroy {};
int hookSetNumber = -1;
auto const& hookSets = ctx.tx.getFieldArray(sfHooks);
@@ -1888,12 +1899,12 @@ SetHook::setHook()
else if(op == hsoNSDELETE && newDirKeylet)
{
printf("Marking a namespace for destruction.... NSDELETE\n");
dirsToDestroy.emplace(*newDirKeylet);
namespacesToDestroy.emplace(*newNamespace);
}
else if (oldDirKeylet)
{
printf("Marking a namespace for destruction.... non-NSDELETE\n");
dirsToDestroy.emplace(*oldDirKeylet);
namespacesToDestroy.emplace(*oldNamespace);
}
else
{
@@ -2165,16 +2176,8 @@ SetHook::setHook()
{
// clean up any Namespace directories marked for deletion and any zero reference Hook Definitions
// dirs
for (auto const& p : dirsToDestroy)
{
auto const& sle = view().peek(p);
if (!sle)
continue;
printf("==>> Destroying namespace\n");
destroyNamespace(ctx, view(), account_, p);
}
for (auto const& ns : namespacesToDestroy)
destroyNamespace(ctx, view(), account_, ns);
// defs

View File

@@ -87,7 +87,7 @@ private:
SetHookCtx& ctx,
ApplyView& view,
const AccountID& account,
const Keylet & dirKeylet // the keylet of the namespace directory
uint256 ns
);
TER

View File

@@ -313,7 +313,7 @@ bool hook::canHook(ripple::TxType txType, uint64_t hookOn) {
}
// Update HookState ledger objects for the hook... only called after accept() or reject()
// Update HookState ledger objects for the hook... only called after accept() or rollback()
// assumes the specified acc has already been checked for authoriation (hook grants)
TER
hook::setHookState(
@@ -357,11 +357,12 @@ hook::setHookState(
return tefBAD_LEDGER;
auto const hint = (*hookState)[sfOwnerNode];
// Remove the node from the namespace directory
if (!view.dirRemove(hookStateDirKeylet, hint, hookStateKeylet.key, false))
return tefBAD_LEDGER;
bool nsDestroyed = !view.peek(hookStateDirKeylet);
// remove the actual hook state obj
view.erase(hookState);
@@ -374,7 +375,35 @@ hook::setHookState(
adjustOwnerCount(view, sleAccount, -1, j);
sleAccount->setFieldU32(sfHookStateCount, stateCount);
if (nsDestroyed)
{
STVector256 const& vec = sleAccount->getFieldV256(sfHookNamespaces);
if (vec.size() - 1 == 0)
sleAccount->makeFieldAbsent(sfHookNamespaces);
else
{
std::vector<uint256> nv { vec.size() - 1 };
for (uint256 u : vec.value())
if (u != ns)
nv.push_back(u);
sleAccount->setFieldV256(sfHookNamespaces, STVector256{std::move(nv)});
}
}
view.update(sleAccount);
/*
// if the root page of this namespace was removed then also remove the root page
// from the owner directory
if (!view.peek(hookStateDirKeylet) && rootHint)
{
if (!view.dirRemove(keylet::ownerDir(acc), *rootHint, hookStateDirKeylet.key, false))
return tefBAD_LEDGER;
}
*/
return tesSUCCESS;
}
@@ -418,22 +447,43 @@ hook::setHookState(
if (createNew)
{
// Add the hook to the account's directory if it wasn't there already
bool nsExists = !!view.peek(hookStateDirKeylet);
auto const page = view.dirInsert(
hookStateDirKeylet,
hookStateKeylet.key,
describeOwnerDir(acc));
if (!page)
return tecDIR_FULL;
hookState->setFieldU64(sfOwnerNode, *page);
// add new data to ledger
view.insert(hookState);
// update namespace vector where necessary
if (!nsExists)
{
if (!sleAccount->isFieldPresent(sfHookNamespaces))
{
sleAccount->setFieldV256(sfHookNamespaces, STVector256{std::vector<uint256>{ns}});
view.update(sleAccount);
}
else
{
STVector256 const& vec = sleAccount->getFieldV256(sfHookNamespaces);
std::vector<uint256> nv { vec.value() };
nv.push_back(ns);
sleAccount->setFieldV256(sfHookNamespaces, STVector256{std::move(nv)});
view.update(sleAccount);
}
}
}
else
{
view.update(hookState);
}
return tesSUCCESS;
}

View File

@@ -531,6 +531,7 @@ extern SF_VECTOR256 const sfIndexes;
extern SF_VECTOR256 const sfHashes;
extern SF_VECTOR256 const sfAmendments;
extern SF_VECTOR256 const sfTokenOffers;
extern SF_VECTOR256 const sfHookNamespaces;
// inner object
// OBJECT/1 is reserved for end of object

View File

@@ -54,7 +54,8 @@ LedgerFormats::LedgerFormats()
{sfDomain, soeOPTIONAL},
{sfTickSize, soeOPTIONAL},
{sfTicketCount, soeOPTIONAL},
{sfHookStateCount, soeOPTIONAL}
{sfHookStateCount, soeOPTIONAL},
{sfHookNamespaces, soeOPTIONAL}
},
commonFields);
@@ -68,6 +69,7 @@ LedgerFormats::LedgerFormats()
{sfTakerGetsIssuer, soeOPTIONAL}, // for order book directories
{sfExchangeRate, soeOPTIONAL}, // for order book directories
{sfReferenceCount, soeOPTIONAL}, // for hook state directories
{sfOwnerNode, soeOPTIONAL}, // for directories that are members of other directories
{sfIndexes, soeREQUIRED},
{sfRootIndex, soeREQUIRED},
{sfIndexNext, soeOPTIONAL},

View File

@@ -280,6 +280,7 @@ CONSTRUCT_TYPED_SFIELD(sfIndexes, "Indexes", VECTOR25
CONSTRUCT_TYPED_SFIELD(sfHashes, "Hashes", VECTOR256, 2);
CONSTRUCT_TYPED_SFIELD(sfAmendments, "Amendments", VECTOR256, 3);
CONSTRUCT_TYPED_SFIELD(sfTokenOffers, "TokenOffers", VECTOR256, 4);
CONSTRUCT_TYPED_SFIELD(sfHookNamespaces, "HookNamespaces", VECTOR256, 5);
// path set
CONSTRUCT_UNTYPED_SFIELD(sfPaths, "Paths", PATHSET, 1);