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 ? xrpl::lsfHighFreeze : xrpl::lsfLowFreeze);
28 }
29 else if (bClearFreeze && !bSetFreeze)
30 {
31 uFlags &= ~(bHigh ? xrpl::lsfHighFreeze : xrpl::lsfLowFreeze);
32 }
33 if (bSetDeepFreeze && !bClearDeepFreeze && !bNoFreeze)
34 {
36 }
37 else if (bClearDeepFreeze && !bSetDeepFreeze)
38 {
40 }
41
42 return uFlags;
43}
44
45} // namespace
46
47namespace xrpl {
48
54
57{
58 auto& tx = ctx.tx;
59 auto& j = ctx.j;
60
61 std::uint32_t const uTxFlags = tx.getFlags();
62
63 if (!ctx.rules.enabled(featureDeepFreeze))
64 {
65 // Even though the deep freeze flags are included in the
66 // `tfTrustSetMask`, they are not valid if the amendment is not enabled.
67 if (uTxFlags & (tfSetDeepFreeze | tfClearDeepFreeze))
68 {
69 return temINVALID_FLAG;
70 }
71 }
72
73 STAmount const saLimitAmount(tx.getFieldAmount(sfLimitAmount));
74
75 if (!isLegalNet(saLimitAmount))
76 return temBAD_AMOUNT;
77
78 if (saLimitAmount.native())
79 {
80 JLOG(j.trace()) << "Malformed transaction: specifies native limit "
81 << saLimitAmount.getFullText();
82 return temBAD_LIMIT;
83 }
84
85 if (badCurrency() == saLimitAmount.getCurrency())
86 {
87 JLOG(j.trace()) << "Malformed transaction: specifies XRP as IOU";
88 return temBAD_CURRENCY;
89 }
90
91 if (saLimitAmount < beast::zero)
92 {
93 JLOG(j.trace()) << "Malformed transaction: Negative credit limit.";
94 return temBAD_LIMIT;
95 }
96
97 // Check if destination makes sense.
98 auto const& issuer = saLimitAmount.getIssuer();
99
100 if (!issuer || issuer == noAccount())
101 {
102 JLOG(j.trace()) << "Malformed transaction: no destination account.";
103 return temDST_NEEDED;
104 }
105
106 return tesSUCCESS;
107}
108
109NotTEC
111{
112 auto const delegate = tx[~sfDelegate];
113 if (!delegate)
114 return tesSUCCESS;
115
116 auto const delegateKey = keylet::delegate(tx[sfAccount], *delegate);
117 auto const sle = view.read(delegateKey);
118
119 if (!sle)
121
122 if (checkTxPermission(sle, tx) == tesSUCCESS)
123 return tesSUCCESS;
124
125 std::uint32_t const txFlags = tx.getFlags();
126
127 // Currently we only support TrustlineAuthorize, TrustlineFreeze and
128 // TrustlineUnfreeze granular permission. Setting other flags returns
129 // error.
130 if (txFlags & tfTrustSetPermissionMask)
132
133 if (tx.isFieldPresent(sfQualityIn) || tx.isFieldPresent(sfQualityOut))
135
136 auto const saLimitAmount = tx.getFieldAmount(sfLimitAmount);
137 auto const sleRippleState = view.read(keylet::line(
138 tx[sfAccount], saLimitAmount.getIssuer(), saLimitAmount.getCurrency()));
139
140 // if the trustline does not exist, granular permissions are
141 // not allowed to create trustline
142 if (!sleRippleState)
144
146 loadGranularPermission(sle, ttTRUST_SET, granularPermissions);
147
148 if (txFlags & tfSetfAuth &&
149 !granularPermissions.contains(TrustlineAuthorize))
151 if (txFlags & tfSetFreeze && !granularPermissions.contains(TrustlineFreeze))
153 if (txFlags & tfClearFreeze &&
154 !granularPermissions.contains(TrustlineUnfreeze))
156
157 // updating LimitAmount is not allowed only with granular permissions,
158 // unless there's a new granular permission for this in the future.
159 auto const curLimit = tx[sfAccount] > saLimitAmount.getIssuer()
160 ? sleRippleState->getFieldAmount(sfHighLimit)
161 : sleRippleState->getFieldAmount(sfLowLimit);
162
163 STAmount saLimitAllow = saLimitAmount;
164 saLimitAllow.setIssuer(tx[sfAccount]);
165
166 if (curLimit != saLimitAllow)
168
169 return tesSUCCESS;
170}
171
172TER
174{
175 auto const id = ctx.tx[sfAccount];
176
177 auto const sle = ctx.view.read(keylet::account(id));
178 if (!sle)
179 return terNO_ACCOUNT;
180
181 std::uint32_t const uTxFlags = ctx.tx.getFlags();
182
183 bool const bSetAuth = (uTxFlags & tfSetfAuth);
184
185 if (bSetAuth && !(sle->getFieldU32(sfFlags) & lsfRequireAuth))
186 {
187 JLOG(ctx.j.trace()) << "Retry: Auth not required.";
188 return tefNO_AUTH_REQUIRED;
189 }
190
191 auto const saLimitAmount = ctx.tx[sfLimitAmount];
192
193 auto const currency = saLimitAmount.getCurrency();
194 auto const uDstAccountID = saLimitAmount.getIssuer();
195
196 if (id == uDstAccountID)
197 return temDST_IS_SRC;
198
199 // This might be nullptr
200 auto const sleDst = ctx.view.read(keylet::account(uDstAccountID));
201 if ((ammEnabled(ctx.view.rules()) ||
202 ctx.view.rules().enabled(featureSingleAssetVault)) &&
203 sleDst == nullptr)
204 return tecNO_DST;
205
206 // If the destination has opted to disallow incoming trustlines
207 // then honour that flag
208 if (sleDst->getFlags() & lsfDisallowIncomingTrustline)
209 {
210 // The original implementation of featureDisallowIncoming was
211 // too restrictive. If
212 // o fixDisallowIncomingV1 is enabled and
213 // o The trust line already exists
214 // Then allow the TrustSet.
215 if (ctx.view.rules().enabled(fixDisallowIncomingV1) &&
216 ctx.view.exists(keylet::line(id, uDstAccountID, currency)))
217 {
218 // pass
219 }
220 else
221 return tecNO_PERMISSION;
222 }
223
224 // In general, trust lines to pseudo accounts are not permitted, unless
225 // enabled in the code section below, for specific cases. This block is not
226 // amendment-gated because sleDst will not have a pseudo-account designator
227 // field populated, unless the appropriate amendment was already enabled.
228 if (sleDst && isPseudoAccount(sleDst))
229 {
230 // If destination is AMM and the trustline doesn't exist then only allow
231 // SetTrust if the asset is AMM LP token and AMM is not in empty state.
232 if (sleDst->isFieldPresent(sfAMMID))
233 {
234 if (ctx.view.exists(keylet::line(id, uDstAccountID, currency)))
235 {
236 // pass
237 }
238 else if (
239 auto const ammSle =
240 ctx.view.read({ltAMM, sleDst->getFieldH256(sfAMMID)}))
241 {
242 if (auto const lpTokens =
243 ammSle->getFieldAmount(sfLPTokenBalance);
244 lpTokens == beast::zero)
245 return tecAMM_EMPTY;
246 else if (lpTokens.getCurrency() != saLimitAmount.getCurrency())
247 return tecNO_PERMISSION;
248 }
249 else
250 return tecINTERNAL; // LCOV_EXCL_LINE
251 }
252 else if (
253 sleDst->isFieldPresent(sfVaultID) ||
254 sleDst->isFieldPresent(sfLoanBrokerID))
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 xrpl
Stream trace() const
Severity stream access functions.
Definition Journal.h:303
virtual beast::Journal journal(std::string const &name)=0
STTx const & tx
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 Rules const & rules() const =0
Returns the tx processing rules.
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 std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:111
std::string getFullText() const override
Definition STAmount.cpp:653
void setIssuer(AccountID const &uIssuer)
Definition STAmount.h:580
Currency const & getCurrency() const
Definition STAmount.h:494
bool native() const noexcept
Definition STAmount.h:450
AccountID const & getIssuer() const
Definition STAmount.h:500
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:596
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:465
STAmount const & getFieldAmount(SField const &field) const
Definition STObject.cpp:652
std::uint32_t getFlags() const
Definition STObject.cpp:518
TER doApply() override
Definition SetTrust.cpp:320
static NotTEC checkPermission(ReadView const &view, STTx const &tx)
Definition SetTrust.cpp:110
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
Definition SetTrust.cpp:50
static NotTEC preflight(PreflightContext const &ctx)
Definition SetTrust.cpp:56
static TER preclaim(PreclaimContext const &ctx)
Definition SetTrust.cpp:173
AccountID const account_
Definition Transactor.h:128
beast::Journal const j_
Definition Transactor.h:126
ApplyView & view()
Definition Transactor.h:144
XRPAmount mPriorBalance
Definition Transactor.h:129
ApplyContext & ctx_
Definition Transactor.h:124
T contains(T... args)
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:226
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition Indexes.cpp:447
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:166
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
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_DELEGATE_PERMISSION
Definition TER.h:211
@ terNO_ACCOUNT
Definition TER.h:198
bool ammEnabled(Rules const &)
Return true if required AMM amendments are enabled.
Definition AMMCore.cpp:110
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
constexpr std::uint32_t tfSetNoRipple
Definition TxFlags.h:97
@ tefNO_AUTH_REQUIRED
Definition TER.h:155
@ tefINTERNAL
Definition TER.h:154
bool isLegalNet(STAmount const &value)
Definition STAmount.h:592
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct, std::set< SField const * > const &pseudoFieldFilter={})
Definition View.cpp:1226
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 tfClearFreeze
Definition TxFlags.h:100
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:1134
constexpr std::uint32_t tfClearDeepFreeze
Definition TxFlags.h:102
constexpr std::uint32_t tfTrustSetPermissionMask
Definition TxFlags.h:106
NotTEC checkTxPermission(std::shared_ptr< SLE const > const &delegate, STTx const &tx)
Check if the delegate account has permission to execute the transaction.
constexpr std::uint32_t tfSetDeepFreeze
Definition TxFlags.h:101
constexpr std::uint32_t tfTrustSetMask
Definition TxFlags.h:103
constexpr std::uint32_t tfClearNoRipple
Definition TxFlags.h:98
constexpr std::uint32_t tfSetfAuth
Definition TxFlags.h:96
AccountID const & noAccount()
A placeholder for empty accounts.
@ temBAD_CURRENCY
Definition TER.h:71
@ temINVALID_FLAG
Definition TER.h:92
@ temDST_IS_SRC
Definition TER.h:89
@ temDST_NEEDED
Definition TER.h:90
@ temBAD_LIMIT
Definition TER.h:75
@ temBAD_AMOUNT
Definition TER.h:70
@ tecPSEUDO_ACCOUNT
Definition TER.h:344
@ tecAMM_EMPTY
Definition TER.h:314
@ tecNO_LINE_INSUF_RESERVE
Definition TER.h:274
@ tecINSUF_RESERVE_LINE
Definition TER.h:270
@ tecINTERNAL
Definition TER.h:292
@ tecNO_LINE_REDUNDANT
Definition TER.h:275
@ tecNO_PERMISSION
Definition TER.h:287
@ tecNO_DST
Definition TER.h:272
@ lsfHighReserve
@ lsfLowReserve
@ lsfNoFreeze
@ lsfRequireAuth
@ lsfDefaultRipple
@ lsfLowDeepFreeze
@ lsfLowNoRipple
@ lsfLowFreeze
@ lsfHighFreeze
@ lsfHighNoRipple
@ lsfHighDeepFreeze
@ lsfHighAuth
@ lsfDisallowIncomingTrustline
TER trustDelete(ApplyView &view, std::shared_ptr< SLE > const &sleRippleState, AccountID const &uLowAccountID, AccountID const &uHighAccountID, beast::Journal j)
Definition View.cpp:1863
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
constexpr std::uint32_t tfSetFreeze
Definition TxFlags.h:99
@ tesSUCCESS
Definition TER.h:226
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