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