diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index f2e73e647f..12fd086f9c 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -249,7 +249,7 @@ void LedgerConsensus::checkLCL() uint256 netLgr = mPrevLedgerHash; int netLgrCount = 0; - boost::unordered_map vals = theApp->getValidations().getCurrentValidations(); + boost::unordered_map vals = theApp->getValidations().getCurrentValidations(mPrevLedgerHash); typedef std::pair u256_int_pair; BOOST_FOREACH(u256_int_pair& it, vals) { diff --git a/src/SerializedValidation.h b/src/SerializedValidation.h index 81e4c1d6e1..299c35a0ed 100644 --- a/src/SerializedValidation.h +++ b/src/SerializedValidation.h @@ -8,6 +8,7 @@ class SerializedValidation : public STObject { protected: STVariableLength mSignature; + uint256 mPreviousHash; bool mTrusted; void setNode(); @@ -40,6 +41,11 @@ public: void addSignature(Serializer&) const; std::vector getSigned() const; std::vector getSignature() const; + + // The validation this replaced + const uint256& getPreviousHash() { return mPreviousHash; } + bool isPreviousHash(const uint256& h) { return mPreviousHash == h; } + void setPreviousHash(const uint256& h) { mPreviousHash = h; } }; #endif diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index b6d109777c..28cb2a59d1 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -41,6 +41,7 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va it->second = val; else if (val->getSignTime() > it->second->getSignTime()) { + val->setPreviousHash(it->second->getPreviousHash()); mStaleValidations.push_back(it->second); it->second = val; condWrite(); @@ -128,9 +129,11 @@ int ValidationCollection::getCurrentValidationCount(uint32 afterTime) return count; } -boost::unordered_map ValidationCollection::getCurrentValidations() +boost::unordered_map ValidationCollection::getCurrentValidations(uint256 currentLedger) { uint32 cutoff = theApp->getOPs().getNetworkTimeNC() - LEDGER_VAL_INTERVAL; + bool valCurrentLedger = currentLedger.isNonZero(); + boost::unordered_map ret; { @@ -149,7 +152,10 @@ boost::unordered_map ValidationCollection::getCurrentValidations() } else { // contains a live record - ++ret[it->second->getLedgerHash()]; + if (valCurrentLedger && it->second->isPreviousHash(currentLedger)) + ++ret[currentLedger]; // count for the favored ledger + else + ++ret[it->second->getLedgerHash()]; ++it; } } @@ -160,6 +166,7 @@ boost::unordered_map ValidationCollection::getCurrentValidations() bool ValidationCollection::isDeadLedger(const uint256& ledger) { + boost::mutex::scoped_lock sl(mValidationLock); BOOST_FOREACH(const uint256& it, mDeadLedgers) if (it == ledger) return true; @@ -168,11 +175,13 @@ bool ValidationCollection::isDeadLedger(const uint256& ledger) void ValidationCollection::addDeadLedger(const uint256& ledger) { + boost::mutex::scoped_lock sl(mValidationLock); + if (isDeadLedger(ledger)) return; mDeadLedgers.push_back(ledger); - if (mDeadLedgers.size() >= 128) + if (mDeadLedgers.size() >= 32) mDeadLedgers.pop_front(); } @@ -220,13 +229,11 @@ void ValidationCollection::doWrite() std::vector vector; mStaleValidations.swap(vector); sl.unlock(); - { - ScopedLock dbl(theApp->getLedgerDB()->getDBLock()); Database *db = theApp->getLedgerDB()->getDB(); + ScopedLock dbl(theApp->getLedgerDB()->getDBLock()); + db->executeSQL("BEGIN TRANSACTION;"); - - BOOST_FOREACH(const SerializedValidation::pointer& it, vector) db->executeSQL(boost::str(insVal % it->getLedgerHash().GetHex() % it->getSignerPublic().humanNodePublic() % it->getFlags() % it->getSignTime() diff --git a/src/ValidationCollection.h b/src/ValidationCollection.h index 4a5912abfe..287ba6b68f 100644 --- a/src/ValidationCollection.h +++ b/src/ValidationCollection.h @@ -37,7 +37,7 @@ public: int getTrustedValidationCount(const uint256& ledger); int getCurrentValidationCount(uint32 afterTime); - boost::unordered_map getCurrentValidations(); + boost::unordered_map getCurrentValidations(uint256 currentLedger = uint256()); void addDeadLedger(const uint256&); bool isDeadLedger(const uint256&);