Compare commits

...

5 Commits

Author SHA1 Message Date
Ed Hennis
2c3f169dec Merge branch 'develop' into ximinez/emptydirectoryinvariant 2025-11-15 03:08:56 -05:00
Ed Hennis
23565405ee Merge branch 'develop' into ximinez/emptydirectoryinvariant 2025-11-13 12:20:06 -05:00
Ed Hennis
a5d08b0cd5 Merge branch 'develop' into ximinez/emptydirectoryinvariant 2025-11-12 14:17:02 -05:00
Ed Hennis
7bf3f543b3 Experiment: Always delete the root 2025-11-10 19:53:38 -05:00
Ed Hennis
c773288df5 Experiment: Add invariant to enforce directory node population 2025-11-10 19:53:38 -05:00
3 changed files with 65 additions and 1 deletions

View File

@@ -191,6 +191,7 @@ ApplyView::dirRemove(
uint256 const& key, uint256 const& key,
bool keepRoot) bool keepRoot)
{ {
keepRoot = false;
auto node = peek(keylet::page(directory, page)); auto node = peek(keylet::page(directory, page));
if (!node) if (!node)

View File

@@ -3096,4 +3096,42 @@ ValidVault::finalize(
return true; return true;
} }
//------------------------------------------------------------------------------
void
NoEmptyDirectory::visitEntry(
bool isDelete,
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after)
{
if (isDelete)
return;
if (before && before->getType() != ltDIR_NODE)
return;
if (after && after->getType() != ltDIR_NODE)
return;
if (!after->isFieldPresent(sfOwner))
// Not an account dir
return;
bad_ = after->at(sfIndexes).empty();
}
bool
NoEmptyDirectory::finalize(
STTx const& tx,
TER const result,
XRPAmount const,
ReadView const& view,
beast::Journal const& j)
{
if (bad_)
{
JLOG(j.fatal()) << "Invariant failed: empty owner directory.";
return false;
}
return true;
}
} // namespace ripple } // namespace ripple

View File

@@ -783,6 +783,30 @@ public:
beast::Journal const&); beast::Journal const&);
}; };
/**
* @brief Invariants: An account's directory should never be empty
*
*/
class NoEmptyDirectory
{
bool bad_ = false;
public:
void
visitEntry(
bool,
std::shared_ptr<SLE const> const&,
std::shared_ptr<SLE const> const&);
bool
finalize(
STTx const&,
TER const,
XRPAmount const,
ReadView const&,
beast::Journal const&);
};
// additional invariant checks can be declared above and then added to this // additional invariant checks can be declared above and then added to this
// tuple // tuple
using InvariantChecks = std::tuple< using InvariantChecks = std::tuple<
@@ -806,7 +830,8 @@ using InvariantChecks = std::tuple<
ValidPermissionedDEX, ValidPermissionedDEX,
ValidAMM, ValidAMM,
ValidPseudoAccounts, ValidPseudoAccounts,
ValidVault>; ValidVault,
NoEmptyDirectory>;
/** /**
* @brief get a tuple of all invariant checks * @brief get a tuple of all invariant checks