adjustOwnerCountObj, more checks, some fixes

This commit is contained in:
Oleksandr
2026-04-30 13:47:15 -04:00
parent 2b4ce0fc21
commit d792e03468
26 changed files with 80 additions and 112 deletions

View File

@@ -105,6 +105,26 @@ adjustOwnerCount(
j);
}
void
adjustOwnerCountObj(
ApplyView& view,
SLE::ref accountSle,
SLE::ref objectSle,
std::int32_t amount,
beast::Journal j);
inline void
adjustOwnerCountObj(
ApplyView& view,
AccountID const& account,
SLE::ref objectSle,
std::int32_t amount,
beast::Journal j)
{
SLE::ref accountSle = view.peek(keylet::account(account));
return adjustOwnerCountObj(view, accountSle, objectSle, amount, j);
}
/** Returns IOU issuer transfer fee as Rate. Rate specifies
* the fee as fractions of 1 billion. For example, 1% transfer rate
* is represented as 1,010,000,000.

View File

@@ -248,13 +248,19 @@ adjustOwnerCount(
std::int32_t adjustment,
beast::Journal j)
{
if (!accountSle)
return;
XRPL_ASSERT(accountSle, "xrpl::adjustOwnerCount : valid account sle");
auto const sleType = accountSle->getType();
bool const validType = sponsorSle ? sleType == ltACCOUNT_ROOT
: sleType == ltLOAN_BROKER || sleType == ltACCOUNT_ROOT;
XRPL_ASSERT(validType, "xrpl::adjustOwnerCount : valid account sle type");
XRPL_ASSERT(adjustment, "xrpl::adjustOwnerCount : nonzero adjustment input");
auto const accountID = accountSle->getAccountID(sfAccount);
if (sponsorSle)
{
XRPL_ASSERT(
sponsorSle->getType() == ltACCOUNT_ROOT,
"xrpl::adjustOwnerCount : valid sponsor sle type");
auto const sponsorID = sponsorSle->getAccountID(sfAccount);
adjustSponsorOwnerCountHlp(
@@ -274,6 +280,21 @@ adjustOwnerCount(
adjustSponsorOwnerCountHlp(view, accountSle, sfOwnerCount, accountID, adjustment, j);
}
void
adjustOwnerCountObj(
ApplyView& view,
SLE::ref accountSle,
SLE::ref objectSle,
std::int32_t amount,
beast::Journal j)
{
XRPL_ASSERT(objectSle, "xrpl::adjustOwnerCount : valid object sle");
XRPL_ASSERT(
objectSle->getType() != ltACCOUNT_ROOT, "xrpl::adjustOwnerCount : valid object sle type");
SLE::ref sponsorSle = getLedgerEntryReserveSponsor(view, objectSle);
adjustOwnerCount(view, accountSle, sponsorSle, amount, j);
}
XRPAmount
accountReserve(
ReadView const& view,

View File

@@ -94,10 +94,7 @@ deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Jou
}
if (isOwner)
{
auto const sponsorSle = getLedgerEntryReserveSponsor(view, sleCredential);
adjustOwnerCount(view, sleAccount, sponsorSle, -1, j);
}
adjustOwnerCountObj(view, sleAccount, sleCredential, -1, j);
return tesSUCCESS;
};

View File

@@ -180,8 +180,7 @@ authorizeMPToken(
keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false))
return tecINTERNAL; // LCOV_EXCL_LINE
auto const sponsor = getLedgerEntryReserveSponsor(view, sleMpt);
adjustOwnerCount(view, sleAcct, sponsor, -1, journal);
adjustOwnerCountObj(view, sleAcct, sleMpt, -1, journal);
view.erase(sleMpt);
return tesSUCCESS;

View File

@@ -451,6 +451,7 @@ removeToken(
auto const prev = loadPage(curr, sfPreviousPageMin);
auto const next = loadPage(curr, sfNextPageMin);
auto nullJ = beast::Journal{beast::Journal::getNullSink()};
if (!arr.empty())
{
// The current page isn't empty. Update it and then try to consolidate
@@ -460,26 +461,10 @@ removeToken(
view.update(curr);
if (prev && mergePages(view, prev, curr))
{
auto const sponsor = getLedgerEntryReserveSponsor(view, prev);
adjustOwnerCount(
view,
view.peek(keylet::account(owner)),
sponsor,
-1,
beast::Journal{beast::Journal::getNullSink()});
}
adjustOwnerCountObj(view, owner, prev, -1, nullJ);
if (next && mergePages(view, curr, next))
{
auto const sponsor = getLedgerEntryReserveSponsor(view, curr);
adjustOwnerCount(
view,
view.peek(keylet::account(owner)),
sponsor,
-1,
beast::Journal{beast::Journal::getNullSink()});
}
adjustOwnerCountObj(view, owner, curr, -1, nullJ);
return tesSUCCESS;
}
@@ -513,13 +498,7 @@ removeToken(
curr->makeFieldAbsent(sfPreviousPageMin);
}
auto const sponsor = getLedgerEntryReserveSponsor(view, prev);
adjustOwnerCount(
view,
view.peek(keylet::account(owner)),
sponsor,
-1,
beast::Journal{beast::Journal::getNullSink()});
adjustOwnerCountObj(view, owner, prev, -1, nullJ);
view.update(curr);
view.erase(prev);
@@ -555,13 +534,7 @@ removeToken(
view.update(next);
}
auto const sponsor = getLedgerEntryReserveSponsor(view, curr);
adjustOwnerCount(
view,
view.peek(keylet::account(owner)),
sponsor,
-1,
beast::Journal{beast::Journal::getNullSink()});
adjustOwnerCountObj(view, owner, curr, -1, nullJ);
view.erase(curr);
@@ -579,12 +552,7 @@ removeToken(
view.peek(Keylet(ltNFTOKEN_PAGE, prev->key())),
view.peek(Keylet(ltNFTOKEN_PAGE, next->key()))))
{
adjustOwnerCount(
view,
view.peek(keylet::account(owner)),
getLedgerEntryReserveSponsor(view, prev),
-1,
beast::Journal{beast::Journal::getNullSink()});
adjustOwnerCountObj(view, owner, prev, -1, nullJ);
}
return tesSUCCESS;
@@ -701,13 +669,7 @@ deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
false))
return false;
auto const sponsor = getLedgerEntryReserveSponsor(view, offer);
adjustOwnerCount(
view,
view.peek(keylet::account(owner)),
sponsor,
-1,
beast::Journal{beast::Journal::getNullSink()});
adjustOwnerCountObj(view, owner, offer, -1, beast::Journal{beast::Journal::getNullSink()});
view.erase(offer);
return true;

View File

@@ -57,8 +57,7 @@ offerDelete(ApplyView& view, std::shared_ptr<SLE> const& sle, beast::Journal j)
}
}
auto const sponsor = getLedgerEntryReserveSponsor(view, sle);
adjustOwnerCount(view, view.peek(keylet::account(owner)), sponsor, -1, j);
adjustOwnerCountObj(view, owner, sle, -1, j);
view.erase(sle);

View File

@@ -58,8 +58,7 @@ closeChannel(
XRPL_ASSERT(
(*slep)[sfAmount] >= (*slep)[sfBalance], "xrpl::closeChannel : minimum channel amount");
(*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance];
auto const sponsor = getLedgerEntryReserveSponsor(view, slep);
adjustOwnerCount(view, sle, sponsor, -1, j);
adjustOwnerCountObj(view, sle, slep, -1, j);
view.update(sle);
// Remove PayChan from ledger

View File

@@ -757,8 +757,7 @@ Transactor::ticketDelete(
}
// Update the Ticket owner's reserve.
auto const sponsor = getLedgerEntryReserveSponsor(view, sleTicket);
adjustOwnerCount(view, sleAccount, sponsor, -1, j);
adjustOwnerCountObj(view, sleAccount, sleTicket, -1, j);
// Remove Ticket from ledger.
view.erase(sleTicket);

View File

@@ -202,8 +202,7 @@ SponsorshipSet::doApply()
if (!sponsorObjSle)
return tecINTERNAL; // LCOV_EXCL_LINE
auto const sponsor = getLedgerEntryReserveSponsor(ctx_.view(), sponsorObjSle);
adjustOwnerCount(ctx_.view(), sponsorAccSle, sponsor, -1, ctx_.journal);
adjustOwnerCountObj(ctx_.view(), sponsorAccSle, sponsorObjSle, -1, ctx_.journal);
ctx_.view().dirRemove(
keylet::ownerDir(sponsorAccountID),

View File

@@ -216,9 +216,8 @@ removeSignersFromLedger(
// LCOV_EXCL_STOP
}
auto const sponsor = getLedgerEntryReserveSponsor(view, signers);
adjustOwnerCount(
view, view.peek(accountKeylet), sponsor, removeFromOwnerCount, registry.getJournal("View"));
adjustOwnerCountObj(
view, view.peek(accountKeylet), signers, removeFromOwnerCount, registry.getJournal("View"));
view.erase(signers);

View File

@@ -726,11 +726,10 @@ finalizeClaimHelper(
return result;
}
adjustOwnerCountObj(outerSb, sleOwner, sleClaimID, -1, j);
// Remove the claim id from the ledger
outerSb.erase(sleClaimID);
auto const sponsor = getLedgerEntryReserveSponsor(outerSb, sleClaimID);
adjustOwnerCount(outerSb, sleOwner, sponsor, -1, j);
}
}

View File

@@ -94,9 +94,7 @@ CheckCancel::doApply()
}
// If we succeeded, update the check owner's reserve.
auto const sleSrc = view().peek(keylet::account(srcId));
auto const sponsor = getLedgerEntryReserveSponsor(view(), sleCheck);
adjustOwnerCount(view(), sleSrc, sponsor, -1, viewJ);
adjustOwnerCountObj(view(), srcId, sleCheck, -1, viewJ);
// Remove check from ledger.
view().erase(sleCheck);

View File

@@ -303,7 +303,7 @@ CheckCash::doApply()
// LCOV_EXCL_STOP
}
auto const sponsorSle = getLedgerEntryReserveSponsor(psb, sleCheck);
auto const sponsorCheckSle = getLedgerEntryReserveSponsor(psb, sleCheck);
// Preclaim already checked that source has at least the requested
// funds.
@@ -333,7 +333,7 @@ CheckCash::doApply()
// from src's directory, we allow them to send that additional
// incremental reserve amount in the transfer. Hence the -1
// argument.
STAmount const srcLiquid{xrpLiquid(psb, srcId, sponsorSle ? 0 : -1, viewJ)};
STAmount const srcLiquid{xrpLiquid(psb, srcId, sponsorCheckSle ? 0 : -1, viewJ)};
// Now, how much do they need in order to be successful?
STAmount const xrpDeliver{
@@ -588,7 +588,7 @@ CheckCash::doApply()
// If we succeeded, update the check owner's reserve.
adjustOwnerCount(psb, psb.peek(keylet::account(srcId)), sponsorSle, -1, viewJ);
adjustOwnerCount(psb, psb.peek(keylet::account(srcId)), sponsorCheckSle, -1, viewJ);
// Remove check from ledger.
psb.erase(sleCheck);

View File

@@ -104,8 +104,7 @@ CredentialAccept::doApply()
auto const credType(ctx_.tx[sfCredentialType]);
Keylet const credentialKey = keylet::credential(account_, issuer, credType);
auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
auto const currentSponsor = getLedgerEntryReserveSponsor(view(), sleCred);
auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
if (checkExpired(sleCred, view().header().parentCloseTime))
{
@@ -118,7 +117,7 @@ CredentialAccept::doApply()
sleCred->setFieldU32(sfFlags, lsfAccepted);
view().update(sleCred);
adjustOwnerCount(view(), sleIssuer, currentSponsor, -1, j_);
adjustOwnerCountObj(view(), sleIssuer, sleCred, -1, j_);
removeSponsorFromLedgerEntry(sleCred);
adjustOwnerCount(view(), sleSubject, newSponsor, 1, j_);
addSponsorToLedgerEntry(sleCred, newSponsor);

View File

@@ -168,8 +168,7 @@ DelegateSet::deleteDelegate(ApplyView& view, std::shared_ptr<SLE> const& sle, be
if (!sleOwner)
return tecINTERNAL; // LCOV_EXCL_LINE
auto const sponsor = getLedgerEntryReserveSponsor(view, sle);
adjustOwnerCount(view, sleOwner, sponsor, -1, j);
adjustOwnerCountObj(view, sleOwner, sle, -1, j);
view.erase(sle);

View File

@@ -57,9 +57,7 @@ DIDDelete::deleteSLE(
if (!sleOwner)
return tecINTERNAL; // LCOV_EXCL_LINE
auto const sponsor = getLedgerEntryReserveSponsor(view, sle);
adjustOwnerCount(view, sleOwner, sponsor, -1, j);
view.update(sleOwner);
adjustOwnerCountObj(view, sleOwner, sle, -1, j);
// Remove object from ledger
view.erase(sle);

View File

@@ -212,9 +212,7 @@ EscrowCancel::doApply()
}
}
auto const sponsor = getLedgerEntryReserveSponsor(ctx_.view(), slep);
adjustOwnerCount(ctx_.view(), sle, sponsor, -1, ctx_.journal);
ctx_.view().update(sle);
adjustOwnerCountObj(ctx_.view(), sle, slep, -1, ctx_.journal);
// Remove escrow from ledger
ctx_.view().erase(slep);

View File

@@ -392,10 +392,7 @@ EscrowFinish::doApply()
ctx_.view().update(sled);
// Adjust source owner count
auto const sle = ctx_.view().peek(keylet::account(account));
auto const sponsor = getLedgerEntryReserveSponsor(ctx_.view(), slep);
adjustOwnerCount(ctx_.view(), sle, sponsor, -1, ctx_.journal);
ctx_.view().update(sle);
adjustOwnerCountObj(ctx_.view(), account, slep, -1, ctx_.journal);
// Remove escrow from ledger
ctx_.view().erase(slep);

View File

@@ -181,17 +181,14 @@ LoanBrokerDelete::doApply()
// Decreases the owner count by two: one for the LoanBroker object, and
// one for the pseudo-account.
// LoanBroker object can be sponsored
auto const sponsor = getLedgerEntryReserveSponsor(view(), broker);
adjustOwnerCount(view(), owner, sponsor, -1, j_);
adjustOwnerCountObj(view(), owner, broker, -1, j_);
// pseudo-account cannot be sponsored
adjustOwnerCount(view(), owner, {}, -1, j_);
}
view().erase(brokerPseudoSLE);
view().erase(broker);
associateAsset(*broker, vaultAsset);
return tesSUCCESS;

View File

@@ -130,8 +130,7 @@ LoanDelete::doApply()
}
}
// Decrement the borrower's owner count
auto const sponsor = getLedgerEntryReserveSponsor(view, loanSle);
adjustOwnerCount(view, borrowerSle, sponsor, -1, j_);
adjustOwnerCountObj(view, borrowerSle, loanSle, -1, j_);
// Delete the Loan object
view.erase(loanSle);

View File

@@ -72,10 +72,7 @@ OracleDelete::deleteOracle(
return tecINTERNAL; // LCOV_EXCL_LINE
auto const count = sle->getFieldArray(sfPriceDataSeries).size() > 5 ? -2 : -1;
auto const sponsor = getLedgerEntryReserveSponsor(view, sle);
adjustOwnerCount(view, sleOwner, sponsor, count, j);
adjustOwnerCountObj(view, sleOwner, sle, count, j);
view.erase(sle);
return tesSUCCESS;

View File

@@ -281,11 +281,10 @@ OracleSet::doApply()
// the sponsor decrease current sponsored owner count.
// Otherwise, the sponsorship will be deleted.
auto const currentSponsorSle = getLedgerEntryReserveSponsor(ctx_.view(), sle);
auto const newSponsorSle = getTxReserveSponsor(ctx_.view(), ctx_.tx);
// decrease current sponsored owner count
adjustOwnerCount(ctx_.view(), accountSle, currentSponsorSle, -oldCount, ctx_.journal);
adjustOwnerCountObj(ctx_.view(), accountSle, sle, -oldCount, ctx_.journal);
removeSponsorFromLedgerEntry(sle);
// increase new owner count
adjustOwnerCount(ctx_.view(), accountSle, newSponsorSle, newCount, ctx_.journal);
@@ -294,8 +293,7 @@ OracleSet::doApply()
else if (adjust < 0)
{
// decrease owner count
auto const sponsorSle = getLedgerEntryReserveSponsor(ctx_.view(), sle);
adjustOwnerCount(ctx_.view(), accountSle, sponsorSle, adjust, ctx_.journal);
adjustOwnerCountObj(ctx_.view(), accountSle, sle, adjust, ctx_.journal);
}
ctx_.view().update(sle);

View File

@@ -288,9 +288,7 @@ DepositPreauth::removeFromLedger(ApplyView& view, uint256 const& preauthIndex, b
if (!sleOwner)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const sponsor = getLedgerEntryReserveSponsor(view, slePreauth);
adjustOwnerCount(view, sleOwner, sponsor, -1, j);
adjustOwnerCountObj(view, sleOwner, slePreauth, -1, j);
// Remove DepositPreauth from ledger.
view.erase(slePreauth);

View File

@@ -68,8 +68,7 @@ PermissionedDomainDelete::doApply()
XRPL_ASSERT(
ownerSle && ownerSle->getFieldU32(sfOwnerCount) > 0,
"xrpl::PermissionedDomainDelete::doApply : nonzero owner count");
auto const sponsor = getLedgerEntryReserveSponsor(view(), slePd);
adjustOwnerCount(view(), ownerSle, sponsor, -1, ctx_.journal);
adjustOwnerCountObj(view(), ownerSle, slePd, -1, ctx_.journal);
view().erase(slePd);
return tesSUCCESS;

View File

@@ -52,10 +52,9 @@ MPTokenIssuanceDestroy::doApply()
if (!view().dirRemove(keylet::ownerDir(account_), (*mpt)[sfOwnerNode], mpt->key(), false))
return tefBAD_LEDGER; // LCOV_EXCL_LINE
auto const sponsor = getLedgerEntryReserveSponsor(view(), mpt);
adjustOwnerCount(view(), view().peek(keylet::account(account_)), sponsor, -1, j_);
adjustOwnerCountObj(view(), account_, mpt, -1, j_);
view().erase(mpt);
return tesSUCCESS;
}

View File

@@ -207,8 +207,7 @@ VaultDelete::doApply()
}
// We are destroying Vault and PseudoAccount, hence decrease by 2
auto const vaultSponsor = getLedgerEntryReserveSponsor(view(), vault);
adjustOwnerCount(view(), owner, vaultSponsor, -2, j_);
adjustOwnerCountObj(view(), owner, vault, -2, j_);
// Destroy the vault.
view().erase(vault);