diff --git a/src/cpp/ripple/Pathfinder.cpp b/src/cpp/ripple/Pathfinder.cpp index 674c811d00..a7f03cc1cf 100644 --- a/src/cpp/ripple/Pathfinder.cpp +++ b/src/cpp/ripple/Pathfinder.cpp @@ -244,8 +244,8 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax } else { - // Remove implied first and last nodes. + spPath.mPath.erase(spPath.mPath.begin()); spPath.mPath.erase(spPath.mPath.begin() + spPath.mPath.size()-1); @@ -301,7 +301,9 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax // Last element is for non-XRP, continue by adding ripple lines and order books. // Create new paths for each outbound account not already in the path. - AccountItems rippleLines(speEnd.mAccountID, mLedger, AccountItem::pointer(new RippleState())); + AccountItems rippleLines(speEnd.mAccountID, mLedger, AccountItem::pointer(new RippleState())); + SLE::pointer sleSrc = lesActive.entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(speEnd.mAccountID)); + bool bRequireAuth = isSetBit(sleSrc->getFieldU32(sfFlags), lsfRequireAuth); BOOST_FOREACH(AccountItem::ref item, rippleLines.getItems()) { @@ -317,9 +319,10 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax % RippleAddress::createHumanAccountID(rspEntry->getAccountIDPeer().getAccountID()) % STAmount::createHumanCurrency(speEnd.mCurrencyID)); } - else if (!rspEntry->getBalance().isPositive() // No IOUs to send. - && (!rspEntry->getLimitPeer() // Peer does not extend credit. - || *rspEntry->getBalance().negate() >= rspEntry->getLimitPeer())) // No credit left. + else if (!rspEntry->getBalance().isPositive() // No IOUs to send. + && (!rspEntry->getLimitPeer() // Peer does not extend credit. + || *rspEntry->getBalance().negate() >= rspEntry->getLimitPeer() // No credit left. + || (bRequireAuth && !rspEntry->getAuth()))) // Not authorized to hold credit. { // Path has no credit left. Ignore it. cLog(lsDEBUG) << diff --git a/src/cpp/ripple/RippleState.cpp b/src/cpp/ripple/RippleState.cpp index 72b20b6c62..1ec6ebdaf8 100644 --- a/src/cpp/ripple/RippleState.cpp +++ b/src/cpp/ripple/RippleState.cpp @@ -14,6 +14,8 @@ RippleState::RippleState(SerializedLedgerEntry::ref ledgerEntry) : AccountItem(l mValid(false), mViewLowest(true) { + mFlags = mLedgerEntry->getFieldU32(sfFlags); + mLowLimit = mLedgerEntry->getFieldAmount(sfLowLimit); mHighLimit = mLedgerEntry->getFieldAmount(sfHighLimit); diff --git a/src/cpp/ripple/RippleState.h b/src/cpp/ripple/RippleState.h index a89c554761..ac79673368 100644 --- a/src/cpp/ripple/RippleState.h +++ b/src/cpp/ripple/RippleState.h @@ -17,6 +17,8 @@ public: typedef boost::shared_ptr pointer; private: + uint32 mFlags; + RippleAddress mLowID; RippleAddress mHighID; @@ -42,16 +44,19 @@ public: void setViewAccount(const uint160& accountID); - const RippleAddress getAccountID() const { return mViewLowest ? mLowID : mHighID; } - const RippleAddress getAccountIDPeer() const { return mViewLowest ? mHighID : mLowID; } + const RippleAddress getAccountID() const { return mViewLowest ? mLowID : mHighID; } + const RippleAddress getAccountIDPeer() const { return !mViewLowest ? mLowID : mHighID; } - STAmount getBalance() const { return mBalance; } + bool getAuth() const { return isSetBit(mFlags, mViewLowest ? lsfLowAuth : lsfHighAuth); } + bool getAuthPeer() const { return isSetBit(mFlags, !mViewLowest ? lsfLowAuth : lsfHighAuth); } - STAmount getLimit() const { return mViewLowest ? mLowLimit : mHighLimit; } - STAmount getLimitPeer() const { return mViewLowest ? mHighLimit : mLowLimit; } + STAmount getBalance() const { return mBalance; } - uint32 getQualityIn() const { return((uint32) (mViewLowest ? mLowQualityIn : mHighQualityIn)); } - uint32 getQualityOut() const { return((uint32) (mViewLowest ? mLowQualityOut : mHighQualityOut)); } + STAmount getLimit() const { return mViewLowest ? mLowLimit : mHighLimit; } + STAmount getLimitPeer() const { return !mViewLowest ? mLowLimit : mHighLimit; } + + uint32 getQualityIn() const { return((uint32) (mViewLowest ? mLowQualityIn : mHighQualityIn)); } + uint32 getQualityOut() const { return((uint32) (mViewLowest ? mLowQualityOut : mHighQualityOut)); } SerializedLedgerEntry::pointer getSLE() { return mLedgerEntry; } const SerializedLedgerEntry& peekSLE() const { return *mLedgerEntry; }