mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-03 04:22:14 +00:00
refactor: Use ApplyViewContext everywhere instead of ApplyView+STTx (#7618)
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -411,6 +412,12 @@ public:
|
||||
emptyDirDelete(Keylet const& directory);
|
||||
};
|
||||
|
||||
struct ApplyViewContext
|
||||
{
|
||||
ApplyView& view;
|
||||
STTx const& tx;
|
||||
};
|
||||
|
||||
namespace directory {
|
||||
/** Helper functions for managing low-level directory operations.
|
||||
These are not part of the ApplyView interface.
|
||||
|
||||
@@ -210,8 +210,7 @@ canWithdraw(ReadView const& view, STTx const& tx);
|
||||
|
||||
[[nodiscard]] TER
|
||||
doWithdraw(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& senderAcct,
|
||||
AccountID const& dstAcct,
|
||||
AccountID const& sourceAcct,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
@@ -99,8 +98,7 @@ accountReserve(ReadView const& view, AccountID const& id, beast::Journal j, Adju
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkInsufficientReserve(
|
||||
ApplyView const& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
SLE::const_ref accSle,
|
||||
STAmount const& accBalance,
|
||||
SLE::const_ref sponsorSle,
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
@@ -29,8 +28,7 @@ namespace xrpl {
|
||||
template <ValidIssueType T>
|
||||
TER
|
||||
escrowUnlockApplyHelper(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
Rate lockedRate,
|
||||
SLE::ref sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -44,8 +42,7 @@ escrowUnlockApplyHelper(
|
||||
template <>
|
||||
inline TER
|
||||
escrowUnlockApplyHelper<Issue>(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
Rate lockedRate,
|
||||
SLE::ref sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -68,15 +65,15 @@ escrowUnlockApplyHelper<Issue>(
|
||||
if (receiverIssuer)
|
||||
return tesSUCCESS;
|
||||
|
||||
if (!view.exists(trustLineKey) && createAsset)
|
||||
if (!ctx.view.exists(trustLineKey) && createAsset)
|
||||
{
|
||||
// Can the account cover the trust line's reserve?
|
||||
auto const sponsorSle = getTxReserveSponsor(view, tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view, tx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
ctx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
JLOG(journal.trace()) << "Trust line does not exist. "
|
||||
@@ -90,7 +87,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
initialBalance.get<Issue>().account = noAccount();
|
||||
|
||||
if (TER const ter = trustCreate(
|
||||
view, // payment sandbox
|
||||
ctx.view, // payment sandbox
|
||||
recvLow, // is dest low?
|
||||
issuer, // source
|
||||
receiver, // destination
|
||||
@@ -111,13 +108,13 @@ escrowUnlockApplyHelper<Issue>(
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
view.update(sleDest);
|
||||
ctx.view.update(sleDest);
|
||||
}
|
||||
|
||||
if (!view.exists(trustLineKey) && !receiverIssuer)
|
||||
if (!ctx.view.exists(trustLineKey) && !receiverIssuer)
|
||||
return tecNO_LINE;
|
||||
|
||||
auto const xferRate = transferRate(view, amount);
|
||||
auto const xferRate = transferRate(ctx.view, amount);
|
||||
// update if issuer rate is less than locked rate
|
||||
if (xferRate < lockedRate)
|
||||
lockedRate = xferRate;
|
||||
@@ -145,7 +142,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
// of the funds
|
||||
if (!createAsset)
|
||||
{
|
||||
auto const sleRippleState = view.peek(trustLineKey);
|
||||
auto const sleRippleState = ctx.view.peek(trustLineKey);
|
||||
if (!sleRippleState)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -171,7 +168,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
// if destination is not the issuer then transfer funds
|
||||
if (!receiverIssuer)
|
||||
{
|
||||
auto const ter = directSendNoFee(view, issuer, receiver, finalAmt, true, journal);
|
||||
auto const ter = directSendNoFee(ctx.view, issuer, receiver, finalAmt, true, journal);
|
||||
if (!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
@@ -181,8 +178,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
template <>
|
||||
inline TER
|
||||
escrowUnlockApplyHelper<MPTIssue>(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
Rate lockedRate,
|
||||
SLE::ref sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -199,33 +195,33 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
auto const mptID = amount.get<MPTIssue>().getMptID();
|
||||
auto const issuanceKey = keylet::mptokenIssuance(mptID);
|
||||
auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver);
|
||||
if (!view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
||||
if (!ctx.view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
||||
{
|
||||
auto const sponsorSle = getTxReserveSponsor(view, tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view, tx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
ctx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
if (auto const ter = createMPToken(view, mptID, receiver, *sponsorSle, 0);
|
||||
if (auto const ter = createMPToken(ctx.view, mptID, receiver, *sponsorSle, 0);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// update owner count.
|
||||
increaseOwnerCount(view, sleDest, *sponsorSle, 1, journal);
|
||||
auto mptSle = view.peek(mptKeylet);
|
||||
increaseOwnerCount(ctx.view, sleDest, *sponsorSle, 1, journal);
|
||||
auto mptSle = ctx.view.peek(mptKeylet);
|
||||
addSponsorToLedgerEntry(mptSle, *sponsorSle);
|
||||
}
|
||||
|
||||
if (!view.exists(mptKeylet) && !receiverIssuer)
|
||||
if (!ctx.view.exists(mptKeylet) && !receiverIssuer)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const xferRate = transferRate(view, amount);
|
||||
auto const xferRate = transferRate(ctx.view, amount);
|
||||
// update if issuer rate is less than locked rate
|
||||
if (xferRate < lockedRate)
|
||||
lockedRate = xferRate;
|
||||
@@ -248,11 +244,11 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
finalAmt = amount.value() - xferFee;
|
||||
}
|
||||
return unlockEscrowMPT(
|
||||
view,
|
||||
ctx.view,
|
||||
sender,
|
||||
receiver,
|
||||
finalAmt,
|
||||
view.rules().enabled(fixTokenEscrowV1) ? amount : finalAmt,
|
||||
ctx.view.rules().enabled(fixTokenEscrowV1) ? amount : finalAmt,
|
||||
journal);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
@@ -87,8 +86,7 @@ canAddHolding(ReadView const& view, MPTIssue const& mptIssue);
|
||||
|
||||
[[nodiscard]] TER
|
||||
authorizeMPToken(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
XRPAmount const& priorBalance,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
@@ -119,8 +117,7 @@ requireAuth(
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
enforceMPTokenAuthorization(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
XRPAmount const& priorBalance,
|
||||
@@ -206,8 +203,7 @@ canMPTTradeAndTransfer(
|
||||
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
MPTIssue const& mptIssue,
|
||||
@@ -215,8 +211,7 @@ addEmptyHolding(
|
||||
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
MPTIssue const& mptIssue,
|
||||
beast::Journal journal);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
@@ -237,8 +236,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
/// canAddHolding() in preflight with the same View and Asset
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Issue const& issue,
|
||||
@@ -246,7 +244,7 @@ addEmptyHolding(
|
||||
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
Issue const& issue,
|
||||
beast::Journal journal);
|
||||
|
||||
@@ -42,12 +42,12 @@ getTxReserveSponsorAccountID(STTx const& tx)
|
||||
}
|
||||
|
||||
inline std::expected<SLE::pointer, TER>
|
||||
getTxReserveSponsor(ApplyView& view, STTx const& tx)
|
||||
getTxReserveSponsor(ApplyViewContext ctx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorAccountID(tx);
|
||||
auto const sponsorID = getTxReserveSponsorAccountID(ctx.tx);
|
||||
if (sponsorID)
|
||||
{
|
||||
auto sle = view.peek(keylet::account(*sponsorID));
|
||||
auto sle = ctx.view.peek(keylet::account(*sponsorID));
|
||||
|
||||
// already checked in Transactor::checkSponsor
|
||||
if (!sle)
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
@@ -304,8 +303,7 @@ canAddHolding(ReadView const& view, Asset const& asset);
|
||||
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Asset const& asset,
|
||||
@@ -313,8 +311,7 @@ addEmptyHolding(
|
||||
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
Asset const& asset,
|
||||
beast::Journal journal);
|
||||
|
||||
@@ -127,6 +127,15 @@ public:
|
||||
TER
|
||||
checkInvariants(TER const result, XRPAmount const fee);
|
||||
|
||||
ApplyViewContext
|
||||
getApplyViewContext()
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
view_.has_value(),
|
||||
"xrpl::ApplyContext::getApplyViewContext : view_ emplaced in constructor");
|
||||
return {.view = *view_, .tx = tx};
|
||||
}
|
||||
|
||||
private:
|
||||
static TER
|
||||
failInvariantCheck(TER const result);
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
beast::Journal const& j) override;
|
||||
|
||||
static std::expected<MPTID, TER>
|
||||
create(ApplyView& view, STTx const& tx, beast::Journal journal, MPTCreateArgs const& args);
|
||||
create(ApplyViewContext ctx, beast::Journal journal, MPTCreateArgs const& args);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -432,8 +432,7 @@ canWithdraw(ReadView const& view, STTx const& tx)
|
||||
|
||||
TER
|
||||
doWithdraw(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& senderAcct,
|
||||
AccountID const& dstAcct,
|
||||
AccountID const& sourceAcct,
|
||||
@@ -444,20 +443,20 @@ doWithdraw(
|
||||
// Create trust line or MPToken for the receiving account
|
||||
if (dstAcct == senderAcct)
|
||||
{
|
||||
if (auto const ter = addEmptyHolding(view, tx, senderAcct, priorBalance, amount.asset(), j);
|
||||
if (auto const ter = addEmptyHolding(ctx, senderAcct, priorBalance, amount.asset(), j);
|
||||
!isTesSuccess(ter) && ter != tecDUPLICATE)
|
||||
return ter;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto dstSle = view.read(keylet::account(dstAcct));
|
||||
if (auto err = verifyDepositPreauth(tx, view, senderAcct, dstAcct, dstSle, j))
|
||||
auto dstSle = ctx.view.read(keylet::account(dstAcct));
|
||||
if (auto err = verifyDepositPreauth(ctx.tx, ctx.view, senderAcct, dstAcct, dstSle, j))
|
||||
return err;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (accountHolds(
|
||||
view,
|
||||
ctx.view,
|
||||
sourceAcct,
|
||||
amount.asset(),
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
@@ -470,13 +469,14 @@ doWithdraw(
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const sponsorSle = getTxReserveSponsor(view, tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
// Move the funds directly from the broker's pseudo-account to the
|
||||
// dstAcct
|
||||
return accountSend(view, sourceAcct, dstAcct, amount, j, *sponsorSle, WaiveTransferFee::Yes);
|
||||
return accountSend(
|
||||
ctx.view, sourceAcct, dstAcct, amount, j, *sponsorSle, WaiveTransferFee::Yes);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -330,8 +330,7 @@ accountReserve(ReadView const& view, SLE::const_ref sle, beast::Journal j, Adjus
|
||||
|
||||
TER
|
||||
checkInsufficientReserve(
|
||||
ApplyView const& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
SLE::const_ref accSle,
|
||||
STAmount const& accBalance,
|
||||
SLE::const_ref sponsorSle,
|
||||
@@ -340,14 +339,14 @@ checkInsufficientReserve(
|
||||
{
|
||||
if (sponsorSle)
|
||||
{
|
||||
auto const sle = view.read(
|
||||
auto const sle = ctx.view.read(
|
||||
keylet::sponsorship(
|
||||
sponsorSle->getAccountID(sfAccount), accSle->getAccountID(sfAccount)));
|
||||
|
||||
// A reserve-sponsored tx must carry a sponsor signature
|
||||
// (cosigning path) and/or have a pre-existing sponsorship SLE
|
||||
// (prefunded path). Absence of both is an internal invariant break.
|
||||
if (isReserveSponsored(tx) && !sle && !tx.isFieldPresent(sfSponsorSignature))
|
||||
if (isReserveSponsored(ctx.tx) && !sle && !ctx.tx.isFieldPresent(sfSponsorSignature))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (sle)
|
||||
@@ -359,14 +358,14 @@ checkInsufficientReserve(
|
||||
}
|
||||
|
||||
auto const sponsorBalance = sponsorSle->getFieldAmount(sfBalance);
|
||||
STAmount const sponsorReserve = accountReserve(view, sponsorSle, j, adj);
|
||||
STAmount const sponsorReserve = accountReserve(ctx.view, sponsorSle, j, adj);
|
||||
|
||||
if (sponsorBalance < sponsorReserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
STAmount const reserve = accountReserve(view, accSle, j, adj);
|
||||
STAmount const reserve = accountReserve(ctx.view, accSle, j, adj);
|
||||
if (accBalance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
@@ -127,31 +126,29 @@ canAddHolding(ReadView const& view, MPTIssue const& mptIssue)
|
||||
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
MPTIssue const& mptIssue,
|
||||
beast::Journal journal)
|
||||
{
|
||||
auto const& mptID = mptIssue.getMptID();
|
||||
auto const mpt = view.peek(keylet::mptokenIssuance(mptID));
|
||||
auto const mpt = ctx.view.peek(keylet::mptokenIssuance(mptID));
|
||||
if (!mpt)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
if (mpt->isFlag(lsfMPTLocked))
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
if (view.peek(keylet::mptoken(mptID, accountID)))
|
||||
if (ctx.view.peek(keylet::mptoken(mptID, accountID)))
|
||||
return tecDUPLICATE;
|
||||
if (accountID == mptIssue.getIssuer())
|
||||
return tesSUCCESS;
|
||||
|
||||
return authorizeMPToken(view, tx, priorBalance, mptID, accountID, journal, 0, std::nullopt);
|
||||
return authorizeMPToken(ctx, priorBalance, mptID, accountID, journal, 0, std::nullopt);
|
||||
}
|
||||
|
||||
[[nodiscard]] TER
|
||||
authorizeMPToken(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
XRPAmount const& priorBalance,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
@@ -159,7 +156,7 @@ authorizeMPToken(
|
||||
std::uint32_t flags,
|
||||
std::optional<AccountID> holderID)
|
||||
{
|
||||
auto const sleAcct = view.peek(keylet::account(account));
|
||||
auto const sleAcct = ctx.view.peek(keylet::account(account));
|
||||
if (!sleAcct)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -174,19 +171,19 @@ authorizeMPToken(
|
||||
if ((flags & tfMPTUnauthorize) != 0u)
|
||||
{
|
||||
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account);
|
||||
auto const sleMpt = view.peek(mptokenKey);
|
||||
auto const sleMpt = ctx.view.peek(mptokenKey);
|
||||
if (!sleMpt || (*sleMpt)[sfMPTAmount] != 0 ||
|
||||
(view.rules().enabled(fixCleanup3_1_3) &&
|
||||
(ctx.view.rules().enabled(fixCleanup3_1_3) &&
|
||||
(*sleMpt)[~sfLockedAmount].valueOr(0) != 0))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (!view.dirRemove(
|
||||
if (!ctx.view.dirRemove(
|
||||
keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
decreaseOwnerCountForObject(view, sleAcct, sleMpt, 1, journal);
|
||||
decreaseOwnerCountForObject(ctx.view, sleAcct, sleMpt, 1, journal);
|
||||
|
||||
view.erase(sleMpt);
|
||||
ctx.view.erase(sleMpt);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -195,9 +192,9 @@ authorizeMPToken(
|
||||
// - create the MPToken object for the holder
|
||||
|
||||
SLE::pointer sponsorSle;
|
||||
if (account == tx[sfAccount])
|
||||
if (account == ctx.tx[sfAccount])
|
||||
{
|
||||
auto sle = getTxReserveSponsor(view, tx);
|
||||
auto sle = getTxReserveSponsor(ctx);
|
||||
if (!sle)
|
||||
return sle.error(); // LCOV_EXCL_LINE
|
||||
sponsorSle = std::move(*sle);
|
||||
@@ -214,40 +211,40 @@ authorizeMPToken(
|
||||
if (sponsorSle || ownerCount(sleAcct, journal) >= 2)
|
||||
{
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view, tx, sleAcct, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
ctx, sleAcct, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Defensive check before we attempt to create MPToken for the issuer
|
||||
auto const mpt = view.read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
auto const mpt = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
if (!mpt || mpt->getAccountID(sfIssuer) == account)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("xrpl::authorizeMPToken : invalid issuance or issuers token");
|
||||
if (view.rules().enabled(featureLendingProtocol))
|
||||
if (ctx.view.rules().enabled(featureLendingProtocol))
|
||||
return tecINTERNAL;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account);
|
||||
auto mptoken = std::make_shared<SLE>(mptokenKey);
|
||||
if (auto ter = dirLink(view, account, mptoken))
|
||||
if (auto ter = dirLink(ctx.view, account, mptoken))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
|
||||
(*mptoken)[sfAccount] = account;
|
||||
(*mptoken)[sfMPTokenIssuanceID] = mptIssuanceID;
|
||||
(*mptoken)[sfFlags] = 0;
|
||||
view.insert(mptoken);
|
||||
ctx.view.insert(mptoken);
|
||||
|
||||
// Update owner count.
|
||||
increaseOwnerCount(view, sleAcct, sponsorSle, 1, journal);
|
||||
increaseOwnerCount(ctx.view, sleAcct, sponsorSle, 1, journal);
|
||||
addSponsorToLedgerEntry(mptoken, sponsorSle);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
auto const sleMptIssuance = view.read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
auto const sleMptIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
if (!sleMptIssuance)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -257,7 +254,7 @@ authorizeMPToken(
|
||||
if (account != (*sleMptIssuance)[sfIssuer])
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID));
|
||||
auto const sleMpt = ctx.view.peek(keylet::mptoken(mptIssuanceID, *holderID));
|
||||
if (!sleMpt)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -280,14 +277,13 @@ authorizeMPToken(
|
||||
if (flagsIn != flagsOut)
|
||||
sleMpt->setFieldU32(sfFlags, flagsOut);
|
||||
|
||||
view.update(sleMpt);
|
||||
ctx.view.update(sleMpt);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
MPTIssue const& mptIssue,
|
||||
beast::Journal journal)
|
||||
@@ -297,7 +293,7 @@ removeEmptyHolding(
|
||||
// a token does exist, it will get deleted. If not, return success.
|
||||
bool const accountIsIssuer = accountID == mptIssue.getIssuer();
|
||||
auto const& mptID = mptIssue.getMptID();
|
||||
auto const mptoken = view.peek(keylet::mptoken(mptID, accountID));
|
||||
auto const mptoken = ctx.view.peek(keylet::mptoken(mptID, accountID));
|
||||
if (!mptoken)
|
||||
return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND;
|
||||
// Unlike a trust line, if the account is the issuer, and the token has a
|
||||
@@ -305,7 +301,7 @@ removeEmptyHolding(
|
||||
// accounting out of balance, so fail. Since this should be impossible
|
||||
// anyway, I'm not going to put any effort into it.
|
||||
if (mptoken->at(sfMPTAmount) != 0 ||
|
||||
(view.rules().enabled(fixCleanup3_1_3) && (*mptoken)[~sfLockedAmount].valueOr(0) != 0))
|
||||
(ctx.view.rules().enabled(fixCleanup3_1_3) && (*mptoken)[~sfLockedAmount].valueOr(0) != 0))
|
||||
return tecHAS_OBLIGATIONS;
|
||||
|
||||
// Don't delete if the token still has confidential balances
|
||||
@@ -318,8 +314,7 @@ removeEmptyHolding(
|
||||
}
|
||||
|
||||
return authorizeMPToken(
|
||||
view,
|
||||
tx,
|
||||
ctx,
|
||||
{}, // priorBalance
|
||||
mptID,
|
||||
accountID,
|
||||
@@ -438,14 +433,13 @@ requireAuth(
|
||||
|
||||
[[nodiscard]] TER
|
||||
enforceMPTokenAuthorization(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
XRPAmount const& priorBalance, // for MPToken authorization
|
||||
beast::Journal j)
|
||||
{
|
||||
auto const sleIssuance = view.read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
auto const sleIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
if (!sleIssuance)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -457,7 +451,7 @@ enforceMPTokenAuthorization(
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const keylet = keylet::mptoken(mptIssuanceID, account);
|
||||
auto const sleToken = view.read(keylet); // NOTE: might be null
|
||||
auto const sleToken = ctx.view.read(keylet); // NOTE: might be null
|
||||
auto const maybeDomainID = sleIssuance->at(~sfDomainID);
|
||||
bool expired = false;
|
||||
bool const authorizedByDomain = [&]() -> bool {
|
||||
@@ -465,7 +459,7 @@ enforceMPTokenAuthorization(
|
||||
if (!maybeDomainID.has_value())
|
||||
return false; // LCOV_EXCL_LINE
|
||||
|
||||
auto const ter = verifyValidDomain(view, account, *maybeDomainID, j);
|
||||
auto const ter = verifyValidDomain(ctx.view, account, *maybeDomainID, j);
|
||||
if (isTesSuccess(ter))
|
||||
return true;
|
||||
if (ter == tecEXPIRED)
|
||||
@@ -520,8 +514,7 @@ enforceMPTokenAuthorization(
|
||||
maybeDomainID.has_value() && sleToken == nullptr,
|
||||
"xrpl::enforceMPTokenAuthorization : new MPToken for domain");
|
||||
if (auto const err = authorizeMPToken(
|
||||
view,
|
||||
tx,
|
||||
ctx,
|
||||
priorBalance, // priorBalance
|
||||
mptIssuanceID, // mptIssuanceID
|
||||
account, // account
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
@@ -634,8 +633,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
|
||||
TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Issue const& issue,
|
||||
@@ -647,29 +645,29 @@ addEmptyHolding(
|
||||
|
||||
auto const& issuerId = issue.getIssuer();
|
||||
auto const& currency = issue.currency;
|
||||
if (isGlobalFrozen(view, issuerId))
|
||||
if (isGlobalFrozen(ctx.view, issuerId))
|
||||
return tecFROZEN; // LCOV_EXCL_LINE
|
||||
|
||||
auto const& srcId = issuerId;
|
||||
auto const& dstId = accountID;
|
||||
auto const high = srcId > dstId;
|
||||
auto const index = keylet::trustLine(srcId, dstId, currency);
|
||||
auto const sleSrc = view.peek(keylet::account(srcId));
|
||||
auto const sleDst = view.peek(keylet::account(dstId));
|
||||
auto const sleSrc = ctx.view.peek(keylet::account(srcId));
|
||||
auto const sleDst = ctx.view.peek(keylet::account(dstId));
|
||||
if (!sleDst || !sleSrc)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
if (!sleSrc->isFlag(lsfDefaultRipple))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
// If the line already exists, don't create it again.
|
||||
if (view.read(index))
|
||||
if (ctx.view.read(index))
|
||||
return tecDUPLICATE;
|
||||
|
||||
SLE::pointer sponsorSle;
|
||||
|
||||
// A reserve sponsor only covers tx.Account's own objects.
|
||||
if (!isPseudoAccount(sleDst) && accountID == tx[sfAccount])
|
||||
if (!isPseudoAccount(sleDst) && accountID == ctx.tx[sfAccount])
|
||||
{
|
||||
auto sle = getTxReserveSponsor(view, tx);
|
||||
auto sle = getTxReserveSponsor(ctx);
|
||||
if (!sle)
|
||||
return sle.error(); // LCOV_EXCL_LINE
|
||||
sponsorSle = std::move(*sle);
|
||||
@@ -677,12 +675,12 @@ addEmptyHolding(
|
||||
|
||||
// Can the account cover the trust line reserve ?
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view, tx, sleDst, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
ctx, sleDst, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
!isTesSuccess(ret))
|
||||
return tecNO_LINE_INSUF_RESERVE;
|
||||
|
||||
return trustCreate(
|
||||
view,
|
||||
ctx.view,
|
||||
high,
|
||||
srcId,
|
||||
dstId,
|
||||
@@ -702,14 +700,14 @@ addEmptyHolding(
|
||||
|
||||
TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
Issue const& issue,
|
||||
beast::Journal journal)
|
||||
{
|
||||
if (issue.native())
|
||||
{
|
||||
auto const sle = view.read(keylet::account(accountID));
|
||||
auto const sle = ctx.view.read(keylet::account(accountID));
|
||||
if (!sle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -724,7 +722,7 @@ removeEmptyHolding(
|
||||
// If the account is the issuer, then no line should exist. Check anyway.
|
||||
// If a line does exist, it will get deleted. If not, return success.
|
||||
bool const accountIsIssuer = accountID == issue.account;
|
||||
auto const line = view.peek(keylet::trustLine(accountID, issue));
|
||||
auto const line = ctx.view.peek(keylet::trustLine(accountID, issue));
|
||||
if (!line)
|
||||
return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND;
|
||||
if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::kZero)
|
||||
@@ -734,13 +732,13 @@ removeEmptyHolding(
|
||||
if (line->isFlag(lsfLowReserve))
|
||||
{
|
||||
// Clear reserve for low account.
|
||||
auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer()));
|
||||
auto sleLowAccount = ctx.view.peek(keylet::account(line->at(sfLowLimit)->getIssuer()));
|
||||
if (!sleLowAccount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const currentLowSponsor = getLedgerEntryReserveSponsor(view, line, sfLowSponsor);
|
||||
auto const currentLowSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfLowSponsor);
|
||||
|
||||
decreaseOwnerCount(view, sleLowAccount, currentLowSponsor, 1, journal);
|
||||
decreaseOwnerCount(ctx.view, sleLowAccount, currentLowSponsor, 1, journal);
|
||||
// It's not really necessary to clear the reserve flag, since the line
|
||||
// is about to be deleted, but this will make the metadata reflect an
|
||||
// accurate state at the time of deletion.
|
||||
@@ -751,13 +749,13 @@ removeEmptyHolding(
|
||||
if (line->isFlag(lsfHighReserve))
|
||||
{
|
||||
// Clear reserve for high account.
|
||||
auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer()));
|
||||
auto sleHighAccount = ctx.view.peek(keylet::account(line->at(sfHighLimit)->getIssuer()));
|
||||
if (!sleHighAccount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const currentHighSponsor = getLedgerEntryReserveSponsor(view, line, sfHighSponsor);
|
||||
auto const currentHighSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfHighSponsor);
|
||||
|
||||
decreaseOwnerCount(view, sleHighAccount, currentHighSponsor, 1, journal);
|
||||
decreaseOwnerCount(ctx.view, sleHighAccount, currentHighSponsor, 1, journal);
|
||||
// It's not really necessary to clear the reserve flag, since the line
|
||||
// is about to be deleted, but this will make the metadata reflect an
|
||||
// accurate state at the time of deletion.
|
||||
@@ -766,7 +764,11 @@ removeEmptyHolding(
|
||||
}
|
||||
|
||||
return trustDelete(
|
||||
view, line, line->at(sfLowLimit)->getIssuer(), line->at(sfHighLimit)->getIssuer(), journal);
|
||||
ctx.view,
|
||||
line,
|
||||
line->at(sfLowLimit)->getIssuer(),
|
||||
line->at(sfHighLimit)->getIssuer(),
|
||||
journal);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
@@ -573,8 +572,7 @@ canAddHolding(ReadView const& view, Asset const& asset)
|
||||
|
||||
TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Asset const& asset,
|
||||
@@ -582,29 +580,21 @@ addEmptyHolding(
|
||||
{
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
|
||||
return addEmptyHolding(view, tx, accountID, priorBalance, issue, journal);
|
||||
return addEmptyHolding(ctx, accountID, priorBalance, issue, journal);
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
|
||||
TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
AccountID const& accountID,
|
||||
Asset const& asset,
|
||||
beast::Journal journal)
|
||||
{
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return removeEmptyHolding(view, accountID, issue, journal);
|
||||
}
|
||||
else
|
||||
{
|
||||
return removeEmptyHolding(view, tx, accountID, issue, journal);
|
||||
}
|
||||
return removeEmptyHolding(ctx, accountID, issue, journal);
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ SponsorshipSet::doApply()
|
||||
|
||||
bool const hasPositiveFeeAmount = feeAmount.has_value() && *feeAmount > beast::kZero;
|
||||
|
||||
auto reserveSponsorAccSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto reserveSponsorAccSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!reserveSponsorAccSle)
|
||||
return reserveSponsorAccSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
@@ -226,8 +226,7 @@ SponsorshipSet::doApply()
|
||||
sponsorBalanceAfterFee -= *feeAmount;
|
||||
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponsorAccSle,
|
||||
sponsorBalanceAfterFee.xrp(),
|
||||
*reserveSponsorAccSle,
|
||||
@@ -294,8 +293,7 @@ SponsorshipSet::doApply()
|
||||
sponsorBalanceAfterFee -= feeAmountDelta;
|
||||
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponsorAccSle,
|
||||
sponsorBalanceAfterFee.xrp(),
|
||||
*reserveSponsorAccSle,
|
||||
|
||||
@@ -322,8 +322,7 @@ SponsorshipTransfer::doApply()
|
||||
// check new sponsor have sufficient balance
|
||||
// NOLINTNEXTLINE(readability-suspicious-call-argument)
|
||||
if (auto const ter = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance),
|
||||
newSponsorSle,
|
||||
@@ -376,8 +375,7 @@ SponsorshipTransfer::doApply()
|
||||
// check new sponsor have sufficient balance
|
||||
// NOLINTNEXTLINE(readability-suspicious-call-argument)
|
||||
if (auto const ter = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance),
|
||||
newSponsorSle,
|
||||
@@ -425,8 +423,7 @@ SponsorshipTransfer::doApply()
|
||||
// The owner takes the reserve burden back when the object is
|
||||
// no longer sponsored.
|
||||
if (auto const ter = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
ownerSle,
|
||||
balanceBeforeFee(ownerSle),
|
||||
SLE::pointer(),
|
||||
@@ -466,8 +463,7 @@ SponsorshipTransfer::doApply()
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ter = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance),
|
||||
newSponsorSle,
|
||||
@@ -495,8 +491,7 @@ SponsorshipTransfer::doApply()
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ter = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance),
|
||||
newSponsorSle,
|
||||
@@ -532,8 +527,7 @@ SponsorshipTransfer::doApply()
|
||||
// The sponsee must be able to hold its own account reserve after
|
||||
// the sponsorship is removed.
|
||||
if (auto const ter = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
balanceBeforeFee(sponseeSle),
|
||||
SLE::pointer(),
|
||||
|
||||
@@ -319,12 +319,11 @@ SignerListSet::replaceSignerList()
|
||||
// We check the reserve against the starting balance because we want to
|
||||
// allow dipping into the reserve to pay fees. This behavior is consistent
|
||||
// with TicketCreate.
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/scope.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
@@ -388,7 +389,8 @@ CheckCash::doApply()
|
||||
STAmount const flowDeliver{
|
||||
optDeliverMin ? maxDeliverMin() : ctx_.tx.getFieldAmount(sfAmount)};
|
||||
|
||||
auto const sponsorSle = getTxReserveSponsor(psb, ctx_.tx);
|
||||
auto applyViewContext = ApplyViewContext({.view = psb, .tx = ctx_.tx});
|
||||
auto const sponsorSle = getTxReserveSponsor(applyViewContext);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
@@ -399,8 +401,7 @@ CheckCash::doApply()
|
||||
|
||||
// Can the account cover the trust line's or MPT reserve?
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
psb,
|
||||
ctx_.tx,
|
||||
applyViewContext,
|
||||
sleDst,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
|
||||
@@ -195,12 +195,11 @@ CheckCreate::doApply()
|
||||
// A check counts against the reserve of the issuing account, but we
|
||||
// check the starting balance because we want to allow dipping into the
|
||||
// reserve to pay fees.
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
|
||||
@@ -99,12 +99,11 @@ DelegateSet::doApply()
|
||||
if (permissions.empty())
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sleOwner,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
|
||||
@@ -181,8 +181,7 @@ EscrowCancel::doApply()
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) {
|
||||
return escrowUnlockApplyHelper<T>(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
kParityRate,
|
||||
ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : slep,
|
||||
preFeeBalance_,
|
||||
|
||||
@@ -437,7 +437,7 @@ EscrowCreate::doApply()
|
||||
STAmount const amount{ctx_.tx[sfAmount]};
|
||||
|
||||
auto const balance = sle->getFieldAmount(sfBalance).xrp();
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
// First check: whoever is on the hook for the new owner increment
|
||||
@@ -446,7 +446,7 @@ EscrowCreate::doApply()
|
||||
// unsponsored this hits the source branch and validates the
|
||||
// source's pre-lock balance against base + (currentOC+1)*increment.
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(), ctx_.tx, sle, balance, *sponsorSle, {.ownerCountDelta = 1}, j_);
|
||||
ctx_.getApplyViewContext(), sle, balance, *sponsorSle, {.ownerCountDelta = 1}, j_);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -463,8 +463,7 @@ EscrowCreate::doApply()
|
||||
// - unsponsored: adj=1 — source owes base + the new increment.
|
||||
std::int32_t const ownerCountAdj = *sponsorSle ? 0 : 1;
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
balance - STAmount(amount).xrp(),
|
||||
{},
|
||||
|
||||
@@ -365,8 +365,7 @@ EscrowFinish::doApply()
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) {
|
||||
return escrowUnlockApplyHelper<T>(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
lockedRate,
|
||||
sled,
|
||||
preFeeBalance_,
|
||||
|
||||
@@ -211,7 +211,14 @@ LoanBrokerCoverWithdraw::doApply()
|
||||
|
||||
associateAsset(*broker, vaultAsset);
|
||||
|
||||
return doWithdraw(view(), tx, accountID_, dstAcct, brokerPseudoID, preFeeBalance_, amount, j_);
|
||||
return doWithdraw(
|
||||
ctx_.getApplyViewContext(),
|
||||
accountID_,
|
||||
dstAcct,
|
||||
brokerPseudoID,
|
||||
preFeeBalance_,
|
||||
amount,
|
||||
j_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -159,7 +159,7 @@ LoanBrokerDelete::doApply()
|
||||
return ter;
|
||||
}
|
||||
|
||||
if (auto ter = removeEmptyHolding(view(), tx, brokerPseudoID, vaultAsset, j_))
|
||||
if (auto ter = removeEmptyHolding(ctx_.getApplyViewContext(), brokerPseudoID, vaultAsset, j_))
|
||||
return ter;
|
||||
|
||||
auto brokerPseudoSLE = view().peek(keylet::account(brokerPseudoID));
|
||||
|
||||
@@ -248,8 +248,8 @@ LoanBrokerSet::doApply()
|
||||
auto& pseudo = *maybePseudo;
|
||||
auto pseudoId = pseudo->at(sfAccount);
|
||||
|
||||
if (auto ter =
|
||||
addEmptyHolding(view, tx, pseudoId, preFeeBalance_, sleVault->at(sfAsset), j_))
|
||||
if (auto ter = addEmptyHolding(
|
||||
ctx_.getApplyViewContext(), pseudoId, preFeeBalance_, sleVault->at(sfAsset), j_))
|
||||
return ter;
|
||||
|
||||
// Initialize data fields:
|
||||
|
||||
@@ -625,7 +625,11 @@ LoanPay::doApply()
|
||||
{
|
||||
// The broker may have deleted their holding. Recreate it if needed
|
||||
if (auto const ter = addEmptyHolding(
|
||||
view, tx, brokerPayee, brokerPayeeSle->at(sfBalance).value().xrp(), asset, j_);
|
||||
ctx_.getApplyViewContext(),
|
||||
brokerPayee,
|
||||
brokerPayeeSle->at(sfBalance).value().xrp(),
|
||||
asset,
|
||||
j_);
|
||||
ter && ter != tecDUPLICATE)
|
||||
{
|
||||
// ignore tecDUPLICATE. That means the holding already exists,
|
||||
|
||||
@@ -538,8 +538,9 @@ LoanSet::doApply()
|
||||
borrower == accountID_ || borrower == counterparty,
|
||||
"xrpl::LoanSet::doApply",
|
||||
"borrower signed transaction");
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
if (auto const ter = addEmptyHolding(
|
||||
view, tx, borrower, borrowerSle->at(sfBalance).value().xrp(), vaultAsset, j_);
|
||||
applyViewContext, borrower, borrowerSle->at(sfBalance).value().xrp(), vaultAsset, j_);
|
||||
ter && ter != tecDUPLICATE)
|
||||
{
|
||||
// ignore tecDUPLICATE. That means the holding already exists, and
|
||||
@@ -562,7 +563,11 @@ LoanSet::doApply()
|
||||
"broker owner signed transaction");
|
||||
|
||||
if (auto const ter = addEmptyHolding(
|
||||
view, tx, brokerOwner, brokerOwnerSle->at(sfBalance).value().xrp(), vaultAsset, j_);
|
||||
applyViewContext,
|
||||
brokerOwner,
|
||||
brokerOwnerSle->at(sfBalance).value().xrp(),
|
||||
vaultAsset,
|
||||
j_);
|
||||
ter && ter != tecDUPLICATE)
|
||||
{
|
||||
// ignore tecDUPLICATE. That means the holding already exists,
|
||||
|
||||
@@ -152,6 +152,7 @@ DepositPreauth::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
DepositPreauth::doApply()
|
||||
{
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
if (ctx_.tx.isFieldPresent(sfAuthorize))
|
||||
{
|
||||
auto const sleOwner = view().peek(keylet::account(accountID_));
|
||||
@@ -161,11 +162,16 @@ DepositPreauth::doApply()
|
||||
// A preauth counts against the reserve of the issuing account, but we
|
||||
// check the starting balance because we want to allow dipping into the
|
||||
// reserve to pay fees.
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(applyViewContext);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view(), ctx_.tx, sleOwner, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_);
|
||||
applyViewContext,
|
||||
sleOwner,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -209,11 +215,16 @@ DepositPreauth::doApply()
|
||||
// A preauth counts against the reserve of the issuing account, but we
|
||||
// check the starting balance because we want to allow dipping into the
|
||||
// reserve to pay fees.
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(applyViewContext);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view(), ctx_.tx, sleOwner, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_);
|
||||
applyViewContext,
|
||||
sleOwner,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ PaymentChannelCreate::doApply()
|
||||
return tecEXPIRED;
|
||||
}
|
||||
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
@@ -147,7 +147,12 @@ PaymentChannelCreate::doApply()
|
||||
// unsponsored this hits the source branch and validates the
|
||||
// source's pre-lock balance against base + (currentOC+1)*increment.
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(), ctx_.tx, sle, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_);
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -161,8 +166,7 @@ PaymentChannelCreate::doApply()
|
||||
// - unsponsored: adj=1 — source owes base + the new increment.
|
||||
std::int32_t const ownerCountAdj = *sponsorSle ? 0 : 1;
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_ - ctx_.tx[sfAmount].xrp(),
|
||||
{},
|
||||
|
||||
@@ -90,16 +90,16 @@ PaymentChannelFund::doApply()
|
||||
{
|
||||
// Check reserve and funds availability
|
||||
auto const balance = (*sle)[sfBalance];
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
if (auto const ret =
|
||||
checkInsufficientReserve(ctx_.view(), ctx_.tx, sle, balance, *sponsorSle, {}, j_);
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.getApplyViewContext(), sle, balance, *sponsorSle, {}, j_);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(), ctx_.tx, sle, balance - ctx_.tx[sfAmount], {}, {}, j_);
|
||||
ctx_.getApplyViewContext(), sle, balance - ctx_.tx[sfAmount], {}, {}, j_);
|
||||
!isTesSuccess(ret))
|
||||
return tecUNFUNDED;
|
||||
}
|
||||
|
||||
@@ -164,8 +164,7 @@ MPTokenAuthorize::doApply()
|
||||
{
|
||||
auto const& tx = ctx_.tx;
|
||||
return authorizeMPToken(
|
||||
ctx_.view(),
|
||||
tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
preFeeBalance_,
|
||||
tx[sfMPTokenIssuanceID],
|
||||
accountID_,
|
||||
|
||||
@@ -116,19 +116,18 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx)
|
||||
|
||||
std::expected<MPTID, TER>
|
||||
MPTokenIssuanceCreate::create(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
ApplyViewContext ctx,
|
||||
beast::Journal journal,
|
||||
MPTCreateArgs const& args)
|
||||
{
|
||||
auto const acct = view.peek(keylet::account(args.account));
|
||||
auto const acct = ctx.view.peek(keylet::account(args.account));
|
||||
if (!acct)
|
||||
return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
SLE::pointer sponsorSle;
|
||||
if (!isPseudoAccount(acct))
|
||||
{
|
||||
auto sle = getTxReserveSponsor(view, tx);
|
||||
auto sle = getTxReserveSponsor(ctx);
|
||||
if (!sle)
|
||||
return std::unexpected(sle.error());
|
||||
sponsorSle = std::move(*sle);
|
||||
@@ -137,7 +136,7 @@ MPTokenIssuanceCreate::create(
|
||||
if (args.priorBalance)
|
||||
{
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view, tx, acct, *(args.priorBalance), sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
ctx, acct, *(args.priorBalance), sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
!isTesSuccess(ret))
|
||||
return std::unexpected(ret); // tecINSUFFICIENT_RESERVE
|
||||
}
|
||||
@@ -147,7 +146,7 @@ MPTokenIssuanceCreate::create(
|
||||
|
||||
// create the MPTokenIssuance
|
||||
{
|
||||
auto const ownerNode = view.dirInsert(
|
||||
auto const ownerNode = ctx.view.dirInsert(
|
||||
keylet::ownerDir(args.account), mptIssuanceKeylet, describeOwnerDir(args.account));
|
||||
|
||||
if (!ownerNode)
|
||||
@@ -185,7 +184,7 @@ MPTokenIssuanceCreate::create(
|
||||
// populate this after the pseudo-account's MPToken /
|
||||
// RippleState has been installed. A missing holding here
|
||||
// would dangle the pointer and is a programmer error.
|
||||
auto const sleHolding = view.read(keylet::unchecked(*args.referenceHolding));
|
||||
auto const sleHolding = ctx.view.read(keylet::unchecked(*args.referenceHolding));
|
||||
if (!sleHolding)
|
||||
return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE
|
||||
auto const type = sleHolding->getType();
|
||||
@@ -196,11 +195,11 @@ MPTokenIssuanceCreate::create(
|
||||
|
||||
addSponsorToLedgerEntry(mptIssuance, sponsorSle);
|
||||
|
||||
view.insert(mptIssuance);
|
||||
ctx.view.insert(mptIssuance);
|
||||
}
|
||||
|
||||
// Update owner count.
|
||||
increaseOwnerCount(view, acct, sponsorSle, 1, journal);
|
||||
increaseOwnerCount(ctx.view, acct, sponsorSle, 1, journal);
|
||||
|
||||
return mptId;
|
||||
}
|
||||
@@ -210,8 +209,7 @@ MPTokenIssuanceCreate::doApply()
|
||||
{
|
||||
auto const& tx = ctx_.tx;
|
||||
auto const result = create(
|
||||
view(),
|
||||
tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
j_,
|
||||
{
|
||||
.priorBalance = preFeeBalance_,
|
||||
|
||||
@@ -328,7 +328,7 @@ TrustSet::doApply()
|
||||
// well. A person with no intention of using the gateway
|
||||
// could use the extra XRP for their own purposes.
|
||||
|
||||
auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx);
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
@@ -539,8 +539,7 @@ TrustSet::doApply()
|
||||
// For PreFunded sponsors, we need to check if there are sufficient reserves before
|
||||
// calling increaseOwnerCount().
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sleLowAccount,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
@@ -574,8 +573,7 @@ TrustSet::doApply()
|
||||
// For PreFunded sponsors, we need to check if there are sufficient reserves before
|
||||
// calling increaseOwnerCount().
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
view(),
|
||||
ctx_.tx,
|
||||
ctx_.getApplyViewContext(),
|
||||
sleHighAccount,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
@@ -614,8 +612,8 @@ TrustSet::doApply()
|
||||
}
|
||||
// Reserve is not scaled by load.
|
||||
else if (
|
||||
auto const ret =
|
||||
checkInsufficientReserve(view(), ctx_.tx, sle, preFeeBalance_, *sponsorSle, {}, j_);
|
||||
auto const ret = checkInsufficientReserve(
|
||||
ctx_.getApplyViewContext(), sle, preFeeBalance_, *sponsorSle, {}, j_);
|
||||
!freeTrustLine && bReserveIncrease && !isTesSuccess(ret))
|
||||
{
|
||||
JLOG(j_.trace()) << "Delay transaction: Insufficent reserve to "
|
||||
@@ -646,7 +644,12 @@ TrustSet::doApply()
|
||||
}
|
||||
else if (
|
||||
auto const ret = checkInsufficientReserve(
|
||||
ctx_.view(), ctx_.tx, sle, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_);
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_);
|
||||
!freeTrustLine && !isTesSuccess(ret)) // Reserve is not scaled by load.
|
||||
{
|
||||
JLOG(j_.trace()) << "Delay transaction: Line does not exist. "
|
||||
|
||||
@@ -399,7 +399,8 @@ VaultClawback::doApply()
|
||||
// Keep MPToken if holder is the vault owner.
|
||||
if (holder != vault->at(sfOwner))
|
||||
{
|
||||
if (auto const ter = removeEmptyHolding(view(), tx, holder, sharesDestroyed.asset(), j_);
|
||||
if (auto const ter =
|
||||
removeEmptyHolding(ctx_.getApplyViewContext(), holder, sharesDestroyed.asset(), j_);
|
||||
isTesSuccess(ter))
|
||||
{
|
||||
JLOG(j_.debug()) //
|
||||
|
||||
@@ -146,6 +146,7 @@ VaultCreate::doApply()
|
||||
// we can consider downgrading them to `tef` or `tem`.
|
||||
|
||||
auto const& tx = ctx_.tx;
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
auto const sequence = tx.getSeqValue();
|
||||
auto const owner = view().peek(keylet::account(accountID_));
|
||||
if (owner == nullptr)
|
||||
@@ -167,7 +168,7 @@ VaultCreate::doApply()
|
||||
AccountID const pseudoId = pseudo->at(sfAccount);
|
||||
auto const asset = tx[sfAsset];
|
||||
|
||||
if (auto ter = addEmptyHolding(view(), tx, pseudoId, preFeeBalance_, asset, j_);
|
||||
if (auto ter = addEmptyHolding(applyViewContext, pseudoId, preFeeBalance_, asset, j_);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
@@ -197,8 +198,7 @@ VaultCreate::doApply()
|
||||
: keylet::trustLine(pseudoId, asset.get<Issue>()).key;
|
||||
}();
|
||||
auto const maybeShare = MPTokenIssuanceCreate::create(
|
||||
view(),
|
||||
tx,
|
||||
applyViewContext,
|
||||
j_,
|
||||
{
|
||||
.priorBalance = std::nullopt,
|
||||
@@ -244,8 +244,8 @@ VaultCreate::doApply()
|
||||
view().insert(vault);
|
||||
|
||||
// Explicitly create MPToken for the vault owner
|
||||
if (auto const err =
|
||||
authorizeMPToken(view(), tx, preFeeBalance_, mptIssuanceID, accountID_, ctx_.journal);
|
||||
if (auto const err = authorizeMPToken(
|
||||
applyViewContext, preFeeBalance_, mptIssuanceID, accountID_, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -253,7 +253,13 @@ VaultCreate::doApply()
|
||||
if (tx.isFlag(tfVaultPrivate))
|
||||
{
|
||||
if (auto const err = authorizeMPToken(
|
||||
view(), tx, preFeeBalance_, mptIssuanceID, pseudoId, ctx_.journal, {}, accountID_);
|
||||
applyViewContext,
|
||||
preFeeBalance_,
|
||||
mptIssuanceID,
|
||||
pseudoId,
|
||||
ctx_.journal,
|
||||
{},
|
||||
accountID_);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -96,13 +96,14 @@ TER
|
||||
VaultDelete::doApply()
|
||||
{
|
||||
auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID]));
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
if (!vault)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Destroy the asset holding.
|
||||
auto asset = vault->at(sfAsset);
|
||||
|
||||
if (auto ter = removeEmptyHolding(view(), ctx_.tx, vault->at(sfAccount), asset, j_);
|
||||
if (auto ter = removeEmptyHolding(applyViewContext, vault->at(sfAccount), asset, j_);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
@@ -132,7 +133,7 @@ VaultDelete::doApply()
|
||||
if (auto const mptoken = view().peek(keylet::mptoken(shareMPTID, accountID_)))
|
||||
{
|
||||
if (auto const ter =
|
||||
removeEmptyHolding(view(), ctx_.tx, accountID_, MPTIssue(shareMPTID), j_);
|
||||
removeEmptyHolding(applyViewContext, accountID_, MPTIssue(shareMPTID), j_);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
@@ -197,6 +197,7 @@ VaultDeposit::doApply()
|
||||
{
|
||||
bool const fix320Enabled = view().rules().enabled(fixCleanup3_2_0);
|
||||
auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID]));
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
if (!vault)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const vaultAsset = vault->at(sfAsset);
|
||||
@@ -231,7 +232,7 @@ VaultDeposit::doApply()
|
||||
if (vault->isFlag(lsfVaultPrivate) && accountID_ != vault->at(sfOwner))
|
||||
{
|
||||
if (auto const err = enforceMPTokenAuthorization(
|
||||
ctx_.view(), ctx_.tx, mptIssuanceID, accountID_, preFeeBalance_, j_);
|
||||
applyViewContext, mptIssuanceID, accountID_, preFeeBalance_, j_);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
@@ -241,8 +242,7 @@ VaultDeposit::doApply()
|
||||
if (!view().exists(keylet::mptoken(mptIssuanceID, accountID_)))
|
||||
{
|
||||
if (auto const err = authorizeMPToken(
|
||||
view(),
|
||||
ctx_.tx,
|
||||
applyViewContext,
|
||||
preFeeBalance_,
|
||||
mptIssuanceID->value(),
|
||||
accountID_,
|
||||
@@ -258,8 +258,7 @@ VaultDeposit::doApply()
|
||||
XRPL_ASSERT(
|
||||
accountID_ == vault->at(sfOwner), "xrpl::VaultDeposit::doApply : account is owner");
|
||||
if (auto const err = authorizeMPToken(
|
||||
view(),
|
||||
ctx_.tx,
|
||||
applyViewContext,
|
||||
preFeeBalance_, // priorBalance
|
||||
mptIssuanceID->value(), // mptIssuanceID
|
||||
sleIssuance->at(sfIssuer), // account
|
||||
|
||||
@@ -194,6 +194,7 @@ TER
|
||||
VaultWithdraw::doApply()
|
||||
{
|
||||
auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID]));
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
if (!vault)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -362,7 +363,7 @@ VaultWithdraw::doApply()
|
||||
if (accountID_ != vault->at(sfOwner))
|
||||
{
|
||||
if (auto const ter =
|
||||
removeEmptyHolding(view(), ctx_.tx, accountID_, sharesRedeemed.asset(), j_);
|
||||
removeEmptyHolding(applyViewContext, accountID_, sharesRedeemed.asset(), j_);
|
||||
isTesSuccess(ter))
|
||||
{
|
||||
JLOG(j_.debug()) //
|
||||
@@ -388,7 +389,7 @@ VaultWithdraw::doApply()
|
||||
|
||||
auto const dstAcct = ctx_.tx[~sfDestination].value_or(accountID_);
|
||||
return doWithdraw(
|
||||
view(), ctx_.tx, accountID_, dstAcct, vaultAccount, preFeeBalance_, assetsWithdrawn, j_);
|
||||
applyViewContext, accountID_, dstAcct, vaultAccount, preFeeBalance_, assetsWithdrawn, j_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -5930,7 +5930,7 @@ class Vault_test : public beast::unit_test::Suite
|
||||
|
||||
auto const dummyTx = *env.jt(noop(holder)).stx;
|
||||
BEAST_EXPECT(
|
||||
removeEmptyHolding(sb, dummyTx, holder.id(), MPTIssue(mpt.issuanceID()), j) ==
|
||||
removeEmptyHolding({sb, dummyTx}, holder.id(), MPTIssue(mpt.issuanceID()), j) ==
|
||||
tecHAS_OBLIGATIONS);
|
||||
BEAST_EXPECT(sb.peek(tokenKeylet) != nullptr);
|
||||
}
|
||||
@@ -7544,7 +7544,7 @@ class Vault_test : public beast::unit_test::Suite
|
||||
// Transaction fails if the data field is set, but is empty
|
||||
{
|
||||
testcase("VaultDelete memo data featureLendingProtocolV1_1 enabled data empty");
|
||||
delTx[sfMemoData] = strHex(std::string(0, 'A'));
|
||||
delTx[sfMemoData] = std::string();
|
||||
env(delTx, Ter(temMALFORMED));
|
||||
env.close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user