Fix a case where a node that closed slightly ahead of other ledgers can

think it's out of sync with the network and cause it to jump backwards one
ledger, causing it to be out of sync because the network was about to catch
up to it.
This commit is contained in:
JoelKatz
2013-03-14 11:48:29 -07:00
parent 82b91a1c41
commit d4323f2ef2
5 changed files with 15 additions and 8 deletions

View File

@@ -373,9 +373,12 @@ void LedgerConsensus::checkLCL()
uint256 netLgr = mPrevLedgerHash; uint256 netLgr = mPrevLedgerHash;
int netLgrCount = 0; int netLgrCount = 0;
uint256 favoredLedger = mPrevLedgerHash; // Don't get stuck one ledger back or jump one forward uint256 favoredLedger = mPrevLedgerHash; // Don't jump forward
uint256 priorLedger;
if (mHaveCorrectLCL)
priorLedger = mPreviousLedger->getParentHash(); // don't jump back
boost::unordered_map<uint256, currentValidationCount> vals = boost::unordered_map<uint256, currentValidationCount> vals =
theApp->getValidations().getCurrentValidations(favoredLedger); theApp->getValidations().getCurrentValidations(favoredLedger, priorLedger);
typedef std::map<uint256, currentValidationCount>::value_type u256_cvc_pair; typedef std::map<uint256, currentValidationCount>::value_type u256_cvc_pair;
BOOST_FOREACH(u256_cvc_pair& it, vals) BOOST_FOREACH(u256_cvc_pair& it, vals)

View File

@@ -7,11 +7,11 @@
// The number of seconds a validation remains current after its ledger's close time // 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 // This is a safety to protect against very old validations and the time it takes to adjust
// the close time accuracy window // the close time accuracy window
# define LEDGER_VAL_INTERVAL 600 # define LEDGER_VAL_INTERVAL 300
// The number of seconds before a close time that we consider a validation acceptable // The number of seconds before a close time that we consider a validation acceptable
// This protects against extreme clock errors // This protects against extreme clock errors
# define LEDGER_EARLY_INTERVAL 240 # define LEDGER_EARLY_INTERVAL 180
// The number of milliseconds we wait minimum to ensure participation // The number of milliseconds we wait minimum to ensure participation
# define LEDGER_MIN_CONSENSUS 2000 # define LEDGER_MIN_CONSENSUS 2000

View File

@@ -685,7 +685,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
boost::unordered_map<uint256, ValidationCount> ledgers; boost::unordered_map<uint256, ValidationCount> ledgers;
{ {
boost::unordered_map<uint256, currentValidationCount> current = boost::unordered_map<uint256, currentValidationCount> current =
theApp->getValidations().getCurrentValidations(closedLedger); theApp->getValidations().getCurrentValidations(closedLedger, prevClosedLedger);
typedef std::map<uint256, currentValidationCount>::value_type u256_cvc_pair; typedef std::map<uint256, currentValidationCount>::value_type u256_cvc_pair;
BOOST_FOREACH(const u256_cvc_pair& it, current) BOOST_FOREACH(const u256_cvc_pair& it, current)
{ {

View File

@@ -228,10 +228,11 @@ std::list<SerializedValidation::pointer> ValidationCollection::getCurrentTrusted
} }
boost::unordered_map<uint256, currentValidationCount> boost::unordered_map<uint256, currentValidationCount>
ValidationCollection::getCurrentValidations(uint256 currentLedger) ValidationCollection::getCurrentValidations(uint256 currentLedger, uint256 priorLedger)
{ {
uint32 cutoff = theApp->getOPs().getNetworkTimeNC() - LEDGER_VAL_INTERVAL; uint32 cutoff = theApp->getOPs().getNetworkTimeNC() - LEDGER_VAL_INTERVAL;
bool valCurrentLedger = currentLedger.isNonZero(); bool valCurrentLedger = currentLedger.isNonZero();
bool valPriorLedger = priorLedger.isNonZero();
boost::unordered_map<uint256, currentValidationCount> ret; boost::unordered_map<uint256, currentValidationCount> ret;
@@ -250,7 +251,8 @@ ValidationCollection::getCurrentValidations(uint256 currentLedger)
} }
else else
{ // contains a live record { // contains a live record
bool countPreferred = valCurrentLedger && it->second->isPreviousHash(currentLedger); bool countPreferred = (valCurrentLedger && it->second->isPreviousHash(currentLedger)) ||
(valPriorLedger && (it->second->getLedgerHash() == priorLedger));
tLog(countPreferred, lsDEBUG) << "Counting for " << currentLedger << " not " << it->second->getLedgerHash(); tLog(countPreferred, lsDEBUG) << "Counting for " << currentLedger << " not " << it->second->getLedgerHash();
currentValidationCount& p = countPreferred ? ret[currentLedger] : ret[it->second->getLedgerHash()]; currentValidationCount& p = countPreferred ? ret[currentLedger] : ret[it->second->getLedgerHash()];

View File

@@ -47,7 +47,9 @@ public:
int getNodesAfter(const uint256& ledger); int getNodesAfter(const uint256& ledger);
int getLoadRatio(bool overLoaded); int getLoadRatio(bool overLoaded);
boost::unordered_map<uint256, currentValidationCount> getCurrentValidations(uint256 currentLedger); boost::unordered_map<uint256, currentValidationCount> getCurrentValidations(
uint256 currentLedger, uint256 previousLedger);
std::list<SerializedValidation::pointer> getCurrentTrustedValidations(); std::list<SerializedValidation::pointer> getCurrentTrustedValidations();
void tune(int size, int age); void tune(int size, int age);