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
28namespace {
29
30uint32_t
31computeFreezeFlags(
32 uint32_t uFlags,
33 bool bHigh,
34 bool bNoFreeze,
35 bool bSetFreeze,
36 bool bClearFreeze,
37 bool bSetDeepFreeze,
38 bool bClearDeepFreeze)
39{
40 if (bSetFreeze && !bClearFreeze && !bNoFreeze)
41 {
42 uFlags |= (bHigh ? ripple::lsfHighFreeze : ripple::lsfLowFreeze);
43 }
44 else if (bClearFreeze && !bSetFreeze)
45 {
46 uFlags &= ~(bHigh ? ripple::lsfHighFreeze : ripple::lsfLowFreeze);
47 }
48 if (bSetDeepFreeze && !bClearDeepFreeze && !bNoFreeze)
49 {
50 uFlags |=
52 }
53 else if (bClearDeepFreeze && !bSetDeepFreeze)
54 {
55 uFlags &=
57 }
58
59 return uFlags;
60}
61
62} // namespace
63
64namespace ripple {
65
68{
69 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
70 return ret;
71
72 auto& tx = ctx.tx;
73 auto& j = ctx.j;
74
75 std::uint32_t const uTxFlags = tx.getFlags();
76
77 if (uTxFlags & tfTrustSetMask)
78 {
79 JLOG(j.trace()) << "Malformed transaction: Invalid flags set.";
80 return temINVALID_FLAG;
81 }
82
83 if (!ctx.rules.enabled(featureDeepFreeze))
84 {
85 // Even though the deep freeze flags are included in the
86 // `tfTrustSetMask`, they are not valid if the amendment is not enabled.
87 if (uTxFlags & (tfSetDeepFreeze | tfClearDeepFreeze))
88 {
89 return temINVALID_FLAG;
90 }
91 }
92
93 STAmount const saLimitAmount(tx.getFieldAmount(sfLimitAmount));
94
95 if (!isLegalNet(saLimitAmount))
96 return temBAD_AMOUNT;
97
98 if (saLimitAmount.native())
99 {
100 JLOG(j.trace()) << "Malformed transaction: specifies native limit "
101 << saLimitAmount.getFullText();
102 return temBAD_LIMIT;
103 }
104
105 if (badCurrency() == saLimitAmount.getCurrency())
106 {
107 JLOG(j.trace()) << "Malformed transaction: specifies XRP as IOU";
108 return temBAD_CURRENCY;
109 }
110
111 if (saLimitAmount < beast::zero)
112 {
113 JLOG(j.trace()) << "Malformed transaction: Negative credit limit.";
114 return temBAD_LIMIT;
115 }
116
117 // Check if destination makes sense.
118 auto const& issuer = saLimitAmount.getIssuer();
119
120 if (!issuer || issuer == noAccount())
121 {
122 JLOG(j.trace()) << "Malformed transaction: no destination account.";
123 return temDST_NEEDED;
124 }
125
126 return preflight2(ctx);
127}
128
129TER
131{
132 auto const id = ctx.tx[sfAccount];
133
134 auto const sle = ctx.view.read(keylet::account(id));
135 if (!sle)
136 return terNO_ACCOUNT;
137
138 std::uint32_t const uTxFlags = ctx.tx.getFlags();
139
140 bool const bSetAuth = (uTxFlags & tfSetfAuth);
141
142 if (bSetAuth && !(sle->getFieldU32(sfFlags) & lsfRequireAuth))
143 {
144 JLOG(ctx.j.trace()) << "Retry: Auth not required.";
145 return tefNO_AUTH_REQUIRED;
146 }
147
148 auto const saLimitAmount = ctx.tx[sfLimitAmount];
149
150 auto const currency = saLimitAmount.getCurrency();
151 auto const uDstAccountID = saLimitAmount.getIssuer();
152
153 if (ctx.view.rules().enabled(fixTrustLinesToSelf))
154 {
155 if (id == uDstAccountID)
156 return temDST_IS_SRC;
157 }
158 else
159 {
160 if (id == uDstAccountID)
161 {
162 // Prevent trustline to self from being created,
163 // unless one has somehow already been created
164 // (in which case doApply will clean it up).
165 auto const sleDelete =
166 ctx.view.read(keylet::line(id, uDstAccountID, currency));
167
168 if (!sleDelete)
169 {
170 JLOG(ctx.j.trace())
171 << "Malformed transaction: Can not extend credit to self.";
172 return temDST_IS_SRC;
173 }
174 }
175 }
176
177 // This might be nullptr
178 auto const sleDst = ctx.view.read(keylet::account(uDstAccountID));
179
180 // If the destination has opted to disallow incoming trustlines
181 // then honour that flag
182 if (ctx.view.rules().enabled(featureDisallowIncoming))
183 {
184 if (!sleDst)
185 return tecNO_DST;
186
187 if (sleDst->getFlags() & lsfDisallowIncomingTrustline)
188 {
189 // The original implementation of featureDisallowIncoming was
190 // too restrictive. If
191 // o fixDisallowIncomingV1 is enabled and
192 // o The trust line already exists
193 // Then allow the TrustSet.
194 if (ctx.view.rules().enabled(fixDisallowIncomingV1) &&
195 ctx.view.exists(keylet::line(id, uDstAccountID, currency)))
196 {
197 // pass
198 }
199 else
200 return tecNO_PERMISSION;
201 }
202 }
203
204 // If destination is AMM and the trustline doesn't exist then only
205 // allow SetTrust if the asset is AMM LP token and AMM is not
206 // in empty state.
207 if (ammEnabled(ctx.view.rules()))
208 {
209 if (!sleDst)
210 return tecNO_DST;
211
212 if (sleDst->isFieldPresent(sfAMMID) &&
213 !ctx.view.read(keylet::line(id, uDstAccountID, currency)))
214 {
215 if (auto const ammSle =
216 ctx.view.read({ltAMM, sleDst->getFieldH256(sfAMMID)}))
217 {
218 if (auto const lpTokens =
219 ammSle->getFieldAmount(sfLPTokenBalance);
220 lpTokens == beast::zero)
221 return tecAMM_EMPTY;
222 else if (lpTokens.getCurrency() != saLimitAmount.getCurrency())
223 return tecNO_PERMISSION;
224 }
225 else
226 return tecINTERNAL;
227 }
228 }
229
230 // Checking all freeze/deep freeze flag invariants.
231 if (ctx.view.rules().enabled(featureDeepFreeze))
232 {
233 bool const bNoFreeze = sle->isFlag(lsfNoFreeze);
234 bool const bSetFreeze = (uTxFlags & tfSetFreeze);
235 bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze);
236
237 if (bNoFreeze && (bSetFreeze || bSetDeepFreeze))
238 {
239 // Cannot freeze the trust line if NoFreeze is set
240 return tecNO_PERMISSION;
241 }
242
243 bool const bClearFreeze = (uTxFlags & tfClearFreeze);
244 bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze);
245 if ((bSetFreeze || bSetDeepFreeze) &&
246 (bClearFreeze || bClearDeepFreeze))
247 {
248 // Freezing and unfreezing in the same transaction should be
249 // illegal
250 return tecNO_PERMISSION;
251 }
252
253 bool const bHigh = id > uDstAccountID;
254 // Fetching current state of trust line
255 auto const sleRippleState =
256 ctx.view.read(keylet::line(id, uDstAccountID, currency));
257 std::uint32_t uFlags =
258 sleRippleState ? sleRippleState->getFieldU32(sfFlags) : 0u;
259 // Computing expected trust line state
260 uFlags = computeFreezeFlags(
261 uFlags,
262 bHigh,
263 bNoFreeze,
264 bSetFreeze,
265 bClearFreeze,
266 bSetDeepFreeze,
267 bClearDeepFreeze);
268
269 auto const frozen = uFlags & (bHigh ? lsfHighFreeze : lsfLowFreeze);
270 auto const deepFrozen =
271 uFlags & (bHigh ? lsfHighDeepFreeze : lsfLowDeepFreeze);
272
273 // Trying to set deep freeze on not already frozen trust line must
274 // fail. This also checks that clearing normal freeze while deep
275 // frozen must not work
276 if (deepFrozen && !frozen)
277 {
278 return tecNO_PERMISSION;
279 }
280 }
281
282 return tesSUCCESS;
283}
284
285TER
287{
288 TER terResult = tesSUCCESS;
289
290 STAmount const saLimitAmount(ctx_.tx.getFieldAmount(sfLimitAmount));
291 bool const bQualityIn(ctx_.tx.isFieldPresent(sfQualityIn));
292 bool const bQualityOut(ctx_.tx.isFieldPresent(sfQualityOut));
293
294 Currency const currency(saLimitAmount.getCurrency());
295 AccountID uDstAccountID(saLimitAmount.getIssuer());
296
297 // true, if current is high account.
298 bool const bHigh = account_ > uDstAccountID;
299
300 auto const sle = view().peek(keylet::account(account_));
301 if (!sle)
302 return tefINTERNAL;
303
304 std::uint32_t const uOwnerCount = sle->getFieldU32(sfOwnerCount);
305
306 // The reserve that is required to create the line. Note
307 // that although the reserve increases with every item
308 // an account owns, in the case of trust lines we only
309 // *enforce* a reserve if the user owns more than two
310 // items.
311 //
312 // We do this because being able to exchange currencies,
313 // which needs trust lines, is a powerful Ripple feature.
314 // So we want to make it easy for a gateway to fund the
315 // accounts of its users without fear of being tricked.
316 //
317 // Without this logic, a gateway that wanted to have a
318 // new user use its services, would have to give that
319 // user enough XRP to cover not only the account reserve
320 // but the incremental reserve for the trust line as
321 // well. A person with no intention of using the gateway
322 // could use the extra XRP for their own purposes.
323
324 XRPAmount const reserveCreate(
325 (uOwnerCount < 2) ? XRPAmount(beast::zero)
326 : view().fees().accountReserve(uOwnerCount + 1));
327
328 std::uint32_t uQualityIn(bQualityIn ? ctx_.tx.getFieldU32(sfQualityIn) : 0);
329 std::uint32_t uQualityOut(
330 bQualityOut ? ctx_.tx.getFieldU32(sfQualityOut) : 0);
331
332 if (bQualityOut && QUALITY_ONE == uQualityOut)
333 uQualityOut = 0;
334
335 std::uint32_t const uTxFlags = ctx_.tx.getFlags();
336
337 bool const bSetAuth = (uTxFlags & tfSetfAuth);
338 bool const bSetNoRipple = (uTxFlags & tfSetNoRipple);
339 bool const bClearNoRipple = (uTxFlags & tfClearNoRipple);
340 bool const bSetFreeze = (uTxFlags & tfSetFreeze);
341 bool const bClearFreeze = (uTxFlags & tfClearFreeze);
342 bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze);
343 bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze);
344
345 auto viewJ = ctx_.app.journal("View");
346
347 // Trust lines to self are impossible but because of the old bug there
348 // are two on 19-02-2022. This code was here to allow those trust lines
349 // to be deleted. The fixTrustLinesToSelf fix amendment will remove them
350 // when it enables so this code will no longer be needed.
351 if (!view().rules().enabled(fixTrustLinesToSelf) &&
352 account_ == uDstAccountID)
353 {
354 return trustDelete(
355 view(),
356 view().peek(keylet::line(account_, uDstAccountID, currency)),
357 account_,
358 uDstAccountID,
359 viewJ);
360 }
361
362 SLE::pointer sleDst = view().peek(keylet::account(uDstAccountID));
363
364 if (!sleDst)
365 {
366 JLOG(j_.trace())
367 << "Delay transaction: Destination account does not exist.";
368 return tecNO_DST;
369 }
370
371 STAmount saLimitAllow = saLimitAmount;
372 saLimitAllow.setIssuer(account_);
373
374 SLE::pointer sleRippleState =
375 view().peek(keylet::line(account_, uDstAccountID, currency));
376
377 if (sleRippleState)
378 {
379 STAmount saLowBalance;
380 STAmount saLowLimit;
381 STAmount saHighBalance;
382 STAmount saHighLimit;
383 std::uint32_t uLowQualityIn;
384 std::uint32_t uLowQualityOut;
385 std::uint32_t uHighQualityIn;
386 std::uint32_t uHighQualityOut;
387 auto const& uLowAccountID = !bHigh ? account_ : uDstAccountID;
388 auto const& uHighAccountID = bHigh ? account_ : uDstAccountID;
389 SLE::ref sleLowAccount = !bHigh ? sle : sleDst;
390 SLE::ref sleHighAccount = bHigh ? sle : sleDst;
391
392 //
393 // Balances
394 //
395
396 saLowBalance = sleRippleState->getFieldAmount(sfBalance);
397 saHighBalance = -saLowBalance;
398
399 //
400 // Limits
401 //
402
403 sleRippleState->setFieldAmount(
404 !bHigh ? sfLowLimit : sfHighLimit, saLimitAllow);
405
406 saLowLimit =
407 !bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfLowLimit);
408 saHighLimit =
409 bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfHighLimit);
410
411 //
412 // Quality in
413 //
414
415 if (!bQualityIn)
416 {
417 // Not setting. Just get it.
418
419 uLowQualityIn = sleRippleState->getFieldU32(sfLowQualityIn);
420 uHighQualityIn = sleRippleState->getFieldU32(sfHighQualityIn);
421 }
422 else if (uQualityIn)
423 {
424 // Setting.
425
426 sleRippleState->setFieldU32(
427 !bHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
428
429 uLowQualityIn = !bHigh
430 ? uQualityIn
431 : sleRippleState->getFieldU32(sfLowQualityIn);
432 uHighQualityIn = bHigh
433 ? uQualityIn
434 : sleRippleState->getFieldU32(sfHighQualityIn);
435 }
436 else
437 {
438 // Clearing.
439
440 sleRippleState->makeFieldAbsent(
441 !bHigh ? sfLowQualityIn : sfHighQualityIn);
442
443 uLowQualityIn =
444 !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityIn);
445 uHighQualityIn =
446 bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityIn);
447 }
448
449 if (QUALITY_ONE == uLowQualityIn)
450 uLowQualityIn = 0;
451
452 if (QUALITY_ONE == uHighQualityIn)
453 uHighQualityIn = 0;
454
455 //
456 // Quality out
457 //
458
459 if (!bQualityOut)
460 {
461 // Not setting. Just get it.
462
463 uLowQualityOut = sleRippleState->getFieldU32(sfLowQualityOut);
464 uHighQualityOut = sleRippleState->getFieldU32(sfHighQualityOut);
465 }
466 else if (uQualityOut)
467 {
468 // Setting.
469
470 sleRippleState->setFieldU32(
471 !bHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
472
473 uLowQualityOut = !bHigh
474 ? uQualityOut
475 : sleRippleState->getFieldU32(sfLowQualityOut);
476 uHighQualityOut = bHigh
477 ? uQualityOut
478 : sleRippleState->getFieldU32(sfHighQualityOut);
479 }
480 else
481 {
482 // Clearing.
483
484 sleRippleState->makeFieldAbsent(
485 !bHigh ? sfLowQualityOut : sfHighQualityOut);
486
487 uLowQualityOut =
488 !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityOut);
489 uHighQualityOut =
490 bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityOut);
491 }
492
493 std::uint32_t const uFlagsIn(sleRippleState->getFieldU32(sfFlags));
494 std::uint32_t uFlagsOut(uFlagsIn);
495
496 if (bSetNoRipple && !bClearNoRipple)
497 {
498 if ((bHigh ? saHighBalance : saLowBalance) >= beast::zero)
499 uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple);
500
501 else if (view().rules().enabled(fix1578))
502 // Cannot set noRipple on a negative balance.
503 return tecNO_PERMISSION;
504 }
505 else if (bClearNoRipple && !bSetNoRipple)
506 {
507 uFlagsOut &= ~(bHigh ? lsfHighNoRipple : lsfLowNoRipple);
508 }
509
510 // Have to use lsfNoFreeze to maintain pre-deep freeze behavior
511 bool const bNoFreeze = sle->isFlag(lsfNoFreeze);
512 uFlagsOut = computeFreezeFlags(
513 uFlagsOut,
514 bHigh,
515 bNoFreeze,
516 bSetFreeze,
517 bClearFreeze,
518 bSetDeepFreeze,
519 bClearDeepFreeze);
520
521 if (QUALITY_ONE == uLowQualityOut)
522 uLowQualityOut = 0;
523
524 if (QUALITY_ONE == uHighQualityOut)
525 uHighQualityOut = 0;
526
527 bool const bLowDefRipple = sleLowAccount->getFlags() & lsfDefaultRipple;
528 bool const bHighDefRipple =
529 sleHighAccount->getFlags() & lsfDefaultRipple;
530
531 bool const bLowReserveSet = uLowQualityIn || uLowQualityOut ||
532 ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple ||
533 (uFlagsOut & lsfLowFreeze) || saLowLimit ||
534 saLowBalance > beast::zero;
535 bool const bLowReserveClear = !bLowReserveSet;
536
537 bool const bHighReserveSet = uHighQualityIn || uHighQualityOut ||
538 ((uFlagsOut & lsfHighNoRipple) == 0) != bHighDefRipple ||
539 (uFlagsOut & lsfHighFreeze) || saHighLimit ||
540 saHighBalance > beast::zero;
541 bool const bHighReserveClear = !bHighReserveSet;
542
543 bool const bDefault = bLowReserveClear && bHighReserveClear;
544
545 bool const bLowReserved = (uFlagsIn & lsfLowReserve);
546 bool const bHighReserved = (uFlagsIn & lsfHighReserve);
547
548 bool bReserveIncrease = false;
549
550 if (bSetAuth)
551 {
552 uFlagsOut |= (bHigh ? lsfHighAuth : lsfLowAuth);
553 }
554
555 if (bLowReserveSet && !bLowReserved)
556 {
557 // Set reserve for low account.
558 adjustOwnerCount(view(), sleLowAccount, 1, viewJ);
559 uFlagsOut |= lsfLowReserve;
560
561 if (!bHigh)
562 bReserveIncrease = true;
563 }
564
565 if (bLowReserveClear && bLowReserved)
566 {
567 // Clear reserve for low account.
568 adjustOwnerCount(view(), sleLowAccount, -1, viewJ);
569 uFlagsOut &= ~lsfLowReserve;
570 }
571
572 if (bHighReserveSet && !bHighReserved)
573 {
574 // Set reserve for high account.
575 adjustOwnerCount(view(), sleHighAccount, 1, viewJ);
576 uFlagsOut |= lsfHighReserve;
577
578 if (bHigh)
579 bReserveIncrease = true;
580 }
581
582 if (bHighReserveClear && bHighReserved)
583 {
584 // Clear reserve for high account.
585 adjustOwnerCount(view(), sleHighAccount, -1, viewJ);
586 uFlagsOut &= ~lsfHighReserve;
587 }
588
589 if (uFlagsIn != uFlagsOut)
590 sleRippleState->setFieldU32(sfFlags, uFlagsOut);
591
592 if (bDefault || badCurrency() == currency)
593 {
594 // Delete.
595
596 terResult = trustDelete(
597 view(), sleRippleState, uLowAccountID, uHighAccountID, viewJ);
598 }
599 // Reserve is not scaled by load.
600 else if (bReserveIncrease && mPriorBalance < reserveCreate)
601 {
602 JLOG(j_.trace()) << "Delay transaction: Insufficent reserve to "
603 "add trust line.";
604
605 // Another transaction could provide XRP to the account and then
606 // this transaction would succeed.
607 terResult = tecINSUF_RESERVE_LINE;
608 }
609 else
610 {
611 view().update(sleRippleState);
612
613 JLOG(j_.trace()) << "Modify ripple line";
614 }
615 }
616 // Line does not exist.
617 else if (
618 !saLimitAmount && // Setting default limit.
619 (!bQualityIn || !uQualityIn) && // Not setting quality in or
620 // setting default quality in.
621 (!bQualityOut || !uQualityOut) && // Not setting quality out or
622 // setting default quality out.
623 (!bSetAuth))
624 {
625 JLOG(j_.trace())
626 << "Redundant: Setting non-existent ripple line to defaults.";
628 }
629 else if (mPriorBalance < reserveCreate) // Reserve is not scaled by
630 // load.
631 {
632 JLOG(j_.trace()) << "Delay transaction: Line does not exist. "
633 "Insufficent reserve to create line.";
634
635 // Another transaction could create the account and then this
636 // transaction would succeed.
637 terResult = tecNO_LINE_INSUF_RESERVE;
638 }
639 else
640 {
641 // Zero balance in currency.
642 STAmount saBalance(Issue{currency, noAccount()});
643
644 auto const k = keylet::line(account_, uDstAccountID, currency);
645
646 JLOG(j_.trace()) << "doTrustSet: Creating ripple line: "
647 << to_string(k.key);
648
649 // Create a new ripple line.
650 terResult = trustCreate(
651 view(),
652 bHigh,
653 account_,
654 uDstAccountID,
655 k.key,
656 sle,
657 bSetAuth,
658 bSetNoRipple && !bClearNoRipple,
659 bSetFreeze && !bClearFreeze,
660 bSetDeepFreeze,
661 saBalance,
662 saLimitAllow, // Limit for who is being charged.
663 uQualityIn,
664 uQualityOut,
665 viewJ);
666 }
667
668 return terResult;
669}
670
671} // namespace ripple
Stream trace() const
Severity stream access functions.
Definition: Journal.h:322
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:130
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:537
bool native() const noexcept
Definition: STAmount.h:449
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:615
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:665
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:484
std::uint32_t getFlags() const
Definition: STObject.cpp:537
static NotTEC preflight(PreflightContext const &ctx)
Definition: SetTrust.cpp:67
static TER preclaim(PreclaimContext const &ctx)
Definition: SetTrust.cpp:130
TER doApply() override
Definition: SetTrust.cpp:286
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:235
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:175
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:185
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
Definition: UintTypes.cpp:133
constexpr std::uint32_t tfSetDeepFreeze
Definition: TxFlags.h:117
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:581
@ lsfHighDeepFreeze
@ lsfDefaultRipple
@ lsfHighNoRipple
@ lsfRequireAuth
@ lsfHighFreeze
@ lsfLowNoRipple
@ lsfHighReserve
@ lsfDisallowIncomingTrustline
@ lsfLowReserve
@ lsfLowFreeze
@ lsfLowDeepFreeze
bool isTesSuccess(TER x)
Definition: TER.h:656
bool ammEnabled(Rules const &)
Return true if required AMM amendments are enabled.
Definition: AMMCore.cpp:141
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:81
@ 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:185
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:133
constexpr std::uint32_t tfSetfAuth
Definition: TxFlags.h:112
constexpr std::uint32_t tfClearFreeze
Definition: TxFlags.h:116
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, bool bDeepFreeze, STAmount const &saBalance, STAmount const &saLimit, std::uint32_t uQualityIn, std::uint32_t uQualityOut, beast::Journal j)
Create a trust line.
Definition: View.cpp:932
TER trustDelete(ApplyView &view, std::shared_ptr< SLE > const &sleRippleState, AccountID const &uLowAccountID, AccountID const &uHighAccountID, beast::Journal j)
Definition: View.cpp:1051
@ 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 tfClearDeepFreeze
Definition: TxFlags.h:118
constexpr std::uint32_t tfTrustSetMask
Definition: TxFlags.h:119
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
@ 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