diff --git a/src/ripple/module/app/book/impl/Taker.cpp b/src/ripple/module/app/book/impl/Taker.cpp index 90421a7b04..ca7452866c 100644 --- a/src/ripple/module/app/book/impl/Taker.cpp +++ b/src/ripple/module/app/book/impl/Taker.cpp @@ -82,7 +82,7 @@ Taker::flow (Amounts amount, Offer const& offer, Account const& taker) taker, amount.in, fhZERO_IF_FROZEN)); // Get fee rate paid by taker - std::uint32_t const taker_charge_rate (view ().rippleTransferRate ( + std::uint32_t const taker_charge_rate (rippleTransferRate (view (), taker, offer.account (), amount.in.getIssuer())); // Skip some math when there's no fee @@ -106,7 +106,7 @@ Taker::flow (Amounts amount, Offer const& offer, Account const& taker) offer.account (), owner_amount.out, fhZERO_IF_FROZEN)); // Get fee rate paid by owner - std::uint32_t const owner_charge_rate (view ().rippleTransferRate ( + std::uint32_t const owner_charge_rate (rippleTransferRate (view (), offer.account (), taker, amount.out.getIssuer())); if (owner_charge_rate == QUALITY_ONE) diff --git a/src/ripple/module/app/ledger/LedgerEntrySet.cpp b/src/ripple/module/app/ledger/LedgerEntrySet.cpp index e4a5528444..75ec07c64e 100644 --- a/src/ripple/module/app/ledger/LedgerEntrySet.cpp +++ b/src/ripple/module/app/ledger/LedgerEntrySet.cpp @@ -258,15 +258,6 @@ void LedgerEntrySet::entryDelete (SLE::ref sle) } } -bool LedgerEntrySet::hasChanges () -{ - for (auto const& it : mEntries) - if (it.second.mAction != taaCACHED) - return true; - - return false; -} - Json::Value LedgerEntrySet::getJson (int) const { Json::Value ret (Json::objectValue); @@ -383,20 +374,22 @@ SLE::pointer LedgerEntrySet::getForMod (uint256 const& node, Ledger::ref ledger, newMods.insert (std::make_pair (node, ret)); return ret; - } bool LedgerEntrySet::threadTx (RippleAddress const& threadTo, Ledger::ref ledger, NodeToLedgerEntry& newMods) { + SLE::pointer sle = getForMod ( + Ledger::getAccountRootIndex (threadTo.getAccountID ()), ledger, newMods); + #ifdef META_DEBUG WriteLog (lsTRACE, LedgerEntrySet) << "Thread to " << threadTo.getAccountID (); #endif - SLE::pointer sle = getForMod (Ledger::getAccountRootIndex (threadTo.getAccountID ()), ledger, newMods); if (!sle) { - WriteLog (lsFATAL, LedgerEntrySet) << "Threading to non-existent account: " << threadTo.humanAccountID (); + WriteLog (lsFATAL, LedgerEntrySet) << + "Threading to non-existent account: " << threadTo.humanAccountID (); assert (false); return false; } @@ -1028,29 +1021,52 @@ uint256 LedgerEntrySet::getNextLedgerIndex ( return next; } -// If there is a count, adjust the owner count by iAmount. Otherwise, compute -// the owner count and store it. -void LedgerEntrySet::ownerCountAdjust ( - Account const& owner, int iAmount, SLE::ref sleAccountRoot) +void LedgerEntrySet::incrementOwnerCount (SLE::ref sleAccount) { - auto sleHold = sleAccountRoot ? SLE::pointer () - : entryCache (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (owner)); + assert (sleAccount); - SLE::ref sleRoot = sleAccountRoot - ? sleAccountRoot - : sleHold; + std::uint32_t const current_count = sleAccount->getFieldU32 (sfOwnerCount); - const std::uint32_t uOwnerCount = sleRoot->getFieldU32 (sfOwnerCount); - - const std::uint32_t uNew = iAmount + int (uOwnerCount) > 0 - ? uOwnerCount + iAmount - : 0; - - if (uOwnerCount != uNew) + if (current_count == std::numeric_limits::max ()) { - sleRoot->setFieldU32 (sfOwnerCount, uOwnerCount + iAmount); - entryModify (sleRoot); + WriteLog (lsFATAL, LedgerEntrySet) << + "Account " << sleAccount->getFieldAccount160 (sfAccount) << + " owner count exceeds max!"; + return; } + + sleAccount->setFieldU32 (sfOwnerCount, current_count + 1); + entryModify (sleAccount); +} + +void LedgerEntrySet::incrementOwnerCount (Account const& owner) +{ + incrementOwnerCount(entryCache (ltACCOUNT_ROOT, + Ledger::getAccountRootIndex (owner))); +} + +void LedgerEntrySet::decrementOwnerCount (SLE::ref sleAccount) +{ + assert (sleAccount); + + std::uint32_t const current_count = sleAccount->getFieldU32 (sfOwnerCount); + + if (current_count == 0) + { + WriteLog (lsFATAL, LedgerEntrySet) << + "Account " << sleAccount->getFieldAccount160 (sfAccount) << + " owner count is already 0!"; + return; + } + + sleAccount->setFieldU32 (sfOwnerCount, current_count - 1); + entryModify (sleAccount); +} + +void LedgerEntrySet::decrementOwnerCount (Account const& owner) +{ + decrementOwnerCount(entryCache (ltACCOUNT_ROOT, + Ledger::getAccountRootIndex (owner))); } TER LedgerEntrySet::offerDelete (SLE::pointer sleOffer) @@ -1074,149 +1090,13 @@ TER LedgerEntrySet::offerDelete (SLE::pointer sleOffer) false, uBookNode, uDirectory, offerIndex, true, false); if (tesSUCCESS == terResult) - ownerCountAdjust (owner, -1); + decrementOwnerCount (owner); entryDelete (sleOffer); return (terResult == tesSUCCESS) ? terResult2 : terResult; } -// Returns amount owed by uToAccountID to uFromAccountID. -// <-- $owed/currency/uToAccountID: -// positive: uFromAccountID holds IOUs., -// negative: uFromAccountID owes IOUs. -STAmount LedgerEntrySet::rippleOwed ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& currency) -{ - STAmount saBalance; - SLE::pointer sleRippleState = entryCache ( - ltRIPPLE_STATE, - Ledger::getRippleStateIndex ( - uToAccountID, uFromAccountID, currency)); - - if (sleRippleState) - { - saBalance = sleRippleState->getFieldAmount (sfBalance); - - if (uToAccountID < uFromAccountID) - saBalance.negate (); - - saBalance.setIssuer (uToAccountID); - } - else - { - saBalance.clear ({currency, uToAccountID}); - - WriteLog (lsDEBUG, LedgerEntrySet) << "rippleOwed:" << - " No credit line between " << - to_string (uFromAccountID) << - " and " << to_string (uToAccountID) << - " for " << to_string (currency); - } - - return saBalance; -} - -// Maximum amount of IOUs uToAccountID will hold from uFromAccountID. -// <-- $amount/currency/uToAccountID. -STAmount LedgerEntrySet::rippleLimit ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& currency) -{ - STAmount saLimit; - auto sleRippleState = entryCache ( - ltRIPPLE_STATE, - Ledger::getRippleStateIndex ( - uToAccountID, uFromAccountID, currency)); - - if (sleRippleState) - { - saLimit = sleRippleState->getFieldAmount ( - uToAccountID < uFromAccountID ? sfLowLimit : sfHighLimit); - saLimit.setIssuer (uToAccountID); - } - else - { - saLimit.clear ({currency, uToAccountID}); - } - - return saLimit; - -} - -std::uint32_t LedgerEntrySet::rippleTransferRate (Account const& issuer) -{ - SLE::pointer sleAccount (entryCache ( - ltACCOUNT_ROOT, Ledger::getAccountRootIndex (issuer))); - - std::uint32_t uQuality = - sleAccount && sleAccount->isFieldPresent (sfTransferRate) - ? sleAccount->getFieldU32 (sfTransferRate) - : QUALITY_ONE; - - WriteLog (lsTRACE, LedgerEntrySet) << "rippleTransferRate:" << - " issuer=" << to_string (issuer) << - " account_exists=" << std::boolalpha << bool(sleAccount) << - " transfer_rate=" << (uQuality / 1000000000.0); - - return uQuality; -} - -std::uint32_t -LedgerEntrySet::rippleTransferRate (Account const& uSenderID, - Account const& uReceiverID, - Account const& issuer) -{ - // If calculating the transfer rate from or to the issuer of the currency - // no fees are assessed. - return uSenderID == issuer || uReceiverID == issuer - ? QUALITY_ONE - : rippleTransferRate (issuer); -} - -// XXX Might not need this, might store in nodes on calc reverse. -std::uint32_t -LedgerEntrySet::rippleQualityIn ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& uCurrencyID, SField::ref sfLow, SField::ref sfHigh) -{ - std::uint32_t uQuality (QUALITY_ONE); - - if (uToAccountID == uFromAccountID) - return uQuality; - - SLE::pointer sleRippleState (entryCache (ltRIPPLE_STATE, - Ledger::getRippleStateIndex (uToAccountID, uFromAccountID, uCurrencyID))); - - if (sleRippleState) - { - SField::ref sfField = uToAccountID < uFromAccountID ? sfLow : sfHigh; - - uQuality = sleRippleState->isFieldPresent (sfField) - ? sleRippleState->getFieldU32 (sfField) - : QUALITY_ONE; - - if (!uQuality) - uQuality = 1; // Avoid divide by zero. - } - else - { - // XXX Ideally, catch no before this. So we can assert to be stricter. - uQuality = QUALITY_ONE; - } - - WriteLog (lsTRACE, LedgerEntrySet) << "rippleQuality: " << - (sfLow == sfLowQualityIn ? "in" : "out") << - " uToAccountID=" << to_string (uToAccountID) << - " uFromAccountID=" << to_string (uFromAccountID) << - " uCurrencyID=" << to_string (uCurrencyID) << - " bLine=" << std::boolalpha << bool(sleRippleState) << - " uQuality=" << (uQuality / 1000000000.0); - - return uQuality; -} - // Return how much of issuer's currency IOUs that account holds. May be // negative. // <-- IOU's account has of issuer. @@ -1292,7 +1172,7 @@ STAmount LedgerEntrySet::accountHolds ( } else { - saAmount = rippleHolds (account, currency, issuer, zeroIfFrozen); + saAmount = rippleHolds (account, currency, issuer, zeroIfFrozen); WriteLog (lsTRACE, LedgerEntrySet) << "accountHolds:" << " account=" << to_string (account) << @@ -1388,7 +1268,7 @@ STAmount LedgerEntrySet::rippleTransferFee ( { if (uSenderID != issuer && uReceiverID != issuer) { - std::uint32_t uTransitRate = rippleTransferRate (issuer); + std::uint32_t uTransitRate = rippleTransferRate (*this, issuer); if (QUALITY_ONE != uTransitRate) { @@ -1477,28 +1357,26 @@ TER LedgerEntrySet::trustCreate ( sleRippleState->setFieldU32 ( bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut); - std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve; + std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve; if (bAuth) { - uFlags |= (bSetHigh ? lsfHighAuth : lsfLowAuth); + uFlags |= (bSetHigh ? lsfHighAuth : lsfLowAuth); } if (bNoRipple) { - uFlags |= (bSetHigh ? lsfHighNoRipple : lsfLowNoRipple); + uFlags |= (bSetHigh ? lsfHighNoRipple : lsfLowNoRipple); } if (bFreeze) { - uFlags |= (!bSetHigh ? lsfLowFreeze : lsfHighFreeze); + uFlags |= (!bSetHigh ? lsfLowFreeze : lsfHighFreeze); } sleRippleState->setFieldU32 (sfFlags, uFlags); - ownerCountAdjust ( - bSetDst ? uDstAccountID : uSrcAccountID, 1, sleAccount); + incrementOwnerCount (sleAccount); // ONLY: Create ripple balance. - sleRippleState->setFieldAmount ( - sfBalance, bSetHigh ? -saBalance : saBalance); + sleRippleState->setFieldAmount (sfBalance, bSetHigh ? -saBalance : saBalance); } return terResult; @@ -1637,10 +1515,7 @@ TER LedgerEntrySet::rippleCredit ( // Sender quality out is 0. { // Clear the reserve of the sender, possibly delete the line! - auto sleSender = entryCache ( - ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uSenderID)); - - ownerCountAdjust (uSenderID, -1, sleSender); + decrementOwnerCount (uSenderID); // Clear reserve flag. sleRippleState->setFieldU32 ( @@ -1824,4 +1699,29 @@ TER LedgerEntrySet::accountSend ( return terResult; } +std::uint32_t +rippleTransferRate (LedgerEntrySet& ledger, Account const& issuer) +{ + SLE::pointer sleAccount (ledger.entryCache ( + ltACCOUNT_ROOT, Ledger::getAccountRootIndex (issuer))); + + std::uint32_t quality = QUALITY_ONE; + + if (sleAccount && sleAccount->isFieldPresent (sfTransferRate)) + quality = sleAccount->getFieldU32 (sfTransferRate); + + return quality; +} + +std::uint32_t +rippleTransferRate (LedgerEntrySet& ledger, Account const& uSenderID, + Account const& uReceiverID, Account const& issuer) +{ + // If calculating the transfer rate from or to the issuer of the currency + // no fees are assessed. + return (uSenderID == issuer || uReceiverID == issuer) + ? QUALITY_ONE + : rippleTransferRate (ledger, issuer); +} + } // ripple diff --git a/src/ripple/module/app/ledger/LedgerEntrySet.h b/src/ripple/module/app/ledger/LedgerEntrySet.h index 27b614d2f1..a81a93226f 100644 --- a/src/ripple/module/app/ledger/LedgerEntrySet.h +++ b/src/ripple/module/app/ledger/LedgerEntrySet.h @@ -163,7 +163,6 @@ public: void entryCreate (SLE::ref); // This entry will be created void entryDelete (SLE::ref); // This entry will be deleted void entryModify (SLE::ref); // This entry will be modified - bool hasChanges (); // True if LES has any changes // higher-level ledger functions SLE::pointer entryCreate (LedgerEntryType letType, uint256 const& uIndex); @@ -194,8 +193,15 @@ public: uint256 getNextLedgerIndex (uint256 const& uHash); uint256 getNextLedgerIndex (uint256 const& uHash, uint256 const& uEnd); - void ownerCountAdjust (Account const& uOwnerID, int iAmount, - SLE::ref sleAccountRoot = SLE::pointer ()); + /** @{ */ + void incrementOwnerCount (SLE::ref sleAccount); + void incrementOwnerCount (Account const& owner); + /** @} */ + + /** @{ */ + void decrementOwnerCount (SLE::ref sleAccount); + void decrementOwnerCount (Account const& owner); + /** @} */ // Offer functions. TER offerDelete (SLE::pointer); @@ -205,33 +211,6 @@ public: } // Balance functions. - std::uint32_t rippleTransferRate (Account const& issuer); - std::uint32_t rippleTransferRate ( - Account const& uSenderID, Account const& uReceiverID, - Account const& issuer); - - STAmount rippleOwed ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& currency); - STAmount rippleLimit ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& currency); - - std::uint32_t rippleQualityIn ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& currency, - SField::ref sfLow = sfLowQualityIn, - SField::ref sfHigh = sfHighQualityIn); - - std::uint32_t rippleQualityOut ( - Account const& uToAccountID, Account const& uFromAccountID, - Currency const& currency) - { - return rippleQualityIn ( - uToAccountID, uFromAccountID, currency, - sfLowQualityOut, sfHighQualityOut); - } - bool isFrozen ( Account const& account, Currency const& currency, @@ -347,6 +326,14 @@ private: Account const& issuer, FreezeHandling zeroIfFrozen); }; +// NIKB FIXME: move these to the right place +std::uint32_t +rippleTransferRate (LedgerEntrySet& ledger, Account const& issuer); + +std::uint32_t +rippleTransferRate (LedgerEntrySet& ledger, Account const& uSenderID, + Account const& uReceiverID, Account const& issuer); + } // ripple #endif diff --git a/src/ripple/module/app/misc/NetworkOPs.cpp b/src/ripple/module/app/misc/NetworkOPs.cpp index 9f5b5eee29..0e357e9351 100644 --- a/src/ripple/module/app/misc/NetworkOPs.cpp +++ b/src/ripple/module/app/misc/NetworkOPs.cpp @@ -3103,7 +3103,7 @@ void NetworkOPsImp::getBookPage ( if (iLeft == 0 || iLeft > 300) iLeft = 300; - auto uTransferRate = lesActive.rippleTransferRate (book.out.account); + auto uTransferRate = rippleTransferRate (lesActive, book.out.account); while (! bDone && iLeft-- > 0) { @@ -3299,7 +3299,7 @@ void NetworkOPsImp::getBookPage ( if (iLeft == 0 || iLeft > 300) iLeft = 300; - auto uTransferRate = lesActive.rippleTransferRate (book.out.account); + auto uTransferRate = rippleTransferRate (lesActive, book.out.account); const bool bGlobalFreeze = lesActive.isGlobalFrozen (book.out.account) || lesActive.isGlobalFrozen (book.in.account); diff --git a/src/ripple/module/app/paths/PathState.cpp b/src/ripple/module/app/paths/PathState.cpp index 899b703652..6a7c04aa4f 100644 --- a/src/ripple/module/app/paths/PathState.cpp +++ b/src/ripple/module/app/paths/PathState.cpp @@ -314,13 +314,13 @@ TER PathState::pushNode ( if (resultCode == tesSUCCESS) { - STAmount saOwed = lesEntries.rippleOwed ( + STAmount saOwed = credit_balance (lesEntries, node.account_, backNode.account_, node.issue_.currency); STAmount saLimit; if (saOwed <= zero) { - saLimit = lesEntries.rippleLimit ( + saLimit = credit_limit (lesEntries, node.account_, backNode.account_, node.issue_.currency); diff --git a/src/ripple/module/app/paths/Pathfinder.cpp b/src/ripple/module/app/paths/Pathfinder.cpp index c47a0c07c3..52cf96e07e 100644 --- a/src/ripple/module/app/paths/Pathfinder.cpp +++ b/src/ripple/module/app/paths/Pathfinder.cpp @@ -1071,4 +1071,51 @@ void Pathfinder::initPathTable() }); } +STAmount +credit_limit ( + LedgerEntrySet& ledger, Account const& account, + Account const& issuer, Currency const& currency) +{ + STAmount saLimit ({currency, account}); + + auto sleRippleState = ledger.entryCache (ltRIPPLE_STATE, + Ledger::getRippleStateIndex (account, issuer, currency)); + + if (sleRippleState) + { + saLimit = sleRippleState->getFieldAmount ( + account < issuer ? sfLowLimit : sfHighLimit); + saLimit.setIssuer (account); + } + + assert (saLimit.getIssuer () == account); + assert (saLimit.getCurrency () == currency); + return saLimit; +} + +STAmount +credit_balance ( + LedgerEntrySet& ledger, Account const& account, + Account const& issuer, Currency const& currency) +{ + STAmount saBalance ({currency, account}); + + auto sleRippleState = ledger.entryCache (ltRIPPLE_STATE, + Ledger::getRippleStateIndex (account, issuer, currency)); + + if (sleRippleState) + { + saBalance = sleRippleState->getFieldAmount (sfBalance); + + if (account < issuer) + saBalance.negate (); + + saBalance.setIssuer (account); + } + + assert (saBalance.getIssuer () == account); + assert (saBalance.getCurrency () == currency); + return saBalance; +} + } // ripple diff --git a/src/ripple/module/app/paths/Pathfinder.h b/src/ripple/module/app/paths/Pathfinder.h index e98ab4a91b..ade1bdb292 100644 --- a/src/ripple/module/app/paths/Pathfinder.h +++ b/src/ripple/module/app/paths/Pathfinder.h @@ -165,6 +165,29 @@ CurrencySet usAccountSourceCurrencies RippleLineCache::ref lrLedger, bool includeXRP); +/** Calculate the maximum amount of IOUs that an account can hold + @param ledger the ledger to check against. + @param account the account of interest. + @param issuer the issuer of the IOU. + @param currency the IOU to check. + @return The maximum amount that can be held. +*/ +STAmount +credit_limit ( + LedgerEntrySet& ledger, Account const& account, + Account const& issuer, Currency const& currency); + +/** Returns the amount of IOUs issued by issuer that are held by an account + @param ledger the ledger to check against. + @param account the account of interest. + @param issuer the issuer of the IOU. + @param currency the IOU to check. +*/ +STAmount +credit_balance ( + LedgerEntrySet& ledger, Account const& account, + Account const& issuer, Currency const& currency); + } // ripple #endif diff --git a/src/ripple/module/app/paths/cursor/ForwardLiquidityForAccount.cpp b/src/ripple/module/app/paths/cursor/ForwardLiquidityForAccount.cpp index 8b5f613c31..98da418a47 100644 --- a/src/ripple/module/app/paths/cursor/ForwardLiquidityForAccount.cpp +++ b/src/ripple/module/app/paths/cursor/ForwardLiquidityForAccount.cpp @@ -52,13 +52,13 @@ TER PathCursor::forwardLiquidityForAccount () const nextNode().isAccount() ? nextNode().account_ : node().account_; std::uint32_t uQualityIn = nodeIndex_ - ? ledger().rippleQualityIn ( + ? quality_in (ledger(), node().account_, previousAccountID, node().issue_.currency) : QUALITY_ONE; std::uint32_t uQualityOut = (nodeIndex_ == lastNodeIndex) - ? ledger().rippleQualityOut ( + ? quality_out (ledger(), node().account_, nextAccountID, node().issue_.currency) @@ -230,7 +230,7 @@ TER PathCursor::forwardLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), previousNode().saFwdRedeem, node().saRevIssue, saPrvRedeemAct, @@ -299,7 +299,7 @@ TER PathCursor::forwardLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), previousNode().saFwdRedeem, node().saRevDeliver, saPrvRedeemAct, @@ -445,7 +445,7 @@ TER PathCursor::forwardLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), previousNode().saFwdDeliver, node().saRevIssue, saPrvDeliverAct, @@ -479,7 +479,7 @@ TER PathCursor::forwardLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), previousNode().saFwdDeliver, node().saRevDeliver, saPrvDeliverAct, diff --git a/src/ripple/module/app/paths/cursor/ReverseLiquidity.cpp b/src/ripple/module/app/paths/cursor/ReverseLiquidity.cpp index 5e9b380829..7cf93c5d41 100644 --- a/src/ripple/module/app/paths/cursor/ReverseLiquidity.cpp +++ b/src/ripple/module/app/paths/cursor/ReverseLiquidity.cpp @@ -53,7 +53,7 @@ TER PathCursor::reverseLiquidity () const // node.transferRate_ caches the output transfer rate for this node. node().transferRate_ = STAmount::saFromRate ( - ledger().rippleTransferRate (node().issue_.account)); + rippleTransferRate (ledger(), node().issue_.account)); if (node().isAccount ()) return reverseLiquidityForAccount (); diff --git a/src/ripple/module/app/paths/cursor/ReverseLiquidityForAccount.cpp b/src/ripple/module/app/paths/cursor/ReverseLiquidityForAccount.cpp index 76dab1734a..6fd6861db9 100644 --- a/src/ripple/module/app/paths/cursor/ReverseLiquidityForAccount.cpp +++ b/src/ripple/module/app/paths/cursor/ReverseLiquidityForAccount.cpp @@ -61,7 +61,7 @@ TER PathCursor::reverseLiquidityForAccount () const // This is the quality from from the previous node to this one. const std::uint32_t uQualityIn = (nodeIndex_ != 0) - ? ledger().rippleQualityIn ( + ? quality_in (ledger(), node().account_, previousAccountID, node().issue_.currency) @@ -70,7 +70,7 @@ TER PathCursor::reverseLiquidityForAccount () const // And this is the quality from the next one to this one. const std::uint32_t uQualityOut = (nodeIndex_ != lastNodeIndex) - ? ledger().rippleQualityOut ( + ? quality_out (ledger(), node().account_, nextAccountID, node().issue_.currency) @@ -79,15 +79,15 @@ TER PathCursor::reverseLiquidityForAccount () const // For previousNodeIsAccount: // Previous account is already owed. const STAmount saPrvOwed = (previousNodeIsAccount && nodeIndex_ != 0) - ? ledger().rippleOwed ( + ? credit_balance (ledger(), node().account_, previousAccountID, node().issue_.currency) - : STAmount (node().issue_); + : STAmount (node().issue_); // The limit amount that the previous account may owe. const STAmount saPrvLimit = (previousNodeIsAccount && nodeIndex_ != 0) - ? ledger().rippleLimit ( + ? credit_limit (ledger(), node().account_, previousAccountID, node().issue_.currency) @@ -95,7 +95,7 @@ TER PathCursor::reverseLiquidityForAccount () const // Next account is owed. const STAmount saNxtOwed = (nextNodeIsAccount && nodeIndex_ != lastNodeIndex) - ? ledger().rippleOwed ( + ? credit_balance (ledger(), node().account_, nextAccountID, node().issue_.currency) @@ -312,7 +312,7 @@ TER PathCursor::reverseLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), saPrvRedeemReq, node().saRevIssue, previousNode().saRevRedeem, @@ -398,7 +398,7 @@ TER PathCursor::reverseLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), saPrvRedeemReq, node().saRevDeliver, previousNode().saRevRedeem, @@ -547,7 +547,7 @@ TER PathCursor::reverseLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), saPrvDeliverReq, node().saRevIssue, previousNode().saRevDeliver, @@ -580,7 +580,7 @@ TER PathCursor::reverseLiquidityForAccount () const rippleLiquidity ( rippleCalc_, QUALITY_ONE, - ledger().rippleTransferRate (node().account_), + rippleTransferRate (ledger(), node().account_), saPrvDeliverReq, node().saRevDeliver, previousNode().saRevDeliver, diff --git a/src/ripple/module/app/paths/cursor/RippleLiquidity.cpp b/src/ripple/module/app/paths/cursor/RippleLiquidity.cpp index 4d13afc376..187807a8c3 100644 --- a/src/ripple/module/app/paths/cursor/RippleLiquidity.cpp +++ b/src/ripple/module/app/paths/cursor/RippleLiquidity.cpp @@ -197,5 +197,62 @@ void rippleLiquidity ( << " saCurAct=" << saCurAct; } +static +std::uint32_t +rippleQuality ( + LedgerEntrySet& ledger, + Account const& destination, + Account const& source, + Currency const& currency, + SField::ref sfLow, + SField::ref sfHigh) +{ + std::uint32_t uQuality (QUALITY_ONE); + + if (destination != source) + { + SLE::pointer sleRippleState (ledger.entryCache (ltRIPPLE_STATE, + Ledger::getRippleStateIndex (destination, source, currency))); + + // we should be able to assert(sleRippleState) here + + if (sleRippleState) + { + SField::ref sfField = destination < source ? sfLow : sfHigh; + + uQuality = sleRippleState->isFieldPresent (sfField) + ? sleRippleState->getFieldU32 (sfField) + : QUALITY_ONE; + + if (!uQuality) + uQuality = 1; // Avoid divide by zero. + } + } + + return uQuality; +} + +std::uint32_t +quality_in ( + LedgerEntrySet& ledger, + Account const& uToAccountID, + Account const& uFromAccountID, + Currency const& currency) +{ + return rippleQuality (ledger, uToAccountID, uFromAccountID, currency, + sfLowQualityIn, sfHighQualityIn); +} + +std::uint32_t +quality_out ( + LedgerEntrySet& ledger, + Account const& uToAccountID, + Account const& uFromAccountID, + Currency const& currency) +{ + return rippleQuality (ledger, uToAccountID, uFromAccountID, currency, + sfLowQualityOut, sfHighQualityOut); +} + } // path } // ripple diff --git a/src/ripple/module/app/paths/cursor/RippleLiquidity.h b/src/ripple/module/app/paths/cursor/RippleLiquidity.h index 465db3ce64..cca77dad90 100644 --- a/src/ripple/module/app/paths/cursor/RippleLiquidity.h +++ b/src/ripple/module/app/paths/cursor/RippleLiquidity.h @@ -39,6 +39,20 @@ void rippleLiquidity ( STAmount& saCurAct, std::uint64_t& uRateMax); +std::uint32_t +quality_in ( + LedgerEntrySet& ledger, + Account const& uToAccountID, + Account const& uFromAccountID, + Currency const& currency); + +std::uint32_t +quality_out ( + LedgerEntrySet& ledger, + Account const& uToAccountID, + Account const& uFromAccountID, + Currency const& currency); + } // path } // ripple diff --git a/src/ripple/module/app/transactors/CancelTicket.cpp b/src/ripple/module/app/transactors/CancelTicket.cpp index 26210d516c..6fcfe11401 100644 --- a/src/ripple/module/app/transactors/CancelTicket.cpp +++ b/src/ripple/module/app/transactors/CancelTicket.cpp @@ -72,7 +72,7 @@ public: TER const result = mEngine->view ().dirDelete (false, hint, Ledger::getOwnerDirIndex (ticket_owner), ticketId, false, (hint == 0)); - mEngine->view ().ownerCountAdjust (ticket_owner, -1); + mEngine->view ().decrementOwnerCount (mTxnAccount); mEngine->view ().entryDelete (sleTicket); return result; diff --git a/src/ripple/module/app/transactors/CreateOffer.cpp b/src/ripple/module/app/transactors/CreateOffer.cpp index a3c7578c26..aa22348de2 100644 --- a/src/ripple/module/app/transactors/CreateOffer.cpp +++ b/src/ripple/module/app/transactors/CreateOffer.cpp @@ -461,7 +461,6 @@ public: { // Ledger is final, insufficent reserve to create offer, processed // something. - // Consider the offer unfunded. Treat as tesSUCCESS. } } @@ -490,7 +489,7 @@ public: if (tesSUCCESS == terResult) { // Update owner count. - view.ownerCountAdjust (mTxnAccountID, 1, sleCreator); + view.incrementOwnerCount (sleCreator); uint256 const uBookBase (Ledger::getBookBase ( {{uPaysCurrency, uPaysIssuerID}, diff --git a/src/ripple/module/app/transactors/CreateTicket.cpp b/src/ripple/module/app/transactors/CreateTicket.cpp index 3df5d34da0..e98ac9e9a9 100644 --- a/src/ripple/module/app/transactors/CreateTicket.cpp +++ b/src/ripple/module/app/transactors/CreateTicket.cpp @@ -111,7 +111,7 @@ public: sleTicket->setFieldU64(sfOwnerNode, hint); // If we succeeded, the new entry counts agains the creator's reserve. - mEngine->view ().ownerCountAdjust (mTxnAccountID, 1, mTxnAccount); + mEngine->view ().incrementOwnerCount (mTxnAccount); return result; } diff --git a/src/ripple/module/app/transactors/SetTrust.cpp b/src/ripple/module/app/transactors/SetTrust.cpp index cf48f5b584..6f8a16596f 100644 --- a/src/ripple/module/app/transactors/SetTrust.cpp +++ b/src/ripple/module/app/transactors/SetTrust.cpp @@ -309,8 +309,7 @@ public: if (bLowReserveSet && !bLowReserved) { // Set reserve for low account. - - mEngine->view ().ownerCountAdjust (uLowAccountID, 1, sleLowAccount); + mEngine->view ().incrementOwnerCount (sleLowAccount); uFlagsOut |= lsfLowReserve; if (!bHigh) @@ -320,16 +319,14 @@ public: if (bLowReserveClear && bLowReserved) { // Clear reserve for low account. - - mEngine->view ().ownerCountAdjust (uLowAccountID, -1, sleLowAccount); + mEngine->view ().decrementOwnerCount (sleLowAccount); uFlagsOut &= ~lsfLowReserve; } if (bHighReserveSet && !bHighReserved) { // Set reserve for high account. - - mEngine->view ().ownerCountAdjust (uHighAccountID, 1, sleHighAccount); + mEngine->view ().incrementOwnerCount (sleHighAccount); uFlagsOut |= lsfHighReserve; if (bHigh) @@ -339,8 +336,7 @@ public: if (bHighReserveClear && bHighReserved) { // Clear reserve for high account. - - mEngine->view ().ownerCountAdjust (uHighAccountID, -1, sleHighAccount); + mEngine->view ().decrementOwnerCount (sleHighAccount); uFlagsOut &= ~lsfHighReserve; }