20 #include <ripple/app/tx/impl/OfferStream.h>
21 #include <ripple/basics/Log.h>
22 #include <ripple/protocol/Feature.h>
28 checkIssuers(ReadView
const& view, Book
const& book)
30 auto issuerExists = [](ReadView
const& view, Issue
const& iss) ->
bool {
33 return issuerExists(view, book.in) && issuerExists(view, book.out);
37 template <
class TIn,
class TOut>
47 , cancelView_(cancelView)
49 , validBook_(checkIssuers(view, book))
59 template <
class TIn,
class TOut>
67 auto p = view.
peek(keylet::page(tip_.dir()));
71 JLOG(j_.
error()) <<
"Missing directory " << tip_.dir() <<
" for offer "
77 auto it(
std::find(v.begin(), v.end(), tip_.index()));
81 JLOG(j_.
error()) <<
"Missing offer " << tip_.index()
82 <<
" for directory " << tip_.dir();
90 JLOG(j_.
trace()) <<
"Missing offer " << tip_.index()
91 <<
" removed from directory " << tip_.dir();
103 return accountFunds(view,
id, saDefault, freezeHandling, j);
136 template <
class TIn,
class TOut>
137 template <
class TTakerPays,
class TTakerGets>
142 std::is_same_v<TTakerPays, IOUAmount> ||
143 std::is_same_v<TTakerPays, XRPAmount>,
144 "STAmount is not supported");
147 std::is_same_v<TTakerGets, IOUAmount> ||
148 std::is_same_v<TTakerGets, XRPAmount>,
149 "STAmount is not supported");
152 !std::is_same_v<TTakerPays, XRPAmount> ||
153 !std::is_same_v<TTakerGets, XRPAmount>,
154 "Cannot have XRP/XRP offers");
162 constexpr
bool const inIsXRP = std::is_same_v<TTakerPays, XRPAmount>;
163 constexpr
bool const outIsXRP = std::is_same_v<TTakerGets, XRPAmount>;
165 if constexpr (outIsXRP)
174 TAmounts<TTakerPays, TTakerGets>
const ofrAmts{
175 toAmount<TTakerPays>(offer_.amount().in),
176 toAmount<TTakerGets>(offer_.amount().out)};
178 if constexpr (!inIsXRP && !outIsXRP)
180 if (ofrAmts.in >= ofrAmts.out)
184 TTakerGets
const ownerFunds = toAmount<TTakerGets>(*ownerFunds_);
186 auto const effectiveAmounts = [&] {
187 if (offer_.owner() != offer_.issueOut().account &&
188 ownerFunds < ofrAmts.out)
191 return offer_.quality().ceil_out(ofrAmts, ownerFunds);
196 if (effectiveAmounts.in > TTakerPays::minPositiveAmount())
199 Quality
const effectiveQuality{effectiveAmounts};
200 return effectiveQuality < offer_.quality();
203 template <
class TIn,
class TOut>
215 ownerFunds_ = std::nullopt;
224 if (!counter_.step())
239 tp{d{(*entry)[sfExpiration]}} <= expire_)
241 JLOG(j_.
trace()) <<
"Removing expired offer " << entry->key();
242 permRmOffer(entry->key());
248 auto const amount(offer_.amount());
253 JLOG(j_.
warn()) <<
"Removing bad offer " << entry->key();
254 permRmOffer(entry->key());
269 if (*ownerFunds_ <= beast::zero)
282 if (original_funds == *ownerFunds_)
284 permRmOffer(entry->key());
285 JLOG(j_.
trace()) <<
"Removing unfunded offer " << entry->key();
290 <<
"Removing became unfunded offer " << entry->key();
297 bool const rmSmallIncreasedQOffer = [&] {
298 bool const inIsXRP =
isXRP(offer_.issueIn());
299 bool const outIsXRP =
isXRP(offer_.issueOut());
300 if (inIsXRP && !outIsXRP)
308 if constexpr (!(std::is_same_v<TIn, IOUAmount> ||
309 std::is_same_v<TOut, XRPAmount>))
310 return shouldRmSmallIncreasedQOffer<XRPAmount, IOUAmount>();
312 if (!inIsXRP && outIsXRP)
315 if constexpr (!(std::is_same_v<TIn, XRPAmount> ||
316 std::is_same_v<TOut, IOUAmount>))
317 return shouldRmSmallIncreasedQOffer<IOUAmount, XRPAmount>();
319 if (!inIsXRP && !outIsXRP)
322 if constexpr (!(std::is_same_v<TIn, XRPAmount> ||
323 std::is_same_v<TOut, XRPAmount>))
324 return shouldRmSmallIncreasedQOffer<IOUAmount, IOUAmount>();
330 if (rmSmallIncreasedQOffer)
340 if (original_funds == *ownerFunds_)
342 permRmOffer(entry->key());
344 <<
"Removing tiny offer due to reduced quality "
349 JLOG(j_.
trace()) <<
"Removing tiny offer that became tiny due "
350 "to reduced quality "
365 OfferStream::permRmOffer(
uint256 const& offerIndex)
367 offerDelete(cancelView_, cancelView_.peek(keylet::offer(offerIndex)), j_);
370 template <
class TIn,
class TOut>
374 permToRemove_.insert(offerIndex);