From e56f7a86898a3b0f7018bcc67f31d440b4c7b2bc Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 14 Mar 2013 09:48:43 -0700 Subject: [PATCH 1/3] Fix a rare race condition. --- src/cpp/ripple/LedgerConsensus.cpp | 2 +- src/cpp/ripple/LedgerConsensus.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index 15b03e8784..ac09032f76 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -900,7 +900,7 @@ SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool do return SHAMap::pointer(); } -void LedgerConsensus::startAcquiring(const TransactionAcquire::pointer& acquire) +void LedgerConsensus::startAcquiring(TransactionAcquire::pointer acquire) { boost::unordered_map< uint256, std::vector< boost::weak_ptr > >::iterator it = mPeerData.find(acquire->getHash()); diff --git a/src/cpp/ripple/LedgerConsensus.h b/src/cpp/ripple/LedgerConsensus.h index 1e6ef47941..e511ad4a01 100644 --- a/src/cpp/ripple/LedgerConsensus.h +++ b/src/cpp/ripple/LedgerConsensus.h @@ -128,7 +128,7 @@ protected: void accept(SHAMap::ref txSet, LoadEvent::pointer); void weHave(const uint256& id, Peer::ref avoidPeer); - void startAcquiring(const TransactionAcquire::pointer&); + void startAcquiring(TransactionAcquire::pointer); SHAMap::pointer find(const uint256& hash); void createDisputes(SHAMap::ref, SHAMap::ref); From 82b91a1c41f6cf8d77a3437f053f8df23837407d Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 14 Mar 2013 10:00:44 -0700 Subject: [PATCH 2/3] Avoid excessive resizing. --- src/cpp/ripple/ValidationCollection.cpp | 1 + src/cpp/ripple/ValidationCollection.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/ValidationCollection.cpp b/src/cpp/ripple/ValidationCollection.cpp index 032ff4066c..acb8c31575 100644 --- a/src/cpp/ripple/ValidationCollection.cpp +++ b/src/cpp/ripple/ValidationCollection.cpp @@ -309,6 +309,7 @@ void ValidationCollection::doWrite(Job&) while (!mStaleValidations.empty()) { std::vector vector; + vector.reserve(512); mStaleValidations.swap(vector); sl.unlock(); { diff --git a/src/cpp/ripple/ValidationCollection.h b/src/cpp/ripple/ValidationCollection.h index 648ea173cb..bcde16aa21 100644 --- a/src/cpp/ripple/ValidationCollection.h +++ b/src/cpp/ripple/ValidationCollection.h @@ -20,7 +20,7 @@ class ValidationCollection { protected: - boost::mutex mValidationLock; + boost::mutex mValidationLock; TaggedCache mValidations; boost::unordered_map mCurrentValidations; std::vector mStaleValidations; @@ -34,7 +34,8 @@ protected: boost::shared_ptr findSet(const uint256& ledgerHash); public: - ValidationCollection() : mValidations("Validations", 128, 600), mWriting(false) { ; } + ValidationCollection() : mValidations("Validations", 128, 600), mWriting(false) + { mStaleValidations.reserve(512); } bool addValidation(SerializedValidation::ref); ValidationSet getValidations(const uint256& ledger); From d4323f2ef2b34e3e4095732f7e8c8f0534b93cb3 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 14 Mar 2013 11:48:29 -0700 Subject: [PATCH 3/3] 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. --- src/cpp/ripple/LedgerConsensus.cpp | 7 +++++-- src/cpp/ripple/LedgerTiming.h | 4 ++-- src/cpp/ripple/NetworkOPs.cpp | 2 +- src/cpp/ripple/ValidationCollection.cpp | 6 ++++-- src/cpp/ripple/ValidationCollection.h | 4 +++- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index ac09032f76..d4fc7d97fa 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -373,9 +373,12 @@ void LedgerConsensus::checkLCL() uint256 netLgr = mPrevLedgerHash; 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 vals = - theApp->getValidations().getCurrentValidations(favoredLedger); + theApp->getValidations().getCurrentValidations(favoredLedger, priorLedger); typedef std::map::value_type u256_cvc_pair; BOOST_FOREACH(u256_cvc_pair& it, vals) diff --git a/src/cpp/ripple/LedgerTiming.h b/src/cpp/ripple/LedgerTiming.h index c7539c081a..246db51cfb 100644 --- a/src/cpp/ripple/LedgerTiming.h +++ b/src/cpp/ripple/LedgerTiming.h @@ -7,11 +7,11 @@ // 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 -# define LEDGER_VAL_INTERVAL 600 +# define LEDGER_VAL_INTERVAL 300 // The number of seconds before a close time that we consider a validation acceptable // 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 # define LEDGER_MIN_CONSENSUS 2000 diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 742e630f13..9bc3745b6f 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -685,7 +685,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis boost::unordered_map ledgers; { boost::unordered_map current = - theApp->getValidations().getCurrentValidations(closedLedger); + theApp->getValidations().getCurrentValidations(closedLedger, prevClosedLedger); typedef std::map::value_type u256_cvc_pair; BOOST_FOREACH(const u256_cvc_pair& it, current) { diff --git a/src/cpp/ripple/ValidationCollection.cpp b/src/cpp/ripple/ValidationCollection.cpp index acb8c31575..cdbb2818e1 100644 --- a/src/cpp/ripple/ValidationCollection.cpp +++ b/src/cpp/ripple/ValidationCollection.cpp @@ -228,10 +228,11 @@ std::list ValidationCollection::getCurrentTrusted } boost::unordered_map -ValidationCollection::getCurrentValidations(uint256 currentLedger) +ValidationCollection::getCurrentValidations(uint256 currentLedger, uint256 priorLedger) { uint32 cutoff = theApp->getOPs().getNetworkTimeNC() - LEDGER_VAL_INTERVAL; bool valCurrentLedger = currentLedger.isNonZero(); + bool valPriorLedger = priorLedger.isNonZero(); boost::unordered_map ret; @@ -250,7 +251,8 @@ ValidationCollection::getCurrentValidations(uint256 currentLedger) } else { // 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(); currentValidationCount& p = countPreferred ? ret[currentLedger] : ret[it->second->getLedgerHash()]; diff --git a/src/cpp/ripple/ValidationCollection.h b/src/cpp/ripple/ValidationCollection.h index bcde16aa21..112e9c1113 100644 --- a/src/cpp/ripple/ValidationCollection.h +++ b/src/cpp/ripple/ValidationCollection.h @@ -47,7 +47,9 @@ public: int getNodesAfter(const uint256& ledger); int getLoadRatio(bool overLoaded); - boost::unordered_map getCurrentValidations(uint256 currentLedger); + boost::unordered_map getCurrentValidations( + uint256 currentLedger, uint256 previousLedger); + std::list getCurrentTrustedValidations(); void tune(int size, int age);