20#include <xrpld/app/misc/DelegateUtils.h>
21#include <xrpld/app/tx/detail/SetAccount.h>
22#include <xrpld/core/Config.h>
24#include <xrpl/basics/Log.h>
25#include <xrpl/ledger/View.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>
39 auto getTxConsequencesCategory = [](
STTx const& tx) {
44 if (
auto const uSetFlag = tx[~sfSetFlag]; uSetFlag &&
49 if (
auto const uClearFlag = tx[~sfClearFlag]; uClearFlag &&
73 JLOG(j.trace()) <<
"Malformed transaction: Invalid flags set.";
80 if ((uSetFlag != 0) && (uSetFlag == uClearFlag))
82 JLOG(j.trace()) <<
"Malformed transaction: Set and clear same flag.";
89 bool bSetRequireAuth =
91 bool bClearRequireAuth =
94 if (bSetRequireAuth && bClearRequireAuth)
96 JLOG(j.trace()) <<
"Malformed transaction: Contradictory flags set.";
103 bool bSetRequireDest =
105 bool bClearRequireDest =
108 if (bSetRequireDest && bClearRequireDest)
110 JLOG(j.trace()) <<
"Malformed transaction: Contradictory flags set.";
117 bool bSetDisallowXRP =
119 bool bClearDisallowXRP =
122 if (bSetDisallowXRP && bClearDisallowXRP)
124 JLOG(j.trace()) <<
"Malformed transaction: Contradictory flags set.";
129 if (tx.isFieldPresent(sfTransferRate))
133 if (uRate && (uRate < QUALITY_ONE))
136 <<
"Malformed transaction: Transfer rate too small.";
140 if (uRate > 2 * QUALITY_ONE)
143 <<
"Malformed transaction: Transfer rate too large.";
149 if (tx.isFieldPresent(sfTickSize))
151 auto uTickSize = tx[sfTickSize];
153 ((uTickSize < Quality::minTickSize) ||
154 (uTickSize > Quality::maxTickSize)))
156 JLOG(j.trace()) <<
"Malformed transaction: Bad tick size.";
161 if (
auto const mk = tx[~sfMessageKey])
165 JLOG(j.trace()) <<
"Invalid message key specified.";
170 if (
auto const domain = tx[~sfDomain];
173 JLOG(j.trace()) <<
"domain too long";
181 !tx.isFieldPresent(sfNFTokenMinter))
185 tx.isFieldPresent(sfNFTokenMinter))
197 auto const delegate = tx[~sfDelegate];
202 auto const sle =
view.
read(delegateKey);
211 auto const uClearFlag = tx.
getFieldU32(sfClearFlag);
212 auto const uTxFlags = tx.
getFlags();
221 !granularPermissions.
contains(AccountEmailHashSet))
229 !granularPermissions.
contains(AccountMessageKeySet))
233 !granularPermissions.
contains(AccountDomainSet))
237 !granularPermissions.
contains(AccountTransferRateSet))
241 !granularPermissions.
contains(AccountTickSizeSet))
250 auto const id = ctx.
tx[sfAccount];
263 bool bSetRequireAuth =
273 JLOG(ctx.
j.
trace()) <<
"Retry: Owner directory not empty.";
287 JLOG(ctx.
j.
trace()) <<
"Can't set Clawback if NoFreeze is set";
293 JLOG(ctx.
j.
trace()) <<
"Owner directory not empty.";
303 <<
"Can't set NoFreeze if clawback is enabled";
328 bool const bSetRequireDest{
330 bool const bClearRequireDest{
332 bool const bSetRequireAuth{
334 bool const bClearRequireAuth{
336 bool const bSetDisallowXRP{
338 bool const bClearDisallowXRP{
341 bool const sigWithMaster{[&tx, &acct =
account_]() {
342 auto const spk = tx.getSigningPubKey();
359 JLOG(
j_.
trace()) <<
"Set RequireAuth.";
365 JLOG(
j_.
trace()) <<
"Clear RequireAuth.";
366 uFlagsOut &= ~lsfRequireAuth;
374 JLOG(
j_.
trace()) <<
"Set lsfRequireDestTag.";
380 JLOG(
j_.
trace()) <<
"Clear lsfRequireDestTag.";
381 uFlagsOut &= ~lsfRequireDestTag;
389 JLOG(
j_.
trace()) <<
"Set lsfDisallowXRP.";
395 JLOG(
j_.
trace()) <<
"Clear lsfDisallowXRP.";
396 uFlagsOut &= ~lsfDisallowXRP;
406 JLOG(
j_.
trace()) <<
"Must use master key to disable master key.";
410 if ((!sle->isFieldPresent(sfRegularKey)) &&
417 JLOG(
j_.
trace()) <<
"Set lsfDisableMaster.";
423 JLOG(
j_.
trace()) <<
"Clear lsfDisableMaster.";
424 uFlagsOut &= ~lsfDisableMaster;
432 JLOG(
j_.
trace()) <<
"Set lsfDefaultRipple.";
437 JLOG(
j_.
trace()) <<
"Clear lsfDefaultRipple.";
438 uFlagsOut &= ~lsfDefaultRipple;
448 JLOG(
j_.
trace()) <<
"Must use master key to set NoFreeze.";
452 JLOG(
j_.
trace()) <<
"Set NoFreeze flag";
459 JLOG(
j_.
trace()) <<
"Set GlobalFreeze flag";
469 JLOG(
j_.
trace()) <<
"Clear GlobalFreeze flag";
470 uFlagsOut &= ~lsfGlobalFreeze;
476 if ((uSetFlag ==
asfAccountTxnID) && !sle->isFieldPresent(sfAccountTxnID))
478 JLOG(
j_.
trace()) <<
"Set AccountTxnID.";
479 sle->makeFieldPresent(sfAccountTxnID);
482 if ((uClearFlag ==
asfAccountTxnID) && sle->isFieldPresent(sfAccountTxnID))
484 JLOG(
j_.
trace()) <<
"Clear AccountTxnID.";
485 sle->makeFieldAbsent(sfAccountTxnID);
491 if (
view().rules().enabled(featureDepositAuth))
495 JLOG(
j_.
trace()) <<
"Set lsfDepositAuth.";
500 JLOG(
j_.
trace()) <<
"Clear lsfDepositAuth.";
501 uFlagsOut &= ~lsfDepositAuth;
508 if (tx.isFieldPresent(sfEmailHash))
510 uint128 const uHash = tx.getFieldH128(sfEmailHash);
514 JLOG(
j_.
trace()) <<
"unset email hash";
515 sle->makeFieldAbsent(sfEmailHash);
519 JLOG(
j_.
trace()) <<
"set email hash";
520 sle->setFieldH128(sfEmailHash, uHash);
527 if (tx.isFieldPresent(sfWalletLocator))
529 uint256 const uHash = tx.getFieldH256(sfWalletLocator);
533 JLOG(
j_.
trace()) <<
"unset wallet locator";
534 sle->makeFieldAbsent(sfWalletLocator);
538 JLOG(
j_.
trace()) <<
"set wallet locator";
539 sle->setFieldH256(sfWalletLocator, uHash);
546 if (tx.isFieldPresent(sfMessageKey))
548 Blob const messageKey = tx.getFieldVL(sfMessageKey);
550 if (messageKey.
empty())
552 JLOG(
j_.
debug()) <<
"set message key";
553 sle->makeFieldAbsent(sfMessageKey);
557 JLOG(
j_.
debug()) <<
"set message key";
558 sle->setFieldVL(sfMessageKey, messageKey);
565 if (tx.isFieldPresent(sfDomain))
567 Blob const domain = tx.getFieldVL(sfDomain);
571 JLOG(
j_.
trace()) <<
"unset domain";
572 sle->makeFieldAbsent(sfDomain);
576 JLOG(
j_.
trace()) <<
"set domain";
577 sle->setFieldVL(sfDomain, domain);
584 if (tx.isFieldPresent(sfTransferRate))
588 if (uRate == 0 || uRate == QUALITY_ONE)
590 JLOG(
j_.
trace()) <<
"unset transfer rate";
591 sle->makeFieldAbsent(sfTransferRate);
595 JLOG(
j_.
trace()) <<
"set transfer rate";
596 sle->setFieldU32(sfTransferRate, uRate);
603 if (tx.isFieldPresent(sfTickSize))
605 auto uTickSize = tx[sfTickSize];
606 if ((uTickSize == 0) || (uTickSize == Quality::maxTickSize))
608 JLOG(
j_.
trace()) <<
"unset tick size";
609 sle->makeFieldAbsent(sfTickSize);
613 JLOG(
j_.
trace()) <<
"set tick size";
614 sle->setFieldU8(sfTickSize, uTickSize);
622 sle->setAccountID(sfNFTokenMinter,
ctx_.
tx[sfNFTokenMinter]);
625 sle->isFieldPresent(sfNFTokenMinter))
626 sle->makeFieldAbsent(sfNFTokenMinter);
635 uFlagsOut &= ~lsfDisallowIncomingNFTokenOffer;
640 uFlagsOut &= ~lsfDisallowIncomingCheck;
645 uFlagsOut &= ~lsfDisallowIncomingPayChan;
650 uFlagsOut &= ~lsfDisallowIncomingTrustline;
659 uFlagsOut &= ~lsfAllowTrustLineLocking;
666 JLOG(
j_.
trace()) <<
"set allow clawback";
670 if (uFlagsIn != uFlagsOut)
671 sle->setFieldU32(sfFlags, uFlagsOut);
Stream trace() const
Severity stream access functions.
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.
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.
std::uint32_t getFieldU32(SField const &field) const
bool isFieldPresent(SField const &field) const
std::uint32_t getFlags() const
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)
Class describing the consequences to the account of applying a transaction if the transaction consume...
@ normal
Moves currency around, creates offers, etc.
@ blocker
Affects the ability of subsequent transactions to claim a fee.
Integers of any length that is a multiple of 32-bits.
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet signers(AccountID const &account) noexcept
A SignerList.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t tfAllowXRP
constexpr std::uint32_t asfGlobalFreeze
constexpr std::uint32_t asfDepositAuth
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer
constexpr std::uint32_t asfAllowTrustLineLocking
constexpr std::uint32_t asfRequireDest
constexpr std::uint32_t asfAuthorizedNFTokenMinter
constexpr std::uint32_t tfOptionalDestTag
@ lsfDisallowIncomingCheck
@ lsfAllowTrustLineClawback
@ lsfDisallowIncomingPayChan
@ lsfDisallowIncomingTrustline
@ lsfAllowTrustLineLocking
@ lsfDisallowIncomingNFTokenOffer
constexpr std::uint32_t tfAccountSetMask
constexpr std::uint32_t tfRequireDestTag
constexpr std::uint32_t asfNoFreeze
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.
constexpr std::uint32_t asfDisableMaster
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
constexpr std::uint32_t asfDisallowIncomingTrustline
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
constexpr std::uint32_t asfDefaultRipple
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)
constexpr std::uint32_t asfDisallowIncomingCheck
constexpr std::uint32_t tfRequireAuth
@ tecNO_DELEGATE_PERMISSION
constexpr std::uint32_t tfOptionalAuth
constexpr std::uint32_t tfDisallowXRP
bool isTesSuccess(TER x) noexcept
constexpr std::uint32_t asfDisallowIncomingPayChan
constexpr std::uint32_t tfUniversalMask
constexpr std::uint32_t asfAllowTrustLineClawback
constexpr std::uint32_t asfRequireAuth
constexpr std::uint32_t asfDisallowXRP
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.