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/SeqProxy.h>
30#include <xrpl/protocol/TER.h>
31#include <xrpl/protocol/XRPAmount.h>
32#include <xrpl/tx/Transactor.h>
62 return validate(*fulfillment, *condition);
74 auto const cb = ctx.
tx[~sfCondition];
75 auto const fb = ctx.
tx[~sfFulfillment];
79 if (
static_cast<bool>(cb) !=
static_cast<bool>(fb))
88 auto const cb = ctx.
tx[~sfCondition];
89 auto const fb = ctx.
tx[~sfFulfillment];
93 auto& router = ctx.
registry.get().getHashRouter();
96 auto const flags = router.getFlags(
id);
125 if (
auto const fb = tx[~sfFulfillment])
127 extraFee +=
view.fees().base * (32 + (fb->size() / 16));
133template <Val
idIssueType T>
177 auto const sleIssuance = ctx.
view.
read(issuanceKey);
213 AccountID const dest = (*slep)[sfDestination];
214 STAmount const amount = (*slep)[sfAmount];
219 [&]<
typename T>(T
const&) {
222 amount.
asset().value());
235 auto const slep =
ctx_.view().peek(k);
238 if (
ctx_.view().rules().enabled(featureTokenEscrow))
246 auto const now =
ctx_.view().header().parentCloseTime;
249 if ((*slep)[~sfFinishAfter] && !
after(now, (*slep)[sfFinishAfter]))
253 if ((*slep)[~sfCancelAfter] &&
after(now, (*slep)[sfCancelAfter]))
258 auto const id =
ctx_.tx.getTransactionID();
259 auto flags =
ctx_.registry.get().getHashRouter().getFlags(
id);
261 auto const cb =
ctx_.tx[~sfCondition];
269 auto const fb =
ctx_.tx[~sfFulfillment];
283 ctx_.registry.get().getHashRouter().setFlags(
id, flags);
293 auto const cond = (*slep)[~sfCondition];
305 if (cond && (cond != cb))
310 AccountID const destID = (*slep)[sfDestination];
320 AccountID const account = (*slep)[sfAccount];
324 auto const page = (*slep)[sfOwnerNode];
328 JLOG(
j_.fatal()) <<
"Unable to delete Escrow from owner.";
335 if (
auto const optPage = (*slep)[~sfDestinationNode])
340 JLOG(
j_.fatal()) <<
"Unable to delete Escrow from recipient.";
352 bool const sponsorEnabled =
ctx_.view().rules().enabled(featureSponsor);
356 STAmount const amount = slep->getFieldAmount(sfAmount);
360 (*sled)[sfBalance] = (*sled)[sfBalance] + amount;
364 if (!
ctx_.view().rules().enabled(featureTokenEscrow))
367 Rate lockedRate = slep->isFieldPresent(sfTransferRate)
368 ?
xrpl::Rate(slep->getFieldU32(sfTransferRate))
371 bool const createAsset = destID ==
accountID_;
373 [&]<
typename T>(T
const&) {
375 ctx_.getApplyViewContext(),
386 amount.
asset().value());
391 if (
auto const optPage = (*slep)[~sfIssuerNode]; optPage)
396 JLOG(
j_.fatal()) <<
"Unable to delete Escrow from recipient.";
403 ctx_.view().update(sled);
410 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
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
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, Rules const &rules, 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 escrow(AccountID const &src, SeqProxy const &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.
Keylet mptokenIssuance(MPTID const &issuanceID) noexcept
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
void decreaseOwnerCountForObject(ApplyView &view, SLE::ref accountSle, SLE::ref objectSle, std::uint32_t count, beast::Journal j)
Decrease owner-count fields for an existing ledger object.
bool isXRP(AccountID const &c)
static TER escrowFinishPreclaimHelper(PreclaimContext const &ctx, AccountID const &dest, STAmount const &amount)
TER escrowUnlockApplyHelper(ApplyViewContext ctx, Rate lockedRate, SLE::ref sleDest, XRPAmount xrpBalance, STAmount const &amount, AccountID const &issuer, AccountID const &sender, AccountID const &receiver, bool createAsset, beast::Journal journal)
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.
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.