From 02b5572ccc1735d7cdcc2269afb281a69603f036 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Tue, 19 Nov 2013 12:56:39 -0800 Subject: [PATCH] Changes to support the ledger cleaner * Rework ledger save return values to indicate errors to callers * Add an extra function to support the ledger cleaner. --- Builds/VisualStudio2012/RippleD.vcxproj | 1 + .../VisualStudio2012/RippleD.vcxproj.filters | 3 +++ src/ripple_app/TODO.md | 7 ------- src/ripple_app/ledger/Ledger.cpp | 14 +++++++++----- src/ripple_app/ledger/Ledger.h | 8 +++++++- src/ripple_app/ledger/LedgerHistory.cpp | 19 +++++++++++++++++-- src/ripple_app/ledger/LedgerHistory.h | 2 ++ src/ripple_app/ledger/LedgerMaster.cpp | 5 +++++ src/ripple_app/ledger/LedgerMaster.h | 2 ++ src/ripple_app/ledger/TODO.md | 18 ++++++++++++++++++ 10 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 src/ripple_app/ledger/TODO.md diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index d5ea8207b..91c7963d1 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -2116,6 +2116,7 @@ + diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 9a170dcd7..861ccf56a 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -2464,6 +2464,9 @@ [2] Old Ripple\ripple_app + + [2] Old Ripple\ripple_app\ledger + diff --git a/src/ripple_app/TODO.md b/src/ripple_app/TODO.md index cdbc1ea85..c933e44f9 100644 --- a/src/ripple_app/TODO.md +++ b/src/ripple_app/TODO.md @@ -12,13 +12,6 @@ ## Peers.cpp -## LedgerMaster.cpp - -- Change getLedgerByHash() to not use "all bits zero" to mean - "return the current ledger" - -- replace uint32 with LedgerIndex and choose appropriate names - ## Beast - Change Stoppable to not require a constructor with parameters diff --git a/src/ripple_app/ledger/Ledger.cpp b/src/ripple_app/ledger/Ledger.cpp index 100e6891f..a70bcf9da 100644 --- a/src/ripple_app/ledger/Ledger.cpp +++ b/src/ripple_app/ledger/Ledger.cpp @@ -538,7 +538,7 @@ uint256 Ledger::getHash () return mHash; } -void Ledger::saveValidatedLedger (bool current) +bool Ledger::saveValidatedLedger (bool current) { WriteLog (lsTRACE, Ledger) << "saveValidatedLedger " << (current ? "" : "fromAcquire ") << getLedgerSeq (); static boost::format deleteLedger ("DELETE FROM Ledgers WHERE LedgerSeq = %u;"); @@ -588,7 +588,7 @@ void Ledger::saveValidatedLedger (bool current) StaticScopedLockType sl (sPendingSaveLock, __FILE__, __LINE__); sPendingSaves.erase(getLedgerSeq()); } - return; + return false; } { @@ -664,6 +664,7 @@ void Ledger::saveValidatedLedger (bool current) StaticScopedLockType sl (sPendingSaveLock, __FILE__, __LINE__); sPendingSaves.erase(getLedgerSeq()); } + return true; } #ifndef NO_SQLITE3_PREPARE @@ -1875,12 +1876,15 @@ uint32 Ledger::roundCloseTime (uint32 closeTime, uint32 closeResolution) return closeTime - (closeTime % closeResolution); } +/** Save, or arrange to save, a fully-validated ledger + Returns false on error +*/ bool Ledger::pendSaveValidated (bool isSynchronous, bool isCurrent) { if (!getApp().getHashRouter ().setFlag (getHash (), SF_SAVED)) { WriteLog (lsDEBUG, Ledger) << "Double pend save for " << getLedgerSeq(); - return false; + return true; } assert (isImmutable ()); @@ -1890,13 +1894,13 @@ bool Ledger::pendSaveValidated (bool isSynchronous, bool isCurrent) if (!sPendingSaves.insert(getLedgerSeq()).second) { WriteLog (lsDEBUG, Ledger) << "Pend save with seq in pending saves " << getLedgerSeq(); - return false; + return true; } } if (isSynchronous) { - saveValidatedLedger(isCurrent); + return saveValidatedLedger(isCurrent); } else if (isCurrent) { diff --git a/src/ripple_app/ledger/Ledger.h b/src/ripple_app/ledger/Ledger.h index 0404041a9..1c6cc3f52 100644 --- a/src/ripple_app/ledger/Ledger.h +++ b/src/ripple_app/ledger/Ledger.h @@ -63,6 +63,12 @@ protected: // class. But then what is the meaning of a Ledger object? Is this // really two classes in one? StoreOfAllLedgers + SingleLedgerObject? // +/** Holds some or all of a ledger. + This can hold just the header, a partial set of data, or the entire set + of data. It all depends on what is in the corresponding SHAMap entry. + Various functions are provided to populate or depopulate the caches that + the object holds references to. +*/ class Ledger : public boost::enable_shared_from_this , public LedgerBase @@ -470,7 +476,7 @@ protected: { saveValidatedLedger(current); } - void saveValidatedLedger (bool current); + bool saveValidatedLedger (bool current); void updateFees (); diff --git a/src/ripple_app/ledger/LedgerHistory.cpp b/src/ripple_app/ledger/LedgerHistory.cpp index 5241de7ac..901d5a31a 100644 --- a/src/ripple_app/ledger/LedgerHistory.cpp +++ b/src/ripple_app/ledger/LedgerHistory.cpp @@ -30,8 +30,8 @@ // FIXME: Need to clean up ledgers by index at some point LedgerHistory::LedgerHistory () - : mLedgersByHash ("LedgerCache", CACHED_LEDGER_NUM, CACHED_LEDGER_AGE) - , mConsensusValidated ("ConsensusValidated", 64, 300) + : mLedgersByHash ("LedgerCache", CACHED_LEDGER_NUM, CACHED_LEDGER_AGE) + , mConsensusValidated ("ConsensusValidated", 64, 300) { ; } @@ -159,6 +159,21 @@ void LedgerHistory::validatedLedger (Ledger::ref ledger) } } +/** Ensure mLedgersByHash doesn't have the wrong hash for a particular index +*/ +bool LedgerHistory::fixIndex (LedgerIndex ledgerIndex, LedgerHash const& ledgerHash) +{ + TaggedCache::ScopedLockType sl (mLedgersByHash.peekMutex (), __FILE__, __LINE__); + std::map::iterator it (mLedgersByIndex.find (ledgerIndex)); + + if ((it != mLedgersByIndex.end ()) && (it->second != ledgerHash) ) + { + it->second = ledgerHash; + return false; + } + return true; +} + void LedgerHistory::tune (int size, int age) { mLedgersByHash.setTargetSize (size); diff --git a/src/ripple_app/ledger/LedgerHistory.h b/src/ripple_app/ledger/LedgerHistory.h index 3fb7d7153..e797af211 100644 --- a/src/ripple_app/ledger/LedgerHistory.h +++ b/src/ripple_app/ledger/LedgerHistory.h @@ -50,6 +50,8 @@ public: void builtLedger (Ledger::ref); void validatedLedger (Ledger::ref); + bool fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash); + private: TaggedCacheType mLedgersByHash; TaggedCacheType , UptimeTimerAdapter> mConsensusValidated; diff --git a/src/ripple_app/ledger/LedgerMaster.cpp b/src/ripple_app/ledger/LedgerMaster.cpp index f2915b686..981a486d8 100644 --- a/src/ripple_app/ledger/LedgerMaster.cpp +++ b/src/ripple_app/ledger/LedgerMaster.cpp @@ -260,6 +260,11 @@ public: checkAccept (lastClosed); } + bool fixIndex (LedgerIndex ledgerIndex, LedgerHash const& ledgerHash) + { + return mLedgerHistory.fixIndex (ledgerIndex, ledgerHash); + } + void storeLedger (Ledger::pointer ledger) { mLedgerHistory.addLedger (ledger, false); diff --git a/src/ripple_app/ledger/LedgerMaster.h b/src/ripple_app/ledger/LedgerMaster.h index 099869370..e89247575 100644 --- a/src/ripple_app/ledger/LedgerMaster.h +++ b/src/ripple_app/ledger/LedgerMaster.h @@ -122,6 +122,8 @@ public: virtual void newPathRequest () = 0; virtual void newOrderBookDB () = 0; + virtual bool fixIndex (LedgerIndex ledgerIndex, LedgerHash const& ledgerHash) = 0; + static bool shouldAcquire (uint32 currentLedgerID, uint32 ledgerHistory, uint32 targetLedger); }; diff --git a/src/ripple_app/ledger/TODO.md b/src/ripple_app/ledger/TODO.md new file mode 100644 index 000000000..25074efe1 --- /dev/null +++ b/src/ripple_app/ledger/TODO.md @@ -0,0 +1,18 @@ +# ripple_app + +## Ledger.cpp + +- Move all inlines into the .cpp, make the interface abstract + +- Move static database functions into a real class, perhaps LedgerMaster + +## LedgerMaster.cpp + +- Change getLedgerByHash() to not use "all bits zero" to mean + "return the current ledger" + +- replace uint32 with LedgerIndex and choose appropriate names + +## Beast + +- Change Stoppable to not require a constructor with parameters