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_);
187 auto const effectiveAmounts = [&] {
188 if (offer_.owner() != offer_.issueOut().account &&
189 ownerFunds < ofrAmts.out)
197 return offer_.quality().ceil_out_strict(
198 ofrAmts, ownerFunds,
false);
200 return offer_.quality().ceil_out(ofrAmts, ownerFunds);
208 (effectiveAmounts.in.signum() <= 0 ||
209 effectiveAmounts.out.signum() <= 0))
212 if (effectiveAmounts.in > TTakerPays::minPositiveAmount())
215 Quality
const effectiveQuality{effectiveAmounts};
216 return effectiveQuality < offer_.quality();
219 template <
class TIn,
class TOut>
231 ownerFunds_ = std::nullopt;
240 if (!counter_.step())
255 tp{d{(*entry)[sfExpiration]}} <= expire_)
257 JLOG(j_.
trace()) <<
"Removing expired offer " << entry->key();
258 permRmOffer(entry->key());
264 auto const amount(offer_.amount());
269 JLOG(j_.
warn()) <<
"Removing bad offer " << entry->key();
270 permRmOffer(entry->key());
285 if (*ownerFunds_ <= beast::zero)
298 if (original_funds == *ownerFunds_)
300 permRmOffer(entry->key());
301 JLOG(j_.
trace()) <<
"Removing unfunded offer " << entry->key();
306 <<
"Removing became unfunded offer " << entry->key();
313 bool const rmSmallIncreasedQOffer = [&] {
314 bool const inIsXRP =
isXRP(offer_.issueIn());
315 bool const outIsXRP =
isXRP(offer_.issueOut());
316 if (inIsXRP && !outIsXRP)
324 if constexpr (!(std::is_same_v<TIn, IOUAmount> ||
325 std::is_same_v<TOut, XRPAmount>))
326 return shouldRmSmallIncreasedQOffer<XRPAmount, IOUAmount>();
328 if (!inIsXRP && outIsXRP)
331 if constexpr (!(std::is_same_v<TIn, XRPAmount> ||
332 std::is_same_v<TOut, IOUAmount>))
333 return shouldRmSmallIncreasedQOffer<IOUAmount, XRPAmount>();
335 if (!inIsXRP && !outIsXRP)
338 if constexpr (!(std::is_same_v<TIn, XRPAmount> ||
339 std::is_same_v<TOut, XRPAmount>))
340 return shouldRmSmallIncreasedQOffer<IOUAmount, IOUAmount>();
346 if (rmSmallIncreasedQOffer)
356 if (original_funds == *ownerFunds_)
358 permRmOffer(entry->key());
360 <<
"Removing tiny offer due to reduced quality "
365 JLOG(j_.
trace()) <<
"Removing tiny offer that became tiny due "
366 "to reduced quality "
381 OfferStream::permRmOffer(
uint256 const& offerIndex)
383 offerDelete(cancelView_, cancelView_.peek(keylet::offer(offerIndex)), j_);
386 template <
class TIn,
class TOut>
390 permToRemove_.insert(offerIndex);