mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Work toward rippling through offers.
This commit is contained in:
@@ -754,7 +754,16 @@ uint256 Ledger::getBookBase(const uint160& uTakerPaysCurrency, const uint160& uT
|
||||
s.add160(uTakerPaysIssuerID); // 20
|
||||
s.add160(uTakerGetsIssuerID); // 20
|
||||
|
||||
return getQualityIndex(s.getSHA512Half()); // Return with quality 0.
|
||||
uint256 uBaseIndex = getQualityIndex(s.getSHA512Half()); // Return with quality 0.
|
||||
|
||||
Log(lsINFO) << str(boost::format("getBookBase(%s,%s,%s,%s) = %s")
|
||||
% STAmount::createHumanCurrency(uTakerPaysCurrency)
|
||||
% NewcoinAddress::createHumanAccountID(uTakerPaysIssuerID)
|
||||
% STAmount::createHumanCurrency(uTakerGetsCurrency)
|
||||
% NewcoinAddress::createHumanAccountID(uTakerGetsIssuerID)
|
||||
% uBaseIndex.ToString());
|
||||
|
||||
return uBaseIndex;
|
||||
}
|
||||
|
||||
uint256 Ledger::getDirNodeIndex(const uint256& uDirRoot, const uint64 uNodeIndex)
|
||||
|
||||
@@ -261,8 +261,8 @@ public:
|
||||
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
|
||||
{ ; }
|
||||
|
||||
STAmount(const uint160& currency, uint64 v = 0, int off = 0)
|
||||
: mCurrency(currency), mValue(v), mOffset(off), mIsNegative(false)
|
||||
STAmount(const uint160& uCurrency, uint64 uV=0, int iOff=0, bool bNegative=false)
|
||||
: mCurrency(uCurrency), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
|
||||
{ canonicalize(); }
|
||||
|
||||
STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0, bool isNeg = false) :
|
||||
@@ -274,6 +274,16 @@ public:
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
static STAmount saFromRate(uint64 uV = 0)
|
||||
{
|
||||
return STAmount(CURRENCY_ONE, uV, -9, false);
|
||||
}
|
||||
|
||||
static STAmount saFromSigned(const uint160& uCurrency, int64 iV=0, int iOff=0)
|
||||
{
|
||||
return STAmount(uCurrency, iV < 0 ? -iV : iV, iOff, iV < 0);
|
||||
}
|
||||
|
||||
int getLength() const { return mIsNative ? 8 : 28; }
|
||||
SerializedTypeID getSType() const { return STI_AMOUNT; }
|
||||
std::string getText() const;
|
||||
|
||||
@@ -149,15 +149,25 @@ uint32 TransactionEngine::rippleTransferRate(const uint160& uIssuerID)
|
||||
{
|
||||
SLE::pointer sleAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uIssuerID));
|
||||
|
||||
return sleAccount->getIFieldPresent(sfTransferRate)
|
||||
? sleAccount->getIFieldU32(sfTransferRate)
|
||||
: QUALITY_ONE;
|
||||
uint32 uQuality = sleAccount && sleAccount->getIFieldPresent(sfTransferRate)
|
||||
? sleAccount->getIFieldU32(sfTransferRate)
|
||||
: QUALITY_ONE;
|
||||
|
||||
Log(lsINFO) << str(boost::format("rippleTransferRate: uIssuerID=%s account_exists=%d transfer_rate=%f")
|
||||
% NewcoinAddress::createHumanAccountID(uIssuerID)
|
||||
% !!sleAccount
|
||||
% (uQuality/1000000000.0));
|
||||
|
||||
assert(sleAccount);
|
||||
|
||||
return uQuality;
|
||||
}
|
||||
|
||||
// XXX Might not need this, might store in nodes on calc reverse.
|
||||
uint32 TransactionEngine::rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID)
|
||||
{
|
||||
uint32 uQualityIn = QUALITY_ONE;
|
||||
uint32 uQualityIn = QUALITY_ONE;
|
||||
SLE::pointer sleRippleState;
|
||||
|
||||
if (uToAccountID == uFromAccountID)
|
||||
{
|
||||
@@ -165,7 +175,7 @@ uint32 TransactionEngine::rippleQualityIn(const uint160& uToAccountID, const uin
|
||||
}
|
||||
else
|
||||
{
|
||||
SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(uToAccountID, uFromAccountID, uCurrencyID));
|
||||
sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(uToAccountID, uFromAccountID, uCurrencyID));
|
||||
|
||||
if (sleRippleState)
|
||||
{
|
||||
@@ -177,12 +187,17 @@ uint32 TransactionEngine::rippleQualityIn(const uint160& uToAccountID, const uin
|
||||
if (!uQualityIn)
|
||||
uQualityIn = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsINFO) << str(boost::format("rippleQualityIn: uToAccountID=%s uFromAccountID=%s uCurrencyID=%s bLine=%d uQualityIn=%f")
|
||||
% NewcoinAddress::createHumanAccountID(uToAccountID)
|
||||
% NewcoinAddress::createHumanAccountID(uFromAccountID)
|
||||
% STAmount::createHumanCurrency(uCurrencyID)
|
||||
% !!sleRippleState
|
||||
% (uQualityIn/1000000000.0));
|
||||
|
||||
assert(uToAccountID == uFromAccountID || !!sleRippleState);
|
||||
|
||||
return uQualityIn;
|
||||
}
|
||||
|
||||
@@ -1915,18 +1930,30 @@ bool TransactionEngine::calcNodeOfferRev(
|
||||
const uint160& uNxtIssuerID = pnNxt.uIssuerID;
|
||||
const uint160& uNxtAccountID = pnNxt.uAccountID;
|
||||
|
||||
const STAmount saTransferRate = STAmount(CURRENCY_ONE, rippleTransferRate(uCurIssuerID), -9);
|
||||
const STAmount saTransferRate = STAmount::saFromRate(rippleTransferRate(uCurIssuerID));
|
||||
|
||||
uint256 uDirectTip = Ledger::getBookBase(uPrvCurrencyID, uPrvIssuerID, uCurCurrencyID, uCurIssuerID);
|
||||
const uint256 uDirectEnd = Ledger::getQualityNext(uDirectTip);
|
||||
bool bAdvance = !entryCache(ltDIR_NODE, uDirectTip);
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNodeOfferRev> uIndex=%d prv=%s/%s cur=%s/%s nxt=%s/%s saTransferRate=%s")
|
||||
% uIndex
|
||||
% STAmount::createHumanCurrency(uPrvCurrencyID)
|
||||
% NewcoinAddress::createHumanAccountID(uPrvIssuerID)
|
||||
% STAmount::createHumanCurrency(uCurCurrencyID)
|
||||
% NewcoinAddress::createHumanAccountID(uCurIssuerID)
|
||||
% STAmount::createHumanCurrency(uNxtCurrencyID)
|
||||
% NewcoinAddress::createHumanAccountID(uNxtIssuerID)
|
||||
% saTransferRate.getText());
|
||||
|
||||
STAmount& saPrvDlvReq = pnPrv.saRevDeliver; // To be adjusted.
|
||||
STAmount saPrvDlvAct;
|
||||
|
||||
const STAmount& saCurDlvReq = pnCur.saRevDeliver; // Reverse driver.
|
||||
STAmount saCurDlvAct;
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNodeOfferRev: uDirectTip=%s") % uDirectTip.ToString());
|
||||
|
||||
while (!!uDirectTip // Have a quality.
|
||||
&& saCurDlvAct != saCurDlvReq)
|
||||
{
|
||||
@@ -1934,6 +1961,8 @@ bool TransactionEngine::calcNodeOfferRev(
|
||||
if (bAdvance)
|
||||
{
|
||||
uDirectTip = mLedger->getNextLedgerIndex(uDirectTip, uDirectEnd);
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNodeOfferRev: uDirectTip=%s") % uDirectTip.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1953,6 +1982,8 @@ bool TransactionEngine::calcNodeOfferRev(
|
||||
while (saCurDlvReq != saCurDlvAct // Have not met request.
|
||||
&& dirNext(uDirectTip, sleDirectDir, uEntry, uCurIndex))
|
||||
{
|
||||
Log(lsINFO) << str(boost::format("calcNodeOfferRev: uCurIndex=%s") % uCurIndex.ToString());
|
||||
|
||||
SLE::pointer sleCurOfr = entryCache(ltOFFER, uCurIndex);
|
||||
uint160 uCurOfrAccountID = sleCurOfr->getIValueFieldAccount(sfAccount).getAccountID();
|
||||
STAmount saCurOfrOutReq = sleCurOfr->getIValueFieldAmount(sfTakerGets);
|
||||
@@ -2085,6 +2116,11 @@ bool TransactionEngine::calcNodeOfferRev(
|
||||
bSuccess = true;
|
||||
}
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNodeOfferRev< uIndex=%d saPrvDlvReq=%s bSuccess=%d")
|
||||
% uIndex
|
||||
% saPrvDlvReq.getText()
|
||||
% bSuccess);
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
@@ -2108,7 +2144,7 @@ bool TransactionEngine::calcNodeOfferFwd(
|
||||
const uint160& uNxtIssuerID = pnNxt.uIssuerID;
|
||||
|
||||
const uint160& uNxtAccountID = pnNxt.uAccountID;
|
||||
const STAmount saTransferRate = STAmount(CURRENCY_ONE, rippleTransferRate(uCurIssuerID), -9);
|
||||
const STAmount saTransferRate = STAmount::saFromRate(rippleTransferRate(uCurIssuerID));
|
||||
|
||||
uint256 uDirectTip = Ledger::getBookBase(uPrvCurrencyID, uPrvIssuerID, uCurCurrencyID, uCurIssuerID);
|
||||
const uint256 uDirectEnd = Ledger::getQualityNext(uDirectTip);
|
||||
@@ -2601,8 +2637,8 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
|
||||
const bool bPrvAccount = !uIndex || !!(pnPrv.uFlags & STPathElement::typeAccount);
|
||||
const bool bNxtAccount = uIndex == uLast || !!(pnNxt.uFlags & STPathElement::typeAccount);
|
||||
|
||||
const uint160& uPrvAccountID = pnPrv.uAccountID;
|
||||
const uint160& uCurAccountID = pnCur.uAccountID;
|
||||
const uint160& uPrvAccountID = bPrvAccount ? pnPrv.uAccountID : uCurAccountID;
|
||||
const uint160& uNxtAccountID = bNxtAccount ? pnNxt.uAccountID : uCurAccountID; // Offers are always issue.
|
||||
|
||||
const uint160& uCurrencyID = pnCur.uCurrencyID;
|
||||
@@ -2614,6 +2650,18 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
|
||||
const STAmount saPrvBalance = uIndex && bPrvAccount ? rippleBalance(uCurAccountID, uPrvAccountID, uCurrencyID) : STAmount(uCurrencyID);
|
||||
const STAmount saPrvLimit = uIndex && bPrvAccount ? rippleLimit(uCurAccountID, uPrvAccountID, uCurrencyID) : STAmount(uCurrencyID);
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNodeAccountRev> uIndex=%d/%d uPrvAccountID=%s uCurAccountID=%s uNxtAccountID=%s uCurrencyID=%s uQualityIn=%d uQualityOut=%d saPrvBalance=%s saPrvLimit=%s")
|
||||
% uIndex
|
||||
% uLast
|
||||
% NewcoinAddress::createHumanAccountID(uPrvAccountID)
|
||||
% NewcoinAddress::createHumanAccountID(uCurAccountID)
|
||||
% NewcoinAddress::createHumanAccountID(uNxtAccountID)
|
||||
% STAmount::createHumanCurrency(uCurrencyID)
|
||||
% uQualityIn
|
||||
% uQualityOut
|
||||
% saPrvBalance.getText()
|
||||
% saPrvLimit.getText());
|
||||
|
||||
const STAmount saPrvRedeemReq = bPrvRedeem && saPrvBalance.isNegative() ? -saPrvBalance : STAmount(uCurrencyID, 0);
|
||||
STAmount& saPrvRedeemAct = pnPrv.saRevRedeem;
|
||||
|
||||
@@ -2621,7 +2669,7 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
|
||||
STAmount& saPrvIssueAct = pnPrv.saRevIssue;
|
||||
|
||||
// For !bPrvAccount
|
||||
const STAmount saPrvDeliverReq = STAmount(uCurrencyID, -1); // Unlimited.
|
||||
const STAmount saPrvDeliverReq = STAmount::saFromSigned(uCurrencyID, -1); // Unlimited.
|
||||
STAmount& saPrvDeliverAct = pnPrv.saRevDeliver;
|
||||
|
||||
// For bNxtAccount
|
||||
@@ -2629,20 +2677,18 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
|
||||
STAmount saCurRedeemAct(saCurRedeemReq.getCurrency());
|
||||
|
||||
const STAmount& saCurIssueReq = pnCur.saRevIssue;
|
||||
STAmount saCurIssueAct(saCurIssueReq.getCurrency()); // Track progress.
|
||||
STAmount saCurIssueAct(saCurIssueReq.getCurrency()); // Track progress.
|
||||
|
||||
// For !bNxtAccount
|
||||
const STAmount& saCurDeliverReq = pnCur.saRevDeliver;
|
||||
STAmount saCurDeliverAct(saCurDeliverReq.getCurrency());
|
||||
|
||||
// For uIndex == uLast
|
||||
const STAmount& saCurWantedReq = pspCur->saOutReq; // XXX Credit limits?
|
||||
const STAmount& saCurWantedReq = pspCur->saOutReq; // XXX Credit limits?
|
||||
// STAmount saPrvDeliverReq = saPrvBalance.isPositive() ? saPrvLimit - saPrvBalance : saPrvLimit;
|
||||
STAmount saCurWantedAct(saCurWantedReq.getCurrency());
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNodeAccountRev> uIndex=%d/%d saPrvRedeemReq=%s/%s saPrvIssueReq=%s/%s saCurWantedReq=%s/%s")
|
||||
% uIndex
|
||||
% uLast
|
||||
Log(lsINFO) << str(boost::format("calcNodeAccountRev: saPrvRedeemReq=%s/%s saPrvIssueReq=%s/%s saCurWantedReq=%s/%s")
|
||||
% saPrvRedeemReq.getText()
|
||||
% saPrvRedeemReq.getHumanCurrency()
|
||||
% saPrvIssueReq.getText()
|
||||
@@ -3188,7 +3234,8 @@ bool PathState::pushImply(uint160 uAccountID, uint160 uCurrencyID, uint160 uIssu
|
||||
#endif
|
||||
|
||||
bValid = pushNode(
|
||||
0, // Offer
|
||||
STPathElement::typeCurrency // Offer.
|
||||
| STPathElement::typeIssuer,
|
||||
ACCOUNT_ONE, // Placeholder for offers.
|
||||
uCurrencyID, // The offer's output is what is now wanted.
|
||||
uIssuerID);
|
||||
@@ -3417,14 +3464,21 @@ PathState::PathState(
|
||||
bValid = pushNode(
|
||||
STPathElement::typeAccount // Last node is always an account.
|
||||
| STPathElement::typeRedeem // Does not matter just pass error check.
|
||||
| STPathElement::typeIssue, // Does not matter just pass error check.
|
||||
| STPathElement::typeIssue // Does not matter just pass error check.
|
||||
| STPathElement::typeCurrency
|
||||
| STPathElement::typeIssuer,
|
||||
uReceiverID, // Receive to output
|
||||
uOutCurrencyID, // Desired currency
|
||||
uOutIssuerID);
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsINFO) << "PathState: " << getJson();
|
||||
Log(lsINFO) << str(boost::format("PathState: in=%s/%s out=%s/%s %s")
|
||||
% STAmount::createHumanCurrency(uInCurrencyID)
|
||||
% NewcoinAddress::createHumanAccountID(uInIssuerID)
|
||||
% STAmount::createHumanCurrency(uOutCurrencyID)
|
||||
% NewcoinAddress::createHumanAccountID(uOutIssuerID)
|
||||
% getJson());
|
||||
}
|
||||
|
||||
Json::Value PathState::getJson() const
|
||||
@@ -3517,6 +3571,8 @@ bool TransactionEngine::calcNode(unsigned int uIndex, PathState::pointer pspCur,
|
||||
const bool bCurAccount = !!(pnCur.uFlags & STPathElement::typeAccount);
|
||||
bool bValid;
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNode> uIndex=%d") % uIndex);
|
||||
|
||||
// Do current node reverse.
|
||||
bValid = bCurAccount
|
||||
? calcNodeAccountRev(uIndex, pspCur, bMultiQuality)
|
||||
@@ -3536,6 +3592,8 @@ bool TransactionEngine::calcNode(unsigned int uIndex, PathState::pointer pspCur,
|
||||
: calcNodeOfferFwd(uIndex, pspCur, bMultiQuality);
|
||||
}
|
||||
|
||||
Log(lsINFO) << str(boost::format("calcNode< uIndex=%d bValid=%d") % uIndex % bValid);
|
||||
|
||||
return bValid;
|
||||
}
|
||||
|
||||
@@ -3553,14 +3611,14 @@ void TransactionEngine::pathNext(PathState::pointer pspCur, int iPaths)
|
||||
|
||||
assert(pspCur->vpnNodes.size() >= 2);
|
||||
|
||||
bool bValid = calcNode(uLast, pspCur, iPaths == 1);
|
||||
pspCur->bValid = calcNode(uLast, pspCur, iPaths == 1);
|
||||
|
||||
Log(lsINFO) << "pathNext: bValid="
|
||||
<< bValid
|
||||
<< pspCur->bValid
|
||||
<< " saOutAct=" << pspCur->saOutAct.getText()
|
||||
<< " saInAct=" << pspCur->saInAct.getText();
|
||||
|
||||
pspCur->uQuality = bValid
|
||||
pspCur->uQuality = pspCur->bValid
|
||||
? STAmount::getRate(pspCur->saOutAct, pspCur->saInAct) // Calculate relative quality.
|
||||
: 0; // Mark path as inactive.
|
||||
|
||||
@@ -3614,7 +3672,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
if (!sleDst)
|
||||
{
|
||||
// Destination account does not exist.
|
||||
@@ -3644,7 +3702,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
|
||||
}
|
||||
|
||||
// XXX Should bMax be sufficient to imply ripple?
|
||||
bool bRipple = bPaths || bMax || !saDstAmount.isNative();
|
||||
bool bRipple = bPaths || bMax || !saDstAmount.isNative();
|
||||
|
||||
if (!bRipple)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user