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