diff --git a/src/Application.cpp b/src/Application.cpp index cc68d9cc39..8e24b10ad1 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -141,7 +141,7 @@ void Application::run() assert(!!secondLedger->getAccountState(rootAddress)); // temporary - mNetOps.setStateTimer(0); + mNetOps.setStateTimer(); mIOService.run(); // This blocks diff --git a/src/Ledger.cpp b/src/Ledger.cpp index c24931a5f9..de0cfb2550 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -22,7 +22,7 @@ #include "Log.h" Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount), - mCloseTime(0), mLedgerSeq(0), mLedgerInterval(LEDGER_INTERVAL), mClosed(false), mValidHash(false), + mCloseTime(0), mLedgerSeq(0), mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false), mTransactionMap(new SHAMap()), mAccountStateMap(new SHAMap()) { // special case: put coins in root account @@ -39,14 +39,13 @@ Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(s Ledger::Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash, uint64 totCoins, uint64 timeStamp, uint32 ledgerSeq) : mParentHash(parentHash), mTransHash(transHash), mAccountHash(accountHash), - mTotCoins(totCoins), mCloseTime(timeStamp), mLedgerSeq(ledgerSeq), mLedgerInterval(LEDGER_INTERVAL), + mTotCoins(totCoins), mCloseTime(timeStamp), mLedgerSeq(ledgerSeq), mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false) { updateHash(); } -Ledger::Ledger(Ledger& ledger, bool isMutable) : mTotCoins(ledger.mTotCoins), - mLedgerSeq(ledger.mLedgerSeq), mLedgerInterval(ledger.mLedgerInterval), +Ledger::Ledger(Ledger& ledger, bool isMutable) : mTotCoins(ledger.mTotCoins), mLedgerSeq(ledger.mLedgerSeq), mClosed(ledger.mClosed), mValidHash(false), mAccepted(ledger.mAccepted), mImmutable(!isMutable), mTransactionMap(ledger.mTransactionMap->snapShot(isMutable)), mAccountStateMap(ledger.mAccountStateMap->snapShot(isMutable)) @@ -55,15 +54,14 @@ Ledger::Ledger(Ledger& ledger, bool isMutable) : mTotCoins(ledger.mTotCoins), } -Ledger::Ledger(bool, Ledger& prevLedger) : mTotCoins(prevLedger.mTotCoins), - mLedgerSeq(prevLedger.mLedgerSeq + 1), mLedgerInterval(prevLedger.mLedgerInterval), +Ledger::Ledger(uint64 closeTime, Ledger& prevLedger) : + mTotCoins(prevLedger.mTotCoins), mCloseTime(closeTime), mLedgerSeq(prevLedger.mLedgerSeq + 1), mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false), mTransactionMap(new SHAMap()), mAccountStateMap(prevLedger.mAccountStateMap->snapShot(true)) { // Create a new ledger that follows this one prevLedger.updateHash(); mParentHash = prevLedger.getHash(); assert(mParentHash.isNonZero()); - mCloseTime = prevLedger.getNextLedgerClose(); } Ledger::Ledger(const std::vector& rawLedger) : mCloseTime(0), @@ -77,7 +75,6 @@ Ledger::Ledger(const std::vector& rawLedger) : mCloseTime(0), if (!s.get256(mTransHash, BLgPTxT)) return; if (!s.get256(mAccountHash, BLgPAcT)) return; if (!s.get64(mCloseTime, BLgPClTs)) return; - if (!s.get16(mLedgerInterval, BLgPNlIn)) return; updateHash(); if(mValidHash) { @@ -97,7 +94,6 @@ Ledger::Ledger(const std::string& rawLedger) : mCloseTime(0), if (!s.get256(mTransHash, BLgPTxT)) return; if (!s.get256(mAccountHash, BLgPAcT)) return; if (!s.get64(mCloseTime, BLgPClTs)) return; - if (!s.get16(mLedgerInterval, BLgPNlIn)) return; updateHash(); if(mValidHash) { @@ -131,7 +127,6 @@ void Ledger::addRaw(Serializer &s) s.add256(mTransHash); s.add256(mAccountHash); s.add64(mCloseTime); - s.add16(mLedgerInterval); } AccountState::pointer Ledger::getAccountState(const NewcoinAddress& accountID) @@ -472,23 +467,28 @@ boost::posix_time::ptime Ledger::getCloseTime() const void Ledger::setCloseTime(boost::posix_time::ptime ptm) { + assert(!mImmutable); mCloseTime = iToSeconds(ptm); } uint64 Ledger::sGenesisClose = 0; -uint64 Ledger::getNextLedgerClose() const +uint64 Ledger::getNextLedgerClose(int prevCloseSeconds) const { if (mCloseTime == 0) { if (sGenesisClose == 0) { - uint64 closeTime = theApp->getOPs().getNetworkTimeNC() + mLedgerInterval - 1; - sGenesisClose = closeTime - (closeTime % mLedgerInterval); + uint64 closeTime = theApp->getOPs().getNetworkTimeNC() + LEDGER_IDLE_INTERVAL - 1; + sGenesisClose = closeTime - (closeTime % LEDGER_IDLE_INTERVAL); } return sGenesisClose; } - return mCloseTime + mLedgerInterval; + if (prevCloseSeconds < 0) + return mCloseTime + LEDGER_IDLE_INTERVAL; + if (prevCloseSeconds < 2) + return mCloseTime + prevCloseSeconds; + return mCloseTime + prevCloseSeconds - 1; } // vim:ts=4 diff --git a/src/Ledger.h b/src/Ledger.h index 482fb27ba3..99cd25a7e3 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -64,9 +64,8 @@ private: uint256 mHash, mParentHash, mTransHash, mAccountHash; uint64 mTotCoins; - uint64 mCloseTime; // when this ledger closes + uint64 mCloseTime; // when this ledger should close / did close uint32 mLedgerSeq; - uint16 mLedgerInterval; bool mClosed, mValidHash, mAccepted, mImmutable; SHAMap::pointer mTransactionMap, mAccountStateMap; @@ -92,7 +91,7 @@ public: uint64 totCoins, uint64 timeStamp, uint32 ledgerSeq); // used for database ledgers Ledger(const std::vector& rawLedger); Ledger(const std::string& rawLedger); - Ledger(bool fromAccepted, Ledger& previous); // ledger after this one + Ledger(uint64 defaultCloseTime, Ledger& previous); // ledger after this one Ledger(Ledger& target, bool isMutable); // snapshot void updateHash(); @@ -120,12 +119,12 @@ public: void destroyCoins(uint64 fee) { mTotCoins -= fee; } uint64 getCloseTimeNC() const { return mCloseTime; } uint32 getLedgerSeq() const { return mLedgerSeq; } - uint16 getInterval() const { return mLedgerInterval; } // close time functions - boost::posix_time::ptime getCloseTime() const; + void setCloseTime(uint64 ct) { assert(!mImmutable); mCloseTime = ct; } void setCloseTime(boost::posix_time::ptime); - uint64 getNextLedgerClose() const; + boost::posix_time::ptime getCloseTime() const; + uint64 getNextLedgerClose(int prevCloseSeconds) const; // low level functions SHAMap::pointer peekTransactionMap() { return mTransactionMap; } diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 6cc8abf844..1602758e60 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -416,7 +416,7 @@ int LedgerConsensus::stateAccepted(int secondsSinceClose) return 4; } -int LedgerConsensus::timerEntry() +void LedgerConsensus::timerEntry() { if (!mHaveCorrectLCL) { @@ -435,16 +435,15 @@ int LedgerConsensus::timerEntry() switch (mState) { - case lcsPRE_CLOSE: return statePreClose(sinceClose); - case lcsPOST_CLOSE: return statePostClose(sinceClose); - case lcsESTABLISH: return stateEstablish(sinceClose); - case lcsCUTOFF: return stateCutoff(sinceClose); - case lcsFINISHED: return stateFinished(sinceClose); - case lcsACCEPTED: return stateAccepted(sinceClose); - case lcsABORTED: return 1; + case lcsPRE_CLOSE: statePreClose(sinceClose); return; + case lcsPOST_CLOSE: statePostClose(sinceClose); return; + case lcsESTABLISH: stateEstablish(sinceClose); return; + case lcsCUTOFF: stateCutoff(sinceClose); return; + case lcsFINISHED: stateFinished(sinceClose); return; + case lcsACCEPTED: stateAccepted(sinceClose); return; + case lcsABORTED: return; } assert(false); - return 1; } bool LedgerConsensus::updateOurPositions(int sinceClose) diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index adf94642ee..0babb9a572 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -144,7 +144,7 @@ public: void mapComplete(const uint256& hash, SHAMap::pointer map, bool acquired); void abort(); - int timerEntry(); + void timerEntry(); // state handlers int statePreClose(int secondsSinceClose); diff --git a/src/LedgerTiming.h b/src/LedgerTiming.h index 90be3584a8..083a064ef1 100644 --- a/src/LedgerTiming.h +++ b/src/LedgerTiming.h @@ -4,8 +4,8 @@ // The number of seconds a ledger may remain idle before closing # define LEDGER_IDLE_INTERVAL 15 -// How long we wait to transition from inactive to active -# define LEDGER_IDLE_SPIN_TIME 2 +// The number of seconds a validation remains current +# define LEDGER_MAX_INTERVAL 60 // 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 3a0419e5f2..1087693eab 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -245,17 +245,9 @@ RippleState::pointer NetworkOPs::getRippleState(const uint256& uLedger, const ui // Other // -void NetworkOPs::setStateTimer(int sec) +void NetworkOPs::setStateTimer() { // set timer early if ledger is closing - if (!mConsensus && ((mMode == omFULL) || (mMode == omTRACKING))) - { - uint64 consensusTime = mLedgerMaster->getCurrentLedger()->getCloseTimeNC() - LEDGER_WOBBLE_TIME; - uint64 now = getNetworkTimeNC(); - - if (now >= consensusTime) sec = 1; - else if (sec > (consensusTime - now)) sec = (consensusTime - now); - } - mNetTimer.expires_from_now(boost::posix_time::seconds(sec)); + mNetTimer.expires_from_now(boost::posix_time::seconds(1)); mNetTimer.async_wait(boost::bind(&NetworkOPs::checkState, this, boost::asio::placeholders::error)); } @@ -292,7 +284,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) Log(lsWARNING) << "Node count (" << peerList.size() << ") has fallen below quorum (" << theConfig.NETWORK_QUORUM << ")."; } - setStateTimer(5); + setStateTimer(); return; } if (mMode == omDISCONNECTED) @@ -303,7 +295,8 @@ void NetworkOPs::checkState(const boost::system::error_code& result) if (mConsensus) { - setStateTimer(mConsensus->timerEntry()); + mConsensus->timerEntry(); + setStateTimer(); return; } @@ -341,13 +334,19 @@ void NetworkOPs::checkState(const boost::system::error_code& result) // check if the ledger is bad enough to go to omTRACKING } - int secondsToClose = theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC() - - theApp->getOPs().getNetworkTimeNC(); - if ((!mConsensus) && (secondsToClose < LEDGER_WOBBLE_TIME)) // pre close wobble - beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger()); + uint64 defaultClose = theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC(); + uint64 now = theApp->getOPs().getNetworkTimeNC(); + if (!mConsensus) + { // if now is past the ledger's default close time or there are transactions in the current ledger, close + if ((theApp->getOPs().getNetworkTimeNC() > theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC()) + || (!!theApp->getMasterLedger().getCurrentLedger()->getTransHash())) + { + beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger()); + } + } if (mConsensus) - setStateTimer(mConsensus->timerEntry()); - else setStateTimer(4); + mConsensus->timerEntry(); + setStateTimer(); } bool NetworkOPs::checkLastClosedLedger(const std::vector& peerList, uint256& networkClosed) diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index f0fa75b7ca..fd534b85dc 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -154,7 +154,7 @@ public: bool checkLastClosedLedger(const std::vector&, uint256& networkClosed); int beginConsensus(const uint256& networkClosed, Ledger::pointer closingLedger); void endConsensus(); - void setStateTimer(int seconds); + void setStateTimer(); Json::Value getServerInfo(); // client information retrieval functions