mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-04 01:06:48 +00:00
fix M7
This commit is contained in:
@@ -497,6 +497,20 @@ AccountRootsDeletedClean::finalize(
|
||||
if (enforce)
|
||||
return false;
|
||||
}
|
||||
// An account should not be deleted with sponsorship fields
|
||||
if (after->isFieldPresent(sfSponsoredOwnerCount) ||
|
||||
after->isFieldPresent(sfSponsoringOwnerCount) ||
|
||||
after->isFieldPresent(sfSponsoringAccountCount) || after->isFieldPresent(sfSponsor))
|
||||
{
|
||||
JLOG(j.fatal()) << "Invariant failed: account deletion left "
|
||||
"behind a sponsorship field";
|
||||
XRPL_ASSERT(
|
||||
enforce,
|
||||
"xrpl::AccountRootsDeletedClean::finalize : "
|
||||
"deleted account has no sponsorship fields");
|
||||
if (enforce)
|
||||
return false;
|
||||
}
|
||||
// Simple types
|
||||
for (auto const& [keyletfunc, _1, _2] : directAccountKeylets)
|
||||
{
|
||||
@@ -849,10 +863,10 @@ ValidPseudoAccounts::visitEntry(
|
||||
// 1. Exactly one of the pseudo-account fields is set.
|
||||
// 2. The sequence number is not changed.
|
||||
// 3. The lsfDisableMaster, lsfDefaultRipple, and lsfDepositAuth
|
||||
// flags are set.
|
||||
// flags are set.
|
||||
// 4. The RegularKey is not set.
|
||||
// 5. The SponsoredOwnerCount, SponsoringOwnerCount, and
|
||||
// SponsorAccount fields are not set.
|
||||
// 5. The SponsoredOwnerCount, SponsoringOwnerCount, SponsoringAccountCount, Sponsor
|
||||
// fields are not set.
|
||||
{
|
||||
std::vector<SField const*> const& fields = getPseudoAccountFields();
|
||||
|
||||
@@ -880,7 +894,8 @@ ValidPseudoAccounts::visitEntry(
|
||||
errors_.emplace_back("pseudo-account has a regular key");
|
||||
}
|
||||
if (after->isFieldPresent(sfSponsoredOwnerCount) ||
|
||||
after->isFieldPresent(sfSponsoringOwnerCount) || after->isFieldPresent(sfSponsor))
|
||||
after->isFieldPresent(sfSponsoringOwnerCount) || after->isFieldPresent(sfSponsor) ||
|
||||
after->isFieldPresent(sfSponsoringAccountCount))
|
||||
{
|
||||
errors_.emplace_back("pseudo-account has a sponsorship field");
|
||||
}
|
||||
|
||||
@@ -277,6 +277,74 @@ class Invariants_test : public beast::unit_test::suite
|
||||
XRPAmount{},
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}});
|
||||
|
||||
doInvariantCheck(
|
||||
{{"account deletion left behind a sponsorship field"}},
|
||||
[&](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
auto const a1 = A1.id();
|
||||
auto const sleA1 = ac.view().peek(keylet::account(a1));
|
||||
if (!sleA1)
|
||||
return false;
|
||||
sleA1->at(sfBalance) = beast::zero;
|
||||
sleA1->setFieldU32(sfSponsoredOwnerCount, 1);
|
||||
|
||||
ac.view().erase(sleA1);
|
||||
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}});
|
||||
|
||||
doInvariantCheck(
|
||||
{{"account deletion left behind a sponsorship field"}},
|
||||
[&](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
auto const a1 = A1.id();
|
||||
auto const sleA1 = ac.view().peek(keylet::account(a1));
|
||||
if (!sleA1)
|
||||
return false;
|
||||
sleA1->at(sfBalance) = beast::zero;
|
||||
sleA1->setFieldU32(sfSponsoringOwnerCount, 1);
|
||||
|
||||
ac.view().erase(sleA1);
|
||||
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}});
|
||||
|
||||
doInvariantCheck(
|
||||
{{"account deletion left behind a sponsorship field"}},
|
||||
[&](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
auto const a1 = A1.id();
|
||||
auto const sleA1 = ac.view().peek(keylet::account(a1));
|
||||
if (!sleA1)
|
||||
return false;
|
||||
sleA1->at(sfBalance) = beast::zero;
|
||||
sleA1->setFieldU32(sfSponsoringAccountCount, 1);
|
||||
|
||||
ac.view().erase(sleA1);
|
||||
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}});
|
||||
|
||||
doInvariantCheck(
|
||||
{{"account deletion left behind a sponsorship field"}},
|
||||
[&](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
auto const a1 = A1.id();
|
||||
auto const sleA1 = ac.view().peek(keylet::account(a1));
|
||||
if (!sleA1)
|
||||
return false;
|
||||
sleA1->at(sfBalance) = beast::zero;
|
||||
sleA1->setAccountID(sfSponsor, A2.id());
|
||||
|
||||
ac.view().erase(sleA1);
|
||||
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}});
|
||||
|
||||
for (auto const& keyletInfo : directAccountKeylets)
|
||||
{
|
||||
// TODO: Use structured binding once LLVM 16 is the minimum
|
||||
@@ -1650,6 +1718,10 @@ class Invariants_test : public beast::unit_test::suite
|
||||
"pseudo-account has a sponsorship field",
|
||||
[](SLE::pointer& sle) { sle->at(sfSponsoringOwnerCount) = 1; },
|
||||
},
|
||||
{
|
||||
"pseudo-account has a sponsorship field",
|
||||
[](SLE::pointer& sle) { sle->at(sfSponsoringAccountCount) = 1; },
|
||||
},
|
||||
{
|
||||
"pseudo-account has a sponsorship field",
|
||||
[](SLE::pointer& sle) { sle->at(sfSponsor) = Account("sponsor").id(); },
|
||||
|
||||
Reference in New Issue
Block a user