mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-02 17:06:00 +00:00
Fix RPC book_offers handling of negative balances and self-issued IOUs.
This commit is contained in:
@@ -1784,7 +1784,16 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays
|
|||||||
STAmount saDirRate;
|
STAmount saDirRate;
|
||||||
|
|
||||||
// unsigned int iLeft = iLimit;
|
// unsigned int iLeft = iLimit;
|
||||||
|
SLE::pointer sleGetsIssuer = lesActive.entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uTakerGetsIssuerID));
|
||||||
|
|
||||||
|
if (!sleGetsIssuer)
|
||||||
|
{
|
||||||
|
// Order book can not exist if TakerGetsIssuer account does not exist.
|
||||||
|
|
||||||
|
nothing();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while (!bDone) {
|
while (!bDone) {
|
||||||
if (bDirectAdvance) {
|
if (bDirectAdvance) {
|
||||||
bDirectAdvance = false;
|
bDirectAdvance = false;
|
||||||
@@ -1814,27 +1823,36 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays
|
|||||||
{
|
{
|
||||||
SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex);
|
SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex);
|
||||||
const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
||||||
|
STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
||||||
|
STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
||||||
STAmount saOwnerFunds;
|
STAmount saOwnerFunds;
|
||||||
|
|
||||||
boost::unordered_map<uint160, STAmount>::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID);
|
if (uTakerGetsIssuerID == uOfferOwnerID)
|
||||||
|
|
||||||
if (umBalanceEntry == umBalance.end())
|
|
||||||
{
|
{
|
||||||
// Did not find balance in table.
|
// If offer is selling issuer's own IOUs, it is fully funded.
|
||||||
STAmount saDefault(uTakerGetsCurrencyID, uTakerGetsIssuerID);
|
saOwnerFunds = saTakerGets;
|
||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saDefault=%s") % saDefault.getFullText());
|
|
||||||
|
|
||||||
saOwnerFunds = lesActive.accountFunds(uOfferOwnerID, saDefault);
|
|
||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
boost::unordered_map<uint160, STAmount>::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID);
|
||||||
|
|
||||||
|
if (umBalanceEntry != umBalance.end())
|
||||||
|
{
|
||||||
|
// Found in running balance table.
|
||||||
|
|
||||||
saOwnerFunds = umBalanceEntry->second;
|
saOwnerFunds = umBalanceEntry->second;
|
||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText());
|
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Did not find balance in table.
|
||||||
|
|
||||||
STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
saOwnerFunds = lesActive.accountHolds(uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID);
|
||||||
STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText());
|
||||||
|
if (saOwnerFunds.isNegative())
|
||||||
|
saOwnerFunds.zero();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Json::Value jvOffer = sleOffer->getJson(0);
|
Json::Value jvOffer = sleOffer->getJson(0);
|
||||||
|
|
||||||
@@ -1883,6 +1901,7 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jvResult["offers"] = jvOffers;
|
jvResult["offers"] = jvOffers;
|
||||||
// jvResult["marker"] = Json::Value(Json::arrayValue);
|
// jvResult["marker"] = Json::Value(Json::arrayValue);
|
||||||
|
|||||||
Reference in New Issue
Block a user