mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-29 01:50:43 +00:00
Merge branch 'develop' into mvadari/constant-field-invariant
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if XRPL_ROCKSDB_AVAILABLE
|
||||
// #include <rocksdb2/port/port_posix.h>
|
||||
#include <rocksdb/cache.h>
|
||||
#include <rocksdb/compaction_filter.h>
|
||||
#include <rocksdb/comparator.h>
|
||||
#include <rocksdb/convenience.h>
|
||||
#include <rocksdb/db.h>
|
||||
#include <rocksdb/env.h>
|
||||
#include <rocksdb/filter_policy.h>
|
||||
#include <rocksdb/flush_block_policy.h>
|
||||
#include <rocksdb/iterator.h>
|
||||
#include <rocksdb/memtablerep.h>
|
||||
#include <rocksdb/merge_operator.h>
|
||||
#include <rocksdb/options.h>
|
||||
#include <rocksdb/perf_context.h>
|
||||
#include <rocksdb/slice.h>
|
||||
#include <rocksdb/slice_transform.h>
|
||||
#include <rocksdb/statistics.h>
|
||||
#include <rocksdb/status.h>
|
||||
#include <rocksdb/table.h>
|
||||
#include <rocksdb/table_properties.h>
|
||||
#include <rocksdb/transaction_log.h>
|
||||
#include <rocksdb/types.h>
|
||||
#include <rocksdb/universal_compaction.h>
|
||||
#include <rocksdb/write_batch.h>
|
||||
|
||||
#endif
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
ASAN flags some false positives with sudden jumps in control flow, like
|
||||
exceptions, or when encountering coroutine stack switches. This macro can be used to disable ASAN
|
||||
intrumentation for specific functions.
|
||||
instrumentation for specific functions.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define XRPL_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address", "hwaddress")))
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/MultiApiJson.h>
|
||||
#include <xrpl/server/InfoSub.h>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/** Listen to public/subscribe messages from a book. */
|
||||
class BookListeners
|
||||
{
|
||||
public:
|
||||
using pointer = std::shared_ptr<BookListeners>;
|
||||
|
||||
BookListeners() = default;
|
||||
|
||||
/** Add a new subscription for this book
|
||||
*/
|
||||
void
|
||||
addSubscriber(InfoSub::ref sub);
|
||||
|
||||
/** Stop publishing to a subscriber
|
||||
*/
|
||||
void
|
||||
removeSubscriber(std::uint64_t sub);
|
||||
|
||||
/** Publish a transaction to subscribers
|
||||
|
||||
Publish a transaction to clients subscribed to changes on this book.
|
||||
Uses havePublished to prevent sending duplicate transactions to clients
|
||||
that have subscribed to multiple books.
|
||||
|
||||
@param jvObj JSON transaction data to publish
|
||||
@param havePublished InfoSub sequence numbers that have already
|
||||
published this transaction.
|
||||
|
||||
*/
|
||||
void
|
||||
publish(MultiApiJson const& jvObj, hash_set<std::uint64_t>& havePublished);
|
||||
|
||||
private:
|
||||
std::recursive_mutex lock_;
|
||||
|
||||
hash_map<std::uint64_t, InfoSub::wptr> listeners_;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/AcceptedLedgerTx.h>
|
||||
#include <xrpl/ledger/BookListeners.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Book.h>
|
||||
#include <xrpl/protocol/MultiApiJson.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -77,34 +77,24 @@ public:
|
||||
*/
|
||||
virtual bool
|
||||
isBookToXRP(Asset const& asset, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
|
||||
/**
|
||||
* Process a transaction for order book tracking.
|
||||
* @param ledger The ledger the transaction was applied to
|
||||
* @param alTx The transaction to process
|
||||
* @param jvObj The JSON object of the transaction
|
||||
*/
|
||||
virtual void
|
||||
processTxn(
|
||||
std::shared_ptr<ReadView const> const& ledger,
|
||||
AcceptedLedgerTx const& alTx,
|
||||
MultiApiJson const& jvObj) = 0;
|
||||
|
||||
/**
|
||||
* Get the book listeners for a book.
|
||||
* @param book The book to get the listeners for
|
||||
* @return The book listeners for the book
|
||||
*/
|
||||
virtual BookListeners::pointer
|
||||
getBookListeners(Book const&) = 0;
|
||||
|
||||
/**
|
||||
* Create a new book listeners for a book.
|
||||
* @param book The book to create the listeners for
|
||||
* @return The new book listeners for the book
|
||||
*/
|
||||
virtual BookListeners::pointer
|
||||
makeBookListeners(Book const&) = 0;
|
||||
};
|
||||
|
||||
/** Extract the set of books affected by a transaction.
|
||||
*
|
||||
* Walks the transaction's metadata nodes and collects every order book
|
||||
* whose offers were created, modified, or deleted. Used by NetworkOPs to
|
||||
* fan transaction notifications out to book subscribers.
|
||||
*
|
||||
* @param alTx The accepted ledger transaction to inspect.
|
||||
* @param j Journal used to log per-node parsing failures. Inspecting an
|
||||
* offer node can throw if a required field is missing; in that
|
||||
* case the bad node is skipped and a warn-level message is
|
||||
* emitted via @p j. Other affected books in the same transaction
|
||||
* are still returned.
|
||||
* @return The set of books whose offers were created, modified, or
|
||||
* deleted. May be empty for non-offer transactions.
|
||||
*/
|
||||
hash_set<Book>
|
||||
affectedBooks(AcceptedLedgerTx const& alTx, beast::Journal const& j);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -37,6 +37,8 @@ reduceOffer(auto const& amount)
|
||||
|
||||
enum class IsDeposit : bool { No = false, Yes = true };
|
||||
|
||||
inline Number const kAMMInvariantRelativeTolerance{1, -11};
|
||||
|
||||
/** Calculate LP Tokens given AMM pool reserves.
|
||||
* @param asset1 AMM one side of the pool reserve
|
||||
* @param asset2 AMM another side of the pool reserve
|
||||
@@ -738,6 +740,30 @@ ammPoolHolds(
|
||||
AuthHandling authHandling,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Check AMM pool product invariant after an AMM operation that changes LP tokens
|
||||
* (deposit/withdraw/clawback) from an already calculated pool product mean.
|
||||
* Returns tecPRECISION_LOSS if poolProductMean < newLPTokenBalance beyond the
|
||||
* invariant tolerance,
|
||||
* tesSUCCESS otherwise. Skips check when newLPTokenBalance is zero (last withdrawal).
|
||||
*/
|
||||
TER
|
||||
checkAMMPrecisionLoss(Number const& poolProductMean, STAmount const& newLPTokenBalance);
|
||||
|
||||
/** Check AMM pool product invariant after an AMM operation that changes LP tokens
|
||||
* (deposit/withdraw/clawback).
|
||||
* Returns tecPRECISION_LOSS if sqrt(asset1 * asset2) < newLPTokenBalance beyond
|
||||
* the invariant tolerance,
|
||||
* tesSUCCESS otherwise. Skips check when newLPTokenBalance is zero (last withdrawal).
|
||||
*/
|
||||
TER
|
||||
checkAMMPrecisionLoss(
|
||||
ReadView const& view,
|
||||
AccountID const& ammAccountID,
|
||||
Asset const& asset1,
|
||||
Asset const& asset2,
|
||||
STAmount const& newLPTokenBalance,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Get AMM pool and LP token balances. If both optIssue are
|
||||
* provided then they are used as the AMM token pair issues.
|
||||
* Otherwise the missing issues are fetched from ammSle.
|
||||
|
||||
@@ -36,13 +36,13 @@ checkFields(STTx const& tx, beast::Journal j);
|
||||
TER
|
||||
valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal j);
|
||||
|
||||
// Check if subject has any credential maching the given domain. If you call it
|
||||
// Check if subject has any credential matching the given domain. If you call it
|
||||
// in preclaim and it returns tecEXPIRED, you should call verifyValidDomain in
|
||||
// doApply. This will ensure that expired credentials are deleted.
|
||||
TER
|
||||
validDomain(ReadView const& view, uint256 domainID, AccountID const& subject);
|
||||
|
||||
// This function is only called when we about to return tecNO_PERMISSION
|
||||
// This function is only called when we are about to return tecNO_PERMISSION
|
||||
// because all the checks for the DepositPreauth authorization failed.
|
||||
TER
|
||||
authorizedDepositPreauth(ReadView const& view, STVector256 const& ctx, AccountID const& dst);
|
||||
@@ -58,7 +58,7 @@ checkArray(STArray const& credentials, unsigned maxSize, beast::Journal j);
|
||||
|
||||
} // namespace credentials
|
||||
|
||||
// Check expired credentials and for credentials maching DomainID of the ledger
|
||||
// Check expired credentials and for credentials matching DomainID of the ledger
|
||||
// object
|
||||
TER
|
||||
verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, beast::Journal j);
|
||||
|
||||
@@ -23,13 +23,9 @@ checkTxPermission(SLE::const_ref delegate, STTx const& tx);
|
||||
* @param delegate The delegate account.
|
||||
* @param type Used to determine which granted granular permissions to load,
|
||||
* based on the transaction type.
|
||||
* @param granularPermissions Granted granular permissions tied to the
|
||||
* transaction type.
|
||||
* @return the granted granular permissions tied to the transaction type.
|
||||
*/
|
||||
void
|
||||
loadGranularPermission(
|
||||
SLE::const_ref delegate,
|
||||
TxType const& type,
|
||||
std::unordered_set<GranularPermissionType>& granularPermissions);
|
||||
std::unordered_set<GranularPermissionType>
|
||||
getGranularPermission(SLE::const_ref delegate, TxType const& type);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -5,9 +5,45 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/** Close a payment channel and return its remaining funds to the channel owner.
|
||||
*
|
||||
* @param slep The SLE for the PayChannel object to close.
|
||||
* @param view The apply view in which ledger state modifications are made.
|
||||
* @param key The ledger key identifying the PayChannel entry.
|
||||
* @param j Journal used for fatal-level diagnostic messages.
|
||||
* @return tesSUCCESS on success; tefBAD_LEDGER if a directory removal
|
||||
* fails; tefINTERNAL if the source account SLE cannot be found.
|
||||
*/
|
||||
TER
|
||||
closeChannel(SLE::ref slep, ApplyView& view, uint256 const& key, beast::Journal j);
|
||||
|
||||
/** Add two uint32_t values with saturation at UINT32_MAX.
|
||||
*
|
||||
* @param rules The current ledger rules used to check amendment status.
|
||||
* @param lhs Left-hand operand.
|
||||
* @param rhs Right-hand operand.
|
||||
* @return @p lhs + @p rhs, saturated at UINT32_MAX when the amendment
|
||||
* is active.
|
||||
*/
|
||||
uint32_t
|
||||
saturatingAdd(Rules const& rules, uint32_t const lhs, uint32_t const rhs);
|
||||
|
||||
/** Determine whether a payment channel time field represents an expired time.
|
||||
*
|
||||
* @param view The apply view providing the parent close time and rules.
|
||||
* @param timeField The optional expiry timestamp (seconds since the XRP
|
||||
* Ledger epoch). If empty, the function returns false.
|
||||
* @return @c true if @p timeField is set and the indicated time is
|
||||
* in the past relative to the view's parent close time;
|
||||
* @c false otherwise.
|
||||
*/
|
||||
bool
|
||||
isChannelExpired(ApplyView const& view, std::optional<std::uint32_t> timeField);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -102,25 +102,32 @@ getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
|
||||
json::Value const maxVersion(
|
||||
betaEnabled ? RPC::kApiBetaVersion : RPC::kApiMaximumSupportedVersion);
|
||||
|
||||
if (jv.isObject())
|
||||
if (!jv.isObject() || !jv.isMember(jss::api_version))
|
||||
return RPC::kApiVersionIfUnspecified;
|
||||
|
||||
try
|
||||
{
|
||||
if (jv.isMember(jss::api_version))
|
||||
auto const& rawVersion = jv[jss::api_version];
|
||||
switch (rawVersion.type())
|
||||
{
|
||||
auto const specifiedVersion = jv[jss::api_version];
|
||||
if (!specifiedVersion.isInt() && !specifiedVersion.isUInt())
|
||||
{
|
||||
return RPC::kApiInvalidVersion;
|
||||
case json::ValueType::Int:
|
||||
if (rawVersion.asInt() < 0)
|
||||
return RPC::kApiInvalidVersion;
|
||||
[[fallthrough]];
|
||||
case json::ValueType::UInt: {
|
||||
auto const apiVersion = rawVersion.asUInt();
|
||||
if (apiVersion < kMinVersion || apiVersion > maxVersion)
|
||||
return RPC::kApiInvalidVersion;
|
||||
return apiVersion;
|
||||
}
|
||||
auto const specifiedVersionInt = specifiedVersion.asInt();
|
||||
if (specifiedVersionInt < kMinVersion || specifiedVersionInt > maxVersion)
|
||||
{
|
||||
default:
|
||||
return RPC::kApiInvalidVersion;
|
||||
}
|
||||
return specifiedVersionInt;
|
||||
}
|
||||
}
|
||||
|
||||
return RPC::kApiVersionIfUnspecified;
|
||||
catch (...)
|
||||
{
|
||||
return RPC::kApiInvalidVersion;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RPC
|
||||
|
||||
@@ -180,12 +180,12 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LSF_FLAG(lsfMPTCanClawback, 0x00000040)) \
|
||||
\
|
||||
LEDGER_OBJECT(MPTokenIssuanceMutable, \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanLock, 0x00000002) \
|
||||
LSF_FLAG(lsmfMPTCanMutateRequireAuth, 0x00000004) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanLock, 0x00000002) \
|
||||
LSF_FLAG(lsmfMPTCanEnableRequireAuth, 0x00000004) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanMutateMetadata, 0x00010000) \
|
||||
LSF_FLAG(lsmfMPTCanMutateTransferFee, 0x00020000)) \
|
||||
\
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STTx;
|
||||
|
||||
/**
|
||||
* We have both transaction type permissions and granular type permissions.
|
||||
* Since we will reuse the TransactionFormats to parse the Transaction
|
||||
@@ -19,15 +24,15 @@ namespace xrpl {
|
||||
// Macro-generated, complex
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum GranularPermissionType : std::uint32_t {
|
||||
#pragma push_macro("PERMISSION")
|
||||
#undef PERMISSION
|
||||
#pragma push_macro("GRANULAR_PERMISSION")
|
||||
#undef GRANULAR_PERMISSION
|
||||
|
||||
#define PERMISSION(type, txType, value) type = (value),
|
||||
#define GRANULAR_PERMISSION(name, txType, value, ...) name = (value),
|
||||
|
||||
#include <xrpl/protocol/detail/permissions.macro>
|
||||
|
||||
#undef PERMISSION
|
||||
#pragma pop_macro("PERMISSION")
|
||||
#undef GRANULAR_PERMISSION
|
||||
#pragma pop_macro("GRANULAR_PERMISSION")
|
||||
};
|
||||
|
||||
// Injected bare enumerators (xrpl::delegable / xrpl::notDelegable) are required by preprocessor
|
||||
@@ -40,15 +45,30 @@ class Permission
|
||||
private:
|
||||
Permission();
|
||||
|
||||
std::unordered_map<std::uint16_t, uint256> txFeatureMap_;
|
||||
struct GranularPermissionEntry
|
||||
{
|
||||
std::string name;
|
||||
TxType txType;
|
||||
std::uint32_t permittedFlags;
|
||||
SOTemplate permittedFields;
|
||||
|
||||
std::unordered_map<std::uint16_t, Delegation> delegableTx_;
|
||||
GranularPermissionEntry(
|
||||
std::string name,
|
||||
TxType txType,
|
||||
std::uint32_t permittedFlags,
|
||||
std::vector<SOElement> fields);
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, GranularPermissionType> granularPermissionMap_;
|
||||
struct TxDelegationEntry
|
||||
{
|
||||
uint256 amendment;
|
||||
Delegation delegable{NotDelegable};
|
||||
};
|
||||
|
||||
std::unordered_map<GranularPermissionType, std::string> granularNameMap_;
|
||||
|
||||
std::unordered_map<GranularPermissionType, TxType> granularTxTypeMap_;
|
||||
std::unordered_set<TxType> granularTxTypes_;
|
||||
std::unordered_map<TxType, TxDelegationEntry> txDelegationMap_;
|
||||
std::unordered_map<std::string, GranularPermissionType> granularPermissionsByName_;
|
||||
std::unordered_map<GranularPermissionType, GranularPermissionEntry> granularPermissions_;
|
||||
|
||||
public:
|
||||
static Permission const&
|
||||
@@ -59,30 +79,52 @@ public:
|
||||
operator=(Permission const&) = delete;
|
||||
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
getPermissionName(std::uint32_t const value) const;
|
||||
getPermissionName(std::uint32_t value) const;
|
||||
|
||||
[[nodiscard]] std::optional<std::uint32_t>
|
||||
getGranularValue(std::string const& name) const;
|
||||
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
getGranularName(GranularPermissionType const& value) const;
|
||||
getGranularName(GranularPermissionType value) const;
|
||||
|
||||
[[nodiscard]] std::optional<TxType>
|
||||
getGranularTxType(GranularPermissionType const& gpType) const;
|
||||
getGranularTxType(GranularPermissionType gpType) const;
|
||||
|
||||
// Returns a reference to avoid copying uint256 - 32 bytes. std::optional
|
||||
// cannot hold references directly, so std::reference_wrapper is used.
|
||||
[[nodiscard]] std::optional<std::reference_wrapper<uint256 const>>
|
||||
getTxFeature(TxType txType) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const;
|
||||
isDelegable(std::uint32_t permissionValue, Rules const& rules) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasGranularPermissions(TxType txType) const;
|
||||
|
||||
// for tx level permission, permission value is equal to tx type plus one
|
||||
static uint32_t
|
||||
txToPermissionType(TxType const& type);
|
||||
[[nodiscard]] static uint32_t
|
||||
txToPermissionType(TxType type);
|
||||
|
||||
// tx type value is permission value minus one
|
||||
static TxType
|
||||
permissionToTxType(uint32_t const& value);
|
||||
[[nodiscard]] static TxType
|
||||
permissionToTxType(std::uint32_t value);
|
||||
|
||||
/**
|
||||
* @brief Verifies a delegated transaction against its granular permission template.
|
||||
*
|
||||
* @note WARNING: Do not move this check before standard transaction-level
|
||||
* format checks, which is in preclaim. This function assumes the transaction's
|
||||
* base structural integrity (fees, sequence, signatures) has already been
|
||||
* validated.
|
||||
*
|
||||
* @param tx The transaction to verify.
|
||||
* @param heldPermissions The granular permissions that the sender hold.
|
||||
* @return true if the transaction fields and flags comply with the granular template.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
checkGranularSandbox(
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldPermissions) const;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -341,38 +341,32 @@ inline constexpr FlagValue tfTrustSetPermissionMask =
|
||||
|
||||
// MPTokenIssuanceCreate MutableFlags:
|
||||
// Indicating specific fields or flags may be changed after issuance.
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanLock = lsmfMPTCanMutateCanLock;
|
||||
inline constexpr FlagValue tmfMPTCanMutateRequireAuth = lsmfMPTCanMutateRequireAuth;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanEscrow = lsmfMPTCanMutateCanEscrow;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanTrade = lsmfMPTCanMutateCanTrade;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTransfer;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanLock = lsmfMPTCanEnableCanLock;
|
||||
inline constexpr FlagValue tmfMPTCanEnableRequireAuth = lsmfMPTCanEnableRequireAuth;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanEscrow = lsmfMPTCanEnableCanEscrow;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanTrade = lsmfMPTCanEnableCanTrade;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanTransfer = lsmfMPTCanEnableCanTransfer;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanClawback = lsmfMPTCanEnableCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
|
||||
inline constexpr FlagValue tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask =
|
||||
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow |
|
||||
tmfMPTCanMutateCanTrade | tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback |
|
||||
~(tmfMPTCanEnableCanLock | tmfMPTCanEnableRequireAuth | tmfMPTCanEnableCanEscrow |
|
||||
tmfMPTCanEnableCanTrade | tmfMPTCanEnableCanTransfer | tmfMPTCanEnableCanClawback |
|
||||
tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
|
||||
|
||||
// MPTokenIssuanceSet MutableFlags:
|
||||
// Set or Clear flags.
|
||||
// Enable mutable capability flags. These flags are one-way: once enabled,
|
||||
// the corresponding capability cannot be disabled by MPTokenIssuanceSet.
|
||||
|
||||
inline constexpr FlagValue tmfMPTSetCanLock = 0x00000001;
|
||||
inline constexpr FlagValue tmfMPTClearCanLock = 0x00000002;
|
||||
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000004;
|
||||
inline constexpr FlagValue tmfMPTClearRequireAuth = 0x00000008;
|
||||
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000010;
|
||||
inline constexpr FlagValue tmfMPTClearCanEscrow = 0x00000020;
|
||||
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000040;
|
||||
inline constexpr FlagValue tmfMPTClearCanTrade = 0x00000080;
|
||||
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000100;
|
||||
inline constexpr FlagValue tmfMPTClearCanTransfer = 0x00000200;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000400;
|
||||
inline constexpr FlagValue tmfMPTClearCanClawback = 0x00000800;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask = ~(
|
||||
tmfMPTSetCanLock | tmfMPTClearCanLock | tmfMPTSetRequireAuth | tmfMPTClearRequireAuth |
|
||||
tmfMPTSetCanEscrow | tmfMPTClearCanEscrow | tmfMPTSetCanTrade | tmfMPTClearCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTClearCanTransfer | tmfMPTSetCanClawback | tmfMPTClearCanClawback);
|
||||
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000002;
|
||||
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000004;
|
||||
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000008;
|
||||
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000010;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000020;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask =
|
||||
~(tmfMPTSetCanLock | tmfMPTSetRequireAuth | tmfMPTSetCanEscrow | tmfMPTSetCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTSetCanClawback);
|
||||
|
||||
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
|
||||
// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
|
||||
|
||||
@@ -21,10 +21,10 @@ XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultN
|
||||
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (BatchInnerSigs, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocol, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DirectoryLimit, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (IncludeKeyletFields, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicMPT, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicMPT, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (TokenEscrowV1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PriceOracleOrder, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -1,49 +1,74 @@
|
||||
#if !defined(PERMISSION)
|
||||
#error "undefined macro: PERMISSION"
|
||||
#if !defined(GRANULAR_PERMISSION)
|
||||
#error "undefined macro: GRANULAR_PERMISSION"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* PERMISSION(name, type, txType, value)
|
||||
* GRANULAR_PERMISSION(name, txType, value, allowedFlags, allowedFields)
|
||||
*
|
||||
* This macro defines a permission:
|
||||
* name: the name of the permission.
|
||||
* type: the GranularPermissionType enum.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
* Defines a granular permission:
|
||||
* name: the granular permission name.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
* allowedFlags: transaction flags permitted under this permission.
|
||||
* allowedFields: transaction fields permitted under this permission.
|
||||
*/
|
||||
|
||||
/** This permission grants the delegated account the ability to authorize a trustline. */
|
||||
PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537)
|
||||
/** Grants the ability to authorize a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537, tfUniversal | tfSetfAuth,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to freeze a trustline. */
|
||||
PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538)
|
||||
/** Grants the ability to freeze a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538, tfUniversal | tfSetFreeze,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to unfreeze a trustline. */
|
||||
PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539)
|
||||
/** Grants the ability to unfreeze a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539, tfUniversal | tfClearFreeze,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set Domain. */
|
||||
PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540)
|
||||
/** Grants the ability to set Domain. */
|
||||
GRANULAR_PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540, tfUniversal,
|
||||
({{sfDomain, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set EmailHashSet. */
|
||||
PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541)
|
||||
/** Grants the ability to set EmailHash. */
|
||||
GRANULAR_PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541, tfUniversal,
|
||||
({{sfEmailHash, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set MessageKey. */
|
||||
PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542)
|
||||
/** Grants the ability to set MessageKey. */
|
||||
GRANULAR_PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542, tfUniversal,
|
||||
({{sfMessageKey, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set TransferRate. */
|
||||
PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543)
|
||||
/** Grants the ability to set TransferRate. */
|
||||
GRANULAR_PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543, tfUniversal,
|
||||
({{sfTransferRate, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set TickSize. */
|
||||
PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544)
|
||||
/** Grants the ability to set TickSize. */
|
||||
GRANULAR_PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544, tfUniversal,
|
||||
({{sfTickSize, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to mint payment, which means sending a payment for a currency where the sending account is the issuer. */
|
||||
PERMISSION(PaymentMint, ttPAYMENT, 65545)
|
||||
/** Grants the ability to mint payment (sending account is the issuer). Cross-currency payments are disallowed. */
|
||||
GRANULAR_PERMISSION(PaymentMint, ttPAYMENT, 65545, tfUniversal,
|
||||
({{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSendMax, SoeOptional},
|
||||
{sfInvoiceID, SoeOptional},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfCredentialIDs, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to burn payment, which means sending a payment for a currency where the destination account is the issuer */
|
||||
PERMISSION(PaymentBurn, ttPAYMENT, 65546)
|
||||
/** Grants the ability to burn payment (destination account is the issuer). Cross-currency payments are disallowed. */
|
||||
GRANULAR_PERMISSION(PaymentBurn, ttPAYMENT, 65546, tfUniversal,
|
||||
({{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSendMax, SoeOptional},
|
||||
{sfInvoiceID, SoeOptional},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfCredentialIDs, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to lock MPToken. */
|
||||
PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547)
|
||||
/** Grants the ability to lock an MPToken. */
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547, tfUniversal | tfMPTLock,
|
||||
({{sfMPTokenIssuanceID, SoeRequired},
|
||||
{sfHolder, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to unlock MPToken. */
|
||||
PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548)
|
||||
/** Grants the ability to unlock an MPToken. */
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548, tfUniversal | tfMPTUnlock,
|
||||
({{sfMPTokenIssuanceID, SoeRequired},
|
||||
{sfHolder, SoeOptional}}))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/Book.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
@@ -26,6 +27,19 @@ public:
|
||||
};
|
||||
|
||||
/** Manages a client's subscription to data feeds.
|
||||
*
|
||||
* An InfoSub holds a non-owning reference to its `Source` (typically the
|
||||
* process-wide `NetworkOPsImp`). The destructor reaches back into the
|
||||
* `Source` to remove this subscriber from every server-side subscription
|
||||
* map.
|
||||
*
|
||||
* @note Lifetime contract: every `InfoSub` instance MUST be destroyed
|
||||
* before the backing `Source`. NetworkOPsImp shutdown drops all
|
||||
* subscriber strong refs before its own teardown to satisfy this.
|
||||
* @note Thread-safety: per-instance state is guarded by `lock_`. The
|
||||
* destructor reads tracking sets without taking `lock_` because
|
||||
* the strong-pointer ref-count is zero at destruction time, so
|
||||
* no other thread can be calling the public mutators.
|
||||
*/
|
||||
class InfoSub : public CountedObject<InfoSub>
|
||||
{
|
||||
@@ -117,8 +131,43 @@ public:
|
||||
|
||||
virtual bool
|
||||
subBook(ref ispListener, Book const&) = 0;
|
||||
|
||||
/**
|
||||
* Remove a book subscription for a live subscriber.
|
||||
*
|
||||
* Clears the book from the subscriber's own tracking set
|
||||
* (InfoSub::bookSubscriptions_) and then removes the server-side
|
||||
* entry from subBook_. Call this from RPC unsubscribe handlers.
|
||||
*
|
||||
* @param ispListener The subscriber requesting removal.
|
||||
* @param book The order book to unsubscribe from.
|
||||
* @return true if the entry was present and removed, false if the
|
||||
* subscriber was not subscribed to @p book.
|
||||
*
|
||||
* @note Thread-safety: acquires subLock_ internally.
|
||||
* @note Do NOT call from ~InfoSub(). Use unsubBookInternal instead
|
||||
* to avoid a redundant write-back to bookSubscriptions_ on a
|
||||
* partially-destroyed object.
|
||||
*/
|
||||
virtual bool
|
||||
unsubBook(std::uint64_t uListener, Book const&) = 0;
|
||||
unsubBook(ref ispListener, Book const&) = 0;
|
||||
|
||||
/**
|
||||
* Remove a book subscription during InfoSub teardown.
|
||||
*
|
||||
* Removes only the server-side entry from subBook_. Does NOT touch
|
||||
* InfoSub::bookSubscriptions_ because the InfoSub is being destroyed.
|
||||
* Called by ~InfoSub() for each book in bookSubscriptions_.
|
||||
*
|
||||
* @param uListener The sequence number of the subscriber being torn down.
|
||||
* @param book The order book entry to remove.
|
||||
* @return true if the entry was present and removed, false otherwise
|
||||
* (e.g., already removed by a concurrent RPC unsubscribe).
|
||||
*
|
||||
* @note Thread-safety: acquires subLock_ internally.
|
||||
*/
|
||||
virtual bool
|
||||
unsubBookInternal(std::uint64_t uListener, Book const&) = 0;
|
||||
|
||||
virtual bool
|
||||
subTransactions(ref ispListener) = 0;
|
||||
@@ -158,6 +207,13 @@ public:
|
||||
addRpcSub(std::string const& strUrl, ref rspEntry) = 0;
|
||||
virtual bool
|
||||
tryRemoveRpcSub(std::string const& strUrl) = 0;
|
||||
|
||||
/** Journal used by InfoSub for diagnostics that occur after the
|
||||
* owning subsystem (e.g. application-level Logs) is the only
|
||||
* surviving sink — primarily destructor-time cleanup failures.
|
||||
*/
|
||||
[[nodiscard]] virtual beast::Journal const&
|
||||
journal() const = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -184,6 +240,31 @@ public:
|
||||
void
|
||||
deleteSubAccountInfo(AccountID const& account, bool rt);
|
||||
|
||||
/** Record that this subscriber is following @p book.
|
||||
*
|
||||
* Called by NetworkOPsImp::subBook so that ~InfoSub() can issue a
|
||||
* matching unsubBook for every book this subscriber is tracking,
|
||||
* keeping per-subscriber state symmetric with the server-side map.
|
||||
*
|
||||
* @param book The order book this subscriber has just subscribed to.
|
||||
* @note Idempotent: re-inserting an already-tracked book is a no-op.
|
||||
* @note Thread-safe: takes InfoSub::lock_.
|
||||
*/
|
||||
void
|
||||
insertBookSubscription(Book const& book);
|
||||
|
||||
/** Stop tracking @p book for this subscriber.
|
||||
*
|
||||
* Called by the unsubscribe RPC handler so that the book is not
|
||||
* re-unsubscribed by ~InfoSub(). Pairs with insertBookSubscription.
|
||||
*
|
||||
* @param book The order book to forget.
|
||||
* @note No-op if @p book was not previously inserted.
|
||||
* @note Thread-safe: takes InfoSub::lock_.
|
||||
*/
|
||||
void
|
||||
deleteBookSubscription(Book const& book);
|
||||
|
||||
// return false if already subscribed to this account
|
||||
bool
|
||||
insertSubAccountHistory(AccountID const& account);
|
||||
@@ -217,6 +298,7 @@ private:
|
||||
std::shared_ptr<InfoSubRequest> request_;
|
||||
std::uint64_t seq_;
|
||||
hash_set<AccountID> accountHistorySubscriptions_;
|
||||
hash_set<Book> bookSubscriptions_;
|
||||
unsigned int apiVersion_ = 0;
|
||||
|
||||
static int
|
||||
|
||||
@@ -249,6 +249,19 @@ public:
|
||||
|
||||
virtual void
|
||||
stateAccounting(json::Value& obj) = 0;
|
||||
|
||||
/** Total number of (book, subscriber) entries currently tracked.
|
||||
*
|
||||
* Counts every weak_ptr stored across every book in subBook_, NOT the
|
||||
* number of distinct subscribers and NOT the number of distinct
|
||||
* books: a single subscriber following N books contributes N entries.
|
||||
*
|
||||
* @note Diagnostic accessor; intended for tests and operator visibility
|
||||
* into per-book subscription state. The returned value is a
|
||||
* snapshot under the subscription lock.
|
||||
*/
|
||||
virtual std::size_t
|
||||
getBookSubscribersCount() = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -222,8 +223,63 @@ public:
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be overridden to introduce additional semantic constraints beyond the
|
||||
* granular template validation for granular permissions. It is called by the base
|
||||
* invokeCheckPermission method only after the transaction has successfully passed
|
||||
* checkGranularSandbox.
|
||||
*/
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions)
|
||||
{
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the transaction is authorized to be executed by the delegated account.
|
||||
* This function enforces the strict permission check hierarchy. It is explicitly
|
||||
* designed NOT to be overridden. Derived transactors must instead implement
|
||||
* checkGranularSemantics to add custom validation logic for granular permissions.
|
||||
*
|
||||
* The evaluation proceeds as follows:
|
||||
* - If transaction-level permission is granted, the function immediately returns tesSUCCESS.
|
||||
* - If transaction-level permission is not granted, the function checks whether the transaction
|
||||
* matches the granular permission template defined in permissions.macro. If it does, it then
|
||||
* calls checkGranularSemantics to perform any additional, fine-grained validation.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
static NotTEC
|
||||
invokeCheckPermission(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// heldGranularPermissions is passed by reference into checkPermission.
|
||||
// It is populated with the sender’s granular permissions only when the sender
|
||||
// lacks tx-level permission but has granular permissions that satisfy the
|
||||
// granular permission template.
|
||||
//
|
||||
// - result is terNO_DELEGATE_PERMISSION: return immediately.
|
||||
// - result is tesSUCCESS and heldGranularPermissions is empty: tx-level permission was
|
||||
// granted, so we returned success before populating it.
|
||||
// - result is tesSUCCESS and heldGranularPermissions is not empty: tx-level permission was
|
||||
// not granted, but the held granular permissions passed checkGranularSandbox, so we proceed
|
||||
// to checkGranularSemantics.
|
||||
//
|
||||
// WARNING: Do not simplify checkPermission to return only
|
||||
// heldGranularPermissions or the ter code. Both the result and the
|
||||
// populated set are required to enforce the strict permission hierarchy
|
||||
// described above.
|
||||
std::unordered_set<GranularPermissionType> heldGranularPermissions;
|
||||
if (NotTEC const result = checkPermission(view, tx, heldGranularPermissions);
|
||||
!isTesSuccess(result) || heldGranularPermissions.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return T::checkGranularSemantics(view, tx, heldGranularPermissions);
|
||||
}
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
// Interface used by AccountDelete
|
||||
@@ -353,13 +409,24 @@ protected:
|
||||
unit::ValueUnit<Unit, T> min = unit::ValueUnit<Unit, T>{});
|
||||
|
||||
private:
|
||||
static NotTEC
|
||||
checkPermission(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType>& heldGranularPermissions);
|
||||
|
||||
std::pair<TER, XRPAmount>
|
||||
reset(XRPAmount fee);
|
||||
|
||||
TER
|
||||
consumeSeqProxy(SLE::pointer const& sleAccount);
|
||||
|
||||
TER
|
||||
payFee();
|
||||
|
||||
std::tuple<TER, XRPAmount, bool>
|
||||
processPersistentChanges(TER result, XRPAmount fee);
|
||||
|
||||
static NotTEC
|
||||
checkSingleSign(
|
||||
ReadView const& view,
|
||||
@@ -367,6 +434,7 @@ private:
|
||||
AccountID const& idAccount,
|
||||
SLE::const_pointer sleAccount,
|
||||
beast::Journal const j);
|
||||
|
||||
static NotTEC
|
||||
checkMultiSign(
|
||||
ReadView const& view,
|
||||
|
||||
@@ -15,7 +15,9 @@ class ValidAMM
|
||||
std::optional<AccountID> ammAccount_;
|
||||
std::optional<STAmount> lptAMMBalanceAfter_;
|
||||
std::optional<STAmount> lptAMMBalanceBefore_;
|
||||
std::optional<STAmount> lptAMMBalanceBeforeDeletion_;
|
||||
bool ammPoolChanged_{false};
|
||||
bool ammDeleted_{false};
|
||||
|
||||
public:
|
||||
enum class ZeroAllowed : bool { No = false, Yes = true };
|
||||
@@ -35,12 +37,17 @@ private:
|
||||
[[nodiscard]] bool
|
||||
finalizeCreate(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDelete(bool enforce, TER res, beast::Journal const&) const;
|
||||
finalizeDelete(bool enforce, bool enforceAMMDelete, TER res, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDeposit(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
// Includes clawback
|
||||
[[nodiscard]] bool
|
||||
finalizeWithdraw(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
finalizeWithdraw(
|
||||
STTx const&,
|
||||
ReadView const&,
|
||||
bool enforce,
|
||||
bool enforceAMMDelete,
|
||||
beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDEX(bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
|
||||
@@ -23,9 +23,6 @@ public:
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -32,7 +32,10 @@ public:
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
@@ -22,9 +22,6 @@ public:
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ public:
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
Reference in New Issue
Block a user