rippled
Loading...
Searching...
No Matches
EscrowCancel.cpp
1#include <xrpl/basics/Log.h>
2#include <xrpl/ledger/ApplyView.h>
3#include <xrpl/ledger/View.h>
4#include <xrpl/ledger/helpers/AccountRootHelpers.h>
5#include <xrpl/ledger/helpers/MPTokenHelpers.h>
6#include <xrpl/ledger/helpers/RippleStateHelpers.h>
7#include <xrpl/protocol/Feature.h>
8#include <xrpl/protocol/Indexes.h>
9#include <xrpl/protocol/Rate.h>
10#include <xrpl/tx/transactors/escrow/EscrowCancel.h>
11
12#include <libxrpl/tx/transactors/escrow/EscrowHelpers.h>
13
14namespace xrpl {
15
21
22template <ValidIssueType T>
23static TER
25 PreclaimContext const& ctx,
26 AccountID const& account,
27 STAmount const& amount);
28
29template <>
32 PreclaimContext const& ctx,
33 AccountID const& account,
34 STAmount const& amount)
35{
36 AccountID const issuer = amount.getIssuer();
37 // If the issuer is the same as the account, return tecINTERNAL
38 if (issuer == account)
39 return tecINTERNAL; // LCOV_EXCL_LINE
40
41 // If the issuer has requireAuth set, check if the account is authorized
42 if (auto const ter = requireAuth(ctx.view, amount.issue(), account); !isTesSuccess(ter))
43 return ter;
44
45 return tesSUCCESS;
46}
47
48template <>
51 PreclaimContext const& ctx,
52 AccountID const& account,
53 STAmount const& amount)
54{
55 AccountID const issuer = amount.getIssuer();
56 // If the issuer is the same as the account, return tecINTERNAL
57 if (issuer == account)
58 return tecINTERNAL; // LCOV_EXCL_LINE
59
60 // If the mpt does not exist, return tecOBJECT_NOT_FOUND
61 auto const issuanceKey = keylet::mptIssuance(amount.get<MPTIssue>().getMptID());
62 auto const sleIssuance = ctx.view.read(issuanceKey);
63 if (!sleIssuance)
65
66 // If the issuer has requireAuth set, check if the account is
67 // authorized
68 auto const& mptIssue = amount.get<MPTIssue>();
69 if (auto const ter = requireAuth(ctx.view, mptIssue, account, AuthType::WeakAuth);
70 !isTesSuccess(ter))
71 return ter;
72
73 return tesSUCCESS;
74}
75
76TER
78{
79 if (ctx.view.rules().enabled(featureTokenEscrow))
80 {
81 auto const k = keylet::escrow(ctx.tx[sfOwner], ctx.tx[sfOfferSequence]);
82 auto const slep = ctx.view.read(k);
83 if (!slep)
84 return tecNO_TARGET;
85
86 AccountID const account = (*slep)[sfAccount];
87 STAmount const amount = (*slep)[sfAmount];
88
89 if (!isXRP(amount))
90 {
91 if (auto const ret = std::visit(
92 [&]<typename T>(T const&) {
93 return escrowCancelPreclaimHelper<T>(ctx, account, amount);
94 },
95 amount.asset().value());
96 !isTesSuccess(ret))
97 return ret;
98 }
99 }
100 return tesSUCCESS;
101}
102
103TER
105{
106 auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
107 auto const slep = ctx_.view().peek(k);
108 if (!slep)
109 {
110 if (ctx_.view().rules().enabled(featureTokenEscrow))
111 return tecINTERNAL; // LCOV_EXCL_LINE
112
113 return tecNO_TARGET;
114 }
115
116 auto const now = ctx_.view().header().parentCloseTime;
117
118 // No cancel time specified: can't execute at all.
119 if (!(*slep)[~sfCancelAfter])
120 return tecNO_PERMISSION;
121
122 // Too soon: can't execute before the cancel time.
123 if (!after(now, (*slep)[sfCancelAfter]))
124 return tecNO_PERMISSION;
125
126 AccountID const account = (*slep)[sfAccount];
127
128 // Remove escrow from owner directory
129 {
130 auto const page = (*slep)[sfOwnerNode];
131 if (!ctx_.view().dirRemove(keylet::ownerDir(account), page, k.key, true))
132 {
133 // LCOV_EXCL_START
134 JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
135 return tefBAD_LEDGER;
136 // LCOV_EXCL_STOP
137 }
138 }
139
140 // Remove escrow from recipient's owner directory, if present.
141 if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
142 {
143 if (!ctx_.view().dirRemove(keylet::ownerDir((*slep)[sfDestination]), *optPage, k.key, true))
144 {
145 // LCOV_EXCL_START
146 JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
147 return tefBAD_LEDGER;
148 // LCOV_EXCL_STOP
149 }
150 }
151
152 auto const sle = ctx_.view().peek(keylet::account(account));
153 STAmount const amount = slep->getFieldAmount(sfAmount);
154
155 // Transfer amount back to the owner
156 if (isXRP(amount))
157 {
158 (*sle)[sfBalance] = (*sle)[sfBalance] + amount;
159 }
160 else
161 {
162 if (!ctx_.view().rules().enabled(featureTokenEscrow))
163 return temDISABLED; // LCOV_EXCL_LINE
164
165 auto const issuer = amount.getIssuer();
166 bool const createAsset = account == account_;
167 if (auto const ret = std::visit(
168 [&]<typename T>(T const&) {
169 return escrowUnlockApplyHelper<T>(
170 ctx_.view(),
172 slep,
174 amount,
175 issuer,
176 account, // sender and receiver are the same
177 account,
178 createAsset,
179 j_);
180 },
181 amount.asset().value());
182 !isTesSuccess(ret))
183 return ret; // LCOV_EXCL_LINE
184
185 // Remove escrow from issuers owner directory, if present.
186 if (auto const optPage = (*slep)[~sfIssuerNode]; optPage)
187 {
188 if (!ctx_.view().dirRemove(keylet::ownerDir(issuer), *optPage, k.key, true))
189 {
190 // LCOV_EXCL_START
191 JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
192 return tefBAD_LEDGER;
193 // LCOV_EXCL_STOP
194 }
195 }
196 }
197
199 ctx_.view().update(sle);
200
201 // Remove escrow from ledger
202 ctx_.view().erase(slep);
203
204 return tesSUCCESS;
205}
206
207} // namespace xrpl
Stream fatal() const
Definition Journal.h:325
STTx const & tx
beast::Journal const journal
ApplyView & view()
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static NotTEC preflight(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
TER doApply() override
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:26
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
virtual std::shared_ptr< SLE const > 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.
Definition Rules.cpp:120
AccountID const account_
Definition Transactor.h:116
beast::Journal const j_
Definition Transactor.h:114
XRPAmount preFeeBalance_
Definition Transactor.h:117
ApplyContext & ctx_
Definition Transactor.h:112
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition Indexes.cpp:351
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:336
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:474
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool isXRP(AccountID const &c)
Definition AccountID.h:70
TER escrowCancelPreclaimHelper< MPTIssue >(PreclaimContext const &ctx, AccountID const &account, STAmount const &amount)
@ tefBAD_LEDGER
Definition TER.h:150
TER escrowCancelPreclaimHelper< Issue >(PreclaimContext const &ctx, AccountID const &account, STAmount const &amount)
TERSubset< CanCvtToTER > TER
Definition TER.h:622
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:523
static TER escrowCancelPreclaimHelper(PreclaimContext const &ctx, AccountID const &account, STAmount const &amount)
@ temDISABLED
Definition TER.h:94
bool isTesSuccess(TER x) noexcept
Definition TER.h:651
@ tecNO_TARGET
Definition TER.h:285
@ tecOBJECT_NOT_FOUND
Definition TER.h:307
@ tecINTERNAL
Definition TER.h:291
@ tecNO_PERMISSION
Definition TER.h:286
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:582
@ tesSUCCESS
Definition TER.h:225
Rate const parityRate
A transfer rate signifying a 1:1 exchange.
TER requireAuth(ReadView const &view, MPTIssue const &mptIssue, AccountID const &account, AuthType authType=AuthType::Legacy, int depth=0)
Check if the account lacks required authorization for MPT.
uint256 key
Definition Keylet.h:20
NetClock::time_point parentCloseTime
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:57
ReadView const & view
Definition Transactor.h:60
State information when preflighting a tx.
Definition Transactor.h:14
T visit(T... args)