From 0b38ffc9723913f3517d5dd6aac883f2f2bbb7f9 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 1 Nov 2012 15:46:11 -0700 Subject: [PATCH] Fix the validation leak. --- src/Application.cpp | 1 + src/SerializedValidation.cpp | 2 ++ src/SerializedValidation.h | 5 ++++- src/ValidationCollection.cpp | 40 +++++++++++++++++++++++++----------- src/ValidationCollection.h | 9 ++++++-- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index f4f1e99d18..37f497827a 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -191,6 +191,7 @@ void Application::sweep() mHashedObjectStore.sweep(); mMasterLedger.sweep(); mTempNodeCache.sweep(); + mValidations.sweep(); mSweepTimer.expires_from_now(boost::posix_time::seconds(60)); mSweepTimer.async_wait(boost::bind(&Application::sweep, this)); } diff --git a/src/SerializedValidation.cpp b/src/SerializedValidation.cpp index 313577a2c4..75d8249abb 100644 --- a/src/SerializedValidation.cpp +++ b/src/SerializedValidation.cpp @@ -4,6 +4,8 @@ #include "HashPrefixes.h" #include "Log.h" +DECLARE_INSTANCE(SerializedValidation); + std::vector sValidationFormat; static bool SVFInit() diff --git a/src/SerializedValidation.h b/src/SerializedValidation.h index eae4dffad8..57b3b42a8b 100644 --- a/src/SerializedValidation.h +++ b/src/SerializedValidation.h @@ -3,8 +3,11 @@ #include "SerializedObject.h" #include "RippleAddress.h" +#include "InstanceCounter.h" -class SerializedValidation : public STObject +DEFINE_INSTANCE(SerializedValidation); + +class SerializedValidation : public STObject, private IS_INSTANCE(SerializedValidation) { protected: uint256 mPreviousHash; diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index 70b83f0c57..a66ca7edf1 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -10,6 +10,23 @@ SETUP_LOG(); typedef std::pair u160_val_pair; +typedef boost::shared_ptr VSpointer; + +VSpointer ValidationCollection::findCreateSet(const uint256& ledgerHash) +{ + VSpointer j = mValidations.fetch(ledgerHash); + if (!j) + { + j = boost::make_shared(); + mValidations.canonicalize(ledgerHash, j); + } + return j; +} + +VSpointer ValidationCollection::findSet(const uint256& ledgerHash) +{ + return mValidations.fetch(ledgerHash); +} bool ValidationCollection::addValidation(const SerializedValidation::pointer& val) { @@ -37,7 +54,7 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va { boost::mutex::scoped_lock sl(mValidationLock); - if (!mValidations[hash].insert(std::make_pair(node, val)).second) + if (!findCreateSet(hash)->insert(std::make_pair(node, val)).second) return false; if (isCurrent) { @@ -63,25 +80,24 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va ValidationSet ValidationCollection::getValidations(const uint256& ledger) { - ValidationSet ret; { boost::mutex::scoped_lock sl(mValidationLock); - boost::unordered_map::iterator it = mValidations.find(ledger); - if (it != mValidations.end()) - ret = it->second; + VSpointer set = findSet(ledger); + if (set != VSpointer()) + return *set; } - return ret; + return ValidationSet(); } void ValidationCollection::getValidationCount(const uint256& ledger, bool currentOnly, int& trusted, int &untrusted) { trusted = untrusted = 0; boost::mutex::scoped_lock sl(mValidationLock); - boost::unordered_map::iterator it = mValidations.find(ledger); + VSpointer set = findSet(ledger); uint32 now = theApp->getOPs().getNetworkTimeNC(); - if (it != mValidations.end()) + if (set) { - for (ValidationSet::iterator vit = it->second.begin(), end = it->second.end(); vit != end; ++vit) + for (ValidationSet::iterator vit = set->begin(), end = set->end(); vit != end; ++vit) { bool isTrusted = vit->second->isTrusted(); if (isTrusted && currentOnly) @@ -107,10 +123,10 @@ int ValidationCollection::getTrustedValidationCount(const uint256& ledger) { int trusted = 0; boost::mutex::scoped_lock sl(mValidationLock); - for (boost::unordered_map::iterator it = mValidations.find(ledger), - end = mValidations.end(); it != end; ++it) + VSpointer set = findSet(ledger); + if (set) { - for (ValidationSet::iterator vit = it->second.begin(), end = it->second.end(); vit != end; ++vit) + for (ValidationSet::iterator vit = set->begin(), end = set->end(); vit != end; ++vit) { if (vit->second->isTrusted()) ++trusted; diff --git a/src/ValidationCollection.h b/src/ValidationCollection.h index c4653a86a4..e4a22ec4fc 100644 --- a/src/ValidationCollection.h +++ b/src/ValidationCollection.h @@ -9,6 +9,7 @@ #include "uint256.h" #include "types.h" #include "SerializedValidation.h" +#include "TaggedCache.h" typedef boost::unordered_map ValidationSet; @@ -19,7 +20,7 @@ class ValidationCollection protected: boost::mutex mValidationLock; - boost::unordered_map mValidations; + TaggedCache mValidations; boost::unordered_map mCurrentValidations; std::vector mStaleValidations; @@ -28,8 +29,11 @@ protected: void doWrite(); void condWrite(); + boost::shared_ptr findCreateSet(const uint256& ledgerHash); + boost::shared_ptr findSet(const uint256& ledgerHash); + public: - ValidationCollection() : mWriting(false) { ; } + ValidationCollection() : mValidations("Validations", 128, 500), mWriting(false) { ; } bool addValidation(const SerializedValidation::pointer&); ValidationSet getValidations(const uint256& ledger); @@ -43,6 +47,7 @@ public: boost::unordered_map getCurrentValidations(uint256 currentLedger); void flush(); + void sweep() { mValidations.sweep(); } }; #endif