mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
Cleanup consensus helper functions:
* Reduce public class interfaces * Use free functions when possible * Add self-documenting function return values * Simplify ledger close resolution calculations
This commit is contained in:
committed by
Vinnie Falco
parent
e838b30def
commit
730cd5d513
@@ -115,7 +115,7 @@ public:
|
||||
getApp().getInboundTransactions().newRound (mPreviousLedger->getLedgerSeq());
|
||||
|
||||
// Adapt close time resolution to recent network conditions
|
||||
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution (
|
||||
mCloseResolution = getNextLedgerTimeResolution (
|
||||
mPreviousLedger->getCloseResolution (),
|
||||
mPreviousLedger->getCloseAgree (),
|
||||
previousLedger->getLedgerSeq () + 1);
|
||||
@@ -292,11 +292,6 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ledger::ref peekPreviousLedger ()
|
||||
{
|
||||
return mPreviousLedger;
|
||||
}
|
||||
|
||||
uint256 getLCL ()
|
||||
{
|
||||
return mPrevLedgerHash;
|
||||
@@ -564,9 +559,10 @@ public:
|
||||
WriteLog (lsINFO, LedgerConsensus) << "Have the consensus ledger " << mPrevLedgerHash;
|
||||
mHaveCorrectLCL = true;
|
||||
|
||||
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution (
|
||||
mPreviousLedger->getCloseResolution (), mPreviousLedger->getCloseAgree (),
|
||||
mPreviousLedger->getLedgerSeq () + 1);
|
||||
mCloseResolution = getNextLedgerTimeResolution (
|
||||
mPreviousLedger->getCloseResolution (),
|
||||
mPreviousLedger->getCloseAgree (),
|
||||
mPreviousLedger->getLedgerSeq () + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -666,7 +662,7 @@ public:
|
||||
idleInterval = std::max (idleInterval, 2 * mPreviousLedger->getCloseResolution ());
|
||||
|
||||
// Decide if we should close the ledger
|
||||
if (ContinuousLedgerTiming::shouldClose (anyTransactions
|
||||
if (shouldCloseLedger (anyTransactions
|
||||
, mPreviousProposers, proposersClosed, proposersValidated
|
||||
, mPreviousMSeconds, sinceClose, mCurrentMSeconds
|
||||
, idleInterval))
|
||||
@@ -681,26 +677,27 @@ public:
|
||||
*/
|
||||
void stateEstablish ()
|
||||
{
|
||||
|
||||
// Give everyone a chance to take an initial position
|
||||
if (mCurrentMSeconds < LEDGER_MIN_CONSENSUS)
|
||||
return;
|
||||
|
||||
updateOurPositions ();
|
||||
|
||||
// Nothing to do if we don't have consensus.
|
||||
if (!haveConsensus ())
|
||||
return;
|
||||
|
||||
if (!mHaveCloseTimeConsensus)
|
||||
{
|
||||
CondLog (haveConsensus (false), lsINFO, LedgerConsensus)
|
||||
<< "We have TX consensus but not CT consensus";
|
||||
}
|
||||
else if (haveConsensus (true))
|
||||
{
|
||||
WriteLog (lsINFO, LedgerConsensus)
|
||||
<< "Converge cutoff (" << mPeerPositions.size ()
|
||||
<< " participants)";
|
||||
mState = lcsFINISHED;
|
||||
beginAccept (false);
|
||||
WriteLog (lsINFO, LedgerConsensus) <<
|
||||
"We have TX consensus but not CT consensus";
|
||||
return;
|
||||
}
|
||||
|
||||
WriteLog (lsINFO, LedgerConsensus) <<
|
||||
"Converge cutoff (" << mPeerPositions.size () << " participants)";
|
||||
mState = lcsFINISHED;
|
||||
beginAccept (false);
|
||||
}
|
||||
|
||||
void stateFinished ()
|
||||
@@ -717,7 +714,7 @@ public:
|
||||
|
||||
/** Check if we've reached consensus
|
||||
*/
|
||||
bool haveConsensus (bool forReal)
|
||||
bool haveConsensus ()
|
||||
{
|
||||
// CHECKME: should possibly count unacquired TX sets as disagreeing
|
||||
int agree = 0, disagree = 0;
|
||||
@@ -762,9 +759,20 @@ public:
|
||||
<< ", disagree=" << disagree;
|
||||
|
||||
// Determine if we actually have consensus or not
|
||||
return ContinuousLedgerTiming::haveConsensus (mPreviousProposers,
|
||||
agree + disagree, agree, currentValidations
|
||||
, mPreviousMSeconds, mCurrentMSeconds, forReal, mConsensusFail);
|
||||
auto ret = checkConsensus (mPreviousProposers, agree + disagree, agree,
|
||||
currentValidations, mPreviousMSeconds, mCurrentMSeconds);
|
||||
|
||||
if (ret == ConsensusState::No)
|
||||
return false;
|
||||
|
||||
// There is consensus, but we need to track if the network moved on
|
||||
// without us.
|
||||
if (ret == ConsensusState::MovedOn)
|
||||
mConsensusFail = true;
|
||||
else
|
||||
mConsensusFail = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<SHAMap> getTransactionTree (uint256 const& hash)
|
||||
@@ -855,11 +863,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isOurPubKey (const RippleAddress & k)
|
||||
{
|
||||
return k == mValPublic;
|
||||
}
|
||||
|
||||
/** Simulate a consensus round without any network traffic
|
||||
*/
|
||||
void simulate ()
|
||||
|
||||
@@ -46,31 +46,15 @@ public:
|
||||
|
||||
virtual Json::Value getJson (bool full) = 0;
|
||||
|
||||
virtual Ledger::ref peekPreviousLedger () = 0;
|
||||
|
||||
virtual uint256 getLCL () = 0;
|
||||
|
||||
virtual void mapComplete (uint256 const& hash,
|
||||
std::shared_ptr<SHAMap> const& map, bool acquired) = 0;
|
||||
|
||||
virtual void checkLCL () = 0;
|
||||
|
||||
virtual void handleLCL (uint256 const& lclHash) = 0;
|
||||
|
||||
virtual void timerEntry () = 0;
|
||||
|
||||
// state handlers
|
||||
virtual void statePreClose () = 0;
|
||||
virtual void stateEstablish () = 0;
|
||||
virtual void stateFinished () = 0;
|
||||
virtual void stateAccepted () = 0;
|
||||
|
||||
virtual bool haveConsensus (bool forReal) = 0;
|
||||
|
||||
virtual bool peerPosition (LedgerProposal::ref) = 0;
|
||||
|
||||
virtual bool isOurPubKey (const RippleAddress & k) = 0;
|
||||
|
||||
// test/debug
|
||||
virtual void simulate () = 0;
|
||||
};
|
||||
|
||||
@@ -53,7 +53,7 @@ Ledger::Ledger (RippleAddress const& masterID, std::uint64_t startAmount)
|
||||
, mLedgerSeq (1) // First Ledger
|
||||
, mCloseTime (0)
|
||||
, mParentCloseTime (0)
|
||||
, mCloseResolution (LEDGER_TIME_ACCURACY)
|
||||
, mCloseResolution (ledgerDefaultTimeResolution)
|
||||
, mCloseFlags (0)
|
||||
, mClosed (false)
|
||||
, mValidated (false)
|
||||
@@ -179,10 +179,8 @@ Ledger::Ledger (bool /* dummy */,
|
||||
|
||||
assert (mParentHash.isNonZero ());
|
||||
|
||||
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution (
|
||||
prevLedger.mCloseResolution,
|
||||
prevLedger.getCloseAgree (),
|
||||
mLedgerSeq);
|
||||
mCloseResolution = getNextLedgerTimeResolution (prevLedger.mCloseResolution,
|
||||
prevLedger.getCloseAgree (), mLedgerSeq);
|
||||
|
||||
if (prevLedger.mCloseTime == 0)
|
||||
{
|
||||
@@ -230,7 +228,7 @@ Ledger::Ledger (std::uint32_t ledgerSeq, std::uint32_t closeTime)
|
||||
mLedgerSeq (ledgerSeq),
|
||||
mCloseTime (closeTime),
|
||||
mParentCloseTime (0),
|
||||
mCloseResolution (LEDGER_TIME_ACCURACY),
|
||||
mCloseResolution (ledgerDefaultTimeResolution),
|
||||
mCloseFlags (0),
|
||||
mClosed (false),
|
||||
mValidated (false),
|
||||
|
||||
@@ -20,31 +20,26 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/LedgerTiming.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// VFALCO Should rename ContinuousLedgerTiming to LedgerTiming
|
||||
|
||||
// NOTE: First and last times must be repeated
|
||||
int ContinuousLedgerTiming::LedgerTimeResolution[] = { 10, 10, 20, 30, 60, 90, 120, 120 };
|
||||
|
||||
// Called when a ledger is open and no close is in progress -- when a transaction is received and no close
|
||||
// is in process, or when a close completes. Returns the number of seconds the ledger should be be open.
|
||||
bool ContinuousLedgerTiming::shouldClose (
|
||||
bool shouldCloseLedger (
|
||||
bool anyTransactions,
|
||||
int previousProposers, // proposers in the last closing
|
||||
int proposersClosed, // proposers who have currently closed this ledgers
|
||||
int proposersValidated, // proposers who have validated the last closed ledger
|
||||
int previousMSeconds, // milliseconds the previous ledger took to reach consensus
|
||||
int currentMSeconds, // milliseconds since the previous ledger closed
|
||||
int openMSeconds, // milliseconds since the previous LCL was computed
|
||||
int idleInterval) // network's desired idle interval
|
||||
int previousProposers,
|
||||
int proposersClosed,
|
||||
int proposersValidated,
|
||||
int previousMSeconds,
|
||||
int currentMSeconds,
|
||||
int openMSeconds,
|
||||
int idleInterval)
|
||||
{
|
||||
if ((previousMSeconds < -1000) || (previousMSeconds > 600000) ||
|
||||
(currentMSeconds < -1000) || (currentMSeconds > 600000))
|
||||
{
|
||||
WriteLog (lsWARNING, LedgerTiming) <<
|
||||
"CLC::shouldClose range Trans=" << (anyTransactions ? "yes" : "no") <<
|
||||
"shouldCloseLedger Trans=" << (anyTransactions ? "yes" : "no") <<
|
||||
" Prop: " << previousProposers << "/" << proposersClosed <<
|
||||
" Secs: " << currentMSeconds << " (last: " << previousMSeconds << ")";
|
||||
return true;
|
||||
@@ -52,8 +47,8 @@ bool ContinuousLedgerTiming::shouldClose (
|
||||
|
||||
if (!anyTransactions)
|
||||
{
|
||||
// no transactions so far this interval
|
||||
if (proposersClosed > (previousProposers / 4)) // did we miss a transaction?
|
||||
// did we miss a transaction?
|
||||
if (proposersClosed > (previousProposers / 4))
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"no transactions, many proposers: now (" << proposersClosed <<
|
||||
@@ -61,118 +56,124 @@ bool ContinuousLedgerTiming::shouldClose (
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0 // This false triggers on the genesis ledger
|
||||
|
||||
if (previousMSeconds > (1000 * (LEDGER_IDLE_INTERVAL + 2))) // the last ledger was very slow to close
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) << "was slow to converge (p=" << (previousMSeconds) << ")";
|
||||
|
||||
if (previousMSeconds < 2000)
|
||||
return previousMSeconds;
|
||||
|
||||
return previousMSeconds - 1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
// Only close if we have idled for too long.
|
||||
return currentMSeconds >= (idleInterval * 1000); // normal idle
|
||||
}
|
||||
|
||||
if ((openMSeconds < LEDGER_MIN_CLOSE) && ((proposersClosed + proposersValidated) < (previousProposers / 2 )))
|
||||
// If we have any transactions, we don't want to close too frequently:
|
||||
if (openMSeconds < LEDGER_MIN_CLOSE)
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) <<
|
||||
"Must wait minimum time before closing";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((currentMSeconds < previousMSeconds) && ((proposersClosed + proposersValidated) < previousProposers))
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) <<
|
||||
"We are waiting for more closes/validations";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // this ledger should close now
|
||||
}
|
||||
|
||||
// Returns whether we have a consensus or not. If so, we expect all honest nodes
|
||||
// to already have everything they need to accept a consensus. Our vote is 'locked in'.
|
||||
bool ContinuousLedgerTiming::haveConsensus (
|
||||
int previousProposers, // proposers in the last closing (not including us)
|
||||
int currentProposers, // proposers in this closing so far (not including us)
|
||||
int currentAgree, // proposers who agree with us
|
||||
int currentFinished, // proposers who have validated a ledger after this one
|
||||
int previousAgreeTime, // how long it took to agree on the last ledger
|
||||
int currentAgreeTime, // how long we've been trying to agree
|
||||
bool forReal, // deciding whether to stop consensus process
|
||||
bool& failed) // we can't reach a consensus
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"CLC::haveConsensus: prop=" << currentProposers <<
|
||||
"/" << previousProposers <<
|
||||
" agree=" << currentAgree << " validated=" << currentFinished <<
|
||||
" time=" << currentAgreeTime << "/" << previousAgreeTime <<
|
||||
(forReal ? "" : "X");
|
||||
|
||||
if (currentAgreeTime <= LEDGER_MIN_CONSENSUS)
|
||||
return false;
|
||||
|
||||
if (currentProposers < (previousProposers * 3 / 4))
|
||||
{
|
||||
// Less than 3/4 of the last ledger's proposers are present, we may need more time
|
||||
if (currentAgreeTime < (previousAgreeTime + LEDGER_MIN_CONSENSUS))
|
||||
if ((proposersClosed + proposersValidated) < (previousProposers / 2 ))
|
||||
{
|
||||
CondLog (forReal, lsTRACE, LedgerTiming) <<
|
||||
"too fast, not enough proposers";
|
||||
WriteLog (lsDEBUG, LedgerTiming) <<
|
||||
"Must wait minimum time before closing";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If 80% of current proposers (plus us) agree on a set, we have consensus
|
||||
if (((currentAgree * 100 + 100) / (currentProposers + 1)) > 80)
|
||||
if (currentMSeconds < previousMSeconds)
|
||||
{
|
||||
CondLog (forReal, lsDEBUG, LedgerTiming) << "normal consensus";
|
||||
failed = false;
|
||||
return true;
|
||||
if ((proposersClosed + proposersValidated) < previousProposers)
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) <<
|
||||
"We are waiting for more closes/validations";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If 80% of the nodes on your UNL have moved on, you should declare consensus
|
||||
if (((currentFinished * 100) / (currentProposers + 1)) > 80)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
checkConsensusReached (int agreeing, int proposing)
|
||||
{
|
||||
int currentPercentage = (agreeing * 100) / (proposing + 1);
|
||||
|
||||
return currentPercentage > minimumConsensusPercentage;
|
||||
}
|
||||
|
||||
ConsensusState checkConsensus (
|
||||
int previousProposers,
|
||||
int currentProposers,
|
||||
int currentAgree,
|
||||
int currentFinished,
|
||||
int previousAgreeTime,
|
||||
int currentAgreeTime)
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"checkConsensus: prop=" << currentProposers <<
|
||||
"/" << previousProposers <<
|
||||
" agree=" << currentAgree << " validated=" << currentFinished <<
|
||||
" time=" << currentAgreeTime << "/" << previousAgreeTime;
|
||||
|
||||
if (currentAgreeTime <= LEDGER_MIN_CONSENSUS)
|
||||
return ConsensusState::No;
|
||||
|
||||
if (currentProposers < (previousProposers * 3 / 4))
|
||||
{
|
||||
CondLog (forReal, lsWARNING, LedgerTiming) <<
|
||||
// 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))
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"too fast, not enough proposers";
|
||||
return ConsensusState::No;
|
||||
}
|
||||
}
|
||||
|
||||
// Have we, together with the nodes on our UNL list, reached the treshold
|
||||
// to declare consensus?
|
||||
if (checkConsensusReached (currentAgree + 1, currentProposers))
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) << "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))
|
||||
{
|
||||
WriteLog (lsWARNING, LedgerTiming) <<
|
||||
"We see no consensus, but 80% of nodes have moved on";
|
||||
failed = true;
|
||||
return true;
|
||||
return ConsensusState::MovedOn;
|
||||
}
|
||||
|
||||
// no consensus yet
|
||||
CondLog (forReal, lsTRACE, LedgerTiming) << "no consensus";
|
||||
return false;
|
||||
WriteLog (lsTRACE, LedgerTiming) << "no consensus";
|
||||
return ConsensusState::No;
|
||||
}
|
||||
|
||||
int ContinuousLedgerTiming::getNextLedgerTimeResolution (int previousResolution, bool previousAgree, int ledgerSeq)
|
||||
int getNextLedgerTimeResolution (
|
||||
int previousResolution,
|
||||
bool previousAgree,
|
||||
std::uint32_t ledgerSeq)
|
||||
{
|
||||
assert (ledgerSeq);
|
||||
|
||||
if ((!previousAgree) && ((ledgerSeq % LEDGER_RES_DECREASE) == 0))
|
||||
// Find the current resolution:
|
||||
auto iter = std::find (std::begin (ledgerPossibleTimeResolutions),
|
||||
std::end (ledgerPossibleTimeResolutions), previousResolution);
|
||||
assert (iter != std::end (ledgerPossibleTimeResolutions));
|
||||
|
||||
// This should never happen, but just as a precaution
|
||||
if (iter == std::end (ledgerPossibleTimeResolutions))
|
||||
return previousResolution;
|
||||
|
||||
// If we did not previously agree, we try to decrease the resolution to
|
||||
// improve the chance that we will agree now.
|
||||
if (!previousAgree && ((ledgerSeq % decreaseLedgerTimeResolutionEvery) == 0))
|
||||
{
|
||||
// reduce resolution
|
||||
int i = 1;
|
||||
|
||||
while (LedgerTimeResolution[i] != previousResolution)
|
||||
++i;
|
||||
|
||||
return LedgerTimeResolution[i + 1];
|
||||
if (++iter != std::end (ledgerPossibleTimeResolutions))
|
||||
return *iter;
|
||||
}
|
||||
|
||||
if ((previousAgree) && ((ledgerSeq % LEDGER_RES_INCREASE) == 0))
|
||||
// If we previously agreed, we try to increase the resolution to determine
|
||||
// if we can continue to agree.
|
||||
if (previousAgree && ((ledgerSeq % increaseLedgerTimeResolutionEvery) == 0))
|
||||
{
|
||||
// increase resolution
|
||||
int i = 1;
|
||||
|
||||
while (LedgerTimeResolution[i] != previousResolution)
|
||||
++i;
|
||||
|
||||
return LedgerTimeResolution[i - 1];
|
||||
if (iter-- != std::begin (ledgerPossibleTimeResolutions))
|
||||
return *iter;
|
||||
}
|
||||
|
||||
return previousResolution;
|
||||
|
||||
@@ -20,42 +20,115 @@
|
||||
#ifndef RIPPLE_APP_LEDGER_LEDGERTIMING_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_LEDGERTIMING_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** 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 previousMSeconds time, in milliseconds, for the previous ledger to
|
||||
reach consensus (in milliseconds)
|
||||
@param currentMSeconds time, in milliseconds since the previous ledger closed
|
||||
@param openMSeconds time, in milliseconds, since the previous LCL was computed
|
||||
@param idleInterval the network's desired idle interval
|
||||
*/
|
||||
bool shouldCloseLedger (
|
||||
bool anyTransactions,
|
||||
int previousProposers,
|
||||
int proposersClosed,
|
||||
int proposersValidated,
|
||||
int previousMSeconds,
|
||||
int currentMSeconds,
|
||||
int openMSeconds,
|
||||
int idleInterval);
|
||||
|
||||
/** What state the consensus process is on. */
|
||||
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
|
||||
*/
|
||||
ConsensusState checkConsensus (
|
||||
int previousProposers,
|
||||
int currentProposers,
|
||||
int currentAgree,
|
||||
int currentClosed,
|
||||
int previousAgreeTime,
|
||||
int currentAgreeTime);
|
||||
|
||||
/** Calculates the close time resolution for the specified ledger.
|
||||
|
||||
The Ripple protocol uses binning to represent time intervals using only one
|
||||
timestamp. This allows servers to derive a common time for the next ledger,
|
||||
without the need for perfectly synchronized clocks.
|
||||
The time resolution (i.e. the size of the intervals) is adjusted dynamically
|
||||
based on what happened in the last ledger, to try to avoid disagreements.
|
||||
*/
|
||||
int getNextLedgerTimeResolution (
|
||||
int previousResolution,
|
||||
bool previousAgree,
|
||||
std::uint32_t ledgerSeq);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// These are protocol parameters used to control the behavior of the system and
|
||||
// they should not be changed arbitrarily.
|
||||
|
||||
// The percentage threshold above which we can declare consensus.
|
||||
int const minimumConsensusPercentage = 80;
|
||||
|
||||
// All possible close time resolutions. Values should not be duplicated.
|
||||
int const ledgerPossibleTimeResolutions[] = { 10, 20, 30, 60, 90, 120 };
|
||||
|
||||
// Initial resolution of ledger close time.
|
||||
int const ledgerDefaultTimeResolution = ledgerPossibleTimeResolutions[2];
|
||||
|
||||
// How often we increase the close time resolution
|
||||
int const increaseLedgerTimeResolutionEvery = 8;
|
||||
|
||||
// How often we decrease the close time resolution
|
||||
int const decreaseLedgerTimeResolutionEvery = 1;
|
||||
|
||||
// The number of seconds a ledger may remain idle before closing
|
||||
const int LEDGER_IDLE_INTERVAL = 15;
|
||||
|
||||
// The number of seconds a validation remains current after its ledger's close time
|
||||
// This is a safety to protect against very old validations and the time it takes to adjust
|
||||
// the close time accuracy window
|
||||
// The number of seconds a validation remains current after its ledger's close
|
||||
// time. This is a safety to protect against very old validations and the time
|
||||
// it takes to adjust the close time accuracy window
|
||||
const int LEDGER_VAL_INTERVAL = 300;
|
||||
|
||||
// The number of seconds before a close time that we consider a validation acceptable
|
||||
// This protects against extreme clock errors
|
||||
// The number of seconds before a close time that we consider a validation
|
||||
// acceptable. This protects against extreme clock errors
|
||||
const int LEDGER_EARLY_INTERVAL = 180;
|
||||
|
||||
// The number of milliseconds we wait minimum to ensure participation
|
||||
const int LEDGER_MIN_CONSENSUS = 2000;
|
||||
|
||||
// The number of milliseconds we wait minimum to ensure others have computed the LCL
|
||||
// Minimum number of milliseconds to wait to ensure others have computed the LCL
|
||||
const int LEDGER_MIN_CLOSE = 2000;
|
||||
|
||||
// Initial resolution of ledger close time
|
||||
const int LEDGER_TIME_ACCURACY = 30;
|
||||
|
||||
// How often to increase resolution
|
||||
const int LEDGER_RES_INCREASE = 8;
|
||||
|
||||
// How often to decrease resolution
|
||||
const int LEDGER_RES_DECREASE = 1;
|
||||
|
||||
// How often we check state or change positions (in milliseconds)
|
||||
const int LEDGER_GRANULARITY = 1000;
|
||||
|
||||
// The percentage of active trusted validators that must be able to
|
||||
// keep up with the network or we consider the network overloaded
|
||||
const int LEDGER_NET_RATIO = 70;
|
||||
|
||||
// How long we consider a proposal fresh
|
||||
const int PROPOSE_FRESHNESS = 20;
|
||||
|
||||
@@ -83,29 +156,6 @@ const int AV_STUCK_CONSENSUS_PCT = 95;
|
||||
|
||||
const int AV_CT_CONSENSUS_PCT = 75;
|
||||
|
||||
class ContinuousLedgerTiming
|
||||
{
|
||||
public:
|
||||
|
||||
static int LedgerTimeResolution[];
|
||||
|
||||
// Returns the number of seconds the ledger was or should be open
|
||||
// Call when a consensus is reached and when any transaction is relayed to be added
|
||||
static bool shouldClose (
|
||||
bool anyTransactions,
|
||||
int previousProposers, int proposersClosed, int proposerersValidated,
|
||||
int previousMSeconds, int currentMSeconds, int openMSeconds,
|
||||
int idleInterval);
|
||||
|
||||
static bool haveConsensus (
|
||||
int previousProposers, int currentProposers,
|
||||
int currentAgree, int currentClosed,
|
||||
int previousAgreeTime, int currentAgreeTime,
|
||||
bool forReal, bool& failed);
|
||||
|
||||
static int getNextLedgerTimeResolution (int previousResolution, bool previousAgree, int ledgerSeq);
|
||||
};
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -449,7 +449,7 @@ close_and_advance(Ledger::pointer& ledger, Ledger::pointer& LCL)
|
||||
std::uint32_t closeTime = time_point_cast<seconds> // now
|
||||
(system_clock::now() - epoch_offset).
|
||||
time_since_epoch().count();
|
||||
int closeResolution = seconds(LEDGER_TIME_ACCURACY).count();
|
||||
int closeResolution = seconds(ledgerDefaultTimeResolution).count();
|
||||
bool closeTimeCorrect = true;
|
||||
newLCL->setAccepted(closeTime, closeResolution, closeTimeCorrect);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/shamap/SHAMap.h>
|
||||
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// This code is used to compare another node's transaction tree
|
||||
@@ -123,12 +123,12 @@ SHAMap::compare (std::shared_ptr<SHAMap> const& otherMap,
|
||||
|
||||
assert (isValid () && otherMap && otherMap->isValid ());
|
||||
|
||||
using StackEntry = std::pair <SHAMapTreeNode*, SHAMapTreeNode*>;
|
||||
std::stack <StackEntry, std::vector<StackEntry>> nodeStack; // track nodes we've pushed
|
||||
|
||||
if (getHash () == otherMap->getHash ())
|
||||
return true;
|
||||
|
||||
using StackEntry = std::pair <SHAMapTreeNode*, SHAMapTreeNode*>;
|
||||
std::stack <StackEntry, std::vector<StackEntry>> nodeStack; // track nodes we've pushed
|
||||
|
||||
nodeStack.push ({root_.get(), otherMap->root_.get()});
|
||||
while (!nodeStack.empty ())
|
||||
{
|
||||
@@ -221,12 +221,12 @@ SHAMap::compare (std::shared_ptr<SHAMap> const& otherMap,
|
||||
|
||||
void SHAMap::walkMap (std::vector<SHAMapMissingNode>& missingNodes, int maxMissing) const
|
||||
{
|
||||
std::stack <std::shared_ptr<SHAMapTreeNode>,
|
||||
std::vector <std::shared_ptr<SHAMapTreeNode>>> nodeStack;
|
||||
|
||||
if (!root_->isInner ()) // root_ is only node, and we have it
|
||||
return;
|
||||
|
||||
using StackEntry = std::shared_ptr<SHAMapTreeNode>;
|
||||
std::stack <StackEntry, std::vector <StackEntry>> nodeStack;
|
||||
|
||||
nodeStack.push (root_);
|
||||
|
||||
while (!nodeStack.empty ())
|
||||
|
||||
Reference in New Issue
Block a user