diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 1f6466c7ae..a8db44aa8c 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -180,7 +180,7 @@ bool LCTransaction::updatePosition(int percentTime, bool proposing) { #ifdef LC_DEBUG Log(lsTRACE) << "No change (" << (mOurPosition ? "YES" : "NO") << ") : weight " - << weight << ", seconds " << seconds; + << weight << ", percent " << percentTime; #endif return false; } @@ -191,14 +191,14 @@ bool LCTransaction::updatePosition(int percentTime, bool proposing) LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint32 closeTime) : mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPrevLedgerHash(prevLCLHash), mPreviousLedger(previousLedger), - mCurrentSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false) + mCurrentMSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false) { mValSeed = theConfig.VALIDATION_SEED; Log(lsDEBUG) << "Creating consensus object"; Log(lsTRACE) << "LCL:" << previousLedger->getHash().GetHex() <<", ct=" << closeTime; mPreviousProposers = theApp->getOPs().getPreviousProposers(); - mPreviousSeconds = theApp->getOPs().getPreviousSeconds(); - assert(mPreviousSeconds); + mPreviousMSeconds = theApp->getOPs().getPreviousConvergeTime(); + assert(mPreviousMSeconds); mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution( previousLedger->getCloseResolution(), previousLedger->getCloseAgree(), previousLedger->getLedgerSeq() + 1); @@ -367,10 +367,11 @@ void LedgerConsensus::statePreClose() bool anyTransactions = theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap()->getHash().isNonZero(); int proposersClosed = mPeerPositions.size(); - int sinceClose = theApp->getOPs().getNetworkTimeNC() - theApp->getOPs().getLastCloseNetTime(); + // This ledger is open. This computes how long since the last ledger closed + int sinceClose = 1000 * (theApp->getOPs().getNetworkTimeNC() - theApp->getOPs().getLastCloseNetTime()); if (sinceClose >= ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed, - mPreviousSeconds, sinceClose)) + mPreviousMSeconds, sinceClose)) { // it is time to close the ledger (swap default and wobble ledgers) Log(lsINFO) << "CLC:: closing ledger"; mState = lcsESTABLISH; @@ -386,7 +387,7 @@ void LedgerConsensus::statePreClose() void LedgerConsensus::stateEstablish() { // we are establishing consensus - if (mCurrentSeconds < LEDGER_MIN_CONSENSUS) + if (mCurrentMSeconds < LEDGER_MIN_CONSENSUS) return; updateOurPositions(); if (!mHaveCloseTimeConsensus) @@ -406,9 +407,7 @@ void LedgerConsensus::stateFinished() // logic of calculating next ledger advances us out of this state // CHECKME: Should we count proposers that didn't converge to our consensus set? - int convergeTime = (boost::posix_time::second_clock::universal_time() - mConsensusStartTime).seconds(); - if (convergeTime <= 0) convergeTime = 1; - theApp->getOPs().newLCL(mPeerPositions.size(), convergeTime, mNewLedgerHash); + theApp->getOPs().newLCL(mPeerPositions.size(), mCurrentMSeconds, mNewLedgerHash); } void LedgerConsensus::stateAccepted() @@ -433,14 +432,15 @@ void LedgerConsensus::timerEntry() else Log(lsINFO) << "We still don't have it"; } - mCurrentSeconds = (mCloseTime != 0) ? (theApp->getOPs().getNetworkTimeNC() - mCloseTime) : 0; - mClosePercent = mCurrentSeconds * 100 / mPreviousSeconds; + mCurrentMSeconds = (mCloseTime == 0) ? 0 : + (boost::posix_time::second_clock::universal_time() - mConsensusStartTime).total_milliseconds(); + mClosePercent = mCurrentMSeconds * 100 / mPreviousMSeconds; switch (mState) { - case lcsPRE_CLOSE: statePreClose(); return; - case lcsESTABLISH: stateEstablish(); return; - case lcsFINISHED: stateFinished(); return; + case lcsPRE_CLOSE: statePreClose(); if (mState != lcsESTABLISH) return; + case lcsESTABLISH: stateEstablish(); if (mState != lcsFINISHED) return; + case lcsFINISHED: stateFinished(); if (mState != lcsACCEPTED) return; case lcsACCEPTED: stateAccepted(); return; } assert(false); @@ -527,7 +527,7 @@ bool LedgerConsensus::haveConsensus() } int currentValidations = theApp->getValidations().getCurrentValidationCount(mPreviousLedger->getCloseTimeNC()); return ContinuousLedgerTiming::haveConsensus(mPreviousProposers, agree + disagree, agree, currentValidations, - mPreviousSeconds, mCurrentSeconds); + mPreviousMSeconds, mCurrentMSeconds); } SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool doAcquire) diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 43fd2e9528..afa0be22ca 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -86,12 +86,12 @@ protected: NewcoinAddress mValSeed; bool mProposing, mValidating, mHaveCorrectLCL; - int mCurrentSeconds, mClosePercent, mCloseResolution; + int mCurrentMSeconds, mClosePercent, mCloseResolution; bool mHaveCloseTimeConsensus; boost::posix_time::ptime mConsensusStartTime; int mPreviousProposers; - int mPreviousSeconds; + int mPreviousMSeconds; // Convergence tracking, trusted peers indexed by hash of public key boost::unordered_map mPeerPositions; diff --git a/src/LedgerTiming.cpp b/src/LedgerTiming.cpp index 360ae2d341..e3ea061640 100644 --- a/src/LedgerTiming.cpp +++ b/src/LedgerTiming.cpp @@ -16,15 +16,15 @@ int ContinuousLedgerTiming::shouldClose( bool anyTransactions, int previousProposers, // proposers in the last closing int proposersClosed, // proposers who have currently closed this ledgers - int previousSeconds, // seconds the previous ledger took to reach consensus - int currentSeconds) // seconds since the previous ledger closed + int previousMSeconds, // seconds the previous ledger took to reach consensus + int currentMSeconds) // seconds since the previous ledger closed { - assert((previousSeconds > 0) && (previousSeconds < 600)); - assert((currentSeconds >= 0) && (currentSeconds < 600)); + assert((previousMSeconds > 0) && (previousMSeconds < 600000)); + assert((currentMSeconds >= 0) && (currentMSeconds < 600000)); #if 0 Log(lsTRACE) << boost::str(boost::format("CLC::shouldClose Trans=%s, Prop: %d/%d, Secs: %d (last:%d)") % - (anyTransactions ? "yes" : "no") % previousProposers % proposersClosed % currentSeconds % previousSeconds); + (anyTransactions ? "yes" : "no") % previousProposers % proposersClosed % currentMSeconds % previousMSeconds); #endif if (!anyTransactions) @@ -32,24 +32,26 @@ int ContinuousLedgerTiming::shouldClose( if (proposersClosed > (previousProposers / 4)) // did we miss a transaction? { Log(lsTRACE) << "no transactions, many proposers: now"; - return currentSeconds; + return currentMSeconds; } - if (previousSeconds > (LEDGER_IDLE_INTERVAL + 2)) // the last ledger was very slow to close + if (previousMSeconds > (1000 * (LEDGER_IDLE_INTERVAL + 2))) // the last ledger was very slow to close { Log(lsTRACE) << "slow to close"; - return previousSeconds - 1; + if (previousMSeconds < 2000) + return previousMSeconds; + return previousMSeconds - 1000; } - return LEDGER_IDLE_INTERVAL; // normal idle + return LEDGER_IDLE_INTERVAL * 1000; // normal idle } - if (previousSeconds == LEDGER_IDLE_INTERVAL) // coming out of idle, close now + if (previousMSeconds == (1000 * LEDGER_IDLE_INTERVAL)) // coming out of idle, close now { Log(lsTRACE) << "leaving idle, close now"; - return currentSeconds; + return currentMSeconds; } Log(lsTRACE) << "close now"; - return currentSeconds; // this ledger should close now + return currentMSeconds; // this ledger should close now } // Returns whether we have a consensus or not. If so, we expect all honest nodes @@ -70,7 +72,7 @@ bool ContinuousLedgerTiming::haveConsensus( 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 + 2)) + if (currentAgreeTime < (previousAgreeTime + LEDGER_MIN_CONSENSUS)) { Log(lsTRACE) << "too fast, not enough proposers"; return false; diff --git a/src/LedgerTiming.h b/src/LedgerTiming.h index 2b580a6057..add26558f1 100644 --- a/src/LedgerTiming.h +++ b/src/LedgerTiming.h @@ -7,8 +7,8 @@ // The number of seconds a validation remains current # define LEDGER_MAX_INTERVAL 60 -// The number of seconds we wait minimum to ensure participation -# define LEDGER_MIN_CONSENSUS 2 +// The number of milliseconds we wait minimum to ensure participation +# define LEDGER_MIN_CONSENSUS 2000 // Initial resolution of ledger close time # define LEDGER_TIME_ACCURACY 30 @@ -19,6 +19,9 @@ // How often to decrease resolution # define LEDGER_RES_DECREASE 1 +// How often we check state or change positions (in milliseconds) +# define LEDGER_GRANULARITY 1000 + // Avalanche tuning #define AV_INIT_CONSENSUS_PCT 50 // percentage of nodes on our UNL that must vote yes diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 085284ff0e..683f7d0c02 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -280,7 +280,7 @@ RippleState::pointer NetworkOPs::accessRippleState(const uint256& uLedger, const void NetworkOPs::setStateTimer() { // set timer early if ledger is closing - mNetTimer.expires_from_now(boost::posix_time::seconds(1)); + mNetTimer.expires_from_now(boost::posix_time::milliseconds(LEDGER_GRANULARITY)); mNetTimer.async_wait(boost::bind(&NetworkOPs::checkState, this, boost::asio::placeholders::error)); } diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index a037e67366..d2828fb919 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -182,7 +182,7 @@ public: void setStateTimer(); void newLCL(int proposers, int convergeTime, const uint256& ledgerHash); int getPreviousProposers() { return mLastCloseProposers; } - int getPreviousSeconds() { return mLastCloseConvergeTime; } + int getPreviousConvergeTime() { return mLastCloseConvergeTime; } uint32 getLastCloseNetTime() { return mLastCloseNetTime; } void setLastCloseNetTime(uint32 t) { mLastCloseNetTime = t; } Json::Value getServerInfo();