Merge branch 'develop' of github.com:jedmccaleb/NewCoin into develop

This commit is contained in:
JoelKatz
2013-04-25 17:37:51 -07:00
6 changed files with 238 additions and 31 deletions

View File

@@ -986,18 +986,19 @@ STAmount STAmount::setRate(uint64 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.
//
// Existing offer is on the books. Offer owner gets their rate.
//
// Taker pays what they can. If taker is an offer, doesn't matter what rate taker is. 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. Therefore, after having some part of their offer fulfilled at a better rate their offer should be reduced accordingly.
//
// YYY Could have a flag for spend up to behaviour vs current limit spend rate.
// 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.
@@ -1012,6 +1013,7 @@ STAmount STAmount::setRate(uint64 rate)
// <-- saTakerIssuerFee: Actual
// <-- saOfferIssuerFee: Actual
bool STAmount::applyOffer(
const bool bSell,
const uint32 uTakerPaysRate, const uint32 uOfferPaysRate,
const STAmount& saOfferRate,
const STAmount& saOfferFunds, const STAmount& saTakerFunds,
@@ -1022,21 +1024,21 @@ bool STAmount::applyOffer(
{
saOfferGets.throwComparable(saTakerFunds);
assert(!saOfferFunds.isZero() && !saTakerFunds.isZero()); // Must have funds.
assert(!saOfferGets.isZero() && !saOfferPays.isZero()); // Must not be a null offer.
assert(!saOfferFunds.isZero() && !saTakerFunds.isZero()); // Both must have funds.
assert(saOfferGets.isPositive() && saOfferPays.isPositive()); // Must not be a null offer.
// Limit offerer funds available, by transfer fees.
STAmount saOfferFundsAvailable = QUALITY_ONE == uOfferPaysRate
? saOfferFunds
: STAmount::divide(saOfferFunds, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferPaysRate, -9));
? saOfferFunds // As is.
: STAmount::divide(saOfferFunds, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferPaysRate, -9)); // Reduce by offer fees.
cLog(lsINFO) << "applyOffer: uOfferPaysRate=" << uOfferPaysRate;
cLog(lsINFO) << "applyOffer: saOfferFundsAvailable=" << saOfferFundsAvailable.getFullText();
// Limit taker funds available, by transfer fees.
STAmount saTakerFundsAvailable = QUALITY_ONE == uTakerPaysRate
? saTakerFunds
: STAmount::divide(saTakerFunds, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uTakerPaysRate, -9));
? saTakerFunds // As is.
: STAmount::divide(saTakerFunds, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uTakerPaysRate, -9)); // Reduce by taker fees.
cLog(lsINFO) << "applyOffer: TAKER_FEES=" << STAmount(CURRENCY_ONE, ACCOUNT_ONE, uTakerPaysRate, -9).getFullText();
cLog(lsINFO) << "applyOffer: uTakerPaysRate=" << uTakerPaysRate;
@@ -1069,12 +1071,14 @@ bool STAmount::applyOffer(
cLog(lsINFO) << "applyOffer: saTakerPaysMax=" << saTakerPaysMax.getFullText();
STAmount saTakerGetsMax = saTakerPaysMax >= saOfferGetsAvailable
? saOfferPaysAvailable // Potentially take entire offer. Avoid math shenanigans.
: std::min(saOfferPaysAvailable, divRound(saTakerPaysMax, saOfferRate, saTakerGets, !saTakerGets.isNative())); // Taker a portion of offer.
: std::min(saOfferPaysAvailable, divRound(saTakerPaysMax, saOfferRate, saTakerGets, true)); // Taker a portion of offer.
cLog(lsINFO) << "applyOffer: saOfferRate=" << saOfferRate.getFullText();
cLog(lsINFO) << "applyOffer: saTakerGetsMax=" << saTakerGetsMax.getFullText();
saTakerGot = std::min(saTakerGets, saTakerGetsMax); // Limit by wanted.
saTakerPaid = saTakerGot == saOfferPaysAvailable
saTakerGot = bSell
? saTakerGetsMax // Get all available that are paid for.
: std::min(saTakerGets, saTakerGetsMax); // Limit by wanted.
saTakerPaid = saTakerGot >= saOfferPaysAvailable
? saOfferGetsAvailable
: std::min(saOfferGetsAvailable, mulRound(saTakerGot, saOfferRate, saTakerFunds, true));
@@ -1120,7 +1124,7 @@ bool STAmount::applyOffer(
cLog(lsINFO) << "applyOffer: saTakerGot=" << saTakerGot.getFullText();
return saTakerGot >= saOfferPaysAvailable;
return saTakerGot >= saOfferPaysAvailable; // True, if consumed offer.
}
STAmount STAmount::getPay(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)

View File

@@ -92,6 +92,7 @@ bool OfferCreateTransactor::bValidOffer(
TER OfferCreateTransactor::takeOffers(
const bool bOpenLedger,
const bool bPassive,
const bool bSell,
const uint256& uBookBase,
const uint160& uTakerAccountID,
SLE::ref sleTakerAccount,
@@ -110,7 +111,7 @@ TER OfferCreateTransactor::takeOffers(
assert(saTakerPays && saTakerGets);
cLog(lsINFO) << "takeOffers: against book: " << uBookBase.ToString();
cLog(lsINFO) << "takeOffers: bSell: " << bSell << ": against book: " << uBookBase.ToString();
LedgerEntrySet& lesActive = mEngine->getNodes();
uint256 uTipIndex = uBookBase;
@@ -244,6 +245,7 @@ TER OfferCreateTransactor::takeOffers(
cLog(lsINFO) << "takeOffers: applyOffer: saTakerGets: " << saTakerGets.getFullText();
bool bOfferDelete = STAmount::applyOffer(
bSell,
lesActive.rippleTransferRate(uTakerAccountID, uOfferOwnerID, uTakerPaysAccountID),
lesActive.rippleTransferRate(uOfferOwnerID, uTakerAccountID, uTakerGetsAccountID),
saOfferRate,
@@ -313,19 +315,24 @@ TER OfferCreateTransactor::takeOffers(
if (tesSUCCESS == terResult)
terResult = lesActive.accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid); // Taker pays offer owner.
// Reduce amount considered paid by taker's rate (not actual cost).
STAmount saTakerCould = saTakerPays - saTakerPaid; // Taker could pay.
if (saTakerFunds < saTakerCould)
saTakerCould = saTakerFunds;
if (!bSell)
{
// Buy semantics: Reduce amount considered paid by taker's rate. Not by actual cost which is lower.
// That is, take less as to just satify our buy requirement.
STAmount saTakerCould = saTakerPays - saTakerPaid; // Taker could pay.
if (saTakerFunds < saTakerCould)
saTakerCould = saTakerFunds;
STAmount saTakerUsed = STAmount::multiply(saSubTakerGot, saTakerRate, saTakerPays);
STAmount saTakerUsed = STAmount::multiply(saSubTakerGot, saTakerRate, saTakerPays);
cLog(lsINFO) << "takeOffers: applyOffer: saTakerCould: " << saTakerCould.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saSubTakerGot: " << saSubTakerGot.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saTakerRate: " << saTakerRate.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saTakerUsed: " << saTakerUsed.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saTakerCould: " << saTakerCould.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saSubTakerGot: " << saSubTakerGot.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saTakerRate: " << saTakerRate.getFullText();
cLog(lsINFO) << "takeOffers: applyOffer: saTakerUsed: " << saTakerUsed.getFullText();
saTakerPaid += std::min(saTakerCould, saTakerUsed);
saSubTakerPaid = std::min(saTakerCould, saTakerUsed);
}
saTakerPaid += saSubTakerPaid;
saTakerGot += saSubTakerGot;
if (tesSUCCESS == terResult)
@@ -362,6 +369,7 @@ TER OfferCreateTransactor::doApply()
const bool bPassive = isSetBit(uTxFlags, tfPassive);
const bool bImmediateOrCancel = isSetBit(uTxFlags, tfImmediateOrCancel);
const bool bFillOrKill = isSetBit(uTxFlags, tfFillOrKill);
const bool bSell = isSetBit(uTxFlags, tfSell);
STAmount saTakerPays = mTxn.getFieldAmount(sfTakerPays);
STAmount saTakerGets = mTxn.getFieldAmount(sfTakerGets);
@@ -498,12 +506,13 @@ TER OfferCreateTransactor::doApply()
terResult = takeOffers(
bOpenLedger,
bPassive,
bSell,
uTakeBookBase,
mTxnAccountID,
sleCreator,
saTakerGets, // Reverse as we are the taker for taking.
saTakerPays,
saPaid, // How much would have spent at full price.
saPaid, // Buy semantics: how much would have sold at full price. Sell semantics: how much was sold.
saGot, // How much was got.
bUnfunded);

View File

@@ -21,6 +21,7 @@ protected:
TER takeOffers(
const bool bOpenLedger,
const bool bPassive,
const bool bSell,
const uint256& uBookBase,
const uint160& uTakerAccountID,
SLE::ref sleTakerAccount,

View File

@@ -451,6 +451,7 @@ public:
// Someone is offering X for Y, I try to pay Z, how much do I get?
// And what's left of the offer? And how much do I actually pay?
static bool applyOffer(
const bool bSell,
const uint32 uTakerPaysRate, const uint32 uOfferPaysRate,
const STAmount& saOfferRate,
const STAmount& saOfferFunds, const STAmount& saTakerFunds,

View File

@@ -74,7 +74,8 @@ const uint32 tfAccountSetMask = ~(tfRequireDestTag|tfOptionalDestTag
const uint32 tfPassive = 0x00010000;
const uint32 tfImmediateOrCancel = 0x00020000;
const uint32 tfFillOrKill = 0x00040000;
const uint32 tfOfferCreateMask = ~(tfPassive|tfImmediateOrCancel|tfFillOrKill);
const uint32 tfSell = 0x00080000;
const uint32 tfOfferCreateMask = ~(tfPassive|tfImmediateOrCancel|tfFillOrKill|tfSell);
// Payment flags:
const uint32 tfNoRippleDirect = 0x00010000;