mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Consensus refactor preliminary changes (RIPD-1011):
* Standardize names of LedgerConsensusImp members * Rework visitStoredProposals * Clean up mapComplete * Move status helpers out of LedgerConsensusImp * Move applyTransaction out of LedgerConsensusUmp * Clean up applyTransactions
This commit is contained in:
@@ -47,8 +47,8 @@ public:
|
|||||||
|
|
||||||
virtual uint256 getLCL () = 0;
|
virtual uint256 getLCL () = 0;
|
||||||
|
|
||||||
virtual void mapComplete (uint256 const& hash,
|
virtual void gotMap (uint256 const& hash,
|
||||||
std::shared_ptr<SHAMap> const& map, bool acquired) = 0;
|
std::shared_ptr<SHAMap> const& map) = 0;
|
||||||
|
|
||||||
virtual void timerEntry () = 0;
|
virtual void timerEntry () = 0;
|
||||||
|
|
||||||
@@ -74,41 +74,6 @@ public:
|
|||||||
boost::optional<std::chrono::milliseconds> consensusDelay) = 0;
|
boost::optional<std::chrono::milliseconds> consensusDelay) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** Apply a set of transactions to a ledger
|
|
||||||
|
|
||||||
@param set The set of transactions to apply
|
|
||||||
@param applyLedger The ledger to which the transactions should
|
|
||||||
be applied.
|
|
||||||
@param checkLedger A reference ledger for determining error
|
|
||||||
messages (typically new last closed
|
|
||||||
ledger).
|
|
||||||
@param retriableTransactions collect failed transactions in this set
|
|
||||||
@param openLgr true if applyLedger is open, else false.
|
|
||||||
*/
|
|
||||||
void applyTransactions (
|
|
||||||
Application& app,
|
|
||||||
SHAMap const* set,
|
|
||||||
OpenView& view,
|
|
||||||
ReadView const& checkLedger,
|
|
||||||
CanonicalTXSet& retriableTransactions,
|
|
||||||
ApplyFlags flags);
|
|
||||||
|
|
||||||
/** Apply a single transaction to a ledger
|
|
||||||
@param view The open view to apply to
|
|
||||||
@param txn The transaction to apply
|
|
||||||
@param retryAssured True if another pass is assured
|
|
||||||
@param flags Flags for transactor
|
|
||||||
@return resultSuccess, resultFail or resultRetry
|
|
||||||
*/
|
|
||||||
int applyTransaction (
|
|
||||||
Application& app,
|
|
||||||
OpenView& view,
|
|
||||||
std::shared_ptr<STTx const> const& txn,
|
|
||||||
bool retryAssured,
|
|
||||||
ApplyFlags flags,
|
|
||||||
beast::Journal j);
|
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -107,10 +107,6 @@ public:
|
|||||||
return signature_;
|
return signature_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrevLedger (uint256 const& pl) const
|
|
||||||
{
|
|
||||||
return mPreviousLedger == pl;
|
|
||||||
}
|
|
||||||
bool isInitial () const
|
bool isInitial () const
|
||||||
{
|
{
|
||||||
return mProposeSeq == seqJoin;
|
return mProposeSeq == seqJoin;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <ripple/basics/chrono.h>
|
#include <ripple/basics/chrono.h>
|
||||||
|
#include <ripple/beast/utility/Journal.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -50,6 +51,80 @@ roundCloseTime (
|
|||||||
NetClock::time_point closeTime,
|
NetClock::time_point closeTime,
|
||||||
NetClock::duration closeResolution);
|
NetClock::duration closeResolution);
|
||||||
|
|
||||||
|
/** Determines whether the current ledger should close at this time.
|
||||||
|
|
||||||
|
This function should be called when a ledger is open and there is no close
|
||||||
|
in progress, or when a transaction is received and no close is in progress.
|
||||||
|
|
||||||
|
@param anyTransactions indicates whether any transactions have been received
|
||||||
|
@param previousProposers proposers in the last closing
|
||||||
|
@param proposersClosed proposers who have currently closed this ledger
|
||||||
|
@param proposersValidated proposers who have validated the last closed
|
||||||
|
ledger
|
||||||
|
@param previousTime time for the previous ledger to reach consensus
|
||||||
|
@param currentTime time since the previous ledger's
|
||||||
|
(possibly rounded) close time
|
||||||
|
@param openTime time waiting to close this ledger
|
||||||
|
@param idleInterval the network's desired idle interval
|
||||||
|
@param j journal for logging
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
shouldCloseLedger (
|
||||||
|
bool anyTransactions,
|
||||||
|
int previousProposers,
|
||||||
|
int proposersClosed,
|
||||||
|
int proposersValidated,
|
||||||
|
std::chrono::milliseconds previousTime,
|
||||||
|
std::chrono::milliseconds currentTime, // Time since last ledger's close time
|
||||||
|
std::chrono::milliseconds openTime, // Time waiting to close this ledger
|
||||||
|
std::chrono::seconds idleInterval,
|
||||||
|
beast::Journal j);
|
||||||
|
|
||||||
|
|
||||||
|
/** Determine if a consensus has been reached
|
||||||
|
|
||||||
|
This function determines if a consensus has been reached
|
||||||
|
|
||||||
|
@param agreeing count of agreements with our position
|
||||||
|
@param total count of participants other than us
|
||||||
|
@param count_self whether we count ourselves
|
||||||
|
@return True if a consensus has been reached
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
checkConsensusReached (int agreeing, int total, bool count_self);
|
||||||
|
|
||||||
|
/** Whether we have or don't have a consensus */
|
||||||
|
enum class ConsensusState
|
||||||
|
{
|
||||||
|
No, // We do not have consensus
|
||||||
|
MovedOn, // The network has consensus without us
|
||||||
|
Yes // We have consensus along with the network
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Determine whether the network reached consensus and whether we joined.
|
||||||
|
|
||||||
|
@param previousProposers proposers in the last closing (not including us)
|
||||||
|
@param currentProposers proposers in this closing so far (not including us)
|
||||||
|
@param currentAgree proposers who agree with us
|
||||||
|
@param currentFinished proposers who have validated a ledger after this one
|
||||||
|
@param previousAgreeTime how long, in milliseconds, it took to agree on the
|
||||||
|
last ledger
|
||||||
|
@param currentAgreeTime how long, in milliseconds, we've been trying to
|
||||||
|
agree
|
||||||
|
@param proposing whether we should count ourselves
|
||||||
|
@param j journal for logging
|
||||||
|
*/
|
||||||
|
ConsensusState
|
||||||
|
checkConsensus (
|
||||||
|
int previousProposers,
|
||||||
|
int currentProposers,
|
||||||
|
int currentAgree,
|
||||||
|
int currentFinished,
|
||||||
|
std::chrono::milliseconds previousAgreeTime,
|
||||||
|
std::chrono::milliseconds currentAgreeTime,
|
||||||
|
bool proposing,
|
||||||
|
beast::Journal j);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// These are protocol parameters used to control the behavior of the system and
|
// These are protocol parameters used to control the behavior of the system and
|
||||||
|
|||||||
@@ -177,15 +177,22 @@ ConsensusImp::takePosition (int seq, std::shared_ptr<SHAMap> const& position)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
std::vector <std::shared_ptr <LedgerProposal>>
|
||||||
ConsensusImp::visitStoredProposals (
|
ConsensusImp::getStoredProposals (uint256 const& prevLedger)
|
||||||
std::function<void(LedgerProposal::ref)> const& f)
|
{
|
||||||
|
|
||||||
|
std::vector <std::shared_ptr <LedgerProposal>> ret;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard <std::mutex> _(lock_);
|
std::lock_guard <std::mutex> _(lock_);
|
||||||
|
|
||||||
for (auto const& it : storedProposals_)
|
for (auto const& it : storedProposals_)
|
||||||
for (auto const& prop : it.second)
|
for (auto const& prop : it.second)
|
||||||
f(prop);
|
if (prop->getPrevLedger() == prevLedger)
|
||||||
|
ret.push_back (prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ public:
|
|||||||
|
|
||||||
void takePosition (int seq, std::shared_ptr<SHAMap> const& position);
|
void takePosition (int seq, std::shared_ptr<SHAMap> const& position);
|
||||||
|
|
||||||
void
|
std::vector <std::shared_ptr <LedgerProposal>>
|
||||||
visitStoredProposals (std::function<void(LedgerProposal::ref)> const&);
|
getStoredProposals (uint256 const& previousLedger);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
beast::Journal journal_;
|
beast::Journal journal_;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -129,10 +129,9 @@ public:
|
|||||||
@param map the transaction set.
|
@param map the transaction set.
|
||||||
@param acquired true if we have acquired the transaction set.
|
@param acquired true if we have acquired the transaction set.
|
||||||
*/
|
*/
|
||||||
void mapComplete (
|
void gotMap (
|
||||||
uint256 const& hash,
|
uint256 const& hash,
|
||||||
std::shared_ptr<SHAMap> const& map,
|
std::shared_ptr<SHAMap> const& map) override;
|
||||||
bool acquired) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
On timer call the correct handler for each state.
|
On timer call the correct handler for each state.
|
||||||
@@ -303,56 +302,57 @@ private:
|
|||||||
Application& app_;
|
Application& app_;
|
||||||
ConsensusImp& consensus_;
|
ConsensusImp& consensus_;
|
||||||
InboundTransactions& inboundTransactions_;
|
InboundTransactions& inboundTransactions_;
|
||||||
LocalTxs& m_localTX;
|
LocalTxs& localTX_;
|
||||||
LedgerMaster& ledgerMaster_;
|
LedgerMaster& ledgerMaster_;
|
||||||
FeeVote& m_feeVote;
|
FeeVote& feeVote_;
|
||||||
std::recursive_mutex lock_;
|
std::recursive_mutex lock_;
|
||||||
|
|
||||||
State state_;
|
State state_;
|
||||||
|
|
||||||
// The wall time this ledger closed
|
// The wall time this ledger closed
|
||||||
NetClock::time_point mCloseTime;
|
NetClock::time_point closeTime_;
|
||||||
|
|
||||||
uint256 mPrevLedgerHash;
|
uint256 prevLedgerHash_;
|
||||||
uint256 mAcquiringLedger;
|
uint256 acquiringLedger_;
|
||||||
|
|
||||||
std::shared_ptr<Ledger const> mPreviousLedger;
|
std::shared_ptr<Ledger const> previousLedger_;
|
||||||
LedgerProposal::pointer mOurPosition;
|
LedgerProposal::pointer ourPosition_;
|
||||||
PublicKey mValPublic;
|
PublicKey valPublic_;
|
||||||
SecretKey mValSecret;
|
SecretKey valSecret_;
|
||||||
bool mProposing, mValidating, mHaveCorrectLCL, mConsensusFail;
|
bool proposing_, validating_, haveCorrectLCL_, consensusFail_;
|
||||||
|
|
||||||
std::chrono::milliseconds mCurrentMSeconds;
|
// How much time has elapsed since the round started
|
||||||
|
std::chrono::milliseconds roundTime_;
|
||||||
|
|
||||||
// How long the close has taken, expressed as a percentage of the time that
|
// How long the close has taken, expressed as a percentage of the time that
|
||||||
// we expected it to take.
|
// we expected it to take.
|
||||||
int mClosePercent;
|
int closePercent_;
|
||||||
|
|
||||||
NetClock::duration mCloseResolution;
|
NetClock::duration closeResolution_;
|
||||||
|
|
||||||
bool mHaveCloseTimeConsensus;
|
bool haveCloseTimeConsensus_;
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point mConsensusStartTime;
|
std::chrono::steady_clock::time_point consensusStartTime_;
|
||||||
int mPreviousProposers;
|
int previousProposers_;
|
||||||
|
|
||||||
// The time it took for the last consensus process to converge
|
// Time it took for the last consensus round to converge
|
||||||
std::chrono::milliseconds mPreviousMSeconds;
|
std::chrono::milliseconds previousRoundTime_;
|
||||||
|
|
||||||
// Convergence tracking, trusted peers indexed by hash of public key
|
// Convergence tracking, trusted peers indexed by hash of public key
|
||||||
hash_map<NodeID, LedgerProposal::pointer> mPeerPositions;
|
hash_map<NodeID, LedgerProposal::pointer> peerPositions_;
|
||||||
|
|
||||||
// Transaction Sets, indexed by hash of transaction tree
|
// Transaction Sets, indexed by hash of transaction tree
|
||||||
hash_map<uint256, std::shared_ptr<SHAMap>> mAcquired;
|
hash_map<uint256, std::shared_ptr<SHAMap>> acquired_;
|
||||||
|
|
||||||
// Disputed transactions
|
// Disputed transactions
|
||||||
hash_map<uint256, std::shared_ptr <DisputedTx>> mDisputes;
|
hash_map<uint256, std::shared_ptr <DisputedTx>> disputes_;
|
||||||
hash_set<uint256> mCompares;
|
hash_set<uint256> compares_;
|
||||||
|
|
||||||
// Close time estimates, keep ordered for predictable traverse
|
// Close time estimates, keep ordered for predictable traverse
|
||||||
std::map<NetClock::time_point, int> mCloseTimes;
|
std::map<NetClock::time_point, int> closeTimes_;
|
||||||
|
|
||||||
// nodes that have bowed out of this consensus process
|
// nodes that have bowed out of this consensus process
|
||||||
hash_set<NodeID> mDeadNodes;
|
hash_set<NodeID> deadNodes_;
|
||||||
beast::Journal j_;
|
beast::Journal j_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -367,6 +367,24 @@ make_LedgerConsensus (
|
|||||||
LedgerMaster& ledgerMaster,
|
LedgerMaster& ledgerMaster,
|
||||||
FeeVote& feeVote);
|
FeeVote& feeVote);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/** Apply a set of transactions to a ledger
|
||||||
|
|
||||||
|
Typically the txFilter is used to reject transactions
|
||||||
|
that already got in the prior ledger
|
||||||
|
|
||||||
|
@param set set of transactions to apply
|
||||||
|
@param view ledger to apply to
|
||||||
|
@param txFilter callback, return false to reject txn
|
||||||
|
@return retriable transactions
|
||||||
|
*/
|
||||||
|
CanonicalTXSet
|
||||||
|
applyTransactions (
|
||||||
|
Application& app,
|
||||||
|
SHAMap const& set,
|
||||||
|
OpenView& view,
|
||||||
|
std::function<bool(uint256 const&)> txFilter);
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,4 +73,137 @@ roundCloseTime (
|
|||||||
closeTime += (closeResolution / 2);
|
closeTime += (closeResolution / 2);
|
||||||
return closeTime - (closeTime.time_since_epoch() % closeResolution);
|
return closeTime - (closeTime.time_since_epoch() % closeResolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
shouldCloseLedger (
|
||||||
|
bool anyTransactions,
|
||||||
|
int previousProposers,
|
||||||
|
int proposersClosed,
|
||||||
|
int proposersValidated,
|
||||||
|
std::chrono::milliseconds previousTime,
|
||||||
|
std::chrono::milliseconds currentTime, // Time since last ledger's close time
|
||||||
|
std::chrono::milliseconds openTime, // Time waiting to close this ledger
|
||||||
|
std::chrono::seconds idleInterval,
|
||||||
|
beast::Journal j)
|
||||||
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
if ((previousTime < -1s) || (previousTime > 10min) ||
|
||||||
|
(currentTime > 10min))
|
||||||
|
{
|
||||||
|
// These are unexpected cases, we just close the ledger
|
||||||
|
JLOG (j.warn()) <<
|
||||||
|
"shouldCloseLedger Trans=" << (anyTransactions ? "yes" : "no") <<
|
||||||
|
" Prop: " << previousProposers << "/" << proposersClosed <<
|
||||||
|
" Secs: " << currentTime.count() << " (last: " <<
|
||||||
|
previousTime.count() << ")";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proposersClosed + proposersValidated) > (previousProposers / 2))
|
||||||
|
{
|
||||||
|
// If more than half of the network has closed, we close
|
||||||
|
JLOG (j.trace()) << "Others have closed";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!anyTransactions)
|
||||||
|
{
|
||||||
|
// Only close at the end of the idle interval
|
||||||
|
return currentTime >= idleInterval; // normal idle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preserve minimum ledger open time
|
||||||
|
if (openTime < LEDGER_MIN_CLOSE)
|
||||||
|
{
|
||||||
|
JLOG (j.debug()) <<
|
||||||
|
"Must wait minimum time before closing";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't let this ledger close more than twice as fast as the previous
|
||||||
|
// ledger reached consensus so that slower validators can slow down
|
||||||
|
// the network
|
||||||
|
if (openTime < (previousTime / 2))
|
||||||
|
{
|
||||||
|
JLOG (j.debug()) <<
|
||||||
|
"Ledger has not been open long enough";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the ledger
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
checkConsensusReached (int agreeing, int total, bool count_self)
|
||||||
|
{
|
||||||
|
// If we are alone, we have a consensus
|
||||||
|
if (total == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (count_self)
|
||||||
|
{
|
||||||
|
++agreeing;
|
||||||
|
++total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentPercentage = (agreeing * 100) / total;
|
||||||
|
|
||||||
|
return currentPercentage > minimumConsensusPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsensusState
|
||||||
|
checkConsensus (
|
||||||
|
int previousProposers,
|
||||||
|
int currentProposers,
|
||||||
|
int currentAgree,
|
||||||
|
int currentFinished,
|
||||||
|
std::chrono::milliseconds previousAgreeTime,
|
||||||
|
std::chrono::milliseconds currentAgreeTime,
|
||||||
|
bool proposing,
|
||||||
|
beast::Journal j)
|
||||||
|
{
|
||||||
|
JLOG (j.trace()) <<
|
||||||
|
"checkConsensus: prop=" << currentProposers <<
|
||||||
|
"/" << previousProposers <<
|
||||||
|
" agree=" << currentAgree << " validated=" << currentFinished <<
|
||||||
|
" time=" << currentAgreeTime.count() << "/" << previousAgreeTime.count();
|
||||||
|
|
||||||
|
if (currentAgreeTime <= LEDGER_MIN_CONSENSUS)
|
||||||
|
return ConsensusState::No;
|
||||||
|
|
||||||
|
if (currentProposers < (previousProposers * 3 / 4))
|
||||||
|
{
|
||||||
|
// Less than 3/4 of the last ledger's proposers are present; don't
|
||||||
|
// rush: we may need more time.
|
||||||
|
if (currentAgreeTime < (previousAgreeTime + LEDGER_MIN_CONSENSUS))
|
||||||
|
{
|
||||||
|
JLOG (j.trace()) <<
|
||||||
|
"too fast, not enough proposers";
|
||||||
|
return ConsensusState::No;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have we, together with the nodes on our UNL list, reached the threshold
|
||||||
|
// to declare consensus?
|
||||||
|
if (checkConsensusReached (currentAgree, currentProposers, proposing))
|
||||||
|
{
|
||||||
|
JLOG (j.debug()) << "normal consensus";
|
||||||
|
return ConsensusState::Yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have sufficient nodes on our UNL list moved on and reached the threshold
|
||||||
|
// to declare consensus?
|
||||||
|
if (checkConsensusReached (currentFinished, currentProposers, false))
|
||||||
|
{
|
||||||
|
JLOG (j.warn()) <<
|
||||||
|
"We see no consensus, but 80% of nodes have moved on";
|
||||||
|
return ConsensusState::MovedOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no consensus yet
|
||||||
|
JLOG (j.trace()) << "no consensus";
|
||||||
|
return ConsensusState::No;
|
||||||
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -1514,7 +1514,7 @@ void
|
|||||||
NetworkOPsImp::mapComplete (uint256 const& hash,
|
NetworkOPsImp::mapComplete (uint256 const& hash,
|
||||||
std::shared_ptr<SHAMap> const& map)
|
std::shared_ptr<SHAMap> const& map)
|
||||||
{
|
{
|
||||||
mLedgerConsensus->mapComplete (hash, map, true);
|
mLedgerConsensus->gotMap (hash, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkOPsImp::endConsensus (bool correctLCL)
|
void NetworkOPsImp::endConsensus (bool correctLCL)
|
||||||
|
|||||||
@@ -95,6 +95,25 @@ apply (Application& app, OpenView& view,
|
|||||||
STTx const& tx, ApplyFlags flags,
|
STTx const& tx, ApplyFlags flags,
|
||||||
beast::Journal journal);
|
beast::Journal journal);
|
||||||
|
|
||||||
|
|
||||||
|
/** Class for return value from applyTransaction */
|
||||||
|
enum class ApplyResult
|
||||||
|
{
|
||||||
|
Success, // Applied to this ledger
|
||||||
|
Fail, // Should not be retried in this ledger
|
||||||
|
Retry // Should be retried in this ledger
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Transaction application helper
|
||||||
|
|
||||||
|
Provides more detailed logging and decodes the
|
||||||
|
correct behavior based on the TER type
|
||||||
|
*/
|
||||||
|
ApplyResult
|
||||||
|
applyTransaction(Application& app, OpenView& view,
|
||||||
|
STTx const& tx, bool retryAssured, ApplyFlags flags,
|
||||||
|
beast::Journal journal);
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include <BeastConfig.h>
|
#include <BeastConfig.h>
|
||||||
|
#include <ripple/basics/Log.h>
|
||||||
#include <ripple/app/tx/apply.h>
|
#include <ripple/app/tx/apply.h>
|
||||||
#include <ripple/app/tx/applySteps.h>
|
#include <ripple/app/tx/applySteps.h>
|
||||||
#include <ripple/app/misc/HashRouter.h>
|
#include <ripple/app/misc/HashRouter.h>
|
||||||
@@ -114,4 +115,51 @@ apply (Application& app, OpenView& view,
|
|||||||
return doApply(pcresult, app, view);
|
return doApply(pcresult, app, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplyResult
|
||||||
|
applyTransaction (Application& app, OpenView& view,
|
||||||
|
STTx const& txn,
|
||||||
|
bool retryAssured, ApplyFlags flags,
|
||||||
|
beast::Journal j)
|
||||||
|
{
|
||||||
|
// Returns false if the transaction has need not be retried.
|
||||||
|
if (retryAssured)
|
||||||
|
flags = flags | tapRETRY;
|
||||||
|
|
||||||
|
JLOG (j.debug()) << "TXN "
|
||||||
|
<< txn.getTransactionID ()
|
||||||
|
//<< (engine.view().open() ? " open" : " closed")
|
||||||
|
// because of the optional in engine
|
||||||
|
<< (retryAssured ? "/retry" : "/final");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto const result = apply(app,
|
||||||
|
view, txn, flags, j);
|
||||||
|
if (result.second)
|
||||||
|
{
|
||||||
|
JLOG (j.debug())
|
||||||
|
<< "Transaction applied: " << transHuman (result.first);
|
||||||
|
return ApplyResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTefFailure (result.first) || isTemMalformed (result.first) ||
|
||||||
|
isTelLocal (result.first))
|
||||||
|
{
|
||||||
|
// failure
|
||||||
|
JLOG (j.debug())
|
||||||
|
<< "Transaction failure: " << transHuman (result.first);
|
||||||
|
return ApplyResult::Fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
JLOG (j.debug())
|
||||||
|
<< "Transaction retry: " << transHuman (result.first);
|
||||||
|
return ApplyResult::Retry;
|
||||||
|
}
|
||||||
|
catch (std::exception const&)
|
||||||
|
{
|
||||||
|
JLOG (j.warn()) << "Throws";
|
||||||
|
return ApplyResult::Fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
Reference in New Issue
Block a user