Allow a peer position to be removed from the consensus logic if the peer is

not responding. This version uses static timing. A peer takes a position
every 12 seconds and a position is valid for 20 seconds. It might make sense
to either make that timing adaptive or include a "validity time" field in
the position. However, I think this is really only going to be an issue in
fairly small networks (which is why we are seeing it).
This commit is contained in:
JoelKatz
2012-08-31 15:51:41 -07:00
parent f636ae861e
commit ad12e318ba
5 changed files with 41 additions and 21 deletions

View File

@@ -534,10 +534,34 @@ void LedgerConsensus::timerEntry()
void LedgerConsensus::updateOurPositions()
{
boost::posix_time::ptime peerCutoff = boost::posix_time::second_clock::universal_time();
boost::posix_time::ptime ourCutoff = peerCutoff - boost::posix_time::seconds(PROPOSE_INTERVAL);
peerCutoff -= boost::posix_time::seconds(PROPOSE_FRESHNESS);
bool changes = false;
SHAMap::pointer ourPosition;
std::vector<uint256> addedTx, removedTx;
// Verify freshness of peer positions and compute close times
std::map<uint32, int> closeTimes;
boost::unordered_map<uint160, LedgerProposal::pointer>::iterator
it = mPeerPositions.begin(), end = mPeerPositions.end();
while (it != end)
{
if (it->second->isStale(peerCutoff))
{ // proposal is stale
uint160 peerID = it->second->getPeerID();
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
it.second->unVote(peerID);
mPeerPositions.erase(it++);
}
else
{ // proposal is still fresh
++closeTimes[it->second->getCloseTime() - (it->second->getCloseTime() % mCloseResolution)];
++it;
}
}
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
{
if (it.second->updatePosition(mClosePercent, mProposing))
@@ -560,10 +584,6 @@ void LedgerConsensus::updateOurPositions()
}
}
std::map<uint32, int> closeTimes;
BOOST_FOREACH(u160_prop_pair& it, mPeerPositions)
++closeTimes[it.second->getCloseTime() - (it.second->getCloseTime() % mCloseResolution)];
int neededWeight;
if (mClosePercent < AV_MID_CONSENSUS_TIME)
@@ -605,13 +625,12 @@ void LedgerConsensus::updateOurPositions()
}
}
if (closeTime != (mOurPosition->getCloseTime() - (mOurPosition->getCloseTime() % mCloseResolution)))
{
if (!changes)
{
ourPosition = mComplete[mOurPosition->getCurrentHash()]->snapShot(true);
changes = true;
}
if ((!changes) &&
((closeTime != (mOurPosition->getCloseTime() - (mOurPosition->getCloseTime() % mCloseResolution))) ||
(mOurPosition->isStale(ourCutoff))))
{ // close time changed or our position is stale
ourPosition = mComplete[mOurPosition->getCurrentHash()]->snapShot(true);
changes = true;
}
if (changes)
@@ -778,13 +797,6 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
return true;
}
void LedgerConsensus::removePeer(const uint160& peerID)
{
mPeerPositions.erase(peerID);
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
it.second->unVote(peerID);
}
bool LedgerConsensus::peerHasSet(const Peer::pointer& peer, const uint256& hashSet, newcoin::TxSetStatus status)
{
if (status != newcoin::tsHAVE) // Indirect requests are for future support

View File

@@ -172,7 +172,6 @@ public:
bool haveConsensus();
bool peerPosition(const LedgerProposal::pointer&);
void removePeer(const uint160& peerID);
void deferProposal(const LedgerProposal::pointer& proposal, const NewcoinAddress& peerPublic);
bool peerHasSet(const Peer::pointer& peer, const uint256& set, newcoin::TxSetStatus status);

View File

@@ -56,8 +56,9 @@ bool LedgerProposal::checkSign(const std::string& signature, const uint256& sign
void LedgerProposal::changePosition(const uint256& newPosition, uint32 closeTime)
{
mCurrentHash = newPosition;
mCloseTime = closeTime;
mCurrentHash = newPosition;
mCloseTime = closeTime;
mTime = boost::posix_time::second_clock::universal_time();
++mProposeSeq;
}

View File

@@ -56,7 +56,9 @@ public:
void setPrevLedger(const uint256& prevLedger) { mPreviousLedger = prevLedger; }
void setSignature(const std::string& signature) { mSignature = signature; }
const boost::posix_time::ptime getCreateTime() { return mTime; }
bool isStale(boost::posix_time::ptime cutoff) { return mTime > cutoff; }
void changePosition(const uint256& newPosition, uint32 newCloseTime);
Json::Value getJson() const;

View File

@@ -28,6 +28,12 @@
// How often we check state or change positions (in milliseconds)
# define LEDGER_GRANULARITY 1000
// How long we consider a proposal fresh
# define PROPOSE_FRESHNESS 20
// How often we force generating a new proposal to keep ours fresh
# define PROPOSE_INTERVAL 12
// Avalanche tuning
#define AV_INIT_CONSENSUS_PCT 50 // percentage of nodes on our UNL that must vote yes