From 7131564eb1fd98f69b057c662e45382e1d000f24 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 5 Apr 2013 09:41:43 -0700 Subject: [PATCH] Emergency patch to fix ledger not closing. Do not timeout on acquiring a transaction set if a trusted peer still proposes it. Instead, fetch more aggressively. --- src/cpp/ripple/LedgerConsensus.cpp | 12 ++++++++++++ src/cpp/ripple/LedgerConsensus.h | 1 + src/cpp/ripple/NetworkOPs.cpp | 7 +++++++ src/cpp/ripple/NetworkOPs.h | 1 + src/cpp/ripple/TransactionAcquire.cpp | 24 +++++++++++++++++++----- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index 23744cb1e..3ed93cbf9 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -347,6 +347,18 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger) propose(); } +bool LedgerConsensus::stillNeedTXSet(const uint256& hash) +{ + if (mAcquired.find(hash) != mAcquired.end()) + return false; + BOOST_FOREACH(u160_prop_pair& it, mPeerPositions) + { + if (it.second->getCurrentHash() == hash) + return true; + } + return false; +} + void LedgerConsensus::createDisputes(SHAMap::ref m1, SHAMap::ref m2) { SHAMap::SHAMapDiff differences; diff --git a/src/cpp/ripple/LedgerConsensus.h b/src/cpp/ripple/LedgerConsensus.h index e511ad4a0..d09af5c75 100644 --- a/src/cpp/ripple/LedgerConsensus.h +++ b/src/cpp/ripple/LedgerConsensus.h @@ -170,6 +170,7 @@ public: SHAMap::pointer getTransactionTree(const uint256& hash, bool doAcquire); TransactionAcquire::pointer getAcquiring(const uint256& hash); void mapComplete(const uint256& hash, SHAMap::ref map, bool acquired); + bool stillNeedTXSet(const uint256& hash); void checkLCL(); void handleLCL(const uint256& lclHash); diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 7415a605b..769b48c6f 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -996,6 +996,13 @@ bool NetworkOPs::hasTXSet(const boost::shared_ptr& peer, const uint256& se return mConsensus->peerHasSet(peer, set, status); } +bool NetworkOPs::stillNeedTXSet(const uint256& hash) +{ + if (!mConsensus) + return false; + return mConsensus->stillNeedTXSet(hash); +} + void NetworkOPs::mapComplete(const uint256& hash, SHAMap::ref map) { if (haveConsensusObject()) diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index ee656a061..b4aa58c21 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -259,6 +259,7 @@ public: SHAMap::pointer getTXMap(const uint256& hash); bool hasTXSet(const boost::shared_ptr& peer, const uint256& set, ripple::TxSetStatus status); void mapComplete(const uint256& hash, SHAMap::ref map); + bool stillNeedTXSet(const uint256& hash); // network state machine void checkState(const boost::system::error_code& result); diff --git a/src/cpp/ripple/TransactionAcquire.cpp b/src/cpp/ripple/TransactionAcquire.cpp index 662acf47d..f2e1ee548 100644 --- a/src/cpp/ripple/TransactionAcquire.cpp +++ b/src/cpp/ripple/TransactionAcquire.cpp @@ -29,6 +29,7 @@ TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, TX_A void TransactionAcquire::done() { + boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); if (mFailed) { cLog(lsWARNING) << "Failed to acquire TX set " << mHash; @@ -45,14 +46,27 @@ void TransactionAcquire::done() void TransactionAcquire::onTimer(bool progress) { + bool aggressive = false; if (getTimeouts() > 10) { - cLog(lsWARNING) << "Giving up on TX set " << getHash(); - mFailed = true; - done(); - return; + cLog(lsWARNING) << "Ten timeouts on TX set " << getHash(); + { + boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); + if (theApp->getOPs().stillNeedTXSet(mHash)) + { + cLog(lsWARNING) << "Still need it"; + mTimeouts = 0; + aggressive = true; + } + } + if (!aggressive) + { + mFailed = true; + done(); + return; + } } - if (!getPeerCount()) + if (aggressive || !getPeerCount()) { // out of peers cLog(lsWARNING) << "Out of peers for TX set " << getHash();