1#include <xrpl/tx/transactors/escrow/EscrowFinish.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/basics/chrono.h>
6#include <xrpl/conditions/Condition.h>
7#include <xrpl/conditions/Fulfillment.h>
8#include <xrpl/core/HashRouter.h>
9#include <xrpl/ledger/ApplyView.h>
10#include <xrpl/ledger/ReadView.h>
11#include <xrpl/ledger/View.h>
12#include <xrpl/ledger/helpers/AccountRootHelpers.h>
13#include <xrpl/ledger/helpers/CredentialHelpers.h>
14#include <xrpl/ledger/helpers/EscrowHelpers.h>
15#include <xrpl/ledger/helpers/MPTokenHelpers.h>
16#include <xrpl/ledger/helpers/RippleStateHelpers.h>
17#include <xrpl/ledger/helpers/TokenHelpers.h>
18#include <xrpl/protocol/AccountID.h>
19#include <xrpl/protocol/Concepts.h>
20#include <xrpl/protocol/Feature.h>
21#include <xrpl/protocol/Indexes.h>
22#include <xrpl/protocol/Issue.h>
23#include <xrpl/protocol/MPTIssue.h>
24#include <xrpl/protocol/Rate.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/STAmount.h>
27#include <xrpl/protocol/STLedgerEntry.h>
28#include <xrpl/protocol/STTx.h>
29#include <xrpl/protocol/TER.h>
30#include <xrpl/protocol/XRPAmount.h>
31#include <xrpl/tx/Transactor.h>
61 return validate(*fulfillment, *condition);
73 auto const cb = ctx.
tx[~sfCondition];
74 auto const fb = ctx.
tx[~sfFulfillment];
78 if (
static_cast<bool>(cb) !=
static_cast<bool>(fb))
87 auto const cb = ctx.
tx[~sfCondition];
88 auto const fb = ctx.
tx[~sfFulfillment];
92 auto& router = ctx.
registry.get().getHashRouter();
95 auto const flags = router.getFlags(
id);
124 if (
auto const fb = tx[~sfFulfillment])
126 extraFee +=
view.fees().base * (32 + (fb->size() / 16));
132template <Val
idIssueType T>
176 auto const sleIssuance = ctx.
view.
read(issuanceKey);
211 AccountID const dest = (*slep)[sfDestination];
212 STAmount const amount = (*slep)[sfAmount];
217 [&]<
typename T>(T
const&) {
220 amount.
asset().value());
232 auto const slep =
ctx_.view().peek(k);
235 if (
ctx_.view().rules().enabled(featureTokenEscrow))
243 auto const now =
ctx_.view().header().parentCloseTime;
246 if ((*slep)[~sfFinishAfter] && !
after(now, (*slep)[sfFinishAfter]))
250 if ((*slep)[~sfCancelAfter] &&
after(now, (*slep)[sfCancelAfter]))
255 auto const id =
ctx_.tx.getTransactionID();
256 auto flags =
ctx_.registry.get().getHashRouter().getFlags(
id);
258 auto const cb =
ctx_.tx[~sfCondition];
266 auto const fb =
ctx_.tx[~sfFulfillment];
280 ctx_.registry.get().getHashRouter().setFlags(
id, flags);
290 auto const cond = (*slep)[~sfCondition];
302 if (cond && (cond != cb))
307 AccountID const destID = (*slep)[sfDestination];
317 AccountID const account = (*slep)[sfAccount];
321 auto const page = (*slep)[sfOwnerNode];
325 JLOG(
j_.fatal()) <<
"Unable to delete Escrow from owner.";
332 if (
auto const optPage = (*slep)[~sfDestinationNode])
337 JLOG(
j_.fatal()) <<
"Unable to delete Escrow from recipient.";
343 STAmount const amount = slep->getFieldAmount(sfAmount);
347 (*sled)[sfBalance] = (*sled)[sfBalance] + amount;
351 if (!
ctx_.view().rules().enabled(featureTokenEscrow))
354 Rate lockedRate = slep->isFieldPresent(sfTransferRate)
355 ?
xrpl::Rate(slep->getFieldU32(sfTransferRate))
358 bool const createAsset = destID ==
accountID_;
360 [&]<
typename T>(T
const&) {
373 amount.
asset().value());
378 if (
auto const optPage = (*slep)[~sfIssuerNode]; optPage)
383 JLOG(
j_.fatal()) <<
"Unable to delete Escrow from recipient.";
390 ctx_.view().update(sled);
395 ctx_.view().update(sle);
398 ctx_.view().erase(slep);
A generic endpoint for log messages.
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
static bool checkExtraFeatures(PreflightContext const &ctx)
bool finalizeInvariants(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j) override
Check transaction-specific post-conditions after all entries have been visited.
static TER preclaim(PreclaimContext const &ctx)
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
static NotTEC preflight(PreflightContext const &ctx)
static NotTEC preflightSigValidated(PreflightContext const &ctx)
A currency issued by an account.
constexpr MPTID const & getMptID() const
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
constexpr TIss const & get() const
Asset const & asset() const
AccountID const & getIssuer() const
std::shared_ptr< STLedgerEntry const > const & const_ref
bool isFieldPresent(SField const &field) const
uint256 getTransactionID() const
An immutable linear range of bytes.
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
AccountID const accountID_
static std::unique_ptr< Condition > deserialize(Slice s, std::error_code &ec)
Load a condition from its binary form.
NotTEC checkFields(STTx const &tx, beast::Journal j)
TER valid(STTx const &tx, ReadView const &view, AccountID const &src, beast::Journal j)
bool validate(Fulfillment const &f, Condition const &c, Slice m)
Verify if the given message satisfies the fulfillment.
Keylet mptokenIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
TER escrowUnlockApplyHelper(ApplyView &view, Rate lockedRate, SLE::ref sleDest, STAmount const &xrpBalance, STAmount const &amount, AccountID const &issuer, AccountID const &sender, AccountID const &receiver, bool createAsset, beast::Journal journal)
bool isXRP(AccountID const &c)
static TER escrowFinishPreclaimHelper(PreclaimContext const &ctx, AccountID const &dest, STAmount const &amount)
constexpr HashRouterFlags kSfCfInvalid
bool isDeepFrozen(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer)
TER escrowFinishPreclaimHelper< Issue >(PreclaimContext const &ctx, AccountID const &dest, STAmount const &amount)
constexpr HashRouterFlags kSfCfValid
TERSubset< CanCvtToNotTEC > NotTEC
TER escrowFinishPreclaimHelper< MPTIssue >(PreclaimContext const &ctx, AccountID const &dest, STAmount const &amount)
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Rate const kParityRate
A transfer rate signifying a 1:1 exchange.
void adjustOwnerCount(ApplyView &view, SLE::ref sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
bool isFrozen(ReadView const &view, AccountID const &account, MPTIssue const &mptIssue, std::uint8_t depth=0)
static bool checkCondition(Slice f, Slice c)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
TER requireAuth(ReadView const &view, MPTIssue const &mptIssue, AccountID const &account, AuthType authType=AuthType::Legacy, std::uint8_t depth=0)
Check if the account lacks required authorization for MPT.
@ tecCRYPTOCONDITION_ERROR
TER verifyDepositPreauth(STTx const &tx, ApplyView &view, AccountID const &src, AccountID const &dst, SLE::const_ref sleDst, beast::Journal j)
constexpr bool any(HashRouterFlags flags)
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.
std::reference_wrapper< ServiceRegistry > registry
Represents a transfer rate.
static std::unique_ptr< Fulfillment > deserialize(Slice s, std::error_code &ec)
Load a fulfillment from its binary form.