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