From c07b28c89948233ff0d912468d6be8cd160172a0 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Tue, 6 Aug 2013 09:41:48 -0700 Subject: [PATCH] Offer fix rollup: Fix a case where an offer is not detected becoming unfunded. Make sure we skip unfunded offers in calcNodeDeliverFwd. Issuer of TakerGets can always trade (since funds are unlimited). Enable multi-quality until some funds move. Don't let a placed offer take an expired crossing offer. --- modules/ripple_app/paths/ripple_RippleCalc.cpp | 14 +++++++------- modules/ripple_app/tx/OfferCreateTransactor.cpp | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/ripple_app/paths/ripple_RippleCalc.cpp b/modules/ripple_app/paths/ripple_RippleCalc.cpp index 55fec68c5..e96635879 100644 --- a/modules/ripple_app/paths/ripple_RippleCalc.cpp +++ b/modules/ripple_app/paths/ripple_RippleCalc.cpp @@ -237,7 +237,7 @@ TER RippleCalc::calcNodeAdvance ( // Only a allow a source to be used once, in the first node encountered from initial path scan. // This prevents conflicting uses of the same balance when going reverse vs forward. - if (bFoundForward && itForward->second != uNode) + if (bFoundForward && (itForward->second != uNode) && (uOfrOwnerID != uCurIssuerID)) { // Temporarily unfunded. Another node uses this source, ignore in this offer. WriteLog (lsTRACE, RippleCalc) << "calcNodeAdvance: temporarily unfunded offer (forward)"; @@ -250,7 +250,7 @@ TER RippleCalc::calcNodeAdvance ( // For this quality increment, only allow a source to be used from a single node, in the first node encountered from applying offers // in reverse. - if (bFoundReverse && itReverse->second != uNode) + if (bFoundReverse && (itReverse->second != uNode) && (uOfrOwnerID != uCurIssuerID)) { // Temporarily unfunded. Another node uses this source, ignore in this offer. WriteLog (lsTRACE, RippleCalc) << "calcNodeAdvance: temporarily unfunded offer (reverse)"; @@ -381,7 +381,7 @@ TER RippleCalc::calcNodeDeliverRev ( STAmount& saTakerGets = pnCur.saTakerGets; STAmount& saRateMax = pnCur.saRateMax; - terResult = calcNodeAdvance (uNode, psCur, bMultiQuality, true); // If needed, advance to next funded offer. + terResult = calcNodeAdvance (uNode, psCur, bMultiQuality || saOutAct.isZero(), true); // If needed, advance to next funded offer. if (tesSUCCESS != terResult || !uOfferIndex) { @@ -481,7 +481,7 @@ TER RippleCalc::calcNodeDeliverRev ( if (saInPassReq > saTakerPays) saInPassReq = saTakerPays; - if (!saInPassReq) + if (!saInPassReq) // FIXME: This is bogus { // After rounding did not want anything. WriteLog (lsINFO, RippleCalc) << boost::str (boost::format ("calcNodeDeliverRev: micro offer is unfunded.")); @@ -656,7 +656,7 @@ TER RippleCalc::calcNodeDeliverFwd ( } // Determine values for pass to adjust saInAct, saInFees, and saCurDeliverAct - terResult = calcNodeAdvance (uNode, psCur, bMultiQuality, false); // If needed, advance to next funded offer. + terResult = calcNodeAdvance (uNode, psCur, bMultiQuality || saInAct.isZero(), false); // If needed, advance to next funded offer. if (tesSUCCESS != terResult) { @@ -717,7 +717,7 @@ TER RippleCalc::calcNodeDeliverFwd ( % saInPassAct % saOutPassMax); - if (!saInSum) + if (!saTakerPays || !saInSum) // FIXME: We remove an offer if WE didn't want anything out of it? { WriteLog (lsINFO, RippleCalc) << "calcNodeDeliverFwd: Microscopic offer unfunded."; @@ -850,7 +850,7 @@ TER RippleCalc::calcNodeDeliverFwd ( lesActive.entryModify (sleOffer); - if (saOutPassAct == saOutFunded) + if ((saOutPassAct == saOutFunded) || saTakerGetsNew.isZero()) { // Offer became unfunded. diff --git a/modules/ripple_app/tx/OfferCreateTransactor.cpp b/modules/ripple_app/tx/OfferCreateTransactor.cpp index 23ea51bca..2d86a7d07 100644 --- a/modules/ripple_app/tx/OfferCreateTransactor.cpp +++ b/modules/ripple_app/tx/OfferCreateTransactor.cpp @@ -8,7 +8,7 @@ SETUP_LOG (OfferCreateTransactor) // Make sure an offer is still valid. If not, mark it unfunded. bool OfferCreateTransactor::bValidOffer ( - SLE::ref sleOfferDir, + SLE::ref sleOffer, uint256 const& uOfferIndex, const uint160& uOfferOwnerID, const STAmount& saOfferPays, @@ -21,7 +21,7 @@ bool OfferCreateTransactor::bValidOffer ( { bool bValid = false; - if (sleOfferDir->isFieldPresent (sfExpiration) && sleOfferDir->getFieldU32 (sfExpiration) <= mEngine->getLedger ()->getParentCloseTimeNC ()) + if (sleOffer->isFieldPresent (sfExpiration) && sleOffer->getFieldU32 (sfExpiration) <= mEngine->getLedger ()->getParentCloseTimeNC ()) { // Offer is expired. Expired offers are considered unfunded. Delete it. WriteLog (lsINFO, OfferCreateTransactor) << "bValidOffer: encountered expired offer"; @@ -224,7 +224,7 @@ TER OfferCreateTransactor::takeOffers ( bool bValid; bValid = bValidOffer ( - sleOfferDir, uOfferIndex, uOfferOwnerID, saOfferPays, saOfferGets, + sleOffer, uOfferIndex, uOfferOwnerID, saOfferPays, saOfferGets, uTakerAccountID, usOfferUnfundedFound, usOfferUnfundedBecame, usAccountTouched, saOfferFunds);