refactor: Use EscrowEntry everywhere (#8354)

This commit is contained in:
Mayukha Vadari
2026-10-05 17:51:18 +00:00
committed by GitHub
parent 5c5f7d315a
commit cd633b9ac9
3 changed files with 65 additions and 64 deletions

View File

@@ -3,6 +3,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/ledger/entries/EscrowEntry.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/EscrowHelpers.h>
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
@@ -94,13 +95,12 @@ EscrowCancel::preclaim(PreclaimContext const& ctx)
if (ctx.view.rules().enabled(featureTokenEscrow))
{
auto const seqProxy = SeqProxy::rawSequence(ctx.tx[sfOfferSequence]);
auto const k = keylet::escrow(ctx.tx[sfOwner], seqProxy);
auto const slep = ctx.view.read(k);
if (!slep)
EscrowEntryR const escrow(ctx.tx[sfOwner], seqProxy, ctx.view);
if (!escrow)
return tecNO_TARGET;
AccountID const account = (*slep)[sfAccount];
STAmount const amount = (*slep)[sfAmount];
AccountID const account = (*escrow)[sfAccount];
STAmount const amount = (*escrow)[sfAmount];
if (!isXRP(amount))
{
@@ -120,9 +120,8 @@ TER
EscrowCancel::doApply()
{
auto const seqProxy = SeqProxy::rawSequence(ctx_.tx[sfOfferSequence]);
auto const k = keylet::escrow(ctx_.tx[sfOwner], seqProxy);
auto const slep = ctx_.view().peek(k);
if (!slep)
EscrowEntryW escrow(ctx_.tx[sfOwner], seqProxy, ctx_.view(), j_);
if (!escrow)
{
if (ctx_.view().rules().enabled(featureTokenEscrow))
return tecINTERNAL; // LCOV_EXCL_LINE
@@ -133,19 +132,19 @@ EscrowCancel::doApply()
auto const now = ctx_.view().header().parentCloseTime;
// No cancel time specified: can't execute at all.
if (!(*slep)[~sfCancelAfter])
if (!(*escrow)[~sfCancelAfter])
return tecNO_PERMISSION;
// Too soon: can't execute before the cancel time.
if (!after(now, (*slep)[sfCancelAfter]))
if (!after(now, (*escrow)[sfCancelAfter]))
return tecNO_PERMISSION;
AccountID const account = (*slep)[sfAccount];
AccountID const account = (*escrow)[sfAccount];
// Remove escrow from owner directory
{
auto const page = (*slep)[sfOwnerNode];
if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, k.key, true))
auto const page = (*escrow)[sfOwnerNode];
if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, escrow.key(), true))
{
// LCOV_EXCL_START
JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
@@ -155,9 +154,10 @@ EscrowCancel::doApply()
}
// Remove escrow from recipient's owner directory, if present.
if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
if (auto const optPage = (*escrow)[~sfDestinationNode]; optPage)
{
if (!ctx_.view().dirRemove(keylet::ownerDir((*slep)[sfDestination]), *optPage, k.key, true))
if (!ctx_.view().dirRemove(
keylet::ownerDir((*escrow)[sfDestination]), *optPage, escrow.key(), true))
{
// LCOV_EXCL_START
JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
@@ -167,13 +167,13 @@ EscrowCancel::doApply()
}
auto const sle = ctx_.view().peek(keylet::account(account));
STAmount const amount = slep->getFieldAmount(sfAmount);
STAmount const amount = escrow->getFieldAmount(sfAmount);
// The return can re-create a holding the owner deleted while the escrow
// was pending; the removed escrow must not be counted against its reserve.
bool const recycleReserve = ctx_.view().rules().enabled(fixCleanup3_4_0);
if (recycleReserve)
decreaseOwnerCountForObject(ctx_.view(), sle, slep, 1, ctx_.journal);
decreaseOwnerCountForObject(ctx_.view(), sle, escrow.mutableRawSle(), 1, ctx_.journal);
// Transfer amount back to the owner
if (isXRP(amount))
@@ -192,7 +192,7 @@ EscrowCancel::doApply()
return escrowUnlockApplyHelper<T>(
ctx_.getApplyViewContext(),
kParityRate,
ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : slep,
ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : escrow.mutableRawSle(),
preFeeBalance_,
amount,
issuer,
@@ -206,9 +206,9 @@ EscrowCancel::doApply()
return ret; // LCOV_EXCL_LINE
// Remove escrow from issuers owner directory, if present.
if (auto const optPage = (*slep)[~sfIssuerNode]; optPage)
if (auto const optPage = (*escrow)[~sfIssuerNode]; optPage)
{
if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, k.key, true))
if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, escrow.key(), true))
{
// LCOV_EXCL_START
JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
@@ -219,10 +219,10 @@ EscrowCancel::doApply()
}
if (!recycleReserve)
decreaseOwnerCountForObject(ctx_.view(), sle, slep, 1, ctx_.journal);
decreaseOwnerCountForObject(ctx_.view(), sle, escrow.mutableRawSle(), 1, ctx_.journal);
// Remove escrow from ledger
ctx_.view().erase(slep);
escrow.erase();
return tesSUCCESS;
}

View File

@@ -7,6 +7,7 @@
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/ledger/entries/EscrowEntry.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
@@ -481,30 +482,31 @@ EscrowCreate::doApply()
// Create escrow in ledger. Note that we use the value from the
// sequence or ticket. For more explanation see comments in SeqProxy.h.
Keylet const escrowKeylet = keylet::escrow(accountID_, ctx_.tx.getSeqProxy());
auto const slep = std::make_shared<SLE>(escrowKeylet);
(*slep)[sfAmount] = amount;
(*slep)[sfAccount] = accountID_;
(*slep)[~sfCondition] = ctx_.tx[~sfCondition];
(*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
(*slep)[sfDestination] = ctx_.tx[sfDestination];
(*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
(*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
(*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
EscrowEntryW escrow(accountID_, ctx_.tx.getSeqProxy(), ctx_.view(), j_);
Keylet const escrowKeylet = escrow.keylet();
escrow.newSLE();
(*escrow)[sfAmount] = amount;
(*escrow)[sfAccount] = accountID_;
(*escrow)[~sfCondition] = ctx_.tx[~sfCondition];
(*escrow)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
(*escrow)[sfDestination] = ctx_.tx[sfDestination];
(*escrow)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
(*escrow)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
(*escrow)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
if (ctx_.view().rules().enabled(fixIncludeKeyletFields))
{
(*slep)[sfSequence] = ctx_.tx.getSeqProxy().value();
(*escrow)[sfSequence] = ctx_.tx.getSeqProxy().value();
}
if (ctx_.view().rules().enabled(featureTokenEscrow) && !isXRP(amount))
{
auto const xferRate = transferRate(ctx_.view(), amount);
if (xferRate != kParityRate)
(*slep)[sfTransferRate] = xferRate.value;
(*escrow)[sfTransferRate] = xferRate.value;
}
ctx_.view().insert(slep);
escrow.insert();
// Add escrow to sender's owner directory
{
@@ -512,7 +514,7 @@ EscrowCreate::doApply()
keylet::ownerDir(accountID_), escrowKeylet, describeOwnerDir(accountID_));
if (!page)
return tecDIR_FULL; // LCOV_EXCL_LINE
(*slep)[sfOwnerNode] = *page;
(*escrow)[sfOwnerNode] = *page;
}
// If it's not a self-send, add escrow to recipient's owner directory.
@@ -523,7 +525,7 @@ EscrowCreate::doApply()
ctx_.view().dirInsert(keylet::ownerDir(dest), escrowKeylet, describeOwnerDir(dest));
if (!page)
return tecDIR_FULL; // LCOV_EXCL_LINE
(*slep)[sfDestinationNode] = *page;
(*escrow)[sfDestinationNode] = *page;
}
// IOU escrow objects are added to the issuer's owner directory to help
@@ -536,7 +538,7 @@ EscrowCreate::doApply()
ctx_.view().dirInsert(keylet::ownerDir(issuer), escrowKeylet, describeOwnerDir(issuer));
if (!page)
return tecDIR_FULL; // LCOV_EXCL_LINE
(*slep)[sfIssuerNode] = *page;
(*escrow)[sfIssuerNode] = *page;
}
// Deduct owner's balance
@@ -559,7 +561,7 @@ EscrowCreate::doApply()
// increment owner count
increaseOwnerCount(ctx_.getApplyViewContext(), sle, 1, ctx_.journal);
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), slep);
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), escrow.mutableRawSle());
ctx_.view().update(sle);
return tesSUCCESS;
}

View File

@@ -9,6 +9,7 @@
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/ledger/entries/EscrowEntry.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/ledger/helpers/EscrowHelpers.h>
@@ -211,13 +212,12 @@ EscrowFinish::preclaim(PreclaimContext const& ctx)
if (ctx.view.rules().enabled(featureTokenEscrow))
{
auto const seqProxy = SeqProxy::rawSequence(ctx.tx[sfOfferSequence]);
auto const k = keylet::escrow(ctx.tx[sfOwner], seqProxy);
auto const slep = ctx.view.read(k);
if (!slep)
EscrowEntryR const escrow(ctx.tx[sfOwner], seqProxy, ctx.view);
if (!escrow)
return tecNO_TARGET;
AccountID const dest = (*slep)[sfDestination];
STAmount const amount = (*slep)[sfAmount];
AccountID const dest = (*escrow)[sfDestination];
STAmount const amount = (*escrow)[sfAmount];
if (!isXRP(amount))
{
@@ -237,9 +237,8 @@ TER
EscrowFinish::doApply()
{
auto const seqProxy = SeqProxy::rawSequence(ctx_.tx[sfOfferSequence]);
auto const k = keylet::escrow(ctx_.tx[sfOwner], seqProxy);
auto const slep = ctx_.view().peek(k);
if (!slep)
EscrowEntryW escrow(ctx_.tx[sfOwner], seqProxy, ctx_.view(), j_);
if (!escrow)
{
if (ctx_.view().rules().enabled(featureTokenEscrow))
return tecINTERNAL; // LCOV_EXCL_LINE
@@ -252,11 +251,11 @@ EscrowFinish::doApply()
auto const now = ctx_.view().header().parentCloseTime;
// Too soon: can't execute before the finish time
if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
if ((*escrow)[~sfFinishAfter] && !after(now, (*escrow)[sfFinishAfter]))
return tecNO_PERMISSION;
// Too late: can't execute after the cancel time
if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
if ((*escrow)[~sfCancelAfter] && after(now, (*escrow)[sfCancelAfter]))
return tecNO_PERMISSION;
// Check cryptocondition fulfillment
@@ -296,7 +295,7 @@ EscrowFinish::doApply()
return tecCRYPTOCONDITION_ERROR;
// Check against condition in the ledger entry:
auto const cond = (*slep)[~sfCondition];
auto const cond = (*escrow)[~sfCondition];
// If a condition wasn't specified during creation,
// one shouldn't be included now.
@@ -313,7 +312,7 @@ EscrowFinish::doApply()
}
// NOTE: Escrow payments cannot be used to fund accounts.
AccountID const destID = (*slep)[sfDestination];
AccountID const destID = (*escrow)[sfDestination];
auto const sled = ctx_.view().peek(keylet::account(destID));
if (!sled)
return tecNO_DST;
@@ -323,12 +322,12 @@ EscrowFinish::doApply()
!isTesSuccess(err))
return err;
AccountID const account = (*slep)[sfAccount];
AccountID const account = (*escrow)[sfAccount];
// Remove escrow from owner directory
{
auto const page = (*slep)[sfOwnerNode];
if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, k.key, true))
auto const page = (*escrow)[sfOwnerNode];
if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, escrow.key(), true))
{
// LCOV_EXCL_START
JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
@@ -338,9 +337,9 @@ EscrowFinish::doApply()
}
// Remove escrow from recipient's owner directory, if present.
if (auto const optPage = (*slep)[~sfDestinationNode])
if (auto const optPage = (*escrow)[~sfDestinationNode])
{
if (!ctx_.view().dirRemove(keylet::ownerDir(destID), *optPage, k.key, true))
if (!ctx_.view().dirRemove(keylet::ownerDir(destID), *optPage, escrow.key(), true))
{
// LCOV_EXCL_START
JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
@@ -355,9 +354,9 @@ EscrowFinish::doApply()
bool const recycleReserve =
ctx_.view().rules().enabled(featureSponsor) || ctx_.view().rules().enabled(fixCleanup3_4_0);
if (recycleReserve)
decreaseOwnerCountForObject(ctx_.view(), account, slep, 1, ctx_.journal);
decreaseOwnerCountForObject(ctx_.view(), account, escrow.mutableRawSle(), 1, ctx_.journal);
STAmount const amount = slep->getFieldAmount(sfAmount);
STAmount const amount = escrow->getFieldAmount(sfAmount);
// Transfer amount to destination
if (isXRP(amount))
{
@@ -368,8 +367,8 @@ EscrowFinish::doApply()
if (!ctx_.view().rules().enabled(featureTokenEscrow))
return temDISABLED; // LCOV_EXCL_LINE
Rate lockedRate = slep->isFieldPresent(sfTransferRate)
? xrpl::Rate(slep->getFieldU32(sfTransferRate))
Rate lockedRate = escrow->isFieldPresent(sfTransferRate)
? xrpl::Rate(escrow->getFieldU32(sfTransferRate))
: kParityRate;
auto const issuer = amount.getIssuer();
bool const createAsset = destID == accountID_;
@@ -392,9 +391,9 @@ EscrowFinish::doApply()
return ret;
// Remove escrow from issuers owner directory, if present.
if (auto const optPage = (*slep)[~sfIssuerNode]; optPage)
if (auto const optPage = (*escrow)[~sfIssuerNode]; optPage)
{
if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, k.key, true))
if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, escrow.key(), true))
{
// LCOV_EXCL_START
JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
@@ -407,10 +406,10 @@ EscrowFinish::doApply()
ctx_.view().update(sled);
if (!recycleReserve)
decreaseOwnerCountForObject(ctx_.view(), account, slep, 1, ctx_.journal);
decreaseOwnerCountForObject(ctx_.view(), account, escrow.mutableRawSle(), 1, ctx_.journal);
// Remove escrow from ledger
ctx_.view().erase(slep);
escrow.erase();
return tesSUCCESS;
}