mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-03 09:25:51 +00:00
Use new MetaView functionality in RippleCalc (RIPD-954):
RippleCalc is changed to stack views when calculating results instead of making a copy of the MetaView, improving efficiency.
This commit is contained in:
@@ -94,6 +94,7 @@ private:
|
||||
using list_type = std::map<uint256, Item>;
|
||||
|
||||
BasicView* parent_;
|
||||
MetaView* mParent_ = NULL;
|
||||
list_type items_;
|
||||
boost::optional<DeferredCredits> mDeferredCredits;
|
||||
TransactionMetaSet mSet;
|
||||
@@ -115,13 +116,9 @@ public:
|
||||
MetaView (Ledger::ref ledger,
|
||||
TransactionEngineParams tep);
|
||||
|
||||
/** Construct a copy.
|
||||
Effects:
|
||||
The copy is identical except that
|
||||
the sequence number is one higher.
|
||||
/** Construct a nested view.
|
||||
*/
|
||||
// DEPRECATED
|
||||
MetaView (MetaView const&);
|
||||
MetaView (MetaView&);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -69,16 +69,18 @@ MetaView::MetaView (Ledger::ref ledger,
|
||||
{
|
||||
}
|
||||
|
||||
MetaView::MetaView (MetaView const& other)
|
||||
: parent_(other.parent_)
|
||||
MetaView::MetaView (MetaView& other)
|
||||
: parent_(&other)
|
||||
, mParent_(&other)
|
||||
, items_(other.items_)
|
||||
, mDeferredCredits(other.mDeferredCredits)
|
||||
, mSet(other.mSet)
|
||||
// VFALCO NOTE This is a change in behavior,
|
||||
// previous version set tapNONE
|
||||
, mParams(other.mParams)
|
||||
, mSeq(other.mSeq + 1)
|
||||
{
|
||||
if (other.mDeferredCredits)
|
||||
mDeferredCredits.emplace();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -279,8 +281,23 @@ MetaView::deprecatedBalance(
|
||||
STAmount const& amount) const
|
||||
{
|
||||
if (mDeferredCredits)
|
||||
{
|
||||
if (mParent_)
|
||||
{
|
||||
assert (mParent_->mDeferredCredits);
|
||||
return mDeferredCredits->adjustedBalance(
|
||||
account, issuer, mParent_->deprecatedBalance(account, issuer, amount));
|
||||
}
|
||||
|
||||
return mDeferredCredits->adjustedBalance(
|
||||
account, issuer, amount);
|
||||
}
|
||||
else if (mParent_ && mParent_->mDeferredCredits)
|
||||
{
|
||||
return mParent_->mDeferredCredits->adjustedBalance(
|
||||
account, issuer, amount);
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
@@ -422,6 +439,7 @@ MetaView::deprecatedCreditHint(
|
||||
|
||||
void MetaView::apply()
|
||||
{
|
||||
|
||||
// Write back the account states
|
||||
for (auto& item : items_)
|
||||
{
|
||||
@@ -433,7 +451,7 @@ void MetaView::apply()
|
||||
{
|
||||
case taaCACHED:
|
||||
assert(parent_->exists(
|
||||
keylet::child(item.first)));
|
||||
Keylet(sle->getType(), item.first)));
|
||||
break;
|
||||
|
||||
case taaCREATE:
|
||||
@@ -458,6 +476,20 @@ void MetaView::apply()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDeferredCredits)
|
||||
{
|
||||
assert (mParent_ != NULL);
|
||||
if (mParent_->areCreditsDeferred())
|
||||
{
|
||||
for (auto& credit : *mDeferredCredits)
|
||||
{
|
||||
// This will go away soon
|
||||
mParent_->mDeferredCredits->merge (credit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Safety precaution since we moved the
|
||||
// entries out, apply() cannot be called twice.
|
||||
items_.clear();
|
||||
|
||||
@@ -268,7 +268,7 @@ TER PathState::pushNode (
|
||||
auto const& backNode = nodes_.back ();
|
||||
if (backNode.isAccount())
|
||||
{
|
||||
auto sleRippleState = metaView_->peek(
|
||||
auto sleRippleState = metaView_.peek(
|
||||
keylet::line(backNode.account_, node.account_, backNode.issue_.currency));
|
||||
|
||||
// A "RippleState" means a balance betweeen two accounts for a
|
||||
@@ -291,7 +291,7 @@ TER PathState::pushNode (
|
||||
<< backNode.account_ << " and " << node.account_
|
||||
<< " for " << node.issue_.currency << "." ;
|
||||
|
||||
auto sleBck = metaView_->peek (
|
||||
auto sleBck = metaView_.peek (
|
||||
keylet::account(backNode.account_));
|
||||
// Is the source account the highest numbered account ID?
|
||||
bool bHigh = backNode.account_ > node.account_;
|
||||
@@ -318,13 +318,13 @@ TER PathState::pushNode (
|
||||
|
||||
if (resultCode == tesSUCCESS)
|
||||
{
|
||||
STAmount saOwed = creditBalance (*metaView_,
|
||||
STAmount saOwed = creditBalance (metaView_,
|
||||
node.account_, backNode.account_,
|
||||
node.issue_.currency);
|
||||
STAmount saLimit;
|
||||
|
||||
if (saOwed <= zero) {
|
||||
saLimit = creditLimit (*metaView_,
|
||||
saLimit = creditLimit (metaView_,
|
||||
node.account_,
|
||||
backNode.account_,
|
||||
node.issue_.currency);
|
||||
@@ -413,7 +413,6 @@ TER PathState::pushNode (
|
||||
// terStatus = tesSUCCESS, temBAD_PATH, terNO_LINE, terNO_ACCOUNT, terNO_AUTH,
|
||||
// or temBAD_PATH_LOOP
|
||||
TER PathState::expandPath (
|
||||
MetaView const& viewSource,
|
||||
STPath const& spSourcePath,
|
||||
AccountID const& uReceiverID,
|
||||
AccountID const& uSenderID)
|
||||
@@ -432,8 +431,6 @@ TER PathState::expandPath (
|
||||
WriteLog (lsTRACE, RippleCalc)
|
||||
<< "expandPath> " << spSourcePath.getJson (0);
|
||||
|
||||
metaView_.emplace(viewSource);
|
||||
|
||||
terStatus = tesSUCCESS;
|
||||
|
||||
// XRP with issuer is malformed.
|
||||
@@ -627,7 +624,7 @@ void PathState::checkFreeze()
|
||||
// Check each order book for a global freeze
|
||||
if (nodes_[i].uFlags & STPathElement::typeIssuer)
|
||||
{
|
||||
sle = metaView_->peek (keylet::account(nodes_[i].issue_.account));
|
||||
sle = metaView_.peek (keylet::account(nodes_[i].issue_.account));
|
||||
|
||||
if (sle && sle->isFlag (lsfGlobalFreeze))
|
||||
{
|
||||
@@ -645,7 +642,7 @@ void PathState::checkFreeze()
|
||||
|
||||
if (inAccount != outAccount)
|
||||
{
|
||||
sle = metaView_->peek (keylet::account(outAccount));
|
||||
sle = metaView_.peek (keylet::account(outAccount));
|
||||
|
||||
if (sle && sle->isFlag (lsfGlobalFreeze))
|
||||
{
|
||||
@@ -653,7 +650,7 @@ void PathState::checkFreeze()
|
||||
return;
|
||||
}
|
||||
|
||||
sle = metaView_->peek (keylet::line(inAccount,
|
||||
sle = metaView_.peek (keylet::line(inAccount,
|
||||
outAccount, currencyID));
|
||||
|
||||
if (sle && sle->isFlag (
|
||||
@@ -680,9 +677,9 @@ TER PathState::checkNoRipple (
|
||||
Currency const& currency)
|
||||
{
|
||||
// fetch the ripple lines into and out of this node
|
||||
SLE::pointer sleIn = metaView_->peek (
|
||||
SLE::pointer sleIn = metaView_.peek (
|
||||
keylet::line(firstAccount, secondAccount, currency));
|
||||
SLE::pointer sleOut = metaView_->peek (
|
||||
SLE::pointer sleOut = metaView_.peek (
|
||||
keylet::line(secondAccount, thirdAccount, currency));
|
||||
|
||||
if (!sleIn || !sleOut)
|
||||
|
||||
@@ -35,20 +35,18 @@ class PathState : public CountedObject <PathState>
|
||||
using Ptr = std::shared_ptr<PathState>;
|
||||
using List = std::vector<Ptr>;
|
||||
|
||||
PathState (STAmount const& saSend, STAmount const& saSendMax)
|
||||
: mIndex (0)
|
||||
PathState (MetaView& view, STAmount const& saSend, STAmount const& saSendMax)
|
||||
: metaView_ (view)
|
||||
, mIndex (0)
|
||||
, uQuality (0)
|
||||
, saInReq (saSendMax)
|
||||
, saOutReq (saSend)
|
||||
{
|
||||
}
|
||||
|
||||
explicit PathState (const PathState& psSrc) = default;
|
||||
|
||||
void reset(STAmount const& in, STAmount const& out);
|
||||
|
||||
TER expandPath (
|
||||
MetaView const& viewSource,
|
||||
STPath const& spSourcePath,
|
||||
AccountID const& uReceiverID,
|
||||
AccountID const& uSenderID
|
||||
@@ -105,7 +103,12 @@ class PathState : public CountedObject <PathState>
|
||||
|
||||
MetaView& metaView()
|
||||
{
|
||||
return *metaView_;
|
||||
return metaView_;
|
||||
}
|
||||
|
||||
void resetView (MetaView& view)
|
||||
{
|
||||
reconstruct (metaView_, view);
|
||||
}
|
||||
|
||||
bool isDry() const
|
||||
@@ -149,7 +152,7 @@ private:
|
||||
// Source may only be used there if not mentioned by an account.
|
||||
AccountIssueToNodeIndex umReverse;
|
||||
|
||||
boost::optional<MetaView> metaView_;
|
||||
MetaView metaView_;
|
||||
|
||||
int mIndex; // Index/rank amoung siblings.
|
||||
std::uint64_t uQuality; // 0 = no quality/liquity left.
|
||||
|
||||
@@ -94,7 +94,7 @@ RippleCalc::Output RippleCalc::rippleCalculate (
|
||||
bool RippleCalc::addPathState(STPath const& path, TER& resultCode)
|
||||
{
|
||||
auto pathState = std::make_shared<PathState> (
|
||||
saDstAmountReq_, saMaxAmountReq_);
|
||||
metaView, saDstAmountReq_, saMaxAmountReq_);
|
||||
|
||||
if (!pathState)
|
||||
{
|
||||
@@ -103,7 +103,6 @@ bool RippleCalc::addPathState(STPath const& path, TER& resultCode)
|
||||
}
|
||||
|
||||
pathState->expandPath (
|
||||
metaView,
|
||||
path,
|
||||
uDstAccountID_,
|
||||
uSrcAccountID_);
|
||||
@@ -208,7 +207,6 @@ TER RippleCalc::rippleCalculate ()
|
||||
while (resultCode == temUNCERTAIN)
|
||||
{
|
||||
int iBest = -1;
|
||||
MetaView lesCheckpoint = metaView;
|
||||
int iDry = 0;
|
||||
|
||||
// True, if ever computed multi-quality.
|
||||
@@ -228,7 +226,7 @@ TER RippleCalc::rippleCalculate ()
|
||||
|
||||
// Error if done, output met.
|
||||
PathCursor pc(*this, *pathState, multiQuality);
|
||||
pc.nextIncrement (lesCheckpoint);
|
||||
pc.nextIncrement ();
|
||||
|
||||
// Compute increment.
|
||||
WriteLog (lsDEBUG, RippleCalc)
|
||||
@@ -287,13 +285,6 @@ TER RippleCalc::rippleCalculate ()
|
||||
<< " inPass()=" << pathState->inPass()
|
||||
<< " saOutPass=" << pathState->outPass();
|
||||
|
||||
assert (metaView.isValid ());
|
||||
metaView.swapWith (pathState->metaView());
|
||||
// For the path, save ledger state.
|
||||
|
||||
// VFALCO Can this be done without the function call?
|
||||
metaView.deprecatedInvalidate();
|
||||
|
||||
iBest = pathState->index ();
|
||||
}
|
||||
}
|
||||
@@ -339,14 +330,9 @@ TER RippleCalc::rippleCalculate ()
|
||||
pathState->unfundedOffers().begin (),
|
||||
pathState->unfundedOffers().end ());
|
||||
|
||||
// Record best pass' MetaView to build off of and potentially
|
||||
// return.
|
||||
// Apply best pass' MetaView
|
||||
assert (pathState->metaView().isValid ());
|
||||
metaView.swapWith (pathState->metaView());
|
||||
|
||||
// VFALCO Why is this needed? Can it be done
|
||||
// without the function call?
|
||||
pathState->metaView().deprecatedInvalidate();
|
||||
pathState->metaView().apply();
|
||||
|
||||
actualAmountIn_ += pathState->inPass();
|
||||
actualAmountOut_ += pathState->outPass();
|
||||
@@ -421,10 +407,7 @@ TER RippleCalc::rippleCalculate ()
|
||||
}
|
||||
else
|
||||
{
|
||||
// We must restore the activeLedger from lesCheckpoint in the case
|
||||
// when iBest is -1 and just before the result is set to tesSUCCESS.
|
||||
|
||||
metaView.swapWith (lesCheckpoint);
|
||||
// Don't apply any payment increments
|
||||
resultCode = tesSUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,11 +98,10 @@ public:
|
||||
STPathSet const& spsPaths,
|
||||
Input const* const pInputs = nullptr);
|
||||
|
||||
/** The active ledger. */
|
||||
// VFALCO TODO Fix this comment its not the ledger
|
||||
// VFALCO TODO Rename this to view
|
||||
// The view we are currently working on
|
||||
MetaView& metaView;
|
||||
|
||||
|
||||
// If the transaction fails to meet some constraint, still need to delete
|
||||
// unfunded offers.
|
||||
//
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
namespace ripple {
|
||||
namespace path {
|
||||
|
||||
TER PathCursor::liquidity (MetaView const& lesCheckpoint) const
|
||||
TER PathCursor::liquidity () const
|
||||
{
|
||||
TER resultCode = tecPATH_DRY;
|
||||
PathCursor pc = *this;
|
||||
|
||||
// duplicate
|
||||
reconstruct(rippleCalc_.metaView, lesCheckpoint);
|
||||
pathState_.resetView (rippleCalc_.metaView);
|
||||
|
||||
for (pc.nodeIndex_ = pc.nodeSize(); pc.nodeIndex_--; )
|
||||
{
|
||||
@@ -60,9 +59,7 @@ TER PathCursor::liquidity (MetaView const& lesCheckpoint) const
|
||||
if (resultCode != tesSUCCESS)
|
||||
return resultCode;
|
||||
|
||||
// Do forward.
|
||||
// duplicate
|
||||
reconstruct(rippleCalc_.metaView, lesCheckpoint);
|
||||
pathState_.resetView (rippleCalc_.metaView);
|
||||
|
||||
for (pc.nodeIndex_ = 0; pc.nodeIndex_ < pc.nodeSize(); ++pc.nodeIndex_)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace path {
|
||||
// This is the wrapper that restores a checkpointed version of the ledger so we
|
||||
// can write all over it without consequence.
|
||||
|
||||
void PathCursor::nextIncrement (MetaView const& lesCheckpoint) const
|
||||
void PathCursor::nextIncrement () const
|
||||
{
|
||||
// The next state is what is available in preference order.
|
||||
// This is calculated when referenced accounts changed.
|
||||
@@ -42,7 +42,7 @@ void PathCursor::nextIncrement (MetaView const& lesCheckpoint) const
|
||||
// WriteLog (lsTRACE, RippleCalc)
|
||||
// << "nextIncrement: Path In: " << pathState_.getJson ();
|
||||
|
||||
auto status = liquidity(lesCheckpoint);
|
||||
auto status = liquidity();
|
||||
|
||||
if (status == tesSUCCESS)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void nextIncrement(MetaView const& checkpoint) const;
|
||||
void nextIncrement() const;
|
||||
|
||||
private:
|
||||
PathCursor(PathCursor const&) = default;
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
return {rippleCalc_, pathState_, multiQuality_, nodeIndex_ + delta};
|
||||
}
|
||||
|
||||
TER liquidity(MetaView const& lesCheckpoint) const;
|
||||
TER liquidity() const;
|
||||
TER reverseLiquidity () const;
|
||||
TER forwardLiquidity () const;
|
||||
|
||||
@@ -95,7 +95,8 @@ private:
|
||||
MetaView& ledger() const
|
||||
{
|
||||
// VFALCO Rename metaView to view
|
||||
return rippleCalc_.metaView;
|
||||
//return rippleCalc_.metaView;
|
||||
return pathState_.metaView();
|
||||
}
|
||||
|
||||
NodeIndex nodeSize() const
|
||||
|
||||
@@ -59,6 +59,10 @@ public:
|
||||
STAmount const& amount);
|
||||
|
||||
void clear ();
|
||||
|
||||
std::map<Key, Value>::iterator begin() { return map_.begin(); }
|
||||
std::map<Key, Value>::iterator end() { return map_.end(); }
|
||||
void merge (std::pair <Key, Value> const& p);
|
||||
};
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -147,5 +147,16 @@ void DeferredCredits::clear ()
|
||||
map_.clear ();
|
||||
}
|
||||
|
||||
void DeferredCredits::merge (std::pair <Key, Value> const& p)
|
||||
{
|
||||
using std::get;
|
||||
auto r = map_.emplace(p);
|
||||
if (!r.second)
|
||||
{
|
||||
get<0>(r.first->second) += get<0>(p.second);
|
||||
get<1>(r.first->second) += get<1>(p.second);
|
||||
}
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
|
||||
Reference in New Issue
Block a user