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 (
255 sleDst->isFieldPresent(sfVaultID) ||
256 sleDst->isFieldPresent(sfLoanBrokerID))
257 {
258 if (!ctx.view.exists(keylet::line(id, uDstAccountID, currency)))
259 return tecNO_PERMISSION;
260 // else pass
261 }
262 else
263 return tecPSEUDO_ACCOUNT;
264 }
265
266 // Checking all freeze/deep freeze flag invariants.
267 if (ctx.view.rules().enabled(featureDeepFreeze))
268 {
269 bool const bNoFreeze = sle->isFlag(lsfNoFreeze);
270 bool const bSetFreeze = (uTxFlags & tfSetFreeze);
271 bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze);
272
273 if (bNoFreeze && (bSetFreeze || bSetDeepFreeze))
274 {
275 // Cannot freeze the trust line if NoFreeze is set
276 return tecNO_PERMISSION;
277 }
278
279 bool const bClearFreeze = (uTxFlags & tfClearFreeze);
280 bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze);
281 if ((bSetFreeze || bSetDeepFreeze) &&
282 (bClearFreeze || bClearDeepFreeze))
283 {
284 // Freezing and unfreezing in the same transaction should be
285 // illegal
286 return tecNO_PERMISSION;
287 }
288
289 bool const bHigh = id > uDstAccountID;
290 // Fetching current state of trust line
291 auto const sleRippleState =
292 ctx.view.read(keylet::line(id, uDstAccountID, currency));
293 std::uint32_t uFlags =
294 sleRippleState ? sleRippleState->getFieldU32(sfFlags) : 0u;
295 // Computing expected trust line state
296 uFlags = computeFreezeFlags(
297 uFlags,
298 bHigh,
299 bNoFreeze,
300 bSetFreeze,
301 bClearFreeze,
302 bSetDeepFreeze,
303 bClearDeepFreeze);
304
305 auto const frozen = uFlags & (bHigh ? lsfHighFreeze : lsfLowFreeze);
306 auto const deepFrozen =
307 uFlags & (bHigh ? lsfHighDeepFreeze : lsfLowDeepFreeze);
308
309 // Trying to set deep freeze on not already frozen trust line must
310 // fail. This also checks that clearing normal freeze while deep
311 // frozen must not work
312 if (deepFrozen && !frozen)
313 {
314 return tecNO_PERMISSION;
315 }
316 }
317
318 return tesSUCCESS;
319}
320
321TER
323{
324 TER terResult = tesSUCCESS;
325
326 STAmount const saLimitAmount(ctx_.tx.getFieldAmount(sfLimitAmount));
327 bool const bQualityIn(ctx_.tx.isFieldPresent(sfQualityIn));
328 bool const bQualityOut(ctx_.tx.isFieldPresent(sfQualityOut));
329
330 Currency const currency(saLimitAmount.getCurrency());
331 AccountID uDstAccountID(saLimitAmount.getIssuer());
332
333 // true, if current is high account.
334 bool const bHigh = account_ > uDstAccountID;
335
336 auto const sle = view().peek(keylet::account(account_));
337 if (!sle)
338 return tefINTERNAL; // LCOV_EXCL_LINE
339
340 std::uint32_t const uOwnerCount = sle->getFieldU32(sfOwnerCount);
341
342 // The reserve that is required to create the line. Note
343 // that although the reserve increases with every item
344 // an account owns, in the case of trust lines we only
345 // *enforce* a reserve if the user owns more than two
346 // items.
347 //
348 // We do this because being able to exchange currencies,
349 // which needs trust lines, is a powerful Ripple feature.
350 // So we want to make it easy for a gateway to fund the
351 // accounts of its users without fear of being tricked.
352 //
353 // Without this logic, a gateway that wanted to have a
354 // new user use its services, would have to give that
355 // user enough XRP to cover not only the account reserve
356 // but the incremental reserve for the trust line as
357 // well. A person with no intention of using the gateway
358 // could use the extra XRP for their own purposes.
359
360 XRPAmount const reserveCreate(
361 (uOwnerCount < 2) ? XRPAmount(beast::zero)
362 : view().fees().accountReserve(uOwnerCount + 1));
363
364 std::uint32_t uQualityIn(bQualityIn ? ctx_.tx.getFieldU32(sfQualityIn) : 0);
365 std::uint32_t uQualityOut(
366 bQualityOut ? ctx_.tx.getFieldU32(sfQualityOut) : 0);
367
368 if (bQualityOut && QUALITY_ONE == uQualityOut)
369 uQualityOut = 0;
370
371 std::uint32_t const uTxFlags = ctx_.tx.getFlags();
372
373 bool const bSetAuth = (uTxFlags & tfSetfAuth);
374 bool const bSetNoRipple = (uTxFlags & tfSetNoRipple);
375 bool const bClearNoRipple = (uTxFlags & tfClearNoRipple);
376 bool const bSetFreeze = (uTxFlags & tfSetFreeze);
377 bool const bClearFreeze = (uTxFlags & tfClearFreeze);
378 bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze);
379 bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze);
380
381 auto viewJ = ctx_.app.journal("View");
382
383 SLE::pointer sleDst = view().peek(keylet::account(uDstAccountID));
384
385 if (!sleDst)
386 {
387 JLOG(j_.trace())
388 << "Delay transaction: Destination account does not exist.";
389 return tecNO_DST;
390 }
391
392 STAmount saLimitAllow = saLimitAmount;
393 saLimitAllow.setIssuer(account_);
394
395 SLE::pointer sleRippleState =
396 view().peek(keylet::line(account_, uDstAccountID, currency));
397
398 if (sleRippleState)
399 {
400 STAmount saLowBalance;
401 STAmount saLowLimit;
402 STAmount saHighBalance;
403 STAmount saHighLimit;
404 std::uint32_t uLowQualityIn;
405 std::uint32_t uLowQualityOut;
406 std::uint32_t uHighQualityIn;
407 std::uint32_t uHighQualityOut;
408 auto const& uLowAccountID = !bHigh ? account_ : uDstAccountID;
409 auto const& uHighAccountID = bHigh ? account_ : uDstAccountID;
410 SLE::ref sleLowAccount = !bHigh ? sle : sleDst;
411 SLE::ref sleHighAccount = bHigh ? sle : sleDst;
412
413 //
414 // Balances
415 //
416
417 saLowBalance = sleRippleState->getFieldAmount(sfBalance);
418 saHighBalance = -saLowBalance;
419
420 //
421 // Limits
422 //
423
424 sleRippleState->setFieldAmount(
425 !bHigh ? sfLowLimit : sfHighLimit, saLimitAllow);
426
427 saLowLimit =
428 !bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfLowLimit);
429 saHighLimit =
430 bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfHighLimit);
431
432 //
433 // Quality in
434 //
435
436 if (!bQualityIn)
437 {
438 // Not setting. Just get it.
439
440 uLowQualityIn = sleRippleState->getFieldU32(sfLowQualityIn);
441 uHighQualityIn = sleRippleState->getFieldU32(sfHighQualityIn);
442 }
443 else if (uQualityIn)
444 {
445 // Setting.
446
447 sleRippleState->setFieldU32(
448 !bHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
449
450 uLowQualityIn = !bHigh
451 ? uQualityIn
452 : sleRippleState->getFieldU32(sfLowQualityIn);
453 uHighQualityIn = bHigh
454 ? uQualityIn
455 : sleRippleState->getFieldU32(sfHighQualityIn);
456 }
457 else
458 {
459 // Clearing.
460
461 sleRippleState->makeFieldAbsent(
462 !bHigh ? sfLowQualityIn : sfHighQualityIn);
463
464 uLowQualityIn =
465 !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityIn);
466 uHighQualityIn =
467 bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityIn);
468 }
469
470 if (QUALITY_ONE == uLowQualityIn)
471 uLowQualityIn = 0;
472
473 if (QUALITY_ONE == uHighQualityIn)
474 uHighQualityIn = 0;
475
476 //
477 // Quality out
478 //
479
480 if (!bQualityOut)
481 {
482 // Not setting. Just get it.
483
484 uLowQualityOut = sleRippleState->getFieldU32(sfLowQualityOut);
485 uHighQualityOut = sleRippleState->getFieldU32(sfHighQualityOut);
486 }
487 else if (uQualityOut)
488 {
489 // Setting.
490
491 sleRippleState->setFieldU32(
492 !bHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
493
494 uLowQualityOut = !bHigh
495 ? uQualityOut
496 : sleRippleState->getFieldU32(sfLowQualityOut);
497 uHighQualityOut = bHigh
498 ? uQualityOut
499 : sleRippleState->getFieldU32(sfHighQualityOut);
500 }
501 else
502 {
503 // Clearing.
504
505 sleRippleState->makeFieldAbsent(
506 !bHigh ? sfLowQualityOut : sfHighQualityOut);
507
508 uLowQualityOut =
509 !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityOut);
510 uHighQualityOut =
511 bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityOut);
512 }
513
514 std::uint32_t const uFlagsIn(sleRippleState->getFieldU32(sfFlags));
515 std::uint32_t uFlagsOut(uFlagsIn);
516
517 if (bSetNoRipple && !bClearNoRipple)
518 {
519 if ((bHigh ? saHighBalance : saLowBalance) >= beast::zero)
520 uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple);
521
522 else
523 // Cannot set noRipple on a negative balance.
524 return tecNO_PERMISSION;
525 }
526 else if (bClearNoRipple && !bSetNoRipple)
527 {
528 uFlagsOut &= ~(bHigh ? lsfHighNoRipple : lsfLowNoRipple);
529 }
530
531 // Have to use lsfNoFreeze to maintain pre-deep freeze behavior
532 bool const bNoFreeze = sle->isFlag(lsfNoFreeze);
533 uFlagsOut = computeFreezeFlags(
534 uFlagsOut,
535 bHigh,
536 bNoFreeze,
537 bSetFreeze,
538 bClearFreeze,
539 bSetDeepFreeze,
540 bClearDeepFreeze);
541
542 if (QUALITY_ONE == uLowQualityOut)
543 uLowQualityOut = 0;
544
545 if (QUALITY_ONE == uHighQualityOut)
546 uHighQualityOut = 0;
547
548 bool const bLowDefRipple = sleLowAccount->getFlags() & lsfDefaultRipple;
549 bool const bHighDefRipple =
550 sleHighAccount->getFlags() & lsfDefaultRipple;
551
552 bool const bLowReserveSet = uLowQualityIn || uLowQualityOut ||
553 ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple ||
554 (uFlagsOut & lsfLowFreeze) || saLowLimit ||
555 saLowBalance > beast::zero;
556 bool const bLowReserveClear = !bLowReserveSet;
557
558 bool const bHighReserveSet = uHighQualityIn || uHighQualityOut ||
559 ((uFlagsOut & lsfHighNoRipple) == 0) != bHighDefRipple ||
560 (uFlagsOut & lsfHighFreeze) || saHighLimit ||
561 saHighBalance > beast::zero;
562 bool const bHighReserveClear = !bHighReserveSet;
563
564 bool const bDefault = bLowReserveClear && bHighReserveClear;
565
566 bool const bLowReserved = (uFlagsIn & lsfLowReserve);
567 bool const bHighReserved = (uFlagsIn & lsfHighReserve);
568
569 bool bReserveIncrease = false;
570
571 if (bSetAuth)
572 {
573 uFlagsOut |= (bHigh ? lsfHighAuth : lsfLowAuth);
574 }
575
576 if (bLowReserveSet && !bLowReserved)
577 {
578 // Set reserve for low account.
579 adjustOwnerCount(view(), sleLowAccount, 1, viewJ);
580 uFlagsOut |= lsfLowReserve;
581
582 if (!bHigh)
583 bReserveIncrease = true;
584 }
585
586 if (bLowReserveClear && bLowReserved)
587 {
588 // Clear reserve for low account.
589 adjustOwnerCount(view(), sleLowAccount, -1, viewJ);
590 uFlagsOut &= ~lsfLowReserve;
591 }
592
593 if (bHighReserveSet && !bHighReserved)
594 {
595 // Set reserve for high account.
596 adjustOwnerCount(view(), sleHighAccount, 1, viewJ);
597 uFlagsOut |= lsfHighReserve;
598
599 if (bHigh)
600 bReserveIncrease = true;
601 }
602
603 if (bHighReserveClear && bHighReserved)
604 {
605 // Clear reserve for high account.
606 adjustOwnerCount(view(), sleHighAccount, -1, viewJ);
607 uFlagsOut &= ~lsfHighReserve;
608 }
609
610 if (uFlagsIn != uFlagsOut)
611 sleRippleState->setFieldU32(sfFlags, uFlagsOut);
612
613 if (bDefault || badCurrency() == currency)
614 {
615 // Delete.
616
617 terResult = trustDelete(
618 view(), sleRippleState, uLowAccountID, uHighAccountID, viewJ);
619 }
620 // Reserve is not scaled by load.
621 else if (bReserveIncrease && mPriorBalance < reserveCreate)
622 {
623 JLOG(j_.trace()) << "Delay transaction: Insufficent reserve to "
624 "add trust line.";
625
626 // Another transaction could provide XRP to the account and then
627 // this transaction would succeed.
628 terResult = tecINSUF_RESERVE_LINE;
629 }
630 else
631 {
632 view().update(sleRippleState);
633
634 JLOG(j_.trace()) << "Modify ripple line";
635 }
636 }
637 // Line does not exist.
638 else if (
639 !saLimitAmount && // Setting default limit.
640 (!bQualityIn || !uQualityIn) && // Not setting quality in or
641 // setting default quality in.
642 (!bQualityOut || !uQualityOut) && // Not setting quality out or
643 // setting default quality out.
644 (!bSetAuth))
645 {
646 JLOG(j_.trace())
647 << "Redundant: Setting non-existent ripple line to defaults.";
649 }
650 else if (mPriorBalance < reserveCreate) // Reserve is not scaled by
651 // load.
652 {
653 JLOG(j_.trace()) << "Delay transaction: Line does not exist. "
654 "Insufficent reserve to create line.";
655
656 // Another transaction could create the account and then this
657 // transaction would succeed.
658 terResult = tecNO_LINE_INSUF_RESERVE;
659 }
660 else
661 {
662 // Zero balance in currency.
663 STAmount saBalance(Issue{currency, noAccount()});
664
665 auto const k = keylet::line(account_, uDstAccountID, currency);
666
667 JLOG(j_.trace()) << "doTrustSet: Creating ripple line: "
668 << to_string(k.key);
669
670 // Create a new ripple line.
671 terResult = trustCreate(
672 view(),
673 bHigh,
674 account_,
675 uDstAccountID,
676 k.key,
677 sle,
678 bSetAuth,
679 bSetNoRipple && !bClearNoRipple,
680 bSetFreeze && !bClearFreeze,
681 bSetDeepFreeze,
682 saBalance,
683 saLimitAllow, // Limit for who is being charged.
684 uQualityIn,
685 uQualityOut,
686 viewJ);
687 }
688
689 return terResult;
690}
691
692} // 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:580
Currency const & getCurrency() const
Definition STAmount.h:494
AccountID const & getIssuer() const
Definition STAmount.h:500
std::string getFullText() const override
Definition STAmount.cpp:654
bool native() const noexcept
Definition STAmount.h:450
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:322
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:448
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:227
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:167
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...
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct, std::set< SField const * > const &pseudoFieldFilter={})
Definition View.cpp:1226
constexpr std::uint32_t tfSetDeepFreeze
Definition TxFlags.h:101
bool isLegalNet(STAmount const &value)
Definition STAmount.h:592
@ 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:1135
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:1863
@ 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:1635
@ 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
@ 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