diff --git a/src/Ledger.cpp b/src/Ledger.cpp index c93b905323..eb82d387f2 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -434,9 +434,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus) theApp->getOPs().pubLedger(shared_from_this()); if(theConfig.FULL_HISTORY) - { - // WRITEME: check for seamless ledger history - } + theApp->getMasterLedger().checkLedgerGap(shared_from_this()); } diff --git a/src/LedgerAcquire.cpp b/src/LedgerAcquire.cpp index 9cc09b2ee5..71c631eb06 100644 --- a/src/LedgerAcquire.cpp +++ b/src/LedgerAcquire.cpp @@ -647,6 +647,7 @@ void LedgerAcquireSet::onComplete(boost::weak_ptr set, LedgerA { Ledger::pointer ledger = acquired->getLedger(); ledger->setAccepted(); + theApp->getMasterLedger().checkLedgerGap(ledger); lSet->updateCurrentLedger(ledger); } else diff --git a/src/LedgerAcquire.h b/src/LedgerAcquire.h index cbd0459dc3..dc717efee3 100644 --- a/src/LedgerAcquire.h +++ b/src/LedgerAcquire.h @@ -137,8 +137,8 @@ public: void dropLedger(const uint256& ledgerHash); bool gotLedgerData(ripple::TMLedgerData& packet, Peer::ref); - void killSet(const LedgerAcquireSet&) - { mAcquireSet = LedgerAcquireSet::pointer(); } + bool hasSet() { return !!mAcquireSet; } + void killSet(const LedgerAcquireSet&) { mAcquireSet = LedgerAcquireSet::pointer(); } void makeSet(Ledger::ref target, Ledger::ref current) { mAcquireSet = boost::make_shared(boost::ref(target), boost::ref(current)); } }; diff --git a/src/LedgerMaster.cpp b/src/LedgerMaster.cpp index 773e98dbed..83e2cdc3b6 100644 --- a/src/LedgerMaster.cpp +++ b/src/LedgerMaster.cpp @@ -23,7 +23,7 @@ void LedgerMaster::pushLedger(Ledger::ref newLedger) // Caller should already have properly assembled this ledger into "ready-to-close" form -- // all candidate transactions must already be applied Log(lsINFO) << "PushLedger: " << newLedger->getHash(); - ScopedLock sl(mLock); + boost::recursive_mutex::scoped_lock ml(mLock); if (!!mFinalizedLedger) { mFinalizedLedger->setClosed(); @@ -51,8 +51,8 @@ void LedgerMaster::pushLedger(Ledger::ref newLCL, Ledger::ref newOL) Log(lsINFO) << "StashAccepted: " << newLCL->getHash(); } + boost::recursive_mutex::scoped_lock ml(mLock); mFinalizedLedger = newLCL; - ScopedLock sl(mLock); mCurrentLedger = newOL; mEngine.setLedger(newOL); } @@ -60,11 +60,15 @@ void LedgerMaster::pushLedger(Ledger::ref newLCL, Ledger::ref newOL) void LedgerMaster::switchLedgers(Ledger::ref lastClosed, Ledger::ref current) { assert(lastClosed && current); - mFinalizedLedger = lastClosed; - mFinalizedLedger->setClosed(); - mFinalizedLedger->setAccepted(); - mCurrentLedger = current; + { + boost::recursive_mutex::scoped_lock ml(mLock); + mFinalizedLedger = lastClosed; + mFinalizedLedger->setClosed(); + mFinalizedLedger->setAccepted(); + mCurrentLedger = current; + } + assert(!mCurrentLedger->isClosed()); mEngine.setLedger(mCurrentLedger); } @@ -77,7 +81,6 @@ void LedgerMaster::storeLedger(Ledger::ref ledger) } - Ledger::pointer LedgerMaster::closeLedger() { boost::recursive_mutex::scoped_lock sl(mLock); @@ -94,5 +97,25 @@ TER LedgerMaster::doTransaction(const SerializedTransaction& txn, TransactionEng return result; } +void LedgerMaster::checkLedgerGap(Ledger::ref ledger) +{ + boost::recursive_mutex::scoped_lock sl(mLock); + + if (ledger->getParentHash() == mLastFullLedger->getHash()) + { + mLastFullLedger = ledger; + return; + } + + if (theApp->getMasterLedgerAcquire().hasSet()) + return; + + if (ledger->getLedgerSeq() < mLastFullLedger->getLedgerSeq()) + return; + + // we have a gap or discontinuity + theApp->getMasterLedgerAcquire().makeSet(mLastFullLedger, ledger); + +} // vim:ts=4 diff --git a/src/LedgerMaster.h b/src/LedgerMaster.h index 36f9339db5..47cf394b50 100644 --- a/src/LedgerMaster.h +++ b/src/LedgerMaster.h @@ -52,9 +52,12 @@ public: void setLastFullLedger(Ledger::ref ledger) { + boost::recursive_mutex::scoped_lock ml(mLock); mLastFullLedger = ledger; } + void checkLedgerGap(Ledger::ref ledger); + void switchLedgers(Ledger::ref lastClosed, Ledger::ref newCurrent); Ledger::pointer closeLedger();