Handle rounding to zero on small offers.

This commit is contained in:
Arthur Britto
2013-01-26 20:48:33 -08:00
parent 0d9b76c802
commit ddf0a9e78b
2 changed files with 44 additions and 25 deletions

View File

@@ -14,6 +14,7 @@ SETUP_LOG();
// <-- saTakerPaid: What taker paid not including fees. To reduce an offer. // <-- saTakerPaid: What taker paid not including fees. To reduce an offer.
// <-- saTakerGot: What taker got 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 or terNO_ACCOUNT
// <-- bUnfunded: if tesSUCCESS, consider offer unfunded after taking.
TER OfferCreateTransactor::takeOffers( TER OfferCreateTransactor::takeOffers(
bool bPassive, bool bPassive,
const uint256& uBookBase, const uint256& uBookBase,
@@ -22,7 +23,8 @@ TER OfferCreateTransactor::takeOffers(
const STAmount& saTakerPays, const STAmount& saTakerPays,
const STAmount& saTakerGets, const STAmount& saTakerGets,
STAmount& saTakerPaid, STAmount& saTakerPaid,
STAmount& saTakerGot) STAmount& saTakerGot,
bool& bUnfunded)
{ {
assert(saTakerPays && saTakerGets); assert(saTakerPays && saTakerGets);
@@ -41,6 +43,7 @@ TER OfferCreateTransactor::takeOffers(
saTakerPaid = STAmount(saTakerPays.getCurrency(), saTakerPays.getIssuer()); saTakerPaid = STAmount(saTakerPays.getCurrency(), saTakerPays.getIssuer());
saTakerGot = STAmount(saTakerGets.getCurrency(), saTakerGets.getIssuer()); saTakerGot = STAmount(saTakerGets.getCurrency(), saTakerGets.getIssuer());
bUnfunded = false;
while (temUNCERTAIN == terResult) while (temUNCERTAIN == terResult)
{ {
@@ -191,42 +194,53 @@ TER OfferCreateTransactor::takeOffers(
if (bOfferDelete) if (bOfferDelete)
{ {
// Offer now fully claimed or now unfunded. // Offer now fully claimed or now unfunded.
cLog(lsINFO) << "takeOffers: offer claimed: delete"; cLog(lsINFO) << "takeOffers: Offer claimed: Delete.";
usOfferUnfundedBecame.insert(uOfferIndex); // Delete unfunded offer on success. usOfferUnfundedBecame.insert(uOfferIndex); // Delete unfunded offer on success.
// Offer owner's account is no longer pristine. // Offer owner's account is no longer pristine.
usAccountTouched.insert(uOfferOwnerID); usAccountTouched.insert(uOfferOwnerID);
} }
else if (saSubTakerGot)
{
cLog(lsINFO) << "takeOffers: Offer partial claim.";
}
else else
{ {
cLog(lsINFO) << "takeOffers: offer partial claim."; // Taker got nothing, probably due to rounding. Consider taker unfunded.
cLog(lsINFO) << "takeOffers: No claim.";
bUnfunded = true;
terResult = tesSUCCESS; // Done.
} }
assert(uTakerGetsAccountID == saSubTakerGot.getIssuer()); assert(uTakerGetsAccountID == saSubTakerGot.getIssuer());
assert(uTakerPaysAccountID == saSubTakerPaid.getIssuer()); assert(uTakerPaysAccountID == saSubTakerPaid.getIssuer());
// Offer owner pays taker. if (!bUnfunded)
// saSubTakerGot.setIssuer(uTakerGetsAccountID); // XXX Move this earlier? {
// Offer owner pays taker.
// saSubTakerGot.setIssuer(uTakerGetsAccountID); // XXX Move this earlier?
terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerAccountID, saSubTakerGot); terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerAccountID, saSubTakerGot);
if (tesSUCCESS == terResult) if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerGetsAccountID, saOfferIssuerFee); terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerGetsAccountID, saOfferIssuerFee);
// Taker pays offer owner. // Taker pays offer owner.
// saSubTakerPaid.setIssuer(uTakerPaysAccountID); // saSubTakerPaid.setIssuer(uTakerPaysAccountID);
if (tesSUCCESS == terResult) if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid); terResult = mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid);
if (tesSUCCESS == terResult) if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uTakerPaysAccountID, saTakerIssuerFee); terResult = mEngine->getNodes().accountSend(uTakerAccountID, uTakerPaysAccountID, saTakerIssuerFee);
saTakerGot += saSubTakerGot; saTakerGot += saSubTakerGot;
saTakerPaid += saSubTakerPaid; saTakerPaid += saSubTakerPaid;
if (tesSUCCESS == terResult) if (tesSUCCESS == terResult)
terResult = temUNCERTAIN; terResult = temUNCERTAIN;
}
} }
} }
} }
@@ -360,6 +374,7 @@ TER OfferCreateTransactor::doApply()
STAmount saOfferPaid; STAmount saOfferPaid;
STAmount saOfferGot; STAmount saOfferGot;
bool bUnfunded = false;
if (tesSUCCESS == terResult) if (tesSUCCESS == terResult)
{ {
@@ -380,8 +395,8 @@ TER OfferCreateTransactor::doApply()
saTakerGets, saTakerGets,
saTakerPays, saTakerPays,
saOfferPaid, // How much was spent. saOfferPaid, // How much was spent.
saOfferGot // How much was got. saOfferGot, // How much was got.
); bUnfunded);
cLog(lsWARNING) << "OfferCreate: takeOffers=" << terResult; cLog(lsWARNING) << "OfferCreate: takeOffers=" << terResult;
cLog(lsWARNING) << "OfferCreate: takeOffers: saOfferPaid=" << saOfferPaid.getFullText(); cLog(lsWARNING) << "OfferCreate: takeOffers: saOfferPaid=" << saOfferPaid.getFullText();
@@ -389,7 +404,7 @@ TER OfferCreateTransactor::doApply()
cLog(lsWARNING) << "OfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText(); cLog(lsWARNING) << "OfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText();
cLog(lsWARNING) << "OfferCreate: takeOffers: AFTER saTakerGets=" << saTakerGets.getFullText(); cLog(lsWARNING) << "OfferCreate: takeOffers: AFTER saTakerGets=" << saTakerGets.getFullText();
if (tesSUCCESS == terResult) if (tesSUCCESS == terResult && !bUnfunded)
{ {
saTakerPays -= saOfferGot; // Reduce payin from takers by what offer just got. saTakerPays -= saOfferGot; // Reduce payin from takers by what offer just got.
saTakerGets -= saOfferPaid; // Reduce payout to takers by what srcAccount just paid. saTakerGets -= saOfferPaid; // Reduce payout to takers by what srcAccount just paid.
@@ -407,7 +422,8 @@ TER OfferCreateTransactor::doApply()
if (tesSUCCESS != terResult if (tesSUCCESS != terResult
|| !saTakerPays // Wants nothing more. || !saTakerPays // Wants nothing more.
|| !saTakerGets // Offering nothing more. || !saTakerGets // Offering nothing more.
|| !mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive()) // Not funded. || !mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive() // Not funded.
|| bUnfunded) // Consider unfunded.
{ {
// Complete as is. // Complete as is.
nothing(); nothing();

View File

@@ -1,5 +1,7 @@
#include "Transactor.h" #ifndef __OFFERCREATETRANSACTOR__
#define __OFFERCREATETRANSACTOR__
#include "Transactor.h"
class OfferCreateTransactor : public Transactor class OfferCreateTransactor : public Transactor
{ {
@@ -11,12 +13,13 @@ class OfferCreateTransactor : public Transactor
const STAmount& saTakerPays, const STAmount& saTakerPays,
const STAmount& saTakerGets, const STAmount& saTakerGets,
STAmount& saTakerPaid, STAmount& saTakerPaid,
STAmount& saTakerGot); STAmount& saTakerGot,
bool& bUnfunded);
public: public:
OfferCreateTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {} OfferCreateTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
TER doApply(); TER doApply();
}; };
#endif
// vim:ts=4 // vim:ts=4