mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Autobridging hooks and cleanups:
- Detect when we should autobridge and get bridge books. - Move applyOffer from STAmount into the OfferCreate transactor.
This commit is contained in:
committed by
Vinnie Falco
parent
166b8963bb
commit
a5488c3727
@@ -1052,157 +1052,6 @@ STAmount STAmount::setRate (std::uint64_t rate)
|
||||
return STAmount (CURRENCY_ONE, ACCOUNT_ONE, mantissa, exponent);
|
||||
}
|
||||
|
||||
// Existing offer is on the books.
|
||||
// Price is offer owner's, which might be better for taker.
|
||||
// Taker pays what they can.
|
||||
// Taker gets all taker can pay for with saTakerFunds/uTakerPaysRate, limited by saOfferPays and saOfferFunds/uOfferPaysRate.
|
||||
// If taker is an offer, taker is spending at same or better rate than they wanted.
|
||||
// Taker should consider themselves as wanting to buy X amount.
|
||||
// Taker is willing to pay at most the rate of Y/X each.
|
||||
// Buy semantics:
|
||||
// - After having some part of their offer fulfilled at a better rate their offer should be reduced accordingly.
|
||||
//
|
||||
// There are no quality costs for offer vs offer taking.
|
||||
//
|
||||
// --> bSell: True for sell semantics.
|
||||
// --> uTakerPaysRate: >= QUALITY_ONE | TransferRate for third party IOUs paid by taker.
|
||||
// --> uOfferPaysRate: >= QUALITY_ONE | TransferRate for third party IOUs paid by offer owner.
|
||||
// --> saOfferRate: Original saOfferGets/saOfferPays, when offer was made.
|
||||
// --> saOfferFunds: Limit for saOfferPays : How much can pay including fees.
|
||||
// --> saTakerFunds: Limit for saOfferGets : How much can pay including fees.
|
||||
// --> saOfferPays: Request : this should be reduced as the offer is fullfilled.
|
||||
// --> saOfferGets: Request : this should be reduced as the offer is fullfilled.
|
||||
// --> saTakerPays: Limit for taker to pay.
|
||||
// --> saTakerGets: Limit for taker to get.
|
||||
// <-- saTakerPaid: Actual
|
||||
// <-- saTakerGot: Actual
|
||||
// <-- saTakerIssuerFee: Actual
|
||||
// <-- saOfferIssuerFee: Actual
|
||||
bool STAmount::applyOffer (
|
||||
const bool bSell,
|
||||
const std::uint32_t uTakerPaysRate, const std::uint32_t uOfferPaysRate,
|
||||
const STAmount& saOfferRate,
|
||||
const STAmount& saOfferFunds, const STAmount& saTakerFunds,
|
||||
const STAmount& saOfferPays, const STAmount& saOfferGets,
|
||||
const STAmount& saTakerPays, const STAmount& saTakerGets,
|
||||
STAmount& saTakerPaid, STAmount& saTakerGot,
|
||||
STAmount& saTakerIssuerFee, STAmount& saOfferIssuerFee)
|
||||
{
|
||||
saOfferGets.throwComparable (saTakerFunds);
|
||||
|
||||
assert (saOfferFunds.isPositive () && saTakerFunds.isPositive ()); // Both must have funds.
|
||||
assert (saOfferGets.isPositive () && saOfferPays.isPositive ()); // Must not be a null offer.
|
||||
|
||||
// Available = limited by funds.
|
||||
// Limit offerer funds available, by transfer fees.
|
||||
STAmount saOfferFundsAvailable = QUALITY_ONE == uOfferPaysRate
|
||||
? saOfferFunds // As is.
|
||||
: STAmount::divide (saOfferFunds, STAmount (CURRENCY_ONE, ACCOUNT_ONE, uOfferPaysRate, -9)); // Reduce by offer fees.
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: uOfferPaysRate=" << uOfferPaysRate;
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saOfferFundsAvailable=" << saOfferFundsAvailable.getFullText ();
|
||||
|
||||
// Limit taker funds available, by transfer fees.
|
||||
STAmount saTakerFundsAvailable = QUALITY_ONE == uTakerPaysRate
|
||||
? saTakerFunds // As is.
|
||||
: STAmount::divide (saTakerFunds, STAmount (CURRENCY_ONE, ACCOUNT_ONE, uTakerPaysRate, -9)); // Reduce by taker fees.
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: TAKER_FEES=" << STAmount (CURRENCY_ONE, ACCOUNT_ONE, uTakerPaysRate, -9).getFullText ();
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: uTakerPaysRate=" << uTakerPaysRate;
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerFundsAvailable=" << saTakerFundsAvailable.getFullText ();
|
||||
|
||||
STAmount saOfferPaysAvailable; // Amount offer can pay out, limited by offer and offerer funds.
|
||||
STAmount saOfferGetsAvailable; // Amount offer would get, limited by offer funds.
|
||||
|
||||
if (saOfferFundsAvailable >= saOfferPays)
|
||||
{
|
||||
// Offer was fully funded, avoid math shenanigans.
|
||||
|
||||
saOfferPaysAvailable = saOfferPays;
|
||||
saOfferGetsAvailable = saOfferGets;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Offer has limited funding, limit offer gets and pays by funds available.
|
||||
|
||||
saOfferPaysAvailable = saOfferFundsAvailable;
|
||||
saOfferGetsAvailable = std::min (saOfferGets, mulRound (saOfferPaysAvailable, saOfferRate, saOfferGets, true));
|
||||
}
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saOfferPaysAvailable=" << saOfferPaysAvailable.getFullText ();
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saOfferGetsAvailable=" << saOfferGetsAvailable.getFullText ();
|
||||
|
||||
STAmount saTakerPaysAvailable = std::min (saTakerPays, saTakerFundsAvailable);
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerPaysAvailable=" << saTakerPaysAvailable.getFullText ();
|
||||
|
||||
// Limited = limited by other sides raw numbers.
|
||||
// Taker can't pay more to offer than offer can get.
|
||||
STAmount saTakerPaysLimited = std::min (saTakerPaysAvailable, saOfferGetsAvailable);
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerPaysLimited=" << saTakerPaysLimited.getFullText ();
|
||||
|
||||
// Align saTakerGetsLimited with saTakerPaysLimited.
|
||||
STAmount saTakerGetsLimited = saTakerPaysLimited >= saOfferGetsAvailable // Cannot actually be greater
|
||||
? saOfferPaysAvailable // Potentially take entire offer. Avoid math shenanigans.
|
||||
: std::min (saOfferPaysAvailable, divRound (saTakerPaysLimited, saOfferRate, saTakerGets, true)); // Take a portion of offer.
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saOfferRate=" << saOfferRate.getFullText ();
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerGetsLimited=" << saTakerGetsLimited.getFullText ();
|
||||
|
||||
// Got & Paid = Calculated by price and transfered without fees.
|
||||
// Compute from got as when !bSell, we want got to be exact to finish off offer if possible.
|
||||
|
||||
saTakerGot = bSell
|
||||
? saTakerGetsLimited // Get all available that are paid for.
|
||||
: std::min (saTakerGets, saTakerGetsLimited); // Limit by wanted.
|
||||
saTakerPaid = saTakerGot >= saTakerGetsLimited
|
||||
? saTakerPaysLimited
|
||||
: std::min (saTakerPaysLimited, mulRound (saTakerGot, saOfferRate, saTakerFunds, true));
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerGot=" << saTakerGot.getFullText ();
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerPaid=" << saTakerPaid.getFullText ();
|
||||
|
||||
if (uTakerPaysRate == QUALITY_ONE)
|
||||
{
|
||||
saTakerIssuerFee = STAmount (saTakerPaid.getCurrency (), saTakerPaid.getIssuer ());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compute fees in a rounding safe way.
|
||||
|
||||
STAmount saTransferRate = STAmount (CURRENCY_ONE, ACCOUNT_ONE, uTakerPaysRate, -9);
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTransferRate=" << saTransferRate.getFullText ();
|
||||
|
||||
// TakerCost includes transfer fees.
|
||||
STAmount saTakerCost = STAmount::mulRound (saTakerPaid, saTransferRate, true);
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerCost=" << saTakerCost.getFullText ();
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerFunds=" << saTakerFunds.getFullText ();
|
||||
saTakerIssuerFee = saTakerCost > saTakerFunds
|
||||
? saTakerFunds - saTakerPaid // Not enough funds to cover fee, stiff issuer the rounding error.
|
||||
: saTakerCost - saTakerPaid;
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerIssuerFee=" << saTakerIssuerFee.getFullText ();
|
||||
assert (!saTakerIssuerFee.isNegative ());
|
||||
}
|
||||
|
||||
if (uOfferPaysRate == QUALITY_ONE)
|
||||
{
|
||||
saOfferIssuerFee = STAmount (saTakerGot.getCurrency (), saTakerGot.getIssuer ());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compute fees in a rounding safe way.
|
||||
STAmount saOfferCost = STAmount::mulRound (saTakerGot, STAmount (CURRENCY_ONE, ACCOUNT_ONE, uOfferPaysRate, -9), true);
|
||||
|
||||
saOfferIssuerFee = saOfferCost > saOfferFunds
|
||||
? saOfferFunds - saTakerGot // Not enough funds to cover fee, stiff issuer the rounding error.
|
||||
: saOfferCost - saTakerGot;
|
||||
}
|
||||
|
||||
WriteLog (lsINFO, STAmount) << "applyOffer: saTakerGot=" << saTakerGot.getFullText ();
|
||||
|
||||
return saTakerGot >= saOfferPaysAvailable; // True, if consumed offer.
|
||||
}
|
||||
|
||||
STAmount STAmount::getPay (const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)
|
||||
{
|
||||
// Someone wants to get (needed) out of the offer, how much should they pay in?
|
||||
|
||||
Reference in New Issue
Block a user