From f95c39e1c522308ec2da1052371fff1e4bb93acb Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Mar 2013 17:28:44 -0800 Subject: [PATCH] Fixes for resulting negative offers. --- src/cpp/ripple/OfferCreateTransactor.cpp | 45 +++++++++++++++--------- src/cpp/ripple/OfferCreateTransactor.h | 3 +- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/cpp/ripple/OfferCreateTransactor.cpp b/src/cpp/ripple/OfferCreateTransactor.cpp index 225d376c7a..ce1206d358 100644 --- a/src/cpp/ripple/OfferCreateTransactor.cpp +++ b/src/cpp/ripple/OfferCreateTransactor.cpp @@ -11,12 +11,13 @@ SETUP_LOG(); // --> uBookBase: The order book to take against. // --> saTakerPays: What the taker offers (w/ issuer) // --> saTakerGets: What the taker wanted (w/ issuer) -// <-- saTakerPaid: What taker paid including saved not including fees. To reduce an offer. +// <-- saTakerPaid: What taker could have paid including saved not including fees. To reduce an offer. // <-- saTakerGot: What taker got not including fees. To reduce an offer. -// <-- terResult: tesSUCCESS or terNO_ACCOUNT +// <-- terResult: tesSUCCESS, terNO_ACCOUNT, telFAILED_PROCESSING, or tecFAILED_PROCESSING // <-- bUnfunded: if tesSUCCESS, consider offer unfunded after taking. TER OfferCreateTransactor::takeOffers( - bool bPassive, + const bool bOpenLedger, + const bool bPassive, const uint256& uBookBase, const uint160& uTakerAccountID, SLE::ref sleTakerAccount, @@ -58,11 +59,13 @@ TER OfferCreateTransactor::takeOffers( SLE::pointer sleOfferDir; uint64 uTipQuality = 0; STAmount saTakerFunds = mEngine->getNodes().accountFunds(uTakerAccountID, saTakerPays); + STAmount saSubTakerPays = saTakerPays-saTakerPaid; // How much more to spend. + STAmount saSubTakerGets = saTakerGets-saTakerGot; // How much more is wanted. // Figure out next offer to take, if needed. if (saTakerFunds // Taker has funds available. - && saTakerGot < saTakerGets // Have less than wanted. - && saTakerPaid < saTakerPays) // Didn't spend all funds allocated. + && saSubTakerPays.isPositive() + && saSubTakerGets.isPositive()) { sleOfferDir = mEngine->entryCache(ltDIR_NODE, mEngine->getLedger()->getNextLedgerIndex(uTipIndex, uBookEnd)); if (sleOfferDir) @@ -201,6 +204,8 @@ TER OfferCreateTransactor::takeOffers( cLog(lsINFO) << "takeOffers: applyOffer: saOfferPays: " << saOfferPays.getFullText(); cLog(lsINFO) << "takeOffers: applyOffer: saOfferGets: " << saOfferGets.getFullText(); cLog(lsINFO) << "takeOffers: applyOffer: saOfferRate: " << saOfferRate.getFullText(); + cLog(lsINFO) << "takeOffers: applyOffer: saSubTakerPays: " << saSubTakerPays.getFullText(); + cLog(lsINFO) << "takeOffers: applyOffer: saSubTakerGets: " << saSubTakerGets.getFullText(); cLog(lsINFO) << "takeOffers: applyOffer: saTakerPays: " << saTakerPays.getFullText(); cLog(lsINFO) << "takeOffers: applyOffer: saTakerGets: " << saTakerGets.getFullText(); @@ -212,8 +217,8 @@ TER OfferCreateTransactor::takeOffers( saTakerFunds, saOfferPays, saOfferGets, - saTakerPays, - saTakerGets, + saSubTakerPays, + saSubTakerGets, saSubTakerPaid, saSubTakerGot, saTakerIssuerFee, @@ -245,6 +250,13 @@ TER OfferCreateTransactor::takeOffers( else if (saSubTakerGot) { cLog(lsINFO) << "takeOffers: Offer partial claim."; + + if (!saOfferPays.isPositive() || !saOfferGets.isPositive()) + { + cLog(lsWARNING) << "takeOffers: ILLEGAL OFFER RESULT."; + bUnfunded = true; + terResult = bOpenLedger ? telFAILED_PROCESSING : tecFAILED_PROCESSING; + } } else { @@ -268,18 +280,18 @@ TER OfferCreateTransactor::takeOffers( terResult = mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid); // Taker pays offer owner. // Reduce amount considered paid by taker's rate (not actual cost). - STAmount saPay = saTakerPays - saTakerPaid; - if (saTakerFunds < saPay) - saPay = saTakerFunds; + STAmount saTakerCould = saTakerPays - saTakerPaid; // Taker could pay. + if (saTakerFunds < saTakerCould) + saTakerCould = saTakerFunds; STAmount saTakerUsed = STAmount::multiply(saSubTakerGot, saTakerRate, saTakerPays); - cLog(lsINFO) << "takeOffers: applyOffer: saPay: " << saPay.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(saPay, saTakerUsed); + saTakerPaid += std::min(saTakerCould, saTakerUsed); saTakerGot += saSubTakerGot; if (tesSUCCESS == terResult) @@ -420,6 +432,7 @@ TER OfferCreateTransactor::doApply() STAmount saPaid; STAmount saGot; bool bUnfunded = false; + const bool bOpenLedger = isSetBit(mParams, tapOPEN_LEDGER); if (tesSUCCESS == terResult) { @@ -434,6 +447,7 @@ TER OfferCreateTransactor::doApply() cLog(lsWARNING) << "OfferCreate: takeOffers: BEFORE saTakerGets=" << saTakerGets.getFullText(); terResult = takeOffers( + bOpenLedger, bPassive, uTakeBookBase, mTxnAccountID, @@ -473,9 +487,8 @@ TER OfferCreateTransactor::doApply() } else if (saTakerPays.isNegative() || saTakerGets.isNegative()) { - terResult = isSetBit(mParams, tapOPEN_LEDGER) - ? telFAILED_PROCESSING // Ledger is not final, can vote no. - : tecFAILED_PROCESSING; + // If ledger is not final, can vote no. + terResult = bOpenLedger ? telFAILED_PROCESSING : tecFAILED_PROCESSING; } else if ( !saTakerPays // Wants nothing more. @@ -489,7 +502,7 @@ TER OfferCreateTransactor::doApply() } else if (mPriorBalance.getNValue() < mEngine->getLedger()->getReserve(mTxnAccount->getFieldU32(sfOwnerCount)+1)) { - if (isSetBit(mParams, tapOPEN_LEDGER)) // Ledger is not final, can vote no. + if (bOpenLedger) // Ledger is not final, can vote no. { // Hope for more reserve to come in or more offers to consume. terResult = tecINSUF_RESERVE_OFFER; diff --git a/src/cpp/ripple/OfferCreateTransactor.h b/src/cpp/ripple/OfferCreateTransactor.h index ad16717355..a5c3a8d3d9 100644 --- a/src/cpp/ripple/OfferCreateTransactor.h +++ b/src/cpp/ripple/OfferCreateTransactor.h @@ -6,7 +6,8 @@ class OfferCreateTransactor : public Transactor { TER takeOffers( - bool bPassive, + const bool bOpenLedger, + const bool bPassive, const uint256& uBookBase, const uint160& uTakerAccountID, SLE::ref sleTakerAccount,