1#include <xrpl/tx/transactors/payment/DepositPreauth.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/core/ServiceRegistry.h>
7#include <xrpl/ledger/helpers/AccountRootHelpers.h>
8#include <xrpl/ledger/helpers/CredentialHelpers.h>
9#include <xrpl/ledger/helpers/DirectoryHelpers.h>
10#include <xrpl/protocol/AccountID.h>
11#include <xrpl/protocol/Feature.h>
12#include <xrpl/protocol/Indexes.h>
13#include <xrpl/protocol/Keylet.h>
14#include <xrpl/protocol/Protocol.h>
15#include <xrpl/protocol/SField.h>
16#include <xrpl/protocol/STAmount.h>
17#include <xrpl/protocol/STArray.h>
18#include <xrpl/protocol/STLedgerEntry.h>
19#include <xrpl/protocol/STTx.h>
20#include <xrpl/protocol/TER.h>
21#include <xrpl/protocol/XRPAmount.h>
22#include <xrpl/tx/Transactor.h>
36 bool const unauthArrPresent = ctx.
tx.
isFieldPresent(sfUnauthorizeCredentials);
37 bool const authCredPresent = authArrPresent || unauthArrPresent;
39 return !authCredPresent || ctx.
rules.
enabled(featureCredentials);
46 bool const unauthArrPresent = ctx.
tx.
isFieldPresent(sfUnauthorizeCredentials);
47 int const authCredPresent =
48 static_cast<int>(authArrPresent) +
static_cast<int>(unauthArrPresent);
50 auto const optAuth = ctx.
tx[~sfAuthorize];
51 auto const optUnauth = ctx.
tx[~sfUnauthorize];
52 int const authPresent =
53 static_cast<int>(optAuth.has_value()) +
static_cast<int>(optUnauth.has_value());
55 if (authPresent + authCredPresent != 1)
58 JLOG(ctx.
j.
trace()) <<
"Malformed transaction: "
59 "Invalid Authorize and Unauthorize field combination.";
67 AccountID const& target(optAuth ? *optAuth : *optUnauth);
70 JLOG(ctx.
j.
trace()) <<
"Malformed transaction: Authorized or Unauthorized "
76 if (optAuth && (target == ctx.
tx[sfAccount]))
78 JLOG(ctx.
j.
trace()) <<
"Malformed transaction: Attempting to DepositPreauth self.";
86 authArrPresent ? sfAuthorizeCredentials : sfUnauthorizeCredentials),
124 for (
auto const& o : authCred)
126 auto const& issuer = o[sfIssuer];
129 auto [it, ins] = sorted.
emplace(issuer, o[sfCredentialType]);
154 if (
ctx_.tx.isFieldPresent(sfAuthorize))
177 slePreauth->setAccountID(sfAccount,
accountID_);
178 slePreauth->setAccountID(sfAuthorize, auth);
184 JLOG(
j_.trace()) <<
"Adding DepositPreauth to owner directory "
185 <<
to_string(preauthKeylet.
key) <<
": " << (page ?
"success" :
"failure");
190 slePreauth->setFieldU64(sfOwnerNode, *page);
195 else if (
ctx_.tx.isFieldPresent(sfUnauthorize))
201 else if (
ctx_.tx.isFieldPresent(sfAuthorizeCredentials))
221 auto const sortedTX =
223 STArray sortedLE(sfAuthorizeCredentials, sortedTX.size());
224 for (
auto const& p : sortedTX)
227 cred.setAccountID(sfIssuer, p.first);
228 cred.setFieldVL(sfCredentialType, p.second);
237 slePreauth->setAccountID(sfAccount,
accountID_);
238 slePreauth->peekFieldArray(sfAuthorizeCredentials) = std::move(sortedLE);
245 JLOG(
j_.trace()) <<
"Adding DepositPreauth to owner directory " <<
to_string(preauthKey.
key)
246 <<
": " << (page ?
"success" :
"failure");
251 slePreauth->setFieldU64(sfOwnerNode, *page);
256 else if (
ctx_.tx.isFieldPresent(sfUnauthorizeCredentials))
273 JLOG(j.
warn()) <<
"Selected DepositPreauth does not exist.";
277 AccountID const account{(*slePreauth)[sfAccount]};
282 JLOG(j.
fatal()) <<
"Unable to delete DepositPreauth from owner.";
295 view.erase(slePreauth);
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
Writeable view to a ledger, for applying a transaction.
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.
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.
static TER removeFromLedger(ApplyView &view, uint256 const &delIndex, beast::Journal j)
static NotTEC preflight(PreflightContext const &ctx)
static bool checkExtraFeatures(PreflightContext const &ctx)
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
static TER preclaim(PreclaimContext const &ctx)
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.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
void pushBack(STObject const &object)
std::shared_ptr< STLedgerEntry const > const & const_ref
STArray const & getFieldArray(SField const &field) const
bool isFieldPresent(SField const &field) const
static STObject makeInnerObject(SField const &name)
AccountID const accountID_
std::set< std::pair< AccountID, Slice > > makeSorted(STArray const &credentials)
NotTEC checkArray(STArray const &credentials, unsigned maxSize, beast::Journal j)
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string to_string(BaseUInt< Bits, Tag > const &a)
TERSubset< CanCvtToNotTEC > NotTEC
constexpr std::size_t kMaxCredentialsArraySize
The maximum number of credentials can be passed in array.
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.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
@ tecINSUFFICIENT_RESERVE
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.