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