20#include <xrpld/app/misc/PermissionedDEXHelpers.h> 
   21#include <xrpld/app/tx/detail/OfferStream.h> 
   23#include <xrpl/basics/Log.h> 
   24#include <xrpl/ledger/View.h> 
   25#include <xrpl/protocol/Feature.h> 
   26#include <xrpl/protocol/LedgerFormats.h> 
   32checkIssuers(ReadView 
const& view, Book 
const& book)
 
   34    auto issuerExists = [](ReadView 
const& view, Issue 
const& iss) -> 
bool {
 
   37    return issuerExists(view, book.in) && issuerExists(view, book.out);
 
   41template <
class TIn, 
class TOut>
 
   51    , cancelView_(cancelView)
 
   53    , validBook_(checkIssuers(view, book))
 
   59        validBook_, 
"ripple::TOfferStreamBase::TOfferStreamBase : valid book");
 
 
   64template <
class TIn, 
class TOut>
 
   76        JLOG(j_.
error()) << 
"Missing directory " << tip_.dir() << 
" for offer " 
   81    auto v(p->getFieldV256(sfIndexes));
 
   82    auto it(
std::find(v.begin(), v.end(), tip_.index()));
 
   86        JLOG(j_.
error()) << 
"Missing offer " << tip_.index()
 
   87                         << 
" for directory " << tip_.dir();
 
   92    p->setFieldV256(sfIndexes, v);
 
   95    JLOG(j_.
trace()) << 
"Missing offer " << tip_.index()
 
   96                     << 
" removed from directory " << tip_.dir();
 
  108    return accountFunds(view, 
id, saDefault, freezeHandling, j);
 
 
  141template <
class TIn, 
class TOut>
 
  142template <
class TTakerPays, 
class TTakerGets>
 
  149        "STAmount is not supported");
 
  154        "STAmount is not supported");
 
  159        "Cannot have XRP/XRP offers");
 
  167    if constexpr (outIsXRP)
 
  176    TAmounts<TTakerPays, TTakerGets> 
const ofrAmts{
 
  177        toAmount<TTakerPays>(offer_.amount().in),
 
  178        toAmount<TTakerGets>(offer_.amount().out)};
 
  180    if constexpr (!inIsXRP && !outIsXRP)
 
  182        if (ofrAmts.in >= ofrAmts.out)
 
  186    TTakerGets 
const ownerFunds = toAmount<TTakerGets>(*ownerFunds_);
 
  188    auto const effectiveAmounts = [&] {
 
  189        if (offer_.owner() != offer_.issueOut().account &&
 
  190            ownerFunds < ofrAmts.out)
 
  196            return offer_.quality().ceil_out_strict(
 
  197                ofrAmts, ownerFunds,  
false);
 
  203    if (effectiveAmounts.in.signum() <= 0 || effectiveAmounts.out.signum() <= 0)
 
  206    if (effectiveAmounts.in > TTakerPays::minPositiveAmount())
 
  209    Quality 
const effectiveQuality{effectiveAmounts};
 
  210    return effectiveQuality < offer_.quality();
 
 
  213template <
class TIn, 
class TOut>
 
  234        if (!counter_.step())
 
  248        if (entry->isFieldPresent(sfExpiration) &&
 
  249            tp{d{(*entry)[sfExpiration]}} <= expire_)
 
  251            JLOG(j_.
trace()) << 
"Removing expired offer " << entry->key();
 
  252            permRmOffer(entry->key());
 
  258        auto const amount(offer_.amount());
 
  263            JLOG(j_.
warn()) << 
"Removing bad offer " << entry->key();
 
  264            permRmOffer(entry->key());
 
  272            offer_.issueIn().currency,
 
  273            offer_.issueIn().account);
 
  277                << 
"Removing deep frozen unfunded offer " << entry->key();
 
  278            permRmOffer(entry->key());
 
  283        if (entry->isFieldPresent(sfDomainID) &&
 
  285                view_, entry->key(), entry->getFieldH256(sfDomainID), j_))
 
  288                << 
"Removing offer no longer in domain " << entry->key();
 
  289            permRmOffer(entry->key());
 
  304        if (*ownerFunds_ <= beast::zero)
 
  317            if (original_funds == *ownerFunds_)
 
  319                permRmOffer(entry->key());
 
  320                JLOG(j_.
trace()) << 
"Removing unfunded offer " << entry->key();
 
  325                    << 
"Removing became unfunded offer " << entry->key();
 
  332        bool const rmSmallIncreasedQOffer = [&] {
 
  333            bool const inIsXRP = 
isXRP(offer_.issueIn());
 
  334            bool const outIsXRP = 
isXRP(offer_.issueOut());
 
  335            if (inIsXRP && !outIsXRP)
 
  345                    return shouldRmSmallIncreasedQOffer<XRPAmount, IOUAmount>();
 
  347            if (!inIsXRP && outIsXRP)
 
  352                    return shouldRmSmallIncreasedQOffer<IOUAmount, XRPAmount>();
 
  354            if (!inIsXRP && !outIsXRP)
 
  359                    return shouldRmSmallIncreasedQOffer<IOUAmount, IOUAmount>();
 
  363                "rippls::TOfferStreamBase::step::rmSmallIncreasedQOffer : XRP " 
  369        if (rmSmallIncreasedQOffer)
 
  379            if (original_funds == *ownerFunds_)
 
  381                permRmOffer(entry->key());
 
  383                    << 
"Removing tiny offer due to reduced quality " 
  388                JLOG(j_.
trace()) << 
"Removing tiny offer that became tiny due " 
  389                                    "to reduced quality " 
 
 
  404OfferStream::permRmOffer(
uint256 const& offerIndex)
 
  406    offerDelete(cancelView_, cancelView_.peek(keylet::offer(offerIndex)), j_);
 
 
  409template <
class TIn, 
class TOut>
 
  413    permToRemove_.insert(offerIndex);
 
 
 
 
 
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
Writeable view to a ledger, for applying a transaction.
 
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.
 
Presents and consumes the offers in an order book.
 
Floating point representation of amounts with high dynamic range.
 
A currency issued by an account.
 
std::chrono::time_point< NetClock > time_point
 
std::chrono::duration< rep, period > duration
 
void erase(ApplyView &view)
 
bool step()
Advance to the next valid offer.
 
TOfferStreamBase(ApplyView &view, ApplyView &cancelView, Book const &book, NetClock::time_point when, StepCounter &counter, beast::Journal journal)
 
bool shouldRmSmallIncreasedQOffer() const
 
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.
 
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, 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)
 
static STAmount accountFundsHelper(ReadView const &view, AccountID const &id, STAmount const &saDefault, Issue const &, FreezeHandling freezeHandling, beast::Journal j)
 
IOUAmount toAmount< IOUAmount >(STAmount const &amt)
 
void erase(STObject &st, TypedField< U > const &f)
Remove a field in an STObject.
 
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
 
XRPAmount toAmount< XRPAmount >(STAmount const &amt)
 
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.