Infrastructure for continuous ledger close.

This commit is contained in:
JoelKatz
2012-06-30 16:58:05 -07:00
parent 01cdd91b8c
commit 182228b6f9
8 changed files with 49 additions and 52 deletions

View File

@@ -141,7 +141,7 @@ void Application::run()
assert(!!secondLedger->getAccountState(rootAddress));
// temporary
mNetOps.setStateTimer(0);
mNetOps.setStateTimer();
mIOService.run(); // This blocks

View File

@@ -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<unsigned char>& rawLedger) : mCloseTime(0),
@@ -77,7 +75,6 @@ Ledger::Ledger(const std::vector<unsigned char>& 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

View File

@@ -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<unsigned char>& 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; }

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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<Peer::pointer>& peerList, uint256& networkClosed)

View File

@@ -154,7 +154,7 @@ public:
bool checkLastClosedLedger(const std::vector<Peer::pointer>&, 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