add assert when adding/removing sponsor field to LedgerEntry

This commit is contained in:
tequ
2025-10-03 15:05:48 +09:00
parent ee385e9d3b
commit 101b70f0e8
2 changed files with 76 additions and 19 deletions

View File

@@ -1127,6 +1127,11 @@ addSponsorToLedgerEntry(
std::optional<std::shared_ptr<SLE>> const& sponsorSle,
SF_ACCOUNT const& field)
{
XRPL_ASSERT(
(sle->getType() == ltRIPPLE_STATE &&
(field == sfHighSponsorAccount || field == sfLowSponsorAccount)) ||
(sle->getType() != ltRIPPLE_STATE && field == sfSponsorAccount),
"addSponsorToLedgerEntry : Invalid field to the LedgerEntry");
if (sponsorSle)
sle->setAccountID(field, (*sponsorSle)->getAccountID(sfAccount));
}
@@ -1136,6 +1141,11 @@ removeSponsorFromLedgerEntry(
std::shared_ptr<SLE> const& sle,
SF_ACCOUNT const& field)
{
XRPL_ASSERT(
(sle->getType() == ltRIPPLE_STATE &&
(field == sfHighSponsorAccount || field == sfLowSponsorAccount)) ||
(sle->getType() != ltRIPPLE_STATE && field == sfSponsorAccount),
"removeSponsorFromLedgerEntry : Invalid field to the LedgerEntry");
if (sle->isFieldPresent(field))
sle->makeFieldAbsent(field);
}
@@ -2455,7 +2465,7 @@ updateTrustLine(
sfFlags, flags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve));
removeSponsorFromLedgerEntry(
sle, !bSenderHigh ? sfLowSponsorAccount : sfHighSponsorAccount);
state, !bSenderHigh ? sfLowSponsorAccount : sfHighSponsorAccount);
// Balance is zero, receiver reserve is clear.
if (!after // Balance is zero.

View File

@@ -3172,14 +3172,31 @@ public:
env.fund(XRP(1000000), alice, bob, sponsor, sponsor2);
env.close();
auto const validateSponsoredTrustline =
[&](std::shared_ptr<const SLE> const& sle,
bool isIssuerHigh,
Account const& sponsor) {
BEAST_EXPECT(
sle->getAccountID(
isIssuerHigh
? sfLowSponsorAccount
: sfHighSponsorAccount) == sponsor.id());
BEAST_EXPECT(!sle->isFieldPresent(
isIssuerHigh ? sfHighSponsorAccount
: sfLowSponsorAccount));
};
auto const& highAcc = alice > bob ? alice : bob;
auto const& lowAcc = alice > bob ? bob : alice;
// create and delete
for (bool isIssuerHigh : {false, true})
{
auto const& issuer = isIssuerHigh ? highAcc : lowAcc;
auto const& user = isIssuerHigh ? lowAcc : highAcc;
auto const USD = issuer["USD"];
auto const currency = USD.currency;
// create TrustLine
env(trust(user, USD(100)),
@@ -3191,18 +3208,12 @@ public:
BEAST_EXPECT(sponsoredOwnerCount(env, user) == 1);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 1);
auto const line =
env.le(keylet::line(user, issuer, USD.currency));
BEAST_EXPECT(
line->getAccountID(
isIssuerHigh ? sfLowSponsorAccount
: sfHighSponsorAccount) == sponsor.id());
BEAST_EXPECT(!line->isFieldPresent(
isIssuerHigh ? sfHighSponsorAccount : sfLowSponsorAccount));
auto const line = env.le(keylet::line(user, issuer, currency));
validateSponsoredTrustline(line, isIssuerHigh, sponsor);
// transfer sponsor
env(sponsor::transfer(
user, keylet::line(user, issuer, USD.currency).key),
user, keylet::line(user, issuer, currency).key),
sponsor::as(sponsor2, tfSponsorReserve),
sponsor::sig(sponsor2));
env.close();
@@ -3212,14 +3223,8 @@ public:
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor2) == 1);
auto const line2 =
env.le(keylet::line(user, issuer, USD.currency));
BEAST_EXPECT(
line2->getAccountID(
isIssuerHigh ? sfLowSponsorAccount
: sfHighSponsorAccount) == sponsor2.id());
BEAST_EXPECT(!line2->isFieldPresent(
isIssuerHigh ? sfHighSponsorAccount : sfLowSponsorAccount));
auto const line2 = env.le(keylet::line(user, issuer, currency));
validateSponsoredTrustline(line2, isIssuerHigh, sponsor2);
// delete TrustLine
env(trust(user, USD(0)));
@@ -3229,7 +3234,49 @@ public:
BEAST_EXPECT(sponsoredOwnerCount(env, user) == 0);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
BEAST_EXPECT(!env.le(keylet::line(user, issuer, USD.currency)));
BEAST_EXPECT(!env.le(keylet::line(user, issuer, currency)));
}
// update
for (bool isIssuerHigh : {false, true})
{
auto const& issuer = isIssuerHigh ? highAcc : lowAcc;
auto const& user = isIssuerHigh ? lowAcc : highAcc;
auto const USD = issuer["USD"];
auto const currency = USD.currency;
// create TrustLine from issuer
env(trust(issuer, user["USD"](100)));
env.close();
BEAST_EXPECT(env.le(keylet::line(user, issuer, currency)));
// update TrustLine from user to make reserve
env(trust(user, USD(100)),
sponsor::as(sponsor, tfSponsorReserve),
sponsor::sig(sponsor));
env.close();
BEAST_EXPECT(ownerCount(env, user) == 1);
BEAST_EXPECT(sponsoredOwnerCount(env, user) == 1);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 1);
auto const line = env.le(keylet::line(user, issuer, currency));
validateSponsoredTrustline(line, isIssuerHigh, sponsor);
// update TrustLine from user to clear reserve
env(trust(user, USD(0)));
env.close();
BEAST_EXPECT(ownerCount(env, user) == 0);
BEAST_EXPECT(sponsoredOwnerCount(env, user) == 0);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
BEAST_EXPECT(env.le(keylet::line(user, issuer, currency)));
// remove TrustLine from issuer
env(trust(issuer, user["USD"](0)));
env.close();
}
}