mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-04 09:16:47 +00:00
Add InvariantChecks for if OwnerCount < SponsoredOwnerCount
This commit is contained in:
@@ -101,7 +101,8 @@ class Invariants_test : public beast::unit_test::suite
|
||||
if (messages.find(m) == std::string::npos)
|
||||
{
|
||||
// uncomment if you want to log the invariant failure
|
||||
// std::cerr << " --> " << m << std::endl;
|
||||
// std::cerr << " expected --> " << m << std::endl;
|
||||
// std::cerr << " actual --> " << messages << std::endl;
|
||||
fail();
|
||||
}
|
||||
}
|
||||
@@ -3516,6 +3517,26 @@ class Invariants_test : public beast::unit_test::suite
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
auto const expect_message = "OwnerCount must be greater than or equal to SponsoredOwnerCount.";
|
||||
|
||||
doInvariantCheck({{expect_message}}, [&](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
sle->setFieldU32(sfOwnerCount, 0);
|
||||
sle->setFieldU32(sfSponsoredOwnerCount, 1);
|
||||
ac.view().update(sle);
|
||||
|
||||
auto const sle2 = ac.view().peek(keylet::account(A2.id()));
|
||||
if (!sle2)
|
||||
return false;
|
||||
sle2->setFieldU32(sfSponsoringOwnerCount, 1);
|
||||
ac.view().update(sle2);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
auto const expect_message =
|
||||
"Invariant failed: Net delta of SponsoringAccountCount does "
|
||||
|
||||
@@ -3287,6 +3287,17 @@ SponsorshipOwnerCountsMatch::visitEntry(
|
||||
return 0;
|
||||
};
|
||||
|
||||
auto getOwnerCount = [](std::shared_ptr<SLE const> const& sle) -> std::uint32_t {
|
||||
if (sle && sle->getType() == ltACCOUNT_ROOT)
|
||||
return sle->getFieldU32(sfOwnerCount);
|
||||
return 0;
|
||||
};
|
||||
auto getSponsoredOwnerCount = [](std::shared_ptr<SLE const> const& sle) -> std::uint32_t {
|
||||
if (sle && sle->getType() == ltACCOUNT_ROOT)
|
||||
return sle->getFieldU32(sfSponsoredOwnerCount);
|
||||
return 0;
|
||||
};
|
||||
|
||||
std::int64_t const beforeSponsored = getSponsored(before);
|
||||
std::int64_t const afterSponsored = getSponsored(after);
|
||||
std::int64_t const beforeSponsoring = getSponsoring(before);
|
||||
@@ -3294,6 +3305,9 @@ SponsorshipOwnerCountsMatch::visitEntry(
|
||||
|
||||
deltaSponsoredOwnerCount_ += (afterSponsored - beforeSponsored);
|
||||
deltaSponsoringOwnerCount_ += (afterSponsoring - beforeSponsoring);
|
||||
|
||||
if (getOwnerCount(after) < getSponsoredOwnerCount(after))
|
||||
invalidOwnerCountLessThanSponsoredOwnerCount_ += 1;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -3306,6 +3320,12 @@ SponsorshipOwnerCountsMatch::finalize(STTx const&, TER const, XRPAmount const, R
|
||||
return false;
|
||||
}
|
||||
|
||||
if (invalidOwnerCountLessThanSponsoredOwnerCount_ > 0)
|
||||
{
|
||||
JLOG(j.fatal()) << "Invariant failed: OwnerCount must be greater than or equal to SponsoredOwnerCount.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -401,11 +401,13 @@ public:
|
||||
* The following check is made for every transaction:
|
||||
* - The sum of all per-account deltas of `sfSponsoredOwnerCount` equals
|
||||
* the sum of all per-account deltas of `sfSponsoringOwnerCount`.
|
||||
* - Account OwnerCount must be greater than or equal to SponsoredOwnerCount.
|
||||
*/
|
||||
class SponsorshipOwnerCountsMatch
|
||||
{
|
||||
std::int64_t deltaSponsoredOwnerCount_ = 0;
|
||||
std::int64_t deltaSponsoringOwnerCount_ = 0;
|
||||
std::uint64_t invalidOwnerCountLessThanSponsoredOwnerCount_ = 0;
|
||||
|
||||
public:
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user