From 19c69cbb8264e7f81ba64f06c9707be77f8ef76f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 7 Sep 2012 10:46:58 -0700 Subject: [PATCH 1/4] Cosmetic. --- src/LedgerTiming.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LedgerTiming.cpp b/src/LedgerTiming.cpp index b19ee994bd..9ce760fc4d 100644 --- a/src/LedgerTiming.cpp +++ b/src/LedgerTiming.cpp @@ -27,7 +27,7 @@ bool ContinuousLedgerTiming::shouldClose( boost::str(boost::format("CLC::shouldClose range Trans=%s, Prop: %d/%d, Secs: %d (last:%d)") % (anyTransactions ? "yes" : "no") % previousProposers % proposersClosed % currentMSeconds % previousMSeconds); - return true;; + return true; } if (!anyTransactions) From e5573950727a30cdc25c0a0f3f7af838203ccdb2 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 7 Sep 2012 10:47:15 -0700 Subject: [PATCH 2/4] Fix the bug causing ledgers to close immediately even without transactions. Fix a bug that could cause the network to proceed without a consensus. --- src/LedgerConsensus.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index ebe2b08794..5130d398c5 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -491,7 +491,7 @@ void LedgerConsensus::statePreClose() } else { - sinceClose = theApp->getOPs().getLastCloseTime(); + sinceClose = 1000 * (theApp->getOPs().getCloseTimeNC() - theApp->getOPs().getLastCloseTime()); idleInterval = LEDGER_IDLE_INTERVAL; } @@ -517,7 +517,7 @@ void LedgerConsensus::stateEstablish() if (haveConsensus()) Log(lsINFO) << "We have TX consensus but not CT consensus"; } - if (haveConsensus()) + else if (haveConsensus()) { Log(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)"; mState = lcsFINISHED; @@ -638,7 +638,7 @@ void LedgerConsensus::updateOurPositions() for (std::map::iterator it = closeTimes.begin(), end = closeTimes.end(); it != end; ++it) { - Log(lsINFO) << "CCTime: " << it->first << " has " << it->second << " out of " << thresh; + Log(lsINFO) << "CCTime: " << it->first << " has " << it->second << ", " << thresh << " required"; if (it->second > thresh) { Log(lsINFO) << "Close time consensus reached: " << it->first; From adf4ff998becf6b74fe8738761fb00315893d362 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 7 Sep 2012 11:23:06 -0700 Subject: [PATCH 3/4] Make it less likely that a node will get temporarily stuck in a stale consensus process. --- src/LedgerConsensus.cpp | 28 ++++++++++++++++++++++++++-- src/LedgerConsensus.h | 3 +++ src/LedgerProposal.cpp | 16 ++++++++++++++-- src/LedgerProposal.h | 2 ++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 5130d398c5..6500a1ff37 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -321,12 +321,19 @@ void LedgerConsensus::handleLCL(const uint256& lclHash) BOOST_FOREACH(Peer::ref peer, peerList) mAcquiringLedger->peerHas(peer); } + if (mHaveCorrectLCL && mProposing) + { + Log(lsINFO) << "Bowing out of consensus"; + mOurPosition->bowOut(); + propose(); + } mHaveCorrectLCL = false; mProposing = false; mValidating = false; mCloseTimes.clear(); mPeerPositions.clear(); mDisputes.clear(); + mDeadNodes.clear(); return; } @@ -794,11 +801,18 @@ void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vec bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition) { - LedgerProposal::pointer& currentPosition = mPeerPositions[newPosition->getPeerID()]; + uint160 peerID = newPosition->getPeerID(); + if (mDeadNodes.find(peerID) != mDeadNodes.end()) + { + Log(lsINFO) << "Position from dead node"; + return false; + } + + LedgerProposal::pointer& currentPosition = mPeerPositions[peerID]; if (currentPosition) { - assert(newPosition->getPeerID() == currentPosition->getPeerID()); + assert(peerID == currentPosition->getPeerID()); if (newPosition->getProposeSeq() <= currentPosition->getProposeSeq()) return false; } @@ -808,9 +822,19 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition) Log(lsTRACE) << "Peer reports close time as " << newPosition->getCloseTime(); ++mCloseTimes[newPosition->getCloseTime()]; } + else if (newPosition->getProposeSeq() == LedgerProposal::seqLeave) + { + BOOST_FOREACH(u256_lct_pair& it, mDisputes) + it.second->unVote(peerID); + mPeerPositions.erase(peerID); + mDeadNodes.insert(peerID); + return true; + } + Log(lsINFO) << "Processing peer proposal " << newPosition->getProposeSeq() << "/" << newPosition->getCurrentHash(); currentPosition = newPosition; + SHAMap::pointer set = getTransactionTree(newPosition->getCurrentHash(), true); if (set) { diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 4e1db172dd..17aa02691d 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -115,6 +115,9 @@ protected: // deferred proposals (node ID -> proposals from that peer) boost::unordered_map< uint160, std::list > mDeferredProposals; + // nodes that have bowed out of this consensus process + boost::unordered_set mDeadNodes; + // final accept logic static void Saccept(boost::shared_ptr This, SHAMap::pointer txSet); void accept(const SHAMap::pointer& txSet); diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp index d96b397434..5840c10372 100644 --- a/src/LedgerProposal.cpp +++ b/src/LedgerProposal.cpp @@ -62,6 +62,13 @@ void LedgerProposal::changePosition(const uint256& newPosition, uint32 closeTime ++mProposeSeq; } +void LedgerProposal::bowOut() +{ + mCurrentHash = uint256(); + mTime = boost::posix_time::second_clock::universal_time(); + mProposeSeq = seqLeave; +} + std::vector LedgerProposal::sign(void) { std::vector ret; @@ -78,9 +85,14 @@ Json::Value LedgerProposal::getJson() const { Json::Value ret = Json::objectValue; ret["previous_ledger"] = mPreviousLedger.GetHex(); - ret["transaction_hash"] = mCurrentHash.GetHex(); + + if (mProposeSeq != seqLeave) + { + ret["transaction_hash"] = mCurrentHash.GetHex(); + ret["propose_seq"] = mProposeSeq; + } + ret["close_time"] = mCloseTime; - ret["propose_seq"] = mProposeSeq; if (mPublicKey.isValid()) ret["peer_id"] = mPublicKey.humanNodePublic(); diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h index 74d0f7c071..adaa557719 100644 --- a/src/LedgerProposal.h +++ b/src/LedgerProposal.h @@ -26,6 +26,7 @@ protected: boost::posix_time::ptime mTime; public: + static const uint32 seqLeave = 0xffffffff; // leaving the consensus process typedef boost::shared_ptr pointer; @@ -63,6 +64,7 @@ public: bool isStale(boost::posix_time::ptime cutoff) { return mTime <= cutoff; } void changePosition(const uint256& newPosition, uint32 newCloseTime); + void bowOut(); Json::Value getJson() const; }; From 9f6118b7955f355c384009a1421f931c0dd5a9d6 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 7 Sep 2012 11:25:20 -0700 Subject: [PATCH 4/4] Tiny cleanup --- src/LedgerConsensus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 6500a1ff37..8ecccdcd87 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -839,7 +839,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition) if (set) { BOOST_FOREACH(u256_lct_pair& it, mDisputes) - it.second->setVote(newPosition->getPeerID(), set->hasItem(it.first)); + it.second->setVote(peerID, set->hasItem(it.first)); } else Log(lsTRACE) << "Don't have that tx set";