1#include <xrpl/tx/paths/OfferStream.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Number.h>
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/basics/chrono.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/beast/utility/Zero.h>
9#include <xrpl/beast/utility/instrumentation.h>
10#include <xrpl/ledger/ApplyView.h>
11#include <xrpl/ledger/ReadView.h>
12#include <xrpl/ledger/helpers/MPTokenHelpers.h>
13#include <xrpl/ledger/helpers/PermissionedDEXHelpers.h>
14#include <xrpl/ledger/helpers/RippleStateHelpers.h>
15#include <xrpl/ledger/helpers/TokenHelpers.h>
16#include <xrpl/protocol/AccountID.h>
17#include <xrpl/protocol/Asset.h>
18#include <xrpl/protocol/Book.h>
19#include <xrpl/protocol/Concepts.h>
20#include <xrpl/protocol/Feature.h>
21#include <xrpl/protocol/IOUAmount.h>
22#include <xrpl/protocol/Indexes.h>
23#include <xrpl/protocol/MPTAmount.h>
24#include <xrpl/protocol/MPTIssue.h>
25#include <xrpl/protocol/Quality.h>
26#include <xrpl/protocol/SField.h>
27#include <xrpl/protocol/STLedgerEntry.h>
28#include <xrpl/protocol/XRPAmount.h>
39 auto issuerExists = [](
ReadView const& view,
Asset const& asset) ->
bool {
40 auto const& issuer = asset.getIssuer();
43 return issuerExists(view,
book.in) && issuerExists(view,
book.out);
47template <StepAmount TIn, StepAmount TOut>
64 XRPL_ASSERT(
validBook_,
"xrpl::TOfferStreamBase::TOfferStreamBase : valid book");
69template <StepAmount TIn, StepAmount TOut>
81 JLOG(
j_.error()) <<
"Missing directory " <<
tip_.dir() <<
" for offer " <<
tip_.index();
85 auto v(p->getFieldV256(sfIndexes));
90 JLOG(
j_.error()) <<
"Missing offer " <<
tip_.index() <<
" for directory " <<
tip_.dir();
95 p->setFieldV256(sfIndexes, v);
98 JLOG(
j_.trace()) <<
"Missing offer " <<
tip_.index() <<
" removed from directory "
102template <StepAmount T>
132template <StepAmount TIn, StepAmount TOut>
133template <
class TTakerPays,
class TTakerGets>
134 requires ValidTaker<TTakerPays, TTakerGets>
144 if constexpr (kOutIsXrp)
159 if constexpr (!kInIsXrp && !kOutIsXrp)
167 auto const effectiveAmounts = [&] {
180 if (effectiveAmounts.in.signum() <= 0 || effectiveAmounts.out.signum() <= 0)
183 if (effectiveAmounts.in > TTakerPays::minPositiveAmount())
186 Quality const effectiveQuality{effectiveAmounts};
187 return effectiveQuality <
offer_.quality();
190template <StepAmount TIn, StepAmount TOut>
225 if (entry->isFieldPresent(sfExpiration) && tp{d{(*entry)[sfExpiration]}} <=
expire_)
227 JLOG(
j_.trace()) <<
"Removing expired offer " << entry->key();
234 auto const amount(
offer_.amount());
239 JLOG(
j_.warn()) <<
"Removing bad offer " << entry->key();
247 JLOG(
j_.trace()) <<
"Removing deep frozen unfunded offer " << entry->key();
258 if ((!
view_.rules().enabled(fixCleanup3_3_0) ||
book_.domain.has_value()) &&
259 entry->isFieldPresent(sfDomainID) &&
261 view_, entry->key(), entry->getFieldH256(sfDomainID),
j_))
263 JLOG(
j_.trace()) <<
"Removing offer no longer in domain " << entry->key();
297 JLOG(
j_.trace()) <<
"Removing unfunded offer " << entry->key();
301 JLOG(
j_.trace()) <<
"Removing became unfunded offer " << entry->key();
322 JLOG(
j_.trace()) <<
"Removing tiny offer due to reduced quality " << entry->key();
326 JLOG(
j_.trace()) <<
"Removing tiny offer that became tiny due "
327 "to reduced quality "
341template <StepAmount TIn, StepAmount TOut>
A generic endpoint for log messages.
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 update(SLE::ref sle)=0
Indicate changes to a peeked SLE.
constexpr TIss const & get() const
AccountID const & getIssuer() const
Presents and consumes the offers in an order book.
boost::container::flat_set< uint256 > permToRemove_
void permRmOffer(uint256 const &offerIndex) override
std::chrono::time_point< NetClock > time_point
std::chrono::duration< rep, period > duration
Number is a floating point type that can represent a wide range of values.
Represents the logical ratio of output currency to input currency.
std::shared_ptr< STLedgerEntry > pointer
std::optional< TOut > ownerFunds_
TOfferStreamBase(ApplyView &view, ApplyView &cancelView, Book const &book, NetClock::time_point when, StepCounter &counter, beast::Journal journal)
bool shouldRmSmallIncreasedQOffer() const
NetClock::time_point const expire_
TOffer< TIn, TOut > offer_
virtual void permRmOffer(uint256 const &offerIndex)=0
bool step()
Advance to the next valid offer.
void erase(ApplyView &view)
Keylet book(Book const &b)
The beginning of an order book.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
bool offerInDomain(ReadView const &view, uint256 const &offerID, Domain const &domainID, beast::Journal j)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static T accountFundsHelper(ReadView const &view, AccountID const &id, T const &amtDefault, Asset const &asset, FreezeHandling freezeHandling, AuthHandling authHandling, beast::Journal j)
FreezeHandling
Controls the treatment of frozen account balances.
bool isXRP(AccountID const &c)
bool isDeepFrozen(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer)
T toAmount(STAmount const &amt)=delete
AuthHandling
Controls the treatment of unauthorized MPT balances.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
void erase(STObject &st, TypedField< U > const &f)
Remove a field in an STObject.
STAmount issuerFundsToSelfIssue(ReadView const &view, MPTIssue const &issue)
Determine funds available for an issuer to sell in an issuer owned offer.
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j, SpendableHandling includeFullBalance=SpendableHandling::SimpleBalance)
Represents a pair of input and output currencies.