diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 4cdc152d1..af61e7993 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -339,7 +339,7 @@ uint256 Ledger::getHash() void Ledger::saveAcceptedLedger(bool fromConsensus) { // can be called in a different thread - cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus" : "fromAcquire") << getLedgerSeq(); + cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq(); static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers where LedgerSeq = %d;"); static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %d;"); static boost::format AcctTransExists("SELECT LedgerSeq FROM AccountTransactions WHERE TransId = '%s';"); @@ -432,9 +432,10 @@ void Ledger::saveAcceptedLedger(bool fromConsensus) if (!fromConsensus) return; + theApp->getMasterLedger().setFullLedger(shared_from_this()); + theApp->getOPs().pubLedger(shared_from_this()); - theApp->getMasterLedger().setFullLedger(shared_from_this()); } Ledger::pointer Ledger::getSQL(const std::string& sql) diff --git a/src/LedgerHistory.cpp b/src/LedgerHistory.cpp index c0149431b..45ccaad46 100644 --- a/src/LedgerHistory.cpp +++ b/src/LedgerHistory.cpp @@ -50,7 +50,8 @@ Ledger::pointer LedgerHistory::getLedgerBySeq(uint32 index) sl.unlock(); Ledger::pointer ret(Ledger::loadByIndex(index)); - if (!ret) return ret; + if (!ret) + return ret; assert(ret->getLedgerSeq() == index); sl.lock(); diff --git a/src/LedgerMaster.cpp b/src/LedgerMaster.cpp index 2619c893e..872be8920 100644 --- a/src/LedgerMaster.cpp +++ b/src/LedgerMaster.cpp @@ -98,6 +98,11 @@ TER LedgerMaster::doTransaction(const SerializedTransaction& txn, TransactionEng void LedgerMaster::acquireMissingLedger(const uint256& ledgerHash, uint32 ledgerSeq) { mMissingLedger = theApp->getMasterLedgerAcquire().findCreate(ledgerHash); + if (mMissingLedger->isComplete()) + { + mMissingLedger = LedgerAcquire::pointer(); + return; + } mMissingSeq = ledgerSeq; if (mMissingLedger->setAccept()) mMissingLedger->addOnComplete(boost::bind(&LedgerMaster::missingAcquireComplete, this, _1)); @@ -107,20 +112,20 @@ void LedgerMaster::missingAcquireComplete(LedgerAcquire::pointer acq) { boost::recursive_mutex::scoped_lock ml(mLock); - if (acq->isFailed()) + if (acq->isFailed() && (mMissingSeq != 0)) { - if (mMissingSeq != 0) - { - cLog(lsWARNING) << "Acquire failed, invalidating following ledger " << mMissingSeq + 1; - mCompleteLedgers.clearValue(mMissingSeq + 1); - } + cLog(lsWARNING) << "Acquire failed for " << mMissingSeq; } mMissingLedger = LedgerAcquire::pointer(); mMissingSeq = 0; if (!acq->isFailed()) + { + boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, acq->getLedger(), false)); + thread.detach(); setFullLedger(acq->getLedger()); + } } void LedgerMaster::setFullLedger(Ledger::ref ledger) @@ -139,6 +144,9 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) } } + if (mMissingLedger && mMissingLedger->isComplete()) + mMissingLedger = LedgerAcquire::pointer(); + if (mMissingLedger || !theConfig.FULL_HISTORY) return; @@ -154,11 +162,15 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) if (prevMissing != RangeSet::RangeSetAbsent) { cLog(lsINFO) << "Ledger " << prevMissing << " is missing"; - Ledger::pointer nextLedger = getLedgerBySeq(prevMissing); + assert(!mCompleteLedgers.hasValue(prevMissing)); + Ledger::pointer nextLedger = getLedgerBySeq(prevMissing + 1); if (nextLedger) acquireMissingLedger(nextLedger->getParentHash(), nextLedger->getLedgerSeq() - 1); else - cLog(lsWARNING) << "We have a ledger gap we can't quite fix"; + { + mCompleteLedgers.clearValue(prevMissing); + cLog(lsWARNING) << "We have a gap we can't fix: " << prevMissing + 1; + } } } } diff --git a/src/RangeSet.cpp b/src/RangeSet.cpp index fe218df39..e9c4b38f9 100644 --- a/src/RangeSet.cpp +++ b/src/RangeSet.cpp @@ -54,15 +54,18 @@ uint32 RangeSet::getPrev(uint32 v) const uint32 RangeSet::prevMissing(uint32 v) const { // largest number not in the set that is less than the given number + cLog(lsTRACE) << "prevMissing(" << v << ") " << toString(); for (const_reverse_iterator it = rbegin(); it != rend(); ++it) { - if (lower(it) <= v) - { - if (upper(it) < v) - return upper(it) + 1; + if ((upper(it) + 1) < v) + return upper(it) + 1; + if (lower(it) == 0) + return RangeSetAbsent; + if ((lower(it) - 1) < v) return lower(it) - 1; - } } + if (v > 0) + return v - 1; return RangeSetAbsent; }