mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-25 05:25:55 +00:00
Add checking for invalid offers in ledger.
This commit is contained in:
@@ -152,6 +152,14 @@ TER OfferCreateTransactor::takeOffers(
|
|||||||
|
|
||||||
usOfferUnfundedFound.insert(uOfferIndex);
|
usOfferUnfundedFound.insert(uOfferIndex);
|
||||||
}
|
}
|
||||||
|
else if (!saOfferGets.isPositive() || !saOfferPays.isPositive())
|
||||||
|
{
|
||||||
|
// Offer has bad amounts. Consider offer expired. Delete it.
|
||||||
|
cLog(lsWARNING) << boost::str(boost::format("takeOffers: BAD OFFER: saOfferPays=%s saOfferGets=%s")
|
||||||
|
% saOfferPays % saOfferGets);
|
||||||
|
|
||||||
|
usOfferUnfundedFound.insert(uOfferIndex);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Get offer funds available.
|
// Get offer funds available.
|
||||||
|
|||||||
@@ -177,7 +177,8 @@ TER PaymentTransactor::doApply()
|
|||||||
bPartialPayment,
|
bPartialPayment,
|
||||||
bLimitQuality,
|
bLimitQuality,
|
||||||
bNoRippleDirect, // Always compute for finalizing ledger.
|
bNoRippleDirect, // Always compute for finalizing ledger.
|
||||||
false); // Not standalone, delete unfundeds.
|
false, // Not standalone, delete unfundeds.
|
||||||
|
isSetBit(mParams, tapOPEN_LEDGER));
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -909,6 +909,8 @@ TER RippleCalc::calcNodeAdvance(
|
|||||||
// Got a new offer.
|
// Got a new offer.
|
||||||
sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex);
|
sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex);
|
||||||
uOfrOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
uOfrOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
||||||
|
saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
||||||
|
saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
||||||
|
|
||||||
const aciSource asLine = boost::make_tuple(uOfrOwnerID, uCurCurrencyID, uCurIssuerID);
|
const aciSource asLine = boost::make_tuple(uOfrOwnerID, uCurCurrencyID, uCurIssuerID);
|
||||||
|
|
||||||
@@ -923,6 +925,16 @@ TER RippleCalc::calcNodeAdvance(
|
|||||||
bEntryAdvance = true;
|
bEntryAdvance = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (!saTakerPays.isPositive() || !saTakerGets.isPositive())
|
||||||
|
{
|
||||||
|
// Offer is has bad amounts.
|
||||||
|
cLog(lsWARNING) << boost::str(boost::format("calcNodeAdvance: NON-POSITIVE: saTakerPays=%s saTakerGets=%s")
|
||||||
|
% saTakerPays % saTakerGets);
|
||||||
|
|
||||||
|
assert(musUnfundedFound.find(uOfferIndex) != musUnfundedFound.end()); // Verify reverse found it too.
|
||||||
|
bEntryAdvance = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Allowed to access source from this node?
|
// Allowed to access source from this node?
|
||||||
// XXX This can get called multiple times for same source in a row, caching result would be nice.
|
// XXX This can get called multiple times for same source in a row, caching result would be nice.
|
||||||
@@ -964,9 +976,6 @@ TER RippleCalc::calcNodeAdvance(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
|
||||||
saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
|
||||||
|
|
||||||
saOfferFunds = lesActive.accountFunds(uOfrOwnerID, saTakerGets); // Funds left.
|
saOfferFunds = lesActive.accountFunds(uOfrOwnerID, saTakerGets); // Funds left.
|
||||||
|
|
||||||
if (!saOfferFunds.isPositive())
|
if (!saOfferFunds.isPositive())
|
||||||
@@ -1205,8 +1214,22 @@ TER RippleCalc::calcNodeDeliverRev(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Adjust offer
|
// Adjust offer
|
||||||
sleOffer->setFieldAmount(sfTakerGets, saTakerGets - saOutPass);
|
STAmount saTakerGetsNew = saTakerGets - saOutPass;
|
||||||
sleOffer->setFieldAmount(sfTakerPays, saTakerPays - saInPassAct);
|
STAmount saTakerPaysNew = saTakerPays - saInPassAct;
|
||||||
|
|
||||||
|
if (saTakerPaysNew.isNegative() || saTakerGetsNew.isNegative())
|
||||||
|
{
|
||||||
|
cLog(lsWARNING) << boost::str(boost::format("calcNodeDeliverRev: NEGATIVE: saTakerPaysNew=%s saTakerGetsNew=%s")
|
||||||
|
% saTakerPaysNew % saTakerGetsNew);
|
||||||
|
|
||||||
|
terResult = mOpenLedger
|
||||||
|
? telFAILED_PROCESSING // Ledger is not final, can vote no.
|
||||||
|
: tecFAILED_PROCESSING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleOffer->setFieldAmount(sfTakerGets, saTakerGetsNew);
|
||||||
|
sleOffer->setFieldAmount(sfTakerPays, saTakerPaysNew);
|
||||||
|
|
||||||
lesActive.entryModify(sleOffer);
|
lesActive.entryModify(sleOffer);
|
||||||
|
|
||||||
@@ -1399,8 +1422,22 @@ TER RippleCalc::calcNodeDeliverFwd(
|
|||||||
|
|
||||||
// Adjust offer
|
// Adjust offer
|
||||||
// Fees are considered paid from a seperate budget and are not named in the offer.
|
// Fees are considered paid from a seperate budget and are not named in the offer.
|
||||||
sleOffer->setFieldAmount(sfTakerGets, saTakerGets - saOutPassAct);
|
STAmount saTakerGetsNew = saTakerGets - saOutPassAct;
|
||||||
sleOffer->setFieldAmount(sfTakerPays, saTakerPays - saInPassAct);
|
STAmount saTakerPaysNew = saTakerPays - saInPassAct;
|
||||||
|
|
||||||
|
if (saTakerPaysNew.isNegative() || saTakerGetsNew.isNegative())
|
||||||
|
{
|
||||||
|
cLog(lsWARNING) << boost::str(boost::format("calcNodeDeliverFwd: NEGATIVE: saTakerPaysNew=%s saTakerGetsNew=%s")
|
||||||
|
% saTakerPaysNew % saTakerGetsNew);
|
||||||
|
|
||||||
|
terResult = mOpenLedger
|
||||||
|
? telFAILED_PROCESSING // Ledger is not final, can vote no.
|
||||||
|
: tecFAILED_PROCESSING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleOffer->setFieldAmount(sfTakerGets, saTakerGetsNew);
|
||||||
|
sleOffer->setFieldAmount(sfTakerPays, saTakerPaysNew);
|
||||||
|
|
||||||
lesActive.entryModify(sleOffer);
|
lesActive.entryModify(sleOffer);
|
||||||
|
|
||||||
@@ -2431,10 +2468,11 @@ TER RippleCalc::rippleCalc(
|
|||||||
const bool bPartialPayment,
|
const bool bPartialPayment,
|
||||||
const bool bLimitQuality,
|
const bool bLimitQuality,
|
||||||
const bool bNoRippleDirect,
|
const bool bNoRippleDirect,
|
||||||
const bool bStandAlone // True, not to delete unfundeds.
|
const bool bStandAlone, // True, not to delete unfundeds.
|
||||||
|
const bool bOpenLedger
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
RippleCalc rc(lesActive);
|
RippleCalc rc(lesActive, bOpenLedger);
|
||||||
|
|
||||||
TER terResult = temUNCERTAIN;
|
TER terResult = temUNCERTAIN;
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ class RippleCalc
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
LedgerEntrySet& lesActive;
|
LedgerEntrySet& lesActive;
|
||||||
|
bool mOpenLedger;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// First time working in reverse a funding source was mentioned. Source may only be used there.
|
// First time working in reverse a funding source was mentioned. Source may only be used there.
|
||||||
@@ -192,7 +193,8 @@ public:
|
|||||||
STAmount& saPrvAct, STAmount& saCurAct,
|
STAmount& saPrvAct, STAmount& saCurAct,
|
||||||
uint64& uRateMax);
|
uint64& uRateMax);
|
||||||
|
|
||||||
RippleCalc(LedgerEntrySet& lesNodes) : lesActive(lesNodes) { ; }
|
RippleCalc(LedgerEntrySet& lesNodes, const bool bOpenLedger)
|
||||||
|
: lesActive(lesNodes), mOpenLedger(bOpenLedger) { ; }
|
||||||
|
|
||||||
static TER rippleCalc(
|
static TER rippleCalc(
|
||||||
LedgerEntrySet& lesActive,
|
LedgerEntrySet& lesActive,
|
||||||
@@ -207,7 +209,8 @@ public:
|
|||||||
const bool bPartialPayment,
|
const bool bPartialPayment,
|
||||||
const bool bLimitQuality,
|
const bool bLimitQuality,
|
||||||
const bool bNoRippleDirect,
|
const bool bNoRippleDirect,
|
||||||
const bool bStandAlone
|
const bool bStandAlone,
|
||||||
|
const bool bOpenLedger = true
|
||||||
);
|
);
|
||||||
|
|
||||||
static void setCanonical(STPathSet& spsDst, const std::vector<PathState::pointer>& vpsExpanded, bool bKeepDefault);
|
static void setCanonical(STPathSet& spsDst, const std::vector<PathState::pointer>& vpsExpanded, bool bKeepDefault);
|
||||||
|
|||||||
Reference in New Issue
Block a user