rippled
Loading...
Searching...
No Matches
SetAccount.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/misc/DelegateUtils.h>
21#include <xrpld/app/tx/detail/SetAccount.h>
22#include <xrpld/core/Config.h>
23#include <xrpld/ledger/View.h>
24
25#include <xrpl/basics/Log.h>
26#include <xrpl/protocol/Feature.h>
27#include <xrpl/protocol/Indexes.h>
28#include <xrpl/protocol/PublicKey.h>
29#include <xrpl/protocol/Quality.h>
30#include <xrpl/protocol/st.h>
31
32namespace ripple {
33
34TxConsequences
36{
37 // The SetAccount may be a blocker, but only if it sets or clears
38 // specific account flags.
39 auto getTxConsequencesCategory = [](STTx const& tx) {
40 if (std::uint32_t const uTxFlags = tx.getFlags();
41 uTxFlags & (tfRequireAuth | tfOptionalAuth))
43
44 if (auto const uSetFlag = tx[~sfSetFlag]; uSetFlag &&
45 (*uSetFlag == asfRequireAuth || *uSetFlag == asfDisableMaster ||
46 *uSetFlag == asfAccountTxnID))
48
49 if (auto const uClearFlag = tx[~sfClearFlag]; uClearFlag &&
50 (*uClearFlag == asfRequireAuth || *uClearFlag == asfDisableMaster ||
51 *uClearFlag == asfAccountTxnID))
53
55 };
56
57 return TxConsequences{ctx.tx, getTxConsequencesCategory(ctx.tx)};
58}
59
62{
63 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
64 return ret;
65
66 auto& tx = ctx.tx;
67 auto& j = ctx.j;
68
69 std::uint32_t const uTxFlags = tx.getFlags();
70
71 if (uTxFlags & tfAccountSetMask)
72 {
73 JLOG(j.trace()) << "Malformed transaction: Invalid flags set.";
74 return temINVALID_FLAG;
75 }
76
77 std::uint32_t const uSetFlag = tx.getFieldU32(sfSetFlag);
78 std::uint32_t const uClearFlag = tx.getFieldU32(sfClearFlag);
79
80 if ((uSetFlag != 0) && (uSetFlag == uClearFlag))
81 {
82 JLOG(j.trace()) << "Malformed transaction: Set and clear same flag.";
83 return temINVALID_FLAG;
84 }
85
86 //
87 // RequireAuth
88 //
89 bool bSetRequireAuth =
90 (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth);
91 bool bClearRequireAuth =
92 (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth);
93
94 if (bSetRequireAuth && bClearRequireAuth)
95 {
96 JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
97 return temINVALID_FLAG;
98 }
99
100 //
101 // RequireDestTag
102 //
103 bool bSetRequireDest =
104 (uTxFlags & tfRequireDestTag) || (uSetFlag == asfRequireDest);
105 bool bClearRequireDest =
106 (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest);
107
108 if (bSetRequireDest && bClearRequireDest)
109 {
110 JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
111 return temINVALID_FLAG;
112 }
113
114 //
115 // DisallowXRP
116 //
117 bool bSetDisallowXRP =
118 (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP);
119 bool bClearDisallowXRP =
120 (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP);
121
122 if (bSetDisallowXRP && bClearDisallowXRP)
123 {
124 JLOG(j.trace()) << "Malformed transaction: Contradictory flags set.";
125 return temINVALID_FLAG;
126 }
127
128 // TransferRate
129 if (tx.isFieldPresent(sfTransferRate))
130 {
131 std::uint32_t uRate = tx.getFieldU32(sfTransferRate);
132
133 if (uRate && (uRate < QUALITY_ONE))
134 {
135 JLOG(j.trace())
136 << "Malformed transaction: Transfer rate too small.";
138 }
139
140 if (uRate > 2 * QUALITY_ONE)
141 {
142 JLOG(j.trace())
143 << "Malformed transaction: Transfer rate too large.";
145 }
146 }
147
148 // TickSize
149 if (tx.isFieldPresent(sfTickSize))
150 {
151 auto uTickSize = tx[sfTickSize];
152 if (uTickSize &&
153 ((uTickSize < Quality::minTickSize) ||
154 (uTickSize > Quality::maxTickSize)))
155 {
156 JLOG(j.trace()) << "Malformed transaction: Bad tick size.";
157 return temBAD_TICK_SIZE;
158 }
159 }
160
161 if (auto const mk = tx[~sfMessageKey])
162 {
163 if (mk->size() && !publicKeyType({mk->data(), mk->size()}))
164 {
165 JLOG(j.trace()) << "Invalid message key specified.";
166 return telBAD_PUBLIC_KEY;
167 }
168 }
169
170 if (auto const domain = tx[~sfDomain];
171 domain && domain->size() > maxDomainLength)
172 {
173 JLOG(j.trace()) << "domain too long";
174 return telBAD_DOMAIN;
175 }
176
177 if (ctx.rules.enabled(featureNonFungibleTokensV1))
178 {
179 // Configure authorized minting account:
180 if (uSetFlag == asfAuthorizedNFTokenMinter &&
181 !tx.isFieldPresent(sfNFTokenMinter))
182 return temMALFORMED;
183
184 if (uClearFlag == asfAuthorizedNFTokenMinter &&
185 tx.isFieldPresent(sfNFTokenMinter))
186 return temMALFORMED;
187 }
188
189 return preflight2(ctx);
190}
191
192TER
194{
195 // SetAccount is prohibited to be granted on a transaction level,
196 // but some granular permissions are allowed.
197 auto const delegate = tx[~sfDelegate];
198 if (!delegate)
199 return tesSUCCESS;
200
201 auto const delegateKey = keylet::delegate(tx[sfAccount], *delegate);
202 auto const sle = view.read(delegateKey);
203
204 if (!sle)
206
208 loadGranularPermission(sle, ttACCOUNT_SET, granularPermissions);
209
210 auto const uSetFlag = tx.getFieldU32(sfSetFlag);
211 auto const uClearFlag = tx.getFieldU32(sfClearFlag);
212 auto const uTxFlags = tx.getFlags();
213 // We don't support any flag based granular permission under
214 // AccountSet transaction. If any delegated account is trying to
215 // update the flag on behalf of another account, it is not
216 // authorized.
217 if (uSetFlag != 0 || uClearFlag != 0 || uTxFlags & tfUniversalMask)
219
220 if (tx.isFieldPresent(sfEmailHash) &&
221 !granularPermissions.contains(AccountEmailHashSet))
223
224 if (tx.isFieldPresent(sfWalletLocator) ||
225 tx.isFieldPresent(sfNFTokenMinter))
227
228 if (tx.isFieldPresent(sfMessageKey) &&
229 !granularPermissions.contains(AccountMessageKeySet))
231
232 if (tx.isFieldPresent(sfDomain) &&
233 !granularPermissions.contains(AccountDomainSet))
235
236 if (tx.isFieldPresent(sfTransferRate) &&
237 !granularPermissions.contains(AccountTransferRateSet))
239
240 if (tx.isFieldPresent(sfTickSize) &&
241 !granularPermissions.contains(AccountTickSizeSet))
243
244 return tesSUCCESS;
245}
246
247TER
249{
250 auto const id = ctx.tx[sfAccount];
251
252 std::uint32_t const uTxFlags = ctx.tx.getFlags();
253
254 auto const sle = ctx.view.read(keylet::account(id));
255 if (!sle)
256 return terNO_ACCOUNT;
257
258 std::uint32_t const uFlagsIn = sle->getFieldU32(sfFlags);
259
260 std::uint32_t const uSetFlag = ctx.tx.getFieldU32(sfSetFlag);
261
262 // legacy AccountSet flags
263 bool bSetRequireAuth =
264 (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth);
265
266 //
267 // RequireAuth
268 //
269 if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth))
270 {
271 if (!dirIsEmpty(ctx.view, keylet::ownerDir(id)))
272 {
273 JLOG(ctx.j.trace()) << "Retry: Owner directory not empty.";
274 return (ctx.flags & tapRETRY) ? TER{terOWNERS} : TER{tecOWNERS};
275 }
276 }
277
278 //
279 // Clawback
280 //
281 if (ctx.view.rules().enabled(featureClawback))
282 {
283 if (uSetFlag == asfAllowTrustLineClawback)
284 {
285 if (uFlagsIn & lsfNoFreeze)
286 {
287 JLOG(ctx.j.trace()) << "Can't set Clawback if NoFreeze is set";
288 return tecNO_PERMISSION;
289 }
290
291 if (!dirIsEmpty(ctx.view, keylet::ownerDir(id)))
292 {
293 JLOG(ctx.j.trace()) << "Owner directory not empty.";
294 return tecOWNERS;
295 }
296 }
297 else if (uSetFlag == asfNoFreeze)
298 {
299 // Cannot set NoFreeze if clawback is enabled
300 if (uFlagsIn & lsfAllowTrustLineClawback)
301 {
302 JLOG(ctx.j.trace())
303 << "Can't set NoFreeze if clawback is enabled";
304 return tecNO_PERMISSION;
305 }
306 }
307 }
308
309 return tesSUCCESS;
310}
311
312TER
314{
315 auto const sle = view().peek(keylet::account(account_));
316 if (!sle)
317 return tefINTERNAL;
318
319 std::uint32_t const uFlagsIn = sle->getFieldU32(sfFlags);
320 std::uint32_t uFlagsOut = uFlagsIn;
321
322 STTx const& tx{ctx_.tx};
323 std::uint32_t const uSetFlag{tx.getFieldU32(sfSetFlag)};
324 std::uint32_t const uClearFlag{tx.getFieldU32(sfClearFlag)};
325
326 // legacy AccountSet flags
327 std::uint32_t const uTxFlags{tx.getFlags()};
328 bool const bSetRequireDest{
329 (uTxFlags & tfRequireDestTag) || (uSetFlag == asfRequireDest)};
330 bool const bClearRequireDest{
331 (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest)};
332 bool const bSetRequireAuth{
333 (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth)};
334 bool const bClearRequireAuth{
335 (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth)};
336 bool const bSetDisallowXRP{
337 (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP)};
338 bool const bClearDisallowXRP{
339 (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP)};
340
341 bool const sigWithMaster{[&tx, &acct = account_]() {
342 auto const spk = tx.getSigningPubKey();
343
344 if (publicKeyType(makeSlice(spk)))
345 {
346 PublicKey const signingPubKey(makeSlice(spk));
347
348 if (calcAccountID(signingPubKey) == acct)
349 return true;
350 }
351 return false;
352 }()};
353
354 //
355 // RequireAuth
356 //
357 if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth))
358 {
359 JLOG(j_.trace()) << "Set RequireAuth.";
360 uFlagsOut |= lsfRequireAuth;
361 }
362
363 if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth))
364 {
365 JLOG(j_.trace()) << "Clear RequireAuth.";
366 uFlagsOut &= ~lsfRequireAuth;
367 }
368
369 //
370 // RequireDestTag
371 //
372 if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag))
373 {
374 JLOG(j_.trace()) << "Set lsfRequireDestTag.";
375 uFlagsOut |= lsfRequireDestTag;
376 }
377
378 if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag))
379 {
380 JLOG(j_.trace()) << "Clear lsfRequireDestTag.";
381 uFlagsOut &= ~lsfRequireDestTag;
382 }
383
384 //
385 // DisallowXRP
386 //
387 if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP))
388 {
389 JLOG(j_.trace()) << "Set lsfDisallowXRP.";
390 uFlagsOut |= lsfDisallowXRP;
391 }
392
393 if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP))
394 {
395 JLOG(j_.trace()) << "Clear lsfDisallowXRP.";
396 uFlagsOut &= ~lsfDisallowXRP;
397 }
398
399 //
400 // DisableMaster
401 //
402 if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster))
403 {
404 if (!sigWithMaster)
405 {
406 JLOG(j_.trace()) << "Must use master key to disable master key.";
407 return tecNEED_MASTER_KEY;
408 }
409
410 if ((!sle->isFieldPresent(sfRegularKey)) &&
411 (!view().peek(keylet::signers(account_))))
412 {
413 // Account has no regular key or multi-signer signer list.
415 }
416
417 JLOG(j_.trace()) << "Set lsfDisableMaster.";
418 uFlagsOut |= lsfDisableMaster;
419 }
420
421 if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster))
422 {
423 JLOG(j_.trace()) << "Clear lsfDisableMaster.";
424 uFlagsOut &= ~lsfDisableMaster;
425 }
426
427 //
428 // DefaultRipple
429 //
430 if (uSetFlag == asfDefaultRipple)
431 {
432 JLOG(j_.trace()) << "Set lsfDefaultRipple.";
433 uFlagsOut |= lsfDefaultRipple;
434 }
435 else if (uClearFlag == asfDefaultRipple)
436 {
437 JLOG(j_.trace()) << "Clear lsfDefaultRipple.";
438 uFlagsOut &= ~lsfDefaultRipple;
439 }
440
441 //
442 // NoFreeze
443 //
444 if (uSetFlag == asfNoFreeze)
445 {
446 if (!sigWithMaster && !(uFlagsIn & lsfDisableMaster))
447 {
448 JLOG(j_.trace()) << "Must use master key to set NoFreeze.";
449 return tecNEED_MASTER_KEY;
450 }
451
452 JLOG(j_.trace()) << "Set NoFreeze flag";
453 uFlagsOut |= lsfNoFreeze;
454 }
455
456 // Anyone may set global freeze
457 if (uSetFlag == asfGlobalFreeze)
458 {
459 JLOG(j_.trace()) << "Set GlobalFreeze flag";
460 uFlagsOut |= lsfGlobalFreeze;
461 }
462
463 // If you have set NoFreeze, you may not clear GlobalFreeze
464 // This prevents those who have set NoFreeze from using
465 // GlobalFreeze strategically.
466 if ((uSetFlag != asfGlobalFreeze) && (uClearFlag == asfGlobalFreeze) &&
467 ((uFlagsOut & lsfNoFreeze) == 0))
468 {
469 JLOG(j_.trace()) << "Clear GlobalFreeze flag";
470 uFlagsOut &= ~lsfGlobalFreeze;
471 }
472
473 //
474 // Track transaction IDs signed by this account in its root
475 //
476 if ((uSetFlag == asfAccountTxnID) && !sle->isFieldPresent(sfAccountTxnID))
477 {
478 JLOG(j_.trace()) << "Set AccountTxnID.";
479 sle->makeFieldPresent(sfAccountTxnID);
480 }
481
482 if ((uClearFlag == asfAccountTxnID) && sle->isFieldPresent(sfAccountTxnID))
483 {
484 JLOG(j_.trace()) << "Clear AccountTxnID.";
485 sle->makeFieldAbsent(sfAccountTxnID);
486 }
487
488 //
489 // DepositAuth
490 //
491 if (view().rules().enabled(featureDepositAuth))
492 {
493 if (uSetFlag == asfDepositAuth)
494 {
495 JLOG(j_.trace()) << "Set lsfDepositAuth.";
496 uFlagsOut |= lsfDepositAuth;
497 }
498 else if (uClearFlag == asfDepositAuth)
499 {
500 JLOG(j_.trace()) << "Clear lsfDepositAuth.";
501 uFlagsOut &= ~lsfDepositAuth;
502 }
503 }
504
505 //
506 // EmailHash
507 //
508 if (tx.isFieldPresent(sfEmailHash))
509 {
510 uint128 const uHash = tx.getFieldH128(sfEmailHash);
511
512 if (!uHash)
513 {
514 JLOG(j_.trace()) << "unset email hash";
515 sle->makeFieldAbsent(sfEmailHash);
516 }
517 else
518 {
519 JLOG(j_.trace()) << "set email hash";
520 sle->setFieldH128(sfEmailHash, uHash);
521 }
522 }
523
524 //
525 // WalletLocator
526 //
527 if (tx.isFieldPresent(sfWalletLocator))
528 {
529 uint256 const uHash = tx.getFieldH256(sfWalletLocator);
530
531 if (!uHash)
532 {
533 JLOG(j_.trace()) << "unset wallet locator";
534 sle->makeFieldAbsent(sfWalletLocator);
535 }
536 else
537 {
538 JLOG(j_.trace()) << "set wallet locator";
539 sle->setFieldH256(sfWalletLocator, uHash);
540 }
541 }
542
543 //
544 // MessageKey
545 //
546 if (tx.isFieldPresent(sfMessageKey))
547 {
548 Blob const messageKey = tx.getFieldVL(sfMessageKey);
549
550 if (messageKey.empty())
551 {
552 JLOG(j_.debug()) << "set message key";
553 sle->makeFieldAbsent(sfMessageKey);
554 }
555 else
556 {
557 JLOG(j_.debug()) << "set message key";
558 sle->setFieldVL(sfMessageKey, messageKey);
559 }
560 }
561
562 //
563 // Domain
564 //
565 if (tx.isFieldPresent(sfDomain))
566 {
567 Blob const domain = tx.getFieldVL(sfDomain);
568
569 if (domain.empty())
570 {
571 JLOG(j_.trace()) << "unset domain";
572 sle->makeFieldAbsent(sfDomain);
573 }
574 else
575 {
576 JLOG(j_.trace()) << "set domain";
577 sle->setFieldVL(sfDomain, domain);
578 }
579 }
580
581 //
582 // TransferRate
583 //
584 if (tx.isFieldPresent(sfTransferRate))
585 {
586 std::uint32_t uRate = tx.getFieldU32(sfTransferRate);
587
588 if (uRate == 0 || uRate == QUALITY_ONE)
589 {
590 JLOG(j_.trace()) << "unset transfer rate";
591 sle->makeFieldAbsent(sfTransferRate);
592 }
593 else
594 {
595 JLOG(j_.trace()) << "set transfer rate";
596 sle->setFieldU32(sfTransferRate, uRate);
597 }
598 }
599
600 //
601 // TickSize
602 //
603 if (tx.isFieldPresent(sfTickSize))
604 {
605 auto uTickSize = tx[sfTickSize];
606 if ((uTickSize == 0) || (uTickSize == Quality::maxTickSize))
607 {
608 JLOG(j_.trace()) << "unset tick size";
609 sle->makeFieldAbsent(sfTickSize);
610 }
611 else
612 {
613 JLOG(j_.trace()) << "set tick size";
614 sle->setFieldU8(sfTickSize, uTickSize);
615 }
616 }
617
618 // Configure authorized minting account:
619 if (ctx_.view().rules().enabled(featureNonFungibleTokensV1))
620 {
621 if (uSetFlag == asfAuthorizedNFTokenMinter)
622 sle->setAccountID(sfNFTokenMinter, ctx_.tx[sfNFTokenMinter]);
623
624 if (uClearFlag == asfAuthorizedNFTokenMinter &&
625 sle->isFieldPresent(sfNFTokenMinter))
626 sle->makeFieldAbsent(sfNFTokenMinter);
627 }
628
629 // Set or clear flags for disallowing various incoming instruments
630 if (ctx_.view().rules().enabled(featureDisallowIncoming))
631 {
632 if (uSetFlag == asfDisallowIncomingNFTokenOffer)
634 else if (uClearFlag == asfDisallowIncomingNFTokenOffer)
635 uFlagsOut &= ~lsfDisallowIncomingNFTokenOffer;
636
637 if (uSetFlag == asfDisallowIncomingCheck)
638 uFlagsOut |= lsfDisallowIncomingCheck;
639 else if (uClearFlag == asfDisallowIncomingCheck)
640 uFlagsOut &= ~lsfDisallowIncomingCheck;
641
642 if (uSetFlag == asfDisallowIncomingPayChan)
643 uFlagsOut |= lsfDisallowIncomingPayChan;
644 else if (uClearFlag == asfDisallowIncomingPayChan)
645 uFlagsOut &= ~lsfDisallowIncomingPayChan;
646
647 if (uSetFlag == asfDisallowIncomingTrustline)
648 uFlagsOut |= lsfDisallowIncomingTrustline;
649 else if (uClearFlag == asfDisallowIncomingTrustline)
650 uFlagsOut &= ~lsfDisallowIncomingTrustline;
651 }
652
653 // Set or clear flags for disallowing escrow
654 if (ctx_.view().rules().enabled(featureTokenEscrow))
655 {
656 if (uSetFlag == asfAllowTrustLineLocking)
657 uFlagsOut |= lsfAllowTrustLineLocking;
658 else if (uClearFlag == asfAllowTrustLineLocking)
659 uFlagsOut &= ~lsfAllowTrustLineLocking;
660 }
661
662 // Set flag for clawback
663 if (ctx_.view().rules().enabled(featureClawback) &&
664 uSetFlag == asfAllowTrustLineClawback)
665 {
666 JLOG(j_.trace()) << "set allow clawback";
667 uFlagsOut |= lsfAllowTrustLineClawback;
668 }
669
670 if (uFlagsIn != uFlagsOut)
671 sle->setFieldU32(sfFlags, uFlagsOut);
672
673 ctx_.view().update(sle);
674
675 return tesSUCCESS;
676}
677
678} // namespace ripple
Stream debug() const
Definition Journal.h:328
Stream trace() const
Severity stream access functions.
Definition Journal.h:322
ApplyView & view()
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 public key.
Definition PublicKey.h:61
A view into a ledger.
Definition ReadView.h:52
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
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:130
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:615
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:484
std::uint32_t getFlags() const
Definition STObject.cpp:537
static TER checkPermission(ReadView const &view, STTx const &tx)
static TER preclaim(PreclaimContext const &ctx)
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
TER doApply() override
AccountID const account_
Definition Transactor.h:143
ApplyView & view()
Definition Transactor.h:159
beast::Journal const j_
Definition Transactor.h:141
ApplyContext & ctx_
Definition Transactor.h:140
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition applySteps.h:59
@ normal
Moves currency around, creates offers, etc.
Definition applySteps.h:65
@ blocker
Affects the ability of subsequent transactions to claim a fee.
Definition applySteps.h:68
Integers of any length that is a multiple of 32-bits.
Definition base_uint.h:86
T contains(T... args)
T empty(T... args)
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition Indexes.cpp:465
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:184
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
Keylet signers(AccountID const &account) noexcept
A SignerList.
Definition Indexes.cpp:330
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
constexpr std::uint32_t tfAllowXRP
Definition TxFlags.h:71
constexpr std::uint32_t asfGlobalFreeze
Definition TxFlags.h:83
constexpr std::uint32_t asfDepositAuth
Definition TxFlags.h:85
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer
Definition TxFlags.h:90
@ telBAD_PUBLIC_KEY
Definition TER.h:55
@ telBAD_DOMAIN
Definition TER.h:53
constexpr std::uint32_t asfAllowTrustLineLocking
Definition TxFlags.h:95
constexpr std::uint32_t asfRequireDest
Definition TxFlags.h:77
constexpr std::uint32_t asfAuthorizedNFTokenMinter
Definition TxFlags.h:86
constexpr std::uint32_t tfOptionalDestTag
Definition TxFlags.h:67
@ lsfRequireDestTag
@ lsfDefaultRipple
@ lsfDisallowIncomingCheck
@ lsfAllowTrustLineClawback
@ lsfDisableMaster
@ lsfDisallowIncomingPayChan
@ lsfDisallowIncomingTrustline
@ lsfAllowTrustLineLocking
@ lsfDisallowIncomingNFTokenOffer
@ lsfGlobalFreeze
constexpr std::uint32_t tfAccountSetMask
Definition TxFlags.h:72
constexpr std::uint32_t tfRequireDestTag
Definition TxFlags.h:66
constexpr std::uint32_t asfNoFreeze
Definition TxFlags.h:82
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
AccountID calcAccountID(PublicKey const &pk)
std::size_t constexpr maxDomainLength
The maximum length of a domain.
Definition Protocol.h:98
constexpr std::uint32_t asfDisableMaster
Definition TxFlags.h:80
constexpr std::uint32_t asfDisallowIncomingTrustline
Definition TxFlags.h:93
@ tefINTERNAL
Definition TER.h:173
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
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.
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
constexpr std::uint32_t asfAccountTxnID
Definition TxFlags.h:81
constexpr std::uint32_t asfDefaultRipple
Definition TxFlags.h:84
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:244
constexpr std::uint32_t asfDisallowIncomingCheck
Definition TxFlags.h:91
constexpr std::uint32_t tfRequireAuth
Definition TxFlags.h:68
@ tecNO_DELEGATE_PERMISSION
Definition TER.h:364
@ tecNEED_MASTER_KEY
Definition TER.h:308
@ tecOWNERS
Definition TER.h:298
@ tecNO_PERMISSION
Definition TER.h:305
@ tecNO_ALTERNATIVE_KEY
Definition TER.h:296
@ tesSUCCESS
Definition TER.h:244
constexpr std::uint32_t tfOptionalAuth
Definition TxFlags.h:69
constexpr std::uint32_t tfDisallowXRP
Definition TxFlags.h:70
bool isTesSuccess(TER x) noexcept
Definition TER.h:674
constexpr std::uint32_t asfDisallowIncomingPayChan
Definition TxFlags.h:92
constexpr std::uint32_t tfUniversalMask
Definition TxFlags.h:63
constexpr std::uint32_t asfAllowTrustLineClawback
Definition TxFlags.h:94
@ tapRETRY
Definition ApplyView.h:40
constexpr std::uint32_t asfRequireAuth
Definition TxFlags.h:78
@ terOWNERS
Definition TER.h:220
@ terNO_ACCOUNT
Definition TER.h:217
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
Definition View.cpp:905
constexpr std::uint32_t asfDisallowXRP
Definition TxFlags.h:79
@ temMALFORMED
Definition TER.h:87
@ temINVALID_FLAG
Definition TER.h:111
@ temBAD_TICK_SIZE
Definition TER.h:118
@ temBAD_TRANSFER_RATE
Definition TER.h:107
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:79
ReadView const & view
Definition Transactor.h:82
beast::Journal const j
Definition Transactor.h:87
State information when preflighting a tx.
Definition Transactor.h:34
beast::Journal const j
Definition Transactor.h:41