rippled
Loading...
Searching...
No Matches
SetTrust.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/tx/detail/SetTrust.h>
21#include <xrpld/ledger/View.h>
22#include <xrpl/basics/Log.h>
23#include <xrpl/protocol/AMMCore.h>
24#include <xrpl/protocol/Feature.h>
25#include <xrpl/protocol/Indexes.h>
26#include <xrpl/protocol/Quality.h>
27#include <xrpl/protocol/st.h>
28
29namespace ripple {
30
33{
34 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
35 return ret;
36
37 auto& tx = ctx.tx;
38 auto& j = ctx.j;
39
40 std::uint32_t const uTxFlags = tx.getFlags();
41
42 if (uTxFlags & tfTrustSetMask)
43 {
44 JLOG(j.trace()) << "Malformed transaction: Invalid flags set.";
45 return temINVALID_FLAG;
46 }
47
48 STAmount const saLimitAmount(tx.getFieldAmount(sfLimitAmount));
49
50 if (!isLegalNet(saLimitAmount))
51 return temBAD_AMOUNT;
52
53 if (saLimitAmount.native())
54 {
55 JLOG(j.trace()) << "Malformed transaction: specifies native limit "
56 << saLimitAmount.getFullText();
57 return temBAD_LIMIT;
58 }
59
60 if (badCurrency() == saLimitAmount.getCurrency())
61 {
62 JLOG(j.trace()) << "Malformed transaction: specifies XRP as IOU";
63 return temBAD_CURRENCY;
64 }
65
66 if (saLimitAmount < beast::zero)
67 {
68 JLOG(j.trace()) << "Malformed transaction: Negative credit limit.";
69 return temBAD_LIMIT;
70 }
71
72 // Check if destination makes sense.
73 auto const& issuer = saLimitAmount.getIssuer();
74
75 if (!issuer || issuer == noAccount())
76 {
77 JLOG(j.trace()) << "Malformed transaction: no destination account.";
78 return temDST_NEEDED;
79 }
80
81 return preflight2(ctx);
82}
83
84TER
86{
87 auto const id = ctx.tx[sfAccount];
88
89 auto const sle = ctx.view.read(keylet::account(id));
90 if (!sle)
91 return terNO_ACCOUNT;
92
93 std::uint32_t const uTxFlags = ctx.tx.getFlags();
94
95 bool const bSetAuth = (uTxFlags & tfSetfAuth);
96
97 if (bSetAuth && !(sle->getFieldU32(sfFlags) & lsfRequireAuth))
98 {
99 JLOG(ctx.j.trace()) << "Retry: Auth not required.";
100 return tefNO_AUTH_REQUIRED;
101 }
102
103 auto const saLimitAmount = ctx.tx[sfLimitAmount];
104
105 auto const currency = saLimitAmount.getCurrency();
106 auto const uDstAccountID = saLimitAmount.getIssuer();
107
108 if (ctx.view.rules().enabled(fixTrustLinesToSelf))
109 {
110 if (id == uDstAccountID)
111 return temDST_IS_SRC;
112 }
113 else
114 {
115 if (id == uDstAccountID)
116 {
117 // Prevent trustline to self from being created,
118 // unless one has somehow already been created
119 // (in which case doApply will clean it up).
120 auto const sleDelete =
121 ctx.view.read(keylet::line(id, uDstAccountID, currency));
122
123 if (!sleDelete)
124 {
125 JLOG(ctx.j.trace())
126 << "Malformed transaction: Can not extend credit to self.";
127 return temDST_IS_SRC;
128 }
129 }
130 }
131
132 // This might be nullptr
133 auto const sleDst = ctx.view.read(keylet::account(uDstAccountID));
134
135 // If the destination has opted to disallow incoming trustlines
136 // then honour that flag
137 if (ctx.view.rules().enabled(featureDisallowIncoming))
138 {
139 if (!sleDst)
140 return tecNO_DST;
141
142 if (sleDst->getFlags() & lsfDisallowIncomingTrustline)
143 {
144 // The original implementation of featureDisallowIncoming was
145 // too restrictive. If
146 // o fixDisallowIncomingV1 is enabled and
147 // o The trust line already exists
148 // Then allow the TrustSet.
149 if (ctx.view.rules().enabled(fixDisallowIncomingV1) &&
150 ctx.view.exists(keylet::line(id, uDstAccountID, currency)))
151 {
152 // pass
153 }
154 else
155 return tecNO_PERMISSION;
156 }
157 }
158
159 // If destination is AMM and the trustline doesn't exist then only
160 // allow SetTrust if the asset is AMM LP token and AMM is not
161 // in empty state.
162 if (ammEnabled(ctx.view.rules()))
163 {
164 if (!sleDst)
165 return tecNO_DST;
166
167 if (sleDst->isFieldPresent(sfAMMID) &&
168 !ctx.view.read(keylet::line(id, uDstAccountID, currency)))
169 {
170 if (auto const ammSle =
171 ctx.view.read({ltAMM, sleDst->getFieldH256(sfAMMID)}))
172 {
173 if (auto const lpTokens =
174 ammSle->getFieldAmount(sfLPTokenBalance);
175 lpTokens == beast::zero)
176 return tecAMM_EMPTY;
177 else if (lpTokens.getCurrency() != saLimitAmount.getCurrency())
178 return tecNO_PERMISSION;
179 }
180 else
181 return tecINTERNAL;
182 }
183 }
184
185 return tesSUCCESS;
186}
187
188TER
190{
191 TER terResult = tesSUCCESS;
192
193 STAmount const saLimitAmount(ctx_.tx.getFieldAmount(sfLimitAmount));
194 bool const bQualityIn(ctx_.tx.isFieldPresent(sfQualityIn));
195 bool const bQualityOut(ctx_.tx.isFieldPresent(sfQualityOut));
196
197 Currency const currency(saLimitAmount.getCurrency());
198 AccountID uDstAccountID(saLimitAmount.getIssuer());
199
200 // true, iff current is high account.
201 bool const bHigh = account_ > uDstAccountID;
202
203 auto const sle = view().peek(keylet::account(account_));
204 if (!sle)
205 return tefINTERNAL;
206
207 std::uint32_t const uOwnerCount = sle->getFieldU32(sfOwnerCount);
208
209 // The reserve that is required to create the line. Note
210 // that although the reserve increases with every item
211 // an account owns, in the case of trust lines we only
212 // *enforce* a reserve if the user owns more than two
213 // items.
214 //
215 // We do this because being able to exchange currencies,
216 // which needs trust lines, is a powerful Ripple feature.
217 // So we want to make it easy for a gateway to fund the
218 // accounts of its users without fear of being tricked.
219 //
220 // Without this logic, a gateway that wanted to have a
221 // new user use its services, would have to give that
222 // user enough XRP to cover not only the account reserve
223 // but the incremental reserve for the trust line as
224 // well. A person with no intention of using the gateway
225 // could use the extra XRP for their own purposes.
226
227 XRPAmount const reserveCreate(
228 (uOwnerCount < 2) ? XRPAmount(beast::zero)
229 : view().fees().accountReserve(uOwnerCount + 1));
230
231 std::uint32_t uQualityIn(bQualityIn ? ctx_.tx.getFieldU32(sfQualityIn) : 0);
232 std::uint32_t uQualityOut(
233 bQualityOut ? ctx_.tx.getFieldU32(sfQualityOut) : 0);
234
235 if (bQualityOut && QUALITY_ONE == uQualityOut)
236 uQualityOut = 0;
237
238 std::uint32_t const uTxFlags = ctx_.tx.getFlags();
239
240 bool const bSetAuth = (uTxFlags & tfSetfAuth);
241 bool const bSetNoRipple = (uTxFlags & tfSetNoRipple);
242 bool const bClearNoRipple = (uTxFlags & tfClearNoRipple);
243 bool const bSetFreeze = (uTxFlags & tfSetFreeze);
244 bool const bClearFreeze = (uTxFlags & tfClearFreeze);
245
246 auto viewJ = ctx_.app.journal("View");
247
248 // Trust lines to self are impossible but because of the old bug there are
249 // two on 19-02-2022. This code was here to allow those trust lines to be
250 // deleted. The fixTrustLinesToSelf fix amendment will remove them when it
251 // enables so this code will no longer be needed.
252 if (!view().rules().enabled(fixTrustLinesToSelf) &&
253 account_ == uDstAccountID)
254 {
255 return trustDelete(
256 view(),
257 view().peek(keylet::line(account_, uDstAccountID, currency)),
258 account_,
259 uDstAccountID,
260 viewJ);
261 }
262
263 SLE::pointer sleDst = view().peek(keylet::account(uDstAccountID));
264
265 if (!sleDst)
266 {
267 JLOG(j_.trace())
268 << "Delay transaction: Destination account does not exist.";
269 return tecNO_DST;
270 }
271
272 STAmount saLimitAllow = saLimitAmount;
273 saLimitAllow.setIssuer(account_);
274
275 SLE::pointer sleRippleState =
276 view().peek(keylet::line(account_, uDstAccountID, currency));
277
278 if (sleRippleState)
279 {
280 STAmount saLowBalance;
281 STAmount saLowLimit;
282 STAmount saHighBalance;
283 STAmount saHighLimit;
284 std::uint32_t uLowQualityIn;
285 std::uint32_t uLowQualityOut;
286 std::uint32_t uHighQualityIn;
287 std::uint32_t uHighQualityOut;
288 auto const& uLowAccountID = !bHigh ? account_ : uDstAccountID;
289 auto const& uHighAccountID = bHigh ? account_ : uDstAccountID;
290 SLE::ref sleLowAccount = !bHigh ? sle : sleDst;
291 SLE::ref sleHighAccount = bHigh ? sle : sleDst;
292
293 //
294 // Balances
295 //
296
297 saLowBalance = sleRippleState->getFieldAmount(sfBalance);
298 saHighBalance = -saLowBalance;
299
300 //
301 // Limits
302 //
303
304 sleRippleState->setFieldAmount(
305 !bHigh ? sfLowLimit : sfHighLimit, saLimitAllow);
306
307 saLowLimit =
308 !bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfLowLimit);
309 saHighLimit =
310 bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfHighLimit);
311
312 //
313 // Quality in
314 //
315
316 if (!bQualityIn)
317 {
318 // Not setting. Just get it.
319
320 uLowQualityIn = sleRippleState->getFieldU32(sfLowQualityIn);
321 uHighQualityIn = sleRippleState->getFieldU32(sfHighQualityIn);
322 }
323 else if (uQualityIn)
324 {
325 // Setting.
326
327 sleRippleState->setFieldU32(
328 !bHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
329
330 uLowQualityIn = !bHigh
331 ? uQualityIn
332 : sleRippleState->getFieldU32(sfLowQualityIn);
333 uHighQualityIn = bHigh
334 ? uQualityIn
335 : sleRippleState->getFieldU32(sfHighQualityIn);
336 }
337 else
338 {
339 // Clearing.
340
341 sleRippleState->makeFieldAbsent(
342 !bHigh ? sfLowQualityIn : sfHighQualityIn);
343
344 uLowQualityIn =
345 !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityIn);
346 uHighQualityIn =
347 bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityIn);
348 }
349
350 if (QUALITY_ONE == uLowQualityIn)
351 uLowQualityIn = 0;
352
353 if (QUALITY_ONE == uHighQualityIn)
354 uHighQualityIn = 0;
355
356 //
357 // Quality out
358 //
359
360 if (!bQualityOut)
361 {
362 // Not setting. Just get it.
363
364 uLowQualityOut = sleRippleState->getFieldU32(sfLowQualityOut);
365 uHighQualityOut = sleRippleState->getFieldU32(sfHighQualityOut);
366 }
367 else if (uQualityOut)
368 {
369 // Setting.
370
371 sleRippleState->setFieldU32(
372 !bHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
373
374 uLowQualityOut = !bHigh
375 ? uQualityOut
376 : sleRippleState->getFieldU32(sfLowQualityOut);
377 uHighQualityOut = bHigh
378 ? uQualityOut
379 : sleRippleState->getFieldU32(sfHighQualityOut);
380 }
381 else
382 {
383 // Clearing.
384
385 sleRippleState->makeFieldAbsent(
386 !bHigh ? sfLowQualityOut : sfHighQualityOut);
387
388 uLowQualityOut =
389 !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityOut);
390 uHighQualityOut =
391 bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityOut);
392 }
393
394 std::uint32_t const uFlagsIn(sleRippleState->getFieldU32(sfFlags));
395 std::uint32_t uFlagsOut(uFlagsIn);
396
397 if (bSetNoRipple && !bClearNoRipple)
398 {
399 if ((bHigh ? saHighBalance : saLowBalance) >= beast::zero)
400 uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple);
401
402 else if (view().rules().enabled(fix1578))
403 // Cannot set noRipple on a negative balance.
404 return tecNO_PERMISSION;
405 }
406 else if (bClearNoRipple && !bSetNoRipple)
407 {
408 uFlagsOut &= ~(bHigh ? lsfHighNoRipple : lsfLowNoRipple);
409 }
410
411 if (bSetFreeze && !bClearFreeze && !sle->isFlag(lsfNoFreeze))
412 {
413 uFlagsOut |= (bHigh ? lsfHighFreeze : lsfLowFreeze);
414 }
415 else if (bClearFreeze && !bSetFreeze)
416 {
417 uFlagsOut &= ~(bHigh ? lsfHighFreeze : lsfLowFreeze);
418 }
419
420 if (QUALITY_ONE == uLowQualityOut)
421 uLowQualityOut = 0;
422
423 if (QUALITY_ONE == uHighQualityOut)
424 uHighQualityOut = 0;
425
426 bool const bLowDefRipple = sleLowAccount->getFlags() & lsfDefaultRipple;
427 bool const bHighDefRipple =
428 sleHighAccount->getFlags() & lsfDefaultRipple;
429
430 bool const bLowReserveSet = uLowQualityIn || uLowQualityOut ||
431 ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple ||
432 (uFlagsOut & lsfLowFreeze) || saLowLimit ||
433 saLowBalance > beast::zero;
434 bool const bLowReserveClear = !bLowReserveSet;
435
436 bool const bHighReserveSet = uHighQualityIn || uHighQualityOut ||
437 ((uFlagsOut & lsfHighNoRipple) == 0) != bHighDefRipple ||
438 (uFlagsOut & lsfHighFreeze) || saHighLimit ||
439 saHighBalance > beast::zero;
440 bool const bHighReserveClear = !bHighReserveSet;
441
442 bool const bDefault = bLowReserveClear && bHighReserveClear;
443
444 bool const bLowReserved = (uFlagsIn & lsfLowReserve);
445 bool const bHighReserved = (uFlagsIn & lsfHighReserve);
446
447 bool bReserveIncrease = false;
448
449 if (bSetAuth)
450 {
451 uFlagsOut |= (bHigh ? lsfHighAuth : lsfLowAuth);
452 }
453
454 if (bLowReserveSet && !bLowReserved)
455 {
456 // Set reserve for low account.
457 adjustOwnerCount(view(), sleLowAccount, 1, viewJ);
458 uFlagsOut |= lsfLowReserve;
459
460 if (!bHigh)
461 bReserveIncrease = true;
462 }
463
464 if (bLowReserveClear && bLowReserved)
465 {
466 // Clear reserve for low account.
467 adjustOwnerCount(view(), sleLowAccount, -1, viewJ);
468 uFlagsOut &= ~lsfLowReserve;
469 }
470
471 if (bHighReserveSet && !bHighReserved)
472 {
473 // Set reserve for high account.
474 adjustOwnerCount(view(), sleHighAccount, 1, viewJ);
475 uFlagsOut |= lsfHighReserve;
476
477 if (bHigh)
478 bReserveIncrease = true;
479 }
480
481 if (bHighReserveClear && bHighReserved)
482 {
483 // Clear reserve for high account.
484 adjustOwnerCount(view(), sleHighAccount, -1, viewJ);
485 uFlagsOut &= ~lsfHighReserve;
486 }
487
488 if (uFlagsIn != uFlagsOut)
489 sleRippleState->setFieldU32(sfFlags, uFlagsOut);
490
491 if (bDefault || badCurrency() == currency)
492 {
493 // Delete.
494
495 terResult = trustDelete(
496 view(), sleRippleState, uLowAccountID, uHighAccountID, viewJ);
497 }
498 // Reserve is not scaled by load.
499 else if (bReserveIncrease && mPriorBalance < reserveCreate)
500 {
501 JLOG(j_.trace())
502 << "Delay transaction: Insufficent reserve to add trust line.";
503
504 // Another transaction could provide XRP to the account and then
505 // this transaction would succeed.
506 terResult = tecINSUF_RESERVE_LINE;
507 }
508 else
509 {
510 view().update(sleRippleState);
511
512 JLOG(j_.trace()) << "Modify ripple line";
513 }
514 }
515 // Line does not exist.
516 else if (
517 !saLimitAmount && // Setting default limit.
518 (!bQualityIn || !uQualityIn) && // Not setting quality in or setting
519 // default quality in.
520 (!bQualityOut || !uQualityOut) && // Not setting quality out or setting
521 // default quality out.
522 (!bSetAuth))
523 {
524 JLOG(j_.trace())
525 << "Redundant: Setting non-existent ripple line to defaults.";
527 }
528 else if (mPriorBalance < reserveCreate) // Reserve is not scaled by load.
529 {
530 JLOG(j_.trace()) << "Delay transaction: Line does not exist. "
531 "Insufficent reserve to create line.";
532
533 // Another transaction could create the account and then this
534 // transaction would succeed.
535 terResult = tecNO_LINE_INSUF_RESERVE;
536 }
537 else
538 {
539 // Zero balance in currency.
540 STAmount saBalance(Issue{currency, noAccount()});
541
542 auto const k = keylet::line(account_, uDstAccountID, currency);
543
544 JLOG(j_.trace()) << "doTrustSet: Creating ripple line: "
545 << to_string(k.key);
546
547 // Create a new ripple line.
548 terResult = trustCreate(
549 view(),
550 bHigh,
551 account_,
552 uDstAccountID,
553 k.key,
554 sle,
555 bSetAuth,
556 bSetNoRipple && !bClearNoRipple,
557 bSetFreeze && !bClearFreeze,
558 saBalance,
559 saLimitAllow, // Limit for who is being charged.
560 uQualityIn,
561 uQualityOut,
562 viewJ);
563 }
564
565 return terResult;
566}
567
568} // namespace ripple
Stream trace() const
Severity stream access functions.
Definition: Journal.h:311
virtual beast::Journal journal(std::string const &name)=0
Application & app
Definition: ApplyContext.h:47
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
A currency issued by an account.
Definition: Issue.h:36
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:122
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:569
Currency const & getCurrency() const
Definition: STAmount.h:493
AccountID const & getIssuer() const
Definition: STAmount.h:499
std::string getFullText() const override
Definition: STAmount.cpp:505
bool native() const noexcept
Definition: STAmount.h:449
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:585
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:635
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:454
std::uint32_t getFlags() const
Definition: STObject.cpp:507
static NotTEC preflight(PreflightContext const &ctx)
Definition: SetTrust.cpp:32
static TER preclaim(PreclaimContext const &ctx)
Definition: SetTrust.cpp:85
TER doApply() override
Definition: SetTrust.cpp:189
AccountID const account_
Definition: Transactor.h:91
ApplyView & view()
Definition: Transactor.h:107
beast::Journal const j_
Definition: Transactor.h:89
XRPAmount mPriorBalance
Definition: Transactor.h:92
ApplyContext & ctx_
Definition: Transactor.h:88
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:220
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:160
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
AccountID const & noAccount()
A placeholder for empty accounts.
Definition: AccountID.cpp:177
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
Definition: UintTypes.cpp:129
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:581
@ lsfDefaultRipple
@ lsfHighNoRipple
@ lsfRequireAuth
@ lsfHighFreeze
@ lsfLowNoRipple
@ lsfHighReserve
@ lsfDisallowIncomingTrustline
@ lsfLowReserve
@ lsfLowFreeze
bool isTesSuccess(TER x)
Definition: TER.h:656
bool ammEnabled(Rules const &)
Return true if required AMM amendments are enabled.
Definition: AMMCore.cpp:128
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:82
TER trustCreate(ApplyView &view, const bool bSrcHigh, AccountID const &uSrcAccountID, AccountID const &uDstAccountID, uint256 const &uIndex, SLE::ref sleAccount, const bool bAuth, const bool bNoRipple, const bool bFreeze, STAmount const &saBalance, STAmount const &saLimit, std::uint32_t uQualityIn, std::uint32_t uQualityOut, beast::Journal j)
Create a trust line.
Definition: View.cpp:856
@ tefNO_AUTH_REQUIRED
Definition: TER.h:174
@ tefINTERNAL
Definition: TER.h:173
constexpr std::uint32_t tfClearNoRipple
Definition: TxFlags.h:114
static bool adjustOwnerCount(ApplyContext &ctx, int count)
Definition: SetOracle.cpp:186
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:134
constexpr std::uint32_t tfSetfAuth
Definition: TxFlags.h:112
constexpr std::uint32_t tfClearFreeze
Definition: TxFlags.h:116
TER trustDelete(ApplyView &view, std::shared_ptr< SLE > const &sleRippleState, AccountID const &uLowAccountID, AccountID const &uHighAccountID, beast::Journal j)
Definition: View.cpp:970
@ tecNO_LINE_REDUNDANT
Definition: TER.h:280
@ tecNO_DST
Definition: TER.h:277
@ tecNO_LINE_INSUF_RESERVE
Definition: TER.h:279
@ tecINSUF_RESERVE_LINE
Definition: TER.h:275
@ tecAMM_EMPTY
Definition: TER.h:319
@ tecINTERNAL
Definition: TER.h:297
@ tecNO_PERMISSION
Definition: TER.h:292
@ tesSUCCESS
Definition: TER.h:242
constexpr std::uint32_t tfTrustSetMask
Definition: TxFlags.h:117
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:629
@ terNO_ACCOUNT
Definition: TER.h:217
constexpr std::uint32_t tfSetFreeze
Definition: TxFlags.h:115
constexpr std::uint32_t tfSetNoRipple
Definition: TxFlags.h:113
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:587
@ temBAD_AMOUNT
Definition: TER.h:89
@ temBAD_LIMIT
Definition: TER.h:94
@ temDST_NEEDED
Definition: TER.h:109
@ temBAD_CURRENCY
Definition: TER.h:90
@ temINVALID_FLAG
Definition: TER.h:111
@ temDST_IS_SRC
Definition: TER.h:108
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:53
ReadView const & view
Definition: Transactor.h:56
beast::Journal const j
Definition: Transactor.h:60
State information when preflighting a tx.
Definition: Transactor.h:32
beast::Journal const j
Definition: Transactor.h:38