diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 7cad5e55b..aa8b16d57 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -1176,8 +1176,13 @@ void Ledger::pendSave(bool fromConsensus) void Ledger::decPendingSaves() { - boost::recursive_mutex::scoped_lock sl(sPendingSaveLock); - --sPendingSaves; + { + boost::recursive_mutex::scoped_lock sl(sPendingSaveLock); + --sPendingSaves; + if (sPendingSaves != 0) + return; + } + theApp->getLedgerMaster().resumeAcquiring(); } void Ledger::ownerDirDescriber(SLE::ref sle, const uint160& owner) diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 2335813ba..3f0d6ac32 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -124,7 +124,10 @@ void LedgerAcquire::onTimer(bool progress) else if (!progress) { if (!getPeerCount()) + { addPeers(); + resetTimer(); + } else trigger(Peer::pointer(), true); } diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index 4f454408f..be3ba6963 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -171,8 +171,46 @@ static bool shouldAcquire(uint32 currentLedger, uint32 ledgerHistory, uint32 can return ret; } +void LedgerMaster::resumeAcquiring() +{ + boost::recursive_mutex::scoped_lock ml(mLock); + if (!mTooFast) + return; + mTooFast = false; + + if (mMissingLedger && (mMissingLedger->isComplete() || mMissingLedger->isFailed())) + mMissingLedger.reset(); + + if (mMissingLedger || !theConfig.LEDGER_HISTORY) + { + tLog(mMissingLedger, lsDEBUG) << "Fetch already in progress, not resuming"; + return; + } + + uint32 prevMissing = mCompleteLedgers.prevMissing(mFinalizedLedger->getLedgerSeq()); + if (prevMissing == RangeSet::RangeSetAbsent) + { + cLog(lsDEBUG) << "no prior missing ledger, not resuming"; + return; + } + if (shouldAcquire(mCurrentLedger->getLedgerSeq(), theConfig.LEDGER_HISTORY, prevMissing)) + { + cLog(lsINFO) << "Resuming at " << prevMissing; + assert(!mCompleteLedgers.hasValue(prevMissing)); + Ledger::pointer nextLedger = getLedgerBySeq(prevMissing + 1); + if (nextLedger) + acquireMissingLedger(nextLedger->getParentHash(), nextLedger->getLedgerSeq() - 1); + else + { + mCompleteLedgers.clearValue(prevMissing); + cLog(lsWARNING) << "We have a gap at: " << prevMissing + 1; + } + } +} + void LedgerMaster::setFullLedger(Ledger::ref ledger) { // A new ledger has been accepted as part of the trusted chain + cLog(lsDEBUG) << "Ledger " << ledger->getLedgerSeq() << " accepted :" << ledger->getHash(); boost::recursive_mutex::scoped_lock ml(mLock); @@ -197,10 +235,14 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) mMissingLedger.reset(); if (mMissingLedger || !theConfig.LEDGER_HISTORY) - return; - - if (Ledger::getPendingSaves() > 3) { + tLog(mMissingLedger, lsDEBUG) << "Fetch already in progress, " << mMissingLedger->getTimeouts() << " timeouts"; + return; + } + + if (Ledger::getPendingSaves() > 2) + { + mTooFast = true; cLog(lsINFO) << "Too many pending ledger saves"; return; } @@ -217,10 +259,14 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) { uint32 prevMissing = mCompleteLedgers.prevMissing(ledger->getLedgerSeq()); if (prevMissing == RangeSet::RangeSetAbsent) + { + cLog(lsDEBUG) << "no prior missing ledger"; return; + } + cLog(lsTRACE) << "Ledger " << prevMissing << " is missing"; if (shouldAcquire(mCurrentLedger->getLedgerSeq(), theConfig.LEDGER_HISTORY, prevMissing)) { - cLog(lsINFO) << "Ledger " << prevMissing << " is missing"; + cLog(lsINFO) << "Ledger " << prevMissing << " is needed"; assert(!mCompleteLedgers.hasValue(prevMissing)); Ledger::pointer nextLedger = getLedgerBySeq(prevMissing + 1); if (nextLedger) diff --git a/src/cpp/ripple/LedgerMaster.h b/src/cpp/ripple/LedgerMaster.h index 801e2f8d7..8658f1b75 100644 --- a/src/cpp/ripple/LedgerMaster.h +++ b/src/cpp/ripple/LedgerMaster.h @@ -31,6 +31,7 @@ class LedgerMaster RangeSet mCompleteLedgers; LedgerAcquire::pointer mMissingLedger; uint32 mMissingSeq; + bool mTooFast; // We are acquiring faster than we're writing void applyFutureTransactions(uint32 ledgerIndex); bool isValidTransaction(const Transaction::pointer& trans); @@ -41,7 +42,7 @@ class LedgerMaster public: - LedgerMaster() : mHeldTransactions(uint256()), mMissingSeq(0) { ; } + LedgerMaster() : mHeldTransactions(uint256()), mMissingSeq(0), mTooFast(false) { ; } uint32 getCurrentLedgerIndex(); @@ -95,6 +96,8 @@ public: bool haveLedgerRange(uint32 from, uint32 to); + void resumeAcquiring(); + void sweep(void) { mLedgerHistory.sweep(); } };