fix: address PR reviewer comments

This commit is contained in:
Vito
2026-06-10 17:15:54 +02:00
parent cc4e2b412e
commit 66693fb7a4
3 changed files with 48 additions and 20 deletions

View File

@@ -399,7 +399,7 @@ public:
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
private:
SLE::const_pointer sle_;
std::vector<SLE::const_pointer> sles_;
};
// additional invariant checks can be declared above and then added to this
// tuple

View File

@@ -1078,14 +1078,20 @@ ObjectHasPseudoAccount::visitEntry(bool isDelete, SLE::const_ref before, SLE::co
// After should never be null when isDelete = false, if it is, something went horribly wrong
if (!after)
return;
{
XRPL_ASSERT(
after,
"xrpl::ObjectHasPseudoAccount::visitEntry : modified ledger entry missing after state");
return; // LCOV_EXCL_LINE
}
switch (after->getType())
{
case ltAMM:
case ltVAULT:
case ltLOAN_BROKER:
sle_ = after;
sles_.push_back(after);
break;
default:
return;
}
@@ -1102,28 +1108,33 @@ ObjectHasPseudoAccount::finalize(
if (!view.rules().enabled(fixCleanup3_3_0))
return true;
if (!sle_)
if (sles_.empty())
return true;
// For current ledger entry types, pseudo-account is identified by `sfAccount` field.
if (!sle_->isFieldPresent(sfAccount))
bool failed = false;
for (auto const& sle : sles_)
{
JLOG(j.fatal()) << "Invariant failed: ledger entry " << sle_->getSType()
<< " is missing pseudo-account field";
return false;
// For current ledger entry types, pseudo-account is identified by `sfAccount` field.
if (!sle->isFieldPresent(sfAccount))
{
JLOG(j.fatal()) << "Invariant failed: ledger entry " << sle->getSType()
<< " is missing pseudo-account field";
failed = true;
continue;
}
bool const exists = view.read(keylet::account(sle->getAccountID(sfAccount))) != nullptr;
// The pseudo-account must exist on the ledger
if (!exists)
{
JLOG(j.fatal()) << "Invariant failed: ledger entry " << sle->getSType()
<< " pseudo-account does not exist";
failed = true;
}
}
bool const exists = view.read(keylet::account(sle_->getAccountID(sfAccount))) != nullptr;
// The pseudo-account must exist on the ledger
if (!exists)
{
JLOG(j.fatal()) << "Invariant failed: ledger entry " << sle_->getSType()
<< " pseudo-account does not exist";
return false;
}
return true;
return !failed;
}
} // namespace xrpl

View File

@@ -4895,6 +4895,23 @@ class Invariants_test : public beast::unit_test::Suite
// An account that is never funded, so it won't exist in any view.
AccountID const ghostId = Account{"Ghost"}.id();
doInvariantCheck(
Env{*this, amendments},
{{"is missing pseudo-account field"}},
[](Account const& a1, Account const&, ApplyContext& ac) {
auto const brokerKeylet = keylet::loanbroker(a1.id(), ac.view().seq());
auto sle = std::make_shared<SLE>(brokerKeylet);
sle->makeFieldAbsent(sfAccount);
auto const page = ac.view().dirInsert(
keylet::ownerDir(a1.id()), sle->key(), describeOwnerDir(a1.id()));
if (!page)
return false;
sle->setFieldU64(sfOwnerNode, *page);
sle->setFieldU32(sfOwnerCount, 1);
ac.view().insert(sle);
return true;
});
// Vault: pseudo-account is referenced but does not exist on the ledger.
doInvariantCheck(
Env{*this, amendments},