From 1e00940a901a19a351eafdc0820469019fd28a10 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Tue, 3 Dec 2013 10:06:58 -0800 Subject: [PATCH] Move some ledger cleaner helper functions into the ledger master. --- src/ripple_app/ledger/LedgerCleaner.cpp | 28 +---------- src/ripple_app/ledger/LedgerMaster.cpp | 65 +++++++++++++++++++++++++ src/ripple_app/ledger/LedgerMaster.h | 9 ++++ 3 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/ripple_app/ledger/LedgerCleaner.cpp b/src/ripple_app/ledger/LedgerCleaner.cpp index 11ec71f38..ed62ca849 100644 --- a/src/ripple_app/ledger/LedgerCleaner.cpp +++ b/src/ripple_app/ledger/LedgerCleaner.cpp @@ -250,30 +250,6 @@ public: return hash; } - /** Try to get a ledger, acquiring it if needed. */ - Ledger::pointer findAcquireLedger ( - LedgerIndex const& ledgerIndex, LedgerHash const& ledgerHash) - { - Ledger::pointer ledger (getApp().getLedgerMaster().getLedgerByHash( - ledgerHash)); - if (!ledger) - { - m_journal.info << - "Trying to acquire ledger " << ledgerIndex; - InboundLedger::pointer inboundLedger = - getApp().getInboundLedgers().findCreate ( - ledgerHash, ledgerIndex, false); - if (inboundLedger && inboundLedger->isComplete() && - ! inboundLedger->isFailed()) - { - ledger = inboundLedger->getLedger(); - m_journal.info << - "Found ledger " << ledgerIndex << " locally"; - } - } - return ledger; - } - /** Process a single ledger @param ledgerIndex The index of the ledger to process. @param ledgerHash The known correct hash of the ledger. @@ -287,7 +263,7 @@ public: bool doNodes, bool doTxns) { - Ledger::pointer nodeLedger = findAcquireLedger(ledgerIndex, ledgerHash); + Ledger::pointer nodeLedger = getApp().getLedgerMaster().findAcquireLedger(ledgerIndex, ledgerHash); if (!nodeLedger) { m_journal.debug << "Ledger " << ledgerIndex << " not available"; @@ -364,7 +340,7 @@ public: if (meets_precondition (refHash.isNonZero ())) { // We found the hash and sequence of a better reference ledger - referenceLedger = findAcquireLedger (refIndex, refHash); + referenceLedger = getApp().getLedgerMaster().findAcquireLedger (refIndex, refHash); if (referenceLedger) ledgerHash = getLedgerHash(referenceLedger, ledgerIndex); } diff --git a/src/ripple_app/ledger/LedgerMaster.cpp b/src/ripple_app/ledger/LedgerMaster.cpp index 68918ed85..59ab7ee7a 100644 --- a/src/ripple_app/ledger/LedgerMaster.cpp +++ b/src/ripple_app/ledger/LedgerMaster.cpp @@ -1120,6 +1120,21 @@ public: return mCompleteLedgers.toString (); } + /** Find or acquire the ledger with the specified index and the specified hash + Return a pointer to that ledger if it is immediately available + */ + Ledger::pointer findAcquireLedger (uint32 index, uint256 const& hash) + { + Ledger::pointer ledger (getLedgerByHash (hash)); + if (!ledger) + { + InboundLedger::pointer inboundLedger = getApp().getInboundLedgers().findCreate (hash, index, false); + if (inboundLedger && inboundLedger->isComplete() && !inboundLedger->isFailed()) + ledger = inboundLedger->getLedger(); + } + return ledger; + } + uint256 getHashBySeq (uint32 index) { uint256 hash = mLedgerHistory.getLedgerHash (index); @@ -1130,6 +1145,56 @@ public: return Ledger::getHashByIndex (index); } + uint256 walkHashBySeq (uint32 index) + { + uint256 ledgerHash; + Ledger::pointer referenceLedger; + + { + ScopedLockType sl (mLock, __FILE__, __LINE__); + referenceLedger = mValidLedger; + } + if (referenceLedger) + ledgerHash = walkHashBySeq (index, referenceLedger); + return ledgerHash; + } + + /** Walk the chain of ledger hashed to determine the hash of the + ledger with the specified index. The referenceLedger is used as + the base of the chain and should be fully validated and must not + precede the target index. This function may throw if nodes + from the reference ledger or any prior ledger are not present + in the node store. + */ + uint256 walkHashBySeq (uint32 index, Ledger::ref referenceLedger) + { + uint256 ledgerHash; + if (!referenceLedger || (referenceLedger->getLedgerSeq() < index)) + return ledgerHash; // Nothing we can do. No validated ledger. + + // See if the hash for the ledger we need is in the reference ledger + ledgerHash = referenceLedger->getLedgerHash (index); + if (ledgerHash.isZero()) + { + // No, Try to get another ledger that might have the hash we need + // Compute the index and hash of a ledger that will have the hash we need + LedgerIndex refIndex = (index + 255) & (~255); + LedgerHash refHash = referenceLedger->getLedgerHash (refIndex); + + if (meets_precondition (refHash.isNonZero ())) + { + // We found the hash and sequence of a better reference ledger + Ledger::pointer ledger = findAcquireLedger (refIndex, refHash); + if (ledger) + { + ledgerHash = ledger->getLedgerHash (index); + assert (ledgerHash.isNonZero()); + } + } + } + return ledgerHash; + } + Ledger::pointer getLedgerBySeq (uint32 index) { { diff --git a/src/ripple_app/ledger/LedgerMaster.h b/src/ripple_app/ledger/LedgerMaster.h index 3f3e6fd57..05a3c89be 100644 --- a/src/ripple_app/ledger/LedgerMaster.h +++ b/src/ripple_app/ledger/LedgerMaster.h @@ -91,8 +91,17 @@ public: virtual Ledger::pointer closeLedger (bool recoverHeldTransactions) = 0; + /** Get a ledger's hash by sequence number using the cache + */ virtual uint256 getHashBySeq (uint32 index) = 0; + /** Walk to a ledger's hash using the skip list + */ + virtual uint256 walkHashBySeq (uint32 index) = 0; + virtual uint256 walkHashBySeq (uint32 index, Ledger::ref referenceLedger) = 0; + + virtual Ledger::pointer findAcquireLedger (uint32 index, uint256 const& hash) = 0; + virtual Ledger::pointer getLedgerBySeq (uint32 index) = 0; virtual Ledger::pointer getLedgerByHash (uint256 const& hash) = 0;