Don't use stale validiations.

This commit is contained in:
JoelKatz
2012-06-20 13:26:32 -07:00
parent a022f8304d
commit 58dcc8b9c1
7 changed files with 46 additions and 14 deletions

View File

@@ -825,7 +825,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
if (mValidating)
{
SerializedValidation::pointer v = boost::make_shared<SerializedValidation>
(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<PackedMessage>(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);

View File

@@ -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<Peer::pointer>& 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<Peer::pointer>& 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;

View File

@@ -38,6 +38,7 @@ enum SOE_Field
sfBorrowRate,
sfBorrowStart,
sfBorrower,
sfCloseTime,
sfCurrency,
sfCurrencyIn,
sfCurrencyOut,

View File

@@ -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

View File

@@ -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;

View File

@@ -2,12 +2,21 @@
#include "ValidationCollection.h"
#include "Application.h"
#include "LedgerTiming.h"
#include "Log.h"
bool ValidationCollection::addValidation(SerializedValidation::pointer val)
{
bool isTrusted = false;
if (theApp->getUNL().nodeInUNL(val->getSignerPublic()))
val->setTrusted();
{
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<uint160, SerializedValidation::pointer>::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<uint256, ValidationSet>::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;

View File

@@ -16,13 +16,14 @@ class ValidationCollection
boost::mutex mValidationLock;
boost::unordered_map<uint256, ValidationSet> mValidations;
boost::unordered_map<uint160, SerializedValidation::pointer> 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