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.
// <-- saTakerGot: What taker got not including fees. To reduce an offer.
// <-- terResult: tesSUCCESS or terNO_ACCOUNT
// <-- bUnfunded: if tesSUCCESS, consider offer unfunded after taking.
TER OfferCreateTransactor::takeOffers(
bool bPassive,
const uint256& uBookBase,
@@ -22,7 +23,8 @@ TER OfferCreateTransactor::takeOffers(
const STAmount& saTakerPays,
const STAmount& saTakerGets,
STAmount& saTakerPaid,
STAmount& saTakerGot)
STAmount& saTakerGot,
bool& bUnfunded)
{
assert(saTakerPays && saTakerGets);
@@ -41,6 +43,7 @@ TER OfferCreateTransactor::takeOffers(
saTakerPaid = STAmount(saTakerPays.getCurrency(), saTakerPays.getIssuer());
saTakerGot = STAmount(saTakerGets.getCurrency(), saTakerGets.getIssuer());
bUnfunded = false;
while (temUNCERTAIN == terResult)
{
@@ -191,42 +194,53 @@ TER OfferCreateTransactor::takeOffers(
if (bOfferDelete)
{
// 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.
// Offer owner's account is no longer pristine.
usAccountTouched.insert(uOfferOwnerID);
}
else if (saSubTakerGot)
{
cLog(lsINFO) << "takeOffers: Offer partial claim.";
}
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(uTakerPaysAccountID == saSubTakerPaid.getIssuer());
// Offer owner pays taker.
// saSubTakerGot.setIssuer(uTakerGetsAccountID); // XXX Move this earlier?
if (!bUnfunded)
{
// 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)
terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerGetsAccountID, saOfferIssuerFee);
// Taker pays offer owner.
// saSubTakerPaid.setIssuer(uTakerPaysAccountID);
if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerGetsAccountID, saOfferIssuerFee);
// Taker pays offer owner.
// saSubTakerPaid.setIssuer(uTakerPaysAccountID);
if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid);
if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid);
if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uTakerPaysAccountID, saTakerIssuerFee);
if (tesSUCCESS == terResult)
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uTakerPaysAccountID, saTakerIssuerFee);
saTakerGot += saSubTakerGot;
saTakerPaid += saSubTakerPaid;
saTakerGot += saSubTakerGot;
saTakerPaid += saSubTakerPaid;
if (tesSUCCESS == terResult)
terResult = temUNCERTAIN;
if (tesSUCCESS == terResult)
terResult = temUNCERTAIN;
}
}
}
}
@@ -360,6 +374,7 @@ TER OfferCreateTransactor::doApply()
STAmount saOfferPaid;
STAmount saOfferGot;
bool bUnfunded = false;
if (tesSUCCESS == terResult)
{
@@ -380,8 +395,8 @@ TER OfferCreateTransactor::doApply()
saTakerGets,
saTakerPays,
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: saOfferPaid=" << saOfferPaid.getFullText();
@@ -389,7 +404,7 @@ TER OfferCreateTransactor::doApply()
cLog(lsWARNING) << "OfferCreate: takeOffers: saTakerPays=" << saTakerPays.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.
saTakerGets -= saOfferPaid; // Reduce payout to takers by what srcAccount just paid.
@@ -407,7 +422,8 @@ TER OfferCreateTransactor::doApply()
if (tesSUCCESS != terResult
|| !saTakerPays // Wants 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.
nothing();

View File

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