1#include <xrpl/tx/transactors/check/CheckCreate.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/core/ServiceRegistry.h>
6#include <xrpl/ledger/View.h>
7#include <xrpl/ledger/helpers/AccountRootHelpers.h>
8#include <xrpl/ledger/helpers/DirectoryHelpers.h>
9#include <xrpl/ledger/helpers/MPTokenHelpers.h>
10#include <xrpl/ledger/helpers/TokenHelpers.h>
11#include <xrpl/protocol/AccountID.h>
12#include <xrpl/protocol/Asset.h>
13#include <xrpl/protocol/Feature.h>
14#include <xrpl/protocol/Indexes.h>
15#include <xrpl/protocol/Issue.h>
16#include <xrpl/protocol/Keylet.h>
17#include <xrpl/protocol/LedgerFormats.h>
18#include <xrpl/protocol/MPTIssue.h>
19#include <xrpl/protocol/SField.h>
20#include <xrpl/protocol/STAmount.h>
21#include <xrpl/protocol/STLedgerEntry.h>
22#include <xrpl/protocol/STTx.h>
23#include <xrpl/protocol/TER.h>
24#include <xrpl/protocol/XRPAmount.h>
25#include <xrpl/tx/Transactor.h>
42 if (ctx.
tx[sfAccount] == ctx.
tx[sfDestination])
45 JLOG(ctx.
j.
warn()) <<
"Malformed transaction: Check to self.";
53 JLOG(ctx.
j.
warn()) <<
"Malformed transaction: bad sendMax amount: "
60 JLOG(ctx.
j.
warn()) <<
"Malformed transaction: Bad currency.";
65 if (
auto const optExpiry = ctx.
tx[~sfExpiration])
69 JLOG(ctx.
j.
warn()) <<
"Malformed transaction: bad expiration";
85 JLOG(ctx.
j.
warn()) <<
"Destination account does not exist.";
90 if (sleDst->isFlag(lsfDisallowIncomingCheck))
100 if (sleDst->isFlag(lsfRequireDestTag) && !ctx.
tx.
isFieldPresent(sfDestinationTag))
104 JLOG(ctx.
j.
warn()) <<
"Malformed transaction: DestinationTag required.";
116 JLOG(ctx.
j.
warn()) <<
"Creating a check for frozen or locked asset";
126 if (issuerId != srcId)
129 auto const sleTrust =
132 sleTrust->isFlag((issuerId > srcId) ? lsfHighFreeze : lsfLowFreeze))
134 JLOG(ctx.
j.
warn()) <<
"Creating a check for frozen trustline.";
138 if (issuerId != dstId)
141 auto const sleTrust =
144 sleTrust->isFlag((dstId > issuerId) ? lsfHighFreeze : lsfLowFreeze))
146 JLOG(ctx.
j.
warn()) <<
"Creating a check for "
147 "destination frozen trustline.";
155 if (srcId != issuerId &&
isFrozen(ctx.
view, srcId, issue))
157 JLOG(ctx.
j.
warn()) <<
"Creating a check for locked MPT.";
160 if (dstId != issuerId &&
isFrozen(ctx.
view, dstId, issue))
162 JLOG(ctx.
j.
warn()) <<
"Creating a check for locked MPT.";
168 JLOG(ctx.
j.
warn()) <<
"MPT transfer is disabled.";
180 JLOG(ctx.
j.
warn()) <<
"Creating a check that has already expired.";
210 sleCheck->setAccountID(sfAccount,
accountID_);
212 sleCheck->setAccountID(sfDestination, dstAccountId);
213 sleCheck->setFieldU32(sfSequence, seq);
214 sleCheck->setFieldAmount(sfSendMax,
ctx_.tx[sfSendMax]);
215 if (
auto const srcTag =
ctx_.tx[~sfSourceTag])
216 sleCheck->setFieldU32(sfSourceTag, *srcTag);
217 if (
auto const dstTag =
ctx_.tx[~sfDestinationTag])
218 sleCheck->setFieldU32(sfDestinationTag, *dstTag);
219 if (
auto const invoiceId =
ctx_.tx[~sfInvoiceID])
220 sleCheck->setFieldH256(sfInvoiceID, *invoiceId);
221 if (
auto const expiry =
ctx_.tx[~sfExpiration])
222 sleCheck->setFieldU32(sfExpiration, *expiry);
226 auto viewJ =
ctx_.registry.get().getJournal(
"View");
234 JLOG(
j_.trace()) <<
"Adding Check to destination directory " <<
to_string(checkKeylet.
key)
235 <<
": " << (page ?
"success" :
"failure");
240 sleCheck->setFieldU64(sfDestinationNode, *page);
247 JLOG(
j_.trace()) <<
"Adding Check to owner directory " <<
to_string(checkKeylet.
key) <<
": "
248 << (page ?
"success" :
"failure");
253 sleCheck->setFieldU64(sfOwnerNode, *page);
A generic endpoint for log messages.
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void insert(SLE::ref sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(SLE::ref)> const &describe)
Insert an entry to a directory.
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
static TER preclaim(PreclaimContext const &ctx)
bool finalizeInvariants(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j) override
Check transaction-specific post-conditions after all entries have been visited.
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
static bool checkExtraFeatures(xrpl::PreflightContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
A currency issued by an account.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual SLE::const_pointer 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.
std::string getFullText() const override
int signum() const noexcept
bool native() const noexcept
Asset const & asset() const
AccountID const & getIssuer() const
std::shared_ptr< STLedgerEntry const > const & const_ref
bool isFieldPresent(SField const &field) const
STAmount const & getFieldAmount(SField const &field) const
AccountID const accountID_
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool hasExpired(ReadView const &view, std::optional< std::uint32_t > const &exp)
Determines whether the given expiration time has passed.
bool isLegalNet(STAmount const &value)
TER canTransfer(ReadView const &view, MPTIssue const &mptIssue, AccountID const &from, AccountID const &to, WaiveMPTCanTransfer waive=WaiveMPTCanTransfer::No, std::uint8_t depth=0)
Check whether to may receive the given MPT from from.
std::string to_string(BaseUInt< Bits, Tag > const &a)
TERSubset< CanCvtToNotTEC > NotTEC
void adjustOwnerCount(ApplyView &view, SLE::ref sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
bool isFrozen(ReadView const &view, AccountID const &account, MPTIssue const &mptIssue, std::uint8_t depth=0)
TER checkGlobalFrozen(ReadView const &view, Asset const &asset)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
@ tecINSUFFICIENT_RESERVE
BadAsset const & badAsset()
bool isPseudoAccount(SLE::const_pointer sleAcct, std::set< SField const * > const &pseudoFieldFilter={})
Returns true if and only if sleAcct is a pseudo-account or specific pseudo-accounts in pseudoFieldFil...
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
A pair of SHAMap key and LedgerEntryType.
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.