From 58dcc8b9c19863d3d8d1ea40d04900135ddc501a Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 20 Jun 2012 13:26:32 -0700 Subject: [PATCH] Don't use stale validiations. --- src/LedgerConsensus.cpp | 4 ++-- src/NetworkOPs.cpp | 6 ++---- src/SerializedObject.h | 1 + src/SerializedValidation.cpp | 10 +++++++++- src/SerializedValidation.h | 5 +++-- src/ValidationCollection.cpp | 31 +++++++++++++++++++++++++++---- src/ValidationCollection.h | 3 ++- 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index acb269def5..fc6a798c0e 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -825,7 +825,7 @@ void LedgerConsensus::accept(SHAMap::pointer set) if (mValidating) { SerializedValidation::pointer v = boost::make_shared - (newLCLHash, mOurPosition->peekSeed(), true); + (newLCLHash, newLCL->getCloseTimeNC(), mOurPosition->peekSeed(), true); v->setTrusted(); // FIXME: If not proposing, set not full theApp->getValidations().addValidation(v); @@ -833,7 +833,7 @@ void LedgerConsensus::accept(SHAMap::pointer set) newcoin::TMValidation val; val.set_validation(&validation[0], validation.size()); theApp->getConnectionPool().relayMessage(NULL, boost::make_shared(val, newcoin::mtVALIDATION)); - Log(lsINFO) << "Validation sent " << newLCL->getHash().GetHex(); + Log(lsINFO) << "Validation sent " << newLCLHash.GetHex(); } else Log(lsWARNING) << "Not validating"; statusChange(newcoin::neACCEPTED_LEDGER, newLCL); diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 100c9d4a1b..bad18d8862 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -269,8 +269,6 @@ public: { if (trustedValidations > v.trustedValidations) return true; if (trustedValidations < v.trustedValidations) return false; - if (untrustedValidations > v.untrustedValidations) return true; - if (untrustedValidations < v.untrustedValidations) return false; if (nodesUsing > v.nodesUsing) return true; if (nodesUsing < v.nodesUsing) return false; return highNode > v.highNode; @@ -379,7 +377,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis ValidationCount& vc = ledgers[peerLedger]; if (vc.nodesUsing == 0) { - theApp->getValidations().getValidationCount(peerLedger, + theApp->getValidations().getValidationCount(peerLedger, true, vc.trustedValidations, vc.untrustedValidations); Log(lsTRACE) << peerLedger.GetHex() << " has " << vc.trustedValidations << " trusted validations and " << vc.untrustedValidations << " untrusted"; @@ -397,7 +395,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis if (ourVC.nodesUsing == 0) { ourVC.highNode = theApp->getWallet().getNodePublic(); - theApp->getValidations().getValidationCount(closedLedger, + theApp->getValidations().getValidationCount(closedLedger, true, ourVC.trustedValidations, ourVC.untrustedValidations); } ++ourVC.nodesUsing; diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 3c322486da..ab115e1254 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -38,6 +38,7 @@ enum SOE_Field sfBorrowRate, sfBorrowStart, sfBorrower, + sfCloseTime, sfCurrency, sfCurrencyIn, sfCurrencyOut, diff --git a/src/SerializedValidation.cpp b/src/SerializedValidation.cpp index 209f870948..9c19bc7615 100644 --- a/src/SerializedValidation.cpp +++ b/src/SerializedValidation.cpp @@ -4,6 +4,7 @@ SOElement SerializedValidation::sValidationFormat[] = { { sfFlags, "Flags", STI_UINT32, SOE_FLAGS, 0 }, { sfLedgerHash, "LedgerHash", STI_HASH256, SOE_REQUIRED, 0 }, + { sfCloseTime, "CloseTime", STI_UINT64, SOE_REQUIRED, 0 }, { sfSigningKey, "SigningKey", STI_VL, SOE_REQUIRED, 0 }, { sfExtensions, "Extensions", STI_TL, SOE_IFFLAG, 0x01000000 }, { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 }, @@ -18,10 +19,12 @@ SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSi if (!isValid()) throw std::runtime_error("Invalid validation"); } -SerializedValidation::SerializedValidation(const uint256& ledgerHash, const NewcoinAddress& naSeed, bool isFull) +SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint64 closeTime, + const NewcoinAddress& naSeed, bool isFull) : STObject(sValidationFormat), mSignature("Signature"), mTrusted(false) { setValueFieldH256(sfLedgerHash, ledgerHash); + setValueFieldU64(sfCloseTime, closeTime); if (naSeed.isValid()) setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic()); if (!isFull) setFlag(sFullFlag); @@ -47,6 +50,11 @@ uint256 SerializedValidation::getLedgerHash() const return getValueFieldH256(sfLedgerHash); } +uint64 SerializedValidation::getCloseTime() const +{ + return getValueFieldU64(sfCloseTime); +} + bool SerializedValidation::isValid() const { try diff --git a/src/SerializedValidation.h b/src/SerializedValidation.h index 987a883234..ab0886a6bf 100644 --- a/src/SerializedValidation.h +++ b/src/SerializedValidation.h @@ -23,9 +23,10 @@ public: SerializedValidation(SerializerIterator& sit, bool checkSignature = true); SerializedValidation(const Serializer& s, bool checkSignature = true); - SerializedValidation(const uint256& ledgerHash, const NewcoinAddress& naSeed, bool isFull); + SerializedValidation(const uint256& ledgerHash, uint64 closeTime, const NewcoinAddress& naSeed, bool isFull); uint256 getLedgerHash() const; + uint64 getCloseTime() const; NewcoinAddress getSignerPublic() const; bool isValid() const; bool isFull() const; @@ -33,7 +34,7 @@ public: CKey::pointer getSigningKey() const; uint256 getSigningHash() const; - void setTrusted() { mTrusted = true; } + void setTrusted() { mTrusted = true; } void addSigned(Serializer&) const; void addSignature(Serializer&) const; std::vector getSigned() const; diff --git a/src/ValidationCollection.cpp b/src/ValidationCollection.cpp index 15d6d92792..b30ea4a00f 100644 --- a/src/ValidationCollection.cpp +++ b/src/ValidationCollection.cpp @@ -2,12 +2,21 @@ #include "ValidationCollection.h" #include "Application.h" +#include "LedgerTiming.h" #include "Log.h" bool ValidationCollection::addValidation(SerializedValidation::pointer val) { - if(theApp->getUNL().nodeInUNL(val->getSignerPublic())) - val->setTrusted(); + bool isTrusted = false; + if (theApp->getUNL().nodeInUNL(val->getSignerPublic())) + { + uint64 now = theApp->getOPs().getNetworkTimeNC(); + uint64 valClose = val->getCloseTime(); + if ((now > valClose) && (now < (valClose + 2 * LEDGER_INTERVAL))) + isTrusted = true; + else + Log(lsWARNING) << "Received stale validation"; + } uint256 hash = val->getLedgerHash(); uint160 node = val->getSignerPublic().getNodeID(); @@ -16,6 +25,12 @@ bool ValidationCollection::addValidation(SerializedValidation::pointer val) boost::mutex::scoped_lock sl(mValidationLock); if (!mValidations[hash].insert(std::make_pair(node, val)).second) return false; + if (isTrusted) + { + boost::unordered_map::iterator it = mCurrentValidations.find(node); + if ((it == mCurrentValidations.end()) || (val->getCloseTime() >= it->second->getCloseTime())) + mCurrentValidations[node] = val; + } } Log(lsINFO) << "Val for " << hash.GetHex() << " from " << node.GetHex() << " added " << @@ -34,16 +49,24 @@ ValidationSet ValidationCollection::getValidations(const uint256& ledger) return ret; } -void ValidationCollection::getValidationCount(const uint256& ledger, int& trusted, int &untrusted) +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); + uint64 now = theApp->getOPs().getNetworkTimeNC(); if (it != mValidations.end()) { for (ValidationSet::iterator vit = it->second.begin(), end = it->second.end(); vit != end; ++vit) { - if (vit->second->isTrusted()) + bool trusted = vit->second->isTrusted(); + if (trusted && currentOnly) + { + uint64 closeTime = vit->second->getCloseTime(); + if ((now < closeTime) || (now > (closeTime + 2 * LEDGER_INTERVAL))) + trusted = false; + } + if (trusted) ++trusted; else ++untrusted; diff --git a/src/ValidationCollection.h b/src/ValidationCollection.h index 3f41e0fc0f..62540f5853 100644 --- a/src/ValidationCollection.h +++ b/src/ValidationCollection.h @@ -16,13 +16,14 @@ class ValidationCollection boost::mutex mValidationLock; boost::unordered_map mValidations; + boost::unordered_map mCurrentValidations; public: ValidationCollection() { ; } bool addValidation(SerializedValidation::pointer); ValidationSet getValidations(const uint256& ledger); - void getValidationCount(const uint256& ledger, int& trusted, int& untrusted); + void getValidationCount(const uint256& ledger, bool currentOnly, int& trusted, int& untrusted); }; #endif