From f7ac90b2e303683545c1091294d42cbf8a82ed3f Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 20 Dec 2024 07:56:42 -0800 Subject: [PATCH 1/8] Store complete LCL data in BucketListSnapshot --- src/bucket/BucketListSnapshotBase.cpp | 17 ++++-- src/bucket/BucketListSnapshotBase.h | 79 +++++++++++++++++++++++++-- src/bucket/BucketManager.cpp | 6 +- src/bucket/test/BucketTestUtils.cpp | 55 ++++++++++++++++--- src/bucket/test/BucketTestUtils.h | 11 ++++ src/ledger/LedgerManagerImpl.cpp | 6 +- src/ledger/LedgerStateSnapshot.cpp | 26 ++++++++- src/ledger/LedgerStateSnapshot.h | 4 ++ 8 files changed, 181 insertions(+), 23 deletions(-) diff --git a/src/bucket/BucketListSnapshotBase.cpp b/src/bucket/BucketListSnapshotBase.cpp index 2dcfcee435..988fdf2f81 100644 --- a/src/bucket/BucketListSnapshotBase.cpp +++ b/src/bucket/BucketListSnapshotBase.cpp @@ -16,8 +16,8 @@ namespace stellar { template BucketListSnapshot::BucketListSnapshot( - BucketListBase const& bl, LedgerHeader header) - : mHeader(std::move(header)) + BucketListBase const& bl, LastClosedLedger lastClosed) + : mLastClosedLedger(std::move(lastClosed)) { releaseAssert(threadIsMain()); @@ -31,7 +31,7 @@ BucketListSnapshot::BucketListSnapshot( template BucketListSnapshot::BucketListSnapshot( BucketListSnapshot const& snapshot) - : mLevels(snapshot.mLevels), mHeader(snapshot.mHeader) + : mLevels(snapshot.mLevels), mLastClosedLedger(snapshot.mLastClosedLedger) { } @@ -46,7 +46,7 @@ template uint32_t BucketListSnapshot::getLedgerSeq() const { - return mHeader.ledgerSeq; + return mLastClosedLedger.lhhe.header.ledgerSeq; } template @@ -58,6 +58,15 @@ SearchableBucketListSnapshotBase::getLedgerHeader() return mSnapshot->getLedgerHeader(); } +template +LastClosedLedger const& +SearchableBucketListSnapshotBase::getLastClosedLedger() +{ + releaseAssert(mSnapshot); + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + return mSnapshot->getLastClosedLedger(); +} + template void SearchableBucketListSnapshotBase::loopAllBuckets( diff --git a/src/bucket/BucketListSnapshotBase.h b/src/bucket/BucketListSnapshotBase.h index 1a8aef9b31..d0b6d7ef0d 100644 --- a/src/bucket/BucketListSnapshotBase.h +++ b/src/bucket/BucketListSnapshotBase.h @@ -11,6 +11,8 @@ #include "bucket/BucketUtils.h" #include "bucket/HotArchiveBucket.h" #include "bucket/LiveBucket.h" +#include "history/HistoryArchive.h" +#include "ledger/NetworkConfig.h" namespace medida { @@ -34,8 +36,70 @@ template struct BucketLevelSnapshot BucketLevelSnapshot(BucketLevel const& level); }; +// Complete state of last closed ledger: ledger header, soroban network config, +// bucketlist +struct LastClosedLedger +{ + std::optional sorobanNetworkConfig; + LedgerHeaderHistoryEntry lhhe; + HistoryArchiveState has; + LastClosedLedger() = default; + explicit LastClosedLedger( + LedgerHeaderHistoryEntry const& lhhe, HistoryArchiveState const& has, + std::optional const& sorobanNetworkConfig) + : sorobanNetworkConfig(sorobanNetworkConfig), lhhe(lhhe), has(has) + { + } + // Add getters + uint32_t + getProtocolVersion() const + { + return lhhe.header.ledgerVersion; + } + uint32_t + getLastTxFee() const + { + return lhhe.header.baseFee; + } + uint32_t + getLastReserve() const + { + return lhhe.header.baseReserve; + } + uint32_t + getMaxTxSetSize() const + { + return lhhe.header.maxTxSetSize; + } + uint32_t + getLastMaxTxSetSizeOps() const + { + auto n = getMaxTxSetSize(); + return protocolVersionStartsFrom(getProtocolVersion(), + ProtocolVersion::V_11) + ? n + : (n * MAX_OPS_PER_TX); + } + uint32_t + getLedgerSeq() const + { + return lhhe.header.ledgerSeq; + } + LedgerHeaderHistoryEntry const& + getLedgerHeaderHistoryEntry() const + { + return lhhe; + } + std::optional const& + getSorobanNetworkConfig() const + { + return sorobanNetworkConfig; + } +}; + template class BucketListSnapshot : public NonMovable { + BUCKET_TYPE_ASSERT(BucketT); using BucketSnapshotT = std::conditional_t, @@ -44,11 +108,12 @@ template class BucketListSnapshot : public NonMovable private: std::vector> mLevels; - // LedgerHeader associated with this ledger state snapshot - LedgerHeader const mHeader; + // Last closed ledger associated with this snapshot + LastClosedLedger const mLastClosedLedger; public: - BucketListSnapshot(BucketListBase const& bl, LedgerHeader hhe); + BucketListSnapshot(BucketListBase const& bl, + LastClosedLedger lastClosed); // Only allow copies via constructor BucketListSnapshot(BucketListSnapshot const& snapshot); @@ -59,7 +124,12 @@ template class BucketListSnapshot : public NonMovable LedgerHeader const& getLedgerHeader() const { - return mHeader; + return mLastClosedLedger.lhhe.header; + } + LastClosedLedger const& + getLastClosedLedger() const + { + return mLastClosedLedger; } }; @@ -112,6 +182,7 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable } LedgerHeader const& getLedgerHeader(); + LastClosedLedger const& getLastClosedLedger(); // Loads inKeys from the specified historical snapshot. Returns // load_result_vec if the snapshot for the given ledger is diff --git a/src/bucket/BucketManager.cpp b/src/bucket/BucketManager.cpp index 59f6980b00..f7ee00f6e5 100644 --- a/src/bucket/BucketManager.cpp +++ b/src/bucket/BucketManager.cpp @@ -99,10 +99,10 @@ BucketManager::initialize() mHotArchiveBucketList = std::make_unique(); mSnapshotManager = std::make_unique( mApp, - std::make_unique>(*mLiveBucketList, - LedgerHeader()), + std::make_unique>( + *mLiveBucketList, LastClosedLedger()), std::make_unique>( - *mHotArchiveBucketList, LedgerHeader()), + *mHotArchiveBucketList, LastClosedLedger()), mConfig.QUERY_SNAPSHOT_LEDGERS); } diff --git a/src/bucket/test/BucketTestUtils.cpp b/src/bucket/test/BucketTestUtils.cpp index e511f069d7..ba7d9c3127 100644 --- a/src/bucket/test/BucketTestUtils.cpp +++ b/src/bucket/test/BucketTestUtils.cpp @@ -38,16 +38,36 @@ addLiveBatchAndUpdateSnapshot(Application& app, LedgerHeader header, std::vector const& initEntries, std::vector const& liveEntries, std::vector const& deadEntries) +{ + LedgerHeaderHistoryEntry lhe; + lhe.header = header; + auto sorobanConfig = + app.getLedgerManager().hasSorobanNetworkConfig() + ? std::make_optional( + app.getLedgerManager().getSorobanNetworkConfig()) + : std::nullopt; + addLiveBatchAndUpdateSnapshot( + app, + LastClosedLedger(lhe, app.getLedgerManager().getLastClosedLedgerHAS(), + sorobanConfig), + initEntries, liveEntries, deadEntries); +} + +void +addLiveBatchAndUpdateSnapshot(Application& app, LastClosedLedger lcl, + std::vector const& initEntries, + std::vector const& liveEntries, + std::vector const& deadEntries) { auto& liveBl = app.getBucketManager().getLiveBucketList(); - liveBl.addBatch(app, header.ledgerSeq, header.ledgerVersion, initEntries, - liveEntries, deadEntries); + liveBl.addBatch(app, lcl.getLedgerSeq(), lcl.getProtocolVersion(), + initEntries, liveEntries, deadEntries); auto liveSnapshot = - std::make_unique>(liveBl, header); + std::make_unique>(liveBl, lcl); auto hotArchiveSnapshot = std::make_unique>( - app.getBucketManager().getHotArchiveBucketList(), header); + app.getBucketManager().getHotArchiveBucketList(), lcl); app.getBucketManager().getBucketSnapshotManager().updateCurrentSnapshot( std::move(liveSnapshot), std::move(hotArchiveSnapshot)); @@ -59,15 +79,36 @@ addHotArchiveBatchAndUpdateSnapshot( std::vector const& archiveEntries, std::vector const& restoredEntries, std::vector const& deletedEntries) +{ + LedgerHeaderHistoryEntry lhe; + lhe.header = header; + auto sorobanConfig = + app.getLedgerManager().hasSorobanNetworkConfig() + ? std::make_optional( + app.getLedgerManager().getSorobanNetworkConfig()) + : std::nullopt; + addHotArchiveBatchAndUpdateSnapshot( + app, + LastClosedLedger(lhe, app.getLedgerManager().getLastClosedLedgerHAS(), + sorobanConfig), + archiveEntries, restoredEntries, deletedEntries); +} + +void +addHotArchiveBatchAndUpdateSnapshot( + Application& app, LastClosedLedger lcl, + std::vector const& archiveEntries, + std::vector const& restoredEntries, + std::vector const& deletedEntries) { auto& hotArchiveBl = app.getBucketManager().getHotArchiveBucketList(); - hotArchiveBl.addBatch(app, header.ledgerSeq, header.ledgerVersion, + hotArchiveBl.addBatch(app, lcl.getLedgerSeq(), lcl.getProtocolVersion(), archiveEntries, restoredEntries, deletedEntries); auto liveSnapshot = std::make_unique>( - app.getBucketManager().getLiveBucketList(), header); + app.getBucketManager().getLiveBucketList(), lcl); auto hotArchiveSnapshot = std::make_unique>(hotArchiveBl, - header); + lcl); app.getBucketManager().getBucketSnapshotManager().updateCurrentSnapshot( std::move(liveSnapshot), std::move(hotArchiveSnapshot)); diff --git a/src/bucket/test/BucketTestUtils.h b/src/bucket/test/BucketTestUtils.h index 62aa7265b5..22693786db 100644 --- a/src/bucket/test/BucketTestUtils.h +++ b/src/bucket/test/BucketTestUtils.h @@ -17,12 +17,23 @@ void addLiveBatchAndUpdateSnapshot(Application& app, LedgerHeader header, std::vector const& liveEntries, std::vector const& deadEntries); +void addLiveBatchAndUpdateSnapshot(Application& app, LastClosedLedger lcl, + std::vector const& initEntries, + std::vector const& liveEntries, + std::vector const& deadEntries); + void addHotArchiveBatchAndUpdateSnapshot( Application& app, LedgerHeader header, std::vector const& archiveEntries, std::vector const& restoredEntries, std::vector const& deletedEntries); +void addHotArchiveBatchAndUpdateSnapshot( + Application& app, LastClosedLedger lcl, + std::vector const& archiveEntries, + std::vector const& restoredEntries, + std::vector const& deletedEntries); + uint32_t getAppLedgerVersion(Application& app); uint32_t getAppLedgerVersion(std::shared_ptr app); diff --git a/src/ledger/LedgerManagerImpl.cpp b/src/ledger/LedgerManagerImpl.cpp index d56f4e7bed..fb54f15bf1 100644 --- a/src/ledger/LedgerManagerImpl.cpp +++ b/src/ledger/LedgerManagerImpl.cpp @@ -1273,11 +1273,13 @@ LedgerManagerImpl::advanceLedgerPointers(LedgerHeader const& header, if (header.ledgerSeq != prevLedgerSeq) { auto& bm = mApp.getBucketManager(); + auto lcl = LastClosedLedger(mLastClosedLedger, getLastClosedLedgerHAS(), + mSorobanNetworkConfig); auto liveSnapshot = std::make_unique>( - bm.getLiveBucketList(), header); + bm.getLiveBucketList(), lcl); auto hotArchiveSnapshot = std::make_unique>( - bm.getHotArchiveBucketList(), header); + bm.getHotArchiveBucketList(), lcl); bm.getBucketSnapshotManager().updateCurrentSnapshot( std::move(liveSnapshot), std::move(hotArchiveSnapshot)); } diff --git a/src/ledger/LedgerStateSnapshot.cpp b/src/ledger/LedgerStateSnapshot.cpp index ba51424b5b..5951ab8d82 100644 --- a/src/ledger/LedgerStateSnapshot.cpp +++ b/src/ledger/LedgerStateSnapshot.cpp @@ -112,6 +112,13 @@ LedgerTxnReadOnly::getLedgerHeader() const return LedgerHeaderWrapper(mLedgerTxn.loadHeader()); } +LastClosedLedger const& +LedgerTxnReadOnly::getLastClosedLedger() const +{ + throw std::runtime_error( + "LedgerTxnReadOnly::getLastClosedLedger is illegal"); +} + LedgerEntryWrapper LedgerTxnReadOnly::getAccount(AccountID const& account) const { @@ -162,10 +169,11 @@ LedgerTxnReadOnly::executeWithMaybeInnerSnapshot( return f(lsg); } -BucketSnapshotState::BucketSnapshotState(BucketManager& bm) - : mSnapshot(bm.getSearchableLiveBucketListSnapshot()) +BucketSnapshotState::BucketSnapshotState( + std::shared_ptr snapshot) + : mSnapshot(snapshot) , mLedgerHeader(LedgerHeaderWrapper( - std::make_shared(mSnapshot->getLedgerHeader()))) + std::make_shared(snapshot->getLedgerHeader()))) { } @@ -179,6 +187,12 @@ BucketSnapshotState::getLedgerHeader() const return LedgerHeaderWrapper(std::get<1>(mLedgerHeader.mHeader)); } +LastClosedLedger const& +BucketSnapshotState::getLastClosedLedger() const +{ + return mSnapshot->getLastClosedLedger(); +} + LedgerEntryWrapper BucketSnapshotState::getAccount(AccountID const& account) const { @@ -242,6 +256,12 @@ LedgerSnapshot::getLedgerHeader() const return mGetter->getLedgerHeader(); } +LastClosedLedger const& +LedgerSnapshot::getLastClosedLedger() const +{ + return mGetter->getLastClosedLedger(); +} + LedgerEntryWrapper LedgerSnapshot::getAccount(AccountID const& account) const { diff --git a/src/ledger/LedgerStateSnapshot.h b/src/ledger/LedgerStateSnapshot.h index 87833034c2..8b384ac485 100644 --- a/src/ledger/LedgerStateSnapshot.h +++ b/src/ledger/LedgerStateSnapshot.h @@ -65,6 +65,7 @@ class AbstractLedgerStateSnapshot { public: virtual ~AbstractLedgerStateSnapshot() = default; + virtual LastClosedLedger const& getLastClosedLedger() const = 0; virtual LedgerHeaderWrapper getLedgerHeader() const = 0; virtual LedgerEntryWrapper getAccount(AccountID const& account) const = 0; virtual LedgerEntryWrapper getAccount(LedgerHeaderWrapper const& header, @@ -91,6 +92,7 @@ class LedgerTxnReadOnly : public AbstractLedgerStateSnapshot public: LedgerTxnReadOnly(AbstractLedgerTxn& ltx); ~LedgerTxnReadOnly() override; + LastClosedLedger const& getLastClosedLedger() const override; LedgerHeaderWrapper getLedgerHeader() const override; LedgerEntryWrapper getAccount(AccountID const& account) const override; LedgerEntryWrapper getAccount(LedgerHeaderWrapper const& header, @@ -116,6 +118,7 @@ class BucketSnapshotState : public AbstractLedgerStateSnapshot BucketSnapshotState(BucketManager& bm); ~BucketSnapshotState() override; + LastClosedLedger const& getLastClosedLedger() const override; LedgerHeaderWrapper getLedgerHeader() const override; LedgerEntryWrapper getAccount(AccountID const& account) const override; LedgerEntryWrapper getAccount(LedgerHeaderWrapper const& header, @@ -144,6 +147,7 @@ class LedgerSnapshot : public NonMovableOrCopyable LedgerSnapshot(AbstractLedgerTxn& ltx); LedgerSnapshot(Application& app); LedgerHeaderWrapper getLedgerHeader() const; + LastClosedLedger const& getLastClosedLedger() const; LedgerEntryWrapper getAccount(AccountID const& account) const; LedgerEntryWrapper getAccount(LedgerHeaderWrapper const& header, From 5ed0fb2e4d388b7735032d8d8fa6db0c1c73f3a2 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 20 Dec 2024 08:25:45 -0800 Subject: [PATCH 2/8] Switch LedgerStateSnapshot to using LM's snapshot --- src/ledger/LedgerManager.h | 4 ++++ src/ledger/LedgerManagerImpl.cpp | 13 +++++++++++++ src/ledger/LedgerManagerImpl.h | 5 +++++ src/ledger/LedgerStateSnapshot.cpp | 5 +++-- src/ledger/LedgerStateSnapshot.h | 3 ++- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/ledger/LedgerManager.h b/src/ledger/LedgerManager.h index 3fb436cf6d..bff644a201 100644 --- a/src/ledger/LedgerManager.h +++ b/src/ledger/LedgerManager.h @@ -96,6 +96,10 @@ class LedgerManager virtual LedgerHeaderHistoryEntry const& getLastClosedLedgerHeader() const = 0; + // Get bucketlist snapshot + virtual std::shared_ptr + getCurrentLedgerStateSnaphot() = 0; + // return the HAS that corresponds to the last closed ledger as persisted in // the database virtual HistoryArchiveState getLastClosedLedgerHAS() = 0; diff --git a/src/ledger/LedgerManagerImpl.cpp b/src/ledger/LedgerManagerImpl.cpp index fb54f15bf1..ac897ec89d 100644 --- a/src/ledger/LedgerManagerImpl.cpp +++ b/src/ledger/LedgerManagerImpl.cpp @@ -1253,6 +1253,19 @@ LedgerManagerImpl::maybeResetLedgerCloseMetaDebugStream(uint32_t ledgerSeq) } } +std::shared_ptr +LedgerManagerImpl::getCurrentLedgerStateSnaphot() +{ + if (!mReadOnlyLedgerStateSnapshot) + { + mReadOnlyLedgerStateSnapshot = + mApp.getBucketManager() + .getBucketSnapshotManager() + .copySearchableLiveBucketListSnapshot(); + } + return mReadOnlyLedgerStateSnapshot; +} + void LedgerManagerImpl::advanceLedgerPointers(LedgerHeader const& header, bool debugLog) diff --git a/src/ledger/LedgerManagerImpl.h b/src/ledger/LedgerManagerImpl.h index 50432579ed..577a5a9f6c 100644 --- a/src/ledger/LedgerManagerImpl.h +++ b/src/ledger/LedgerManagerImpl.h @@ -68,6 +68,8 @@ class LedgerManagerImpl : public LedgerManager medida::Timer& mMetaStreamWriteTime; VirtualClock::time_point mLastClose; bool mRebuildInMemoryState{false}; + std::shared_ptr + mReadOnlyLedgerStateSnapshot; std::unique_ptr mStartCatchup; medida::Timer& mCatchupDuration; @@ -202,5 +204,8 @@ class LedgerManagerImpl : public LedgerManager void maybeResetLedgerCloseMetaDebugStream(uint32_t ledgerSeq); SorobanMetrics& getSorobanMetrics() override; + + std::shared_ptr + getCurrentLedgerStateSnaphot() override; }; } diff --git a/src/ledger/LedgerStateSnapshot.cpp b/src/ledger/LedgerStateSnapshot.cpp index 5951ab8d82..781ba769a8 100644 --- a/src/ledger/LedgerStateSnapshot.cpp +++ b/src/ledger/LedgerStateSnapshot.cpp @@ -3,8 +3,8 @@ // of this distribution or at http://www.apache.org/licenses/LICENSE-2.0 #include "ledger/LedgerStateSnapshot.h" -#include "bucket/BucketManager.h" #include "bucket/BucketSnapshotManager.h" +#include "ledger/LedgerManager.h" #include "ledger/LedgerTxn.h" #include "main/Application.h" #include "transactions/TransactionFrame.h" @@ -247,7 +247,8 @@ LedgerSnapshot::LedgerSnapshot(Application& app) } else #endif - mGetter = std::make_unique(app.getBucketManager()); + mGetter = std::make_unique( + app.getLedgerManager().getCurrentLedgerStateSnaphot()); } LedgerHeaderWrapper diff --git a/src/ledger/LedgerStateSnapshot.h b/src/ledger/LedgerStateSnapshot.h index 8b384ac485..f6347968fb 100644 --- a/src/ledger/LedgerStateSnapshot.h +++ b/src/ledger/LedgerStateSnapshot.h @@ -115,7 +115,8 @@ class BucketSnapshotState : public AbstractLedgerStateSnapshot LedgerHeaderWrapper mLedgerHeader; public: - BucketSnapshotState(BucketManager& bm); + BucketSnapshotState( + std::shared_ptr snapshot); ~BucketSnapshotState() override; LastClosedLedger const& getLastClosedLedger() const override; From 1cc55a0183e0af35c3c60fde340e550789e25137 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 20 Dec 2024 08:51:27 -0800 Subject: [PATCH 3/8] Allow freezing bucketlist snapshots to be refreshed by callers manually --- src/bucket/BucketListSnapshotBase.cpp | 23 ++++++++++++++++------ src/bucket/BucketListSnapshotBase.h | 7 ++++++- src/bucket/BucketManager.cpp | 7 ++++--- src/bucket/BucketSnapshotManager.cpp | 5 +++-- src/bucket/BucketSnapshotManager.h | 2 +- src/bucket/SearchableBucketList.cpp | 28 +++++++++++++++++++++------ src/bucket/SearchableBucketList.h | 6 ++++-- src/bucket/test/BucketIndexTests.cpp | 10 +++++----- src/bucket/test/BucketListTests.cpp | 3 ++- src/ledger/LedgerManagerImpl.cpp | 7 ++++++- src/ledger/LedgerTxn.cpp | 2 +- src/main/QueryServer.cpp | 3 ++- 12 files changed, 73 insertions(+), 30 deletions(-) diff --git a/src/bucket/BucketListSnapshotBase.cpp b/src/bucket/BucketListSnapshotBase.cpp index 988fdf2f81..bd7f026b55 100644 --- a/src/bucket/BucketListSnapshotBase.cpp +++ b/src/bucket/BucketListSnapshotBase.cpp @@ -54,7 +54,10 @@ LedgerHeader const& SearchableBucketListSnapshotBase::getLedgerHeader() { releaseAssert(mSnapshot); - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + if (mAutoUpdate) + { + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + } return mSnapshot->getLedgerHeader(); } @@ -63,7 +66,10 @@ LastClosedLedger const& SearchableBucketListSnapshotBase::getLastClosedLedger() { releaseAssert(mSnapshot); - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + if (mAutoUpdate) + { + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + } return mSnapshot->getLastClosedLedger(); } @@ -117,7 +123,10 @@ SearchableBucketListSnapshotBase::load(LedgerKey const& k) } }; - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + if (mAutoUpdate) + { + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + } if (threadIsMain()) { mSnapshotManager.startPointLoadTimer(); @@ -150,10 +159,12 @@ BucketLevelSnapshot::BucketLevelSnapshot( template SearchableBucketListSnapshotBase::SearchableBucketListSnapshotBase( - BucketSnapshotManager const& snapshotManager) - : mSnapshotManager(snapshotManager), mHistoricalSnapshots() + BucketSnapshotManager const& snapshotManager, bool autoUpdate) + : mSnapshotManager(snapshotManager) + , mHistoricalSnapshots() + , mAutoUpdate(autoUpdate) { - + // Always create a snapshot based on the latest LCL state. mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); } diff --git a/src/bucket/BucketListSnapshotBase.h b/src/bucket/BucketListSnapshotBase.h index d0b6d7ef0d..d1909330a3 100644 --- a/src/bucket/BucketListSnapshotBase.h +++ b/src/bucket/BucketListSnapshotBase.h @@ -159,6 +159,7 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable // Snapshot managed by SnapshotManager SnapshotPtrT mSnapshot{}; std::map> mHistoricalSnapshots; + bool const mAutoUpdate; // Loops through all buckets, starting with curr at level 0, then snap at // level 0, etc. Calls f on each bucket. Exits early if function @@ -166,8 +167,12 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable void loopAllBuckets(std::function f, BucketListSnapshot const& snapshot) const; + // If `autoUpdate` is true, the snapshot will keep itself consistent with + // LCL automatically. If not, callers are expected to refresh the snapshot + // manually (this is useful to use cases that a consistent view of the state + // for some arbitrary time) SearchableBucketListSnapshotBase( - BucketSnapshotManager const& snapshotManager); + BucketSnapshotManager const& snapshotManager, bool autoUpdate); std::optional> loadKeysInternal(std::set const& inKeys, diff --git a/src/bucket/BucketManager.cpp b/src/bucket/BucketManager.cpp index f7ee00f6e5..a576446fbe 100644 --- a/src/bucket/BucketManager.cpp +++ b/src/bucket/BucketManager.cpp @@ -1054,8 +1054,8 @@ BucketManager::startBackgroundEvictionScan(uint32_t ledgerSeq) releaseAssert(!mEvictionFuture.valid()); releaseAssert(mEvictionStatistics); - auto searchableBL = - mSnapshotManager->copySearchableLiveBucketListSnapshot(); + auto searchableBL = mSnapshotManager->copySearchableLiveBucketListSnapshot( + /* autoUpdate */ true); auto const& cfg = mApp.getLedgerManager().getSorobanNetworkConfig(); auto const& sas = cfg.stateArchivalSettings(); @@ -1588,7 +1588,8 @@ BucketManager::getSearchableLiveBucketListSnapshot() if (!mSearchableBucketListSnapshot) { mSearchableBucketListSnapshot = - mSnapshotManager->copySearchableLiveBucketListSnapshot(); + mSnapshotManager->copySearchableLiveBucketListSnapshot( + /* autoUpdate */ true); } return mSearchableBucketListSnapshot; diff --git a/src/bucket/BucketSnapshotManager.cpp b/src/bucket/BucketSnapshotManager.cpp index 9d9918cd16..d343bbe55b 100644 --- a/src/bucket/BucketSnapshotManager.cpp +++ b/src/bucket/BucketSnapshotManager.cpp @@ -53,11 +53,12 @@ BucketSnapshotManager::BucketSnapshotManager( } std::shared_ptr -BucketSnapshotManager::copySearchableLiveBucketListSnapshot() const +BucketSnapshotManager::copySearchableLiveBucketListSnapshot( + bool autoUpdate) const { // Can't use std::make_shared due to private constructor return std::shared_ptr( - new SearchableLiveBucketListSnapshot(*this)); + new SearchableLiveBucketListSnapshot(*this, autoUpdate)); } std::shared_ptr diff --git a/src/bucket/BucketSnapshotManager.h b/src/bucket/BucketSnapshotManager.h index d2c797238f..67d0cdb48a 100644 --- a/src/bucket/BucketSnapshotManager.h +++ b/src/bucket/BucketSnapshotManager.h @@ -89,7 +89,7 @@ class BucketSnapshotManager : NonMovableOrCopyable uint32_t numHistoricalLedgers); std::shared_ptr - copySearchableLiveBucketListSnapshot() const; + copySearchableLiveBucketListSnapshot(bool autoUpdate) const; std::shared_ptr copySearchableHotArchiveBucketListSnapshot() const; diff --git a/src/bucket/SearchableBucketList.cpp b/src/bucket/SearchableBucketList.cpp index 15b6e4792b..24f837c523 100644 --- a/src/bucket/SearchableBucketList.cpp +++ b/src/bucket/SearchableBucketList.cpp @@ -61,6 +61,12 @@ SearchableLiveBucketListSnapshot::scanForEviction( return result; } +void +SearchableLiveBucketListSnapshot::updateSnapshotToLatest() +{ + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); +} + template std::optional> SearchableBucketListSnapshotBase::loadKeysInternal( @@ -77,7 +83,10 @@ SearchableBucketListSnapshotBase::loadKeysInternal( return keys.empty() ? Loop::COMPLETE : Loop::INCOMPLETE; }; - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + if (mAutoUpdate) + { + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + } if (!ledgerSeq || *ledgerSeq == mSnapshot->getLedgerSeq()) { @@ -111,7 +120,10 @@ SearchableLiveBucketListSnapshot::loadPoolShareTrustLinesByAccountAndAsset( // This query should only be called during TX apply releaseAssert(threadIsMain()); - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + if (mAutoUpdate) + { + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + } releaseAssert(mSnapshot); LedgerKeySet trustlinesToLoad; @@ -152,7 +164,10 @@ SearchableLiveBucketListSnapshot::loadInflationWinners(size_t maxWinners, int64_t minBalance) { ZoneScoped; - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + if (mAutoUpdate) + { + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + } releaseAssert(mSnapshot); // This is a legacy query, should only be called by main thread during @@ -261,14 +276,15 @@ SearchableLiveBucketListSnapshot::loadKeysWithLimits( } SearchableLiveBucketListSnapshot::SearchableLiveBucketListSnapshot( - BucketSnapshotManager const& snapshotManager) - : SearchableBucketListSnapshotBase(snapshotManager) + BucketSnapshotManager const& snapshotManager, bool autoUpdate) + : SearchableBucketListSnapshotBase(snapshotManager, autoUpdate) { } SearchableHotArchiveBucketListSnapshot::SearchableHotArchiveBucketListSnapshot( BucketSnapshotManager const& snapshotManager) - : SearchableBucketListSnapshotBase(snapshotManager) + : SearchableBucketListSnapshotBase(snapshotManager, + /* autoUpdate */ true) { } diff --git a/src/bucket/SearchableBucketList.h b/src/bucket/SearchableBucketList.h index c2a4f9ae65..fe9349c375 100644 --- a/src/bucket/SearchableBucketList.h +++ b/src/bucket/SearchableBucketList.h @@ -14,7 +14,7 @@ class SearchableLiveBucketListSnapshot : public SearchableBucketListSnapshotBase { SearchableLiveBucketListSnapshot( - BucketSnapshotManager const& snapshotManager); + BucketSnapshotManager const& snapshotManager, bool autoUpdate); public: std::vector @@ -35,7 +35,9 @@ class SearchableLiveBucketListSnapshot StateArchivalSettings const& sas); friend std::shared_ptr - BucketSnapshotManager::copySearchableLiveBucketListSnapshot() const; + BucketSnapshotManager::copySearchableLiveBucketListSnapshot( + bool autoUpdate) const; + void updateSnapshotToLatest(); }; class SearchableHotArchiveBucketListSnapshot diff --git a/src/bucket/test/BucketIndexTests.cpp b/src/bucket/test/BucketIndexTests.cpp index 708f7ed5c7..6950794da0 100644 --- a/src/bucket/test/BucketIndexTests.cpp +++ b/src/bucket/test/BucketIndexTests.cpp @@ -133,7 +133,7 @@ class BucketIndexTest auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(true); auto lk = LedgerEntryKey(canonicalEntry); auto currentLoadedEntry = searchableBL->load(lk); @@ -252,7 +252,7 @@ class BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(true); // Test bulk load lookup auto loadResult = @@ -279,7 +279,7 @@ class BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(true); for (size_t i = 0; i < n; ++i) { LedgerKeySet searchSubset; @@ -319,7 +319,7 @@ class BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(true); // Load should return empty vector for keys not in bucket list auto keysNotInBL = @@ -496,7 +496,7 @@ class BucketIndexPoolShareTest : public BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(true); auto loadResult = searchableBL->loadPoolShareTrustLinesByAccountAndAsset( mAccountToSearch.accountID, mAssetToSearch); diff --git a/src/bucket/test/BucketListTests.cpp b/src/bucket/test/BucketListTests.cpp index 6f33d9e717..903432e23b 100644 --- a/src/bucket/test/BucketListTests.cpp +++ b/src/bucket/test/BucketListTests.cpp @@ -1405,7 +1405,8 @@ TEST_CASE_VERSIONS("Searchable BucketListDB snapshots", "[bucketlist]") entry.data.claimableBalance().amount = 0; auto searchableBL = - bm.getBucketSnapshotManager().copySearchableLiveBucketListSnapshot(); + bm.getBucketSnapshotManager().copySearchableLiveBucketListSnapshot( + true); // Update entry every 5 ledgers so we can see bucket merge events for (auto ledgerSeq = 1; ledgerSeq < 101; ++ledgerSeq) diff --git a/src/ledger/LedgerManagerImpl.cpp b/src/ledger/LedgerManagerImpl.cpp index ac897ec89d..1f3193e16a 100644 --- a/src/ledger/LedgerManagerImpl.cpp +++ b/src/ledger/LedgerManagerImpl.cpp @@ -1258,10 +1258,12 @@ LedgerManagerImpl::getCurrentLedgerStateSnaphot() { if (!mReadOnlyLedgerStateSnapshot) { + // Set autoUpdate to false to "freeze" the snapshot + // Update manually at the end of ledger close mReadOnlyLedgerStateSnapshot = mApp.getBucketManager() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(/* autoUpdate */ false); } return mReadOnlyLedgerStateSnapshot; } @@ -1296,6 +1298,9 @@ LedgerManagerImpl::advanceLedgerPointers(LedgerHeader const& header, bm.getBucketSnapshotManager().updateCurrentSnapshot( std::move(liveSnapshot), std::move(hotArchiveSnapshot)); } + // Manually refresh the snapshot now that apply is done + // This has to be done *after* snapshot manager updates current snapshot + getCurrentLedgerStateSnaphot()->updateSnapshotToLatest(); } void diff --git a/src/ledger/LedgerTxn.cpp b/src/ledger/LedgerTxn.cpp index f2d6c1e79d..153df77143 100644 --- a/src/ledger/LedgerTxn.cpp +++ b/src/ledger/LedgerTxn.cpp @@ -3062,7 +3062,7 @@ LedgerTxnRoot::Impl::getSearchableLiveBucketListSnapshot() const mSearchableBucketListSnapshot = mApp.getBucketManager() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(); + .copySearchableLiveBucketListSnapshot(/* autoUpdate */ true); } return *mSearchableBucketListSnapshot; diff --git a/src/main/QueryServer.cpp b/src/main/QueryServer.cpp index 18bba19423..b63184f886 100644 --- a/src/main/QueryServer.cpp +++ b/src/main/QueryServer.cpp @@ -67,7 +67,8 @@ QueryServer::QueryServer(const std::string& address, unsigned short port, for (auto pid : workerPids) { mBucketListSnapshots[pid] = std::move( - bucketSnapshotManager.copySearchableLiveBucketListSnapshot()); + bucketSnapshotManager.copySearchableLiveBucketListSnapshot( + /* autoUpdate */ true)); } } From 15547b0d74ad00e125ceab603235d4311cf2b46c Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 20 Dec 2024 13:19:39 -0800 Subject: [PATCH 4/8] Switch to querying LCL data from read-only snapshots only --- src/bucket/BucketSnapshotManager.cpp | 25 ++- src/bucket/BucketSnapshotManager.h | 6 +- src/bucket/SearchableBucketList.cpp | 2 +- src/catchup/CatchupManagerImpl.cpp | 9 +- src/herder/TxSetFrame.cpp | 2 +- src/herder/test/HerderTests.cpp | 20 +- src/herder/test/TxSetTests.cpp | 13 +- src/ledger/LedgerManagerImpl.cpp | 209 +++++++++--------- src/ledger/LedgerManagerImpl.h | 7 +- src/main/CommandHandler.cpp | 2 +- src/main/Config.cpp | 9 +- src/main/Config.h | 4 - src/main/test/ApplicationUtilsTests.cpp | 1 - .../test/InvokeHostFunctionTests.cpp | 17 +- 14 files changed, 161 insertions(+), 165 deletions(-) diff --git a/src/bucket/BucketSnapshotManager.cpp b/src/bucket/BucketSnapshotManager.cpp index d343bbe55b..46869b8bbc 100644 --- a/src/bucket/BucketSnapshotManager.cpp +++ b/src/bucket/BucketSnapshotManager.cpp @@ -98,22 +98,24 @@ template <> void BucketSnapshotManager::maybeUpdateSnapshot( SnapshotPtrT& snapshot, - std::map>& historicalSnapshots) const + std::map>& historicalSnapshots, + bool forceUpdate) const { maybeUpdateSnapshotInternal(snapshot, historicalSnapshots, - mCurrLiveSnapshot, mLiveHistoricalSnapshots); + mCurrLiveSnapshot, mLiveHistoricalSnapshots, + forceUpdate); } template <> void BucketSnapshotManager::maybeUpdateSnapshot( SnapshotPtrT& snapshot, - std::map>& historicalSnapshots) - const + std::map>& historicalSnapshots, + bool forceUpdate) const { maybeUpdateSnapshotInternal(snapshot, historicalSnapshots, mCurrHotArchiveSnapshot, - mHotArchiveHistoricalSnapshots); + mHotArchiveHistoricalSnapshots, forceUpdate); } template @@ -122,8 +124,8 @@ BucketSnapshotManager::maybeUpdateSnapshotInternal( SnapshotPtrT& snapshot, std::map>& historicalSnapshots, SnapshotPtrT const& managerSnapshot, - std::map> const& managerHistoricalSnapshots) - const + std::map> const& managerHistoricalSnapshots, + bool forceUpdate) const { BUCKET_TYPE_ASSERT(BucketT); @@ -134,11 +136,14 @@ BucketSnapshotManager::maybeUpdateSnapshotInternal( // First update current snapshot if (!snapshot || - snapshot->getLedgerSeq() != managerSnapshot->getLedgerSeq()) + snapshot->getLedgerSeq() != managerSnapshot->getLedgerSeq() || + forceUpdate) { // Should only update with a newer snapshot - releaseAssert(!snapshot || snapshot->getLedgerSeq() < - managerSnapshot->getLedgerSeq()); + releaseAssert(!snapshot || + snapshot->getLedgerSeq() < + managerSnapshot->getLedgerSeq() || + forceUpdate); snapshot = std::make_unique const>( *managerSnapshot); } diff --git a/src/bucket/BucketSnapshotManager.h b/src/bucket/BucketSnapshotManager.h index 67d0cdb48a..530bea2d7a 100644 --- a/src/bucket/BucketSnapshotManager.h +++ b/src/bucket/BucketSnapshotManager.h @@ -72,7 +72,8 @@ class BucketSnapshotManager : NonMovableOrCopyable std::map>& historicalSnapshots, SnapshotPtrT const& managerSnapshot, std::map> const& - managerHistoricalSnapshots) const; + managerHistoricalSnapshots, + bool forceUpdate = false) const; public: // Called by main thread to update snapshots whenever the BucketList @@ -98,7 +99,8 @@ class BucketSnapshotManager : NonMovableOrCopyable template void maybeUpdateSnapshot( SnapshotPtrT& snapshot, - std::map>& historicalSnapshots) const; + std::map>& historicalSnapshots, + bool forceUpdate = false) const; // All metric recording functions must only be called by the main thread void startPointLoadTimer() const; diff --git a/src/bucket/SearchableBucketList.cpp b/src/bucket/SearchableBucketList.cpp index 24f837c523..75f69a91a4 100644 --- a/src/bucket/SearchableBucketList.cpp +++ b/src/bucket/SearchableBucketList.cpp @@ -64,7 +64,7 @@ SearchableLiveBucketListSnapshot::scanForEviction( void SearchableLiveBucketListSnapshot::updateSnapshotToLatest() { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); + mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots, true); } template diff --git a/src/catchup/CatchupManagerImpl.cpp b/src/catchup/CatchupManagerImpl.cpp index 9c101066cf..01f9f0ea07 100644 --- a/src/catchup/CatchupManagerImpl.cpp +++ b/src/catchup/CatchupManagerImpl.cpp @@ -439,8 +439,9 @@ void CatchupManagerImpl::tryApplySyncingLedgers() { ZoneScoped; - auto const& ledgerHeader = - mApp.getLedgerManager().getLastClosedLedgerHeader(); + auto getLcl = [&]() { + return mApp.getLedgerManager().getLastClosedLedgerHeader(); + }; // We can apply multiple ledgers here, which might be slow. This is a rare // occurrence so we should be fine. @@ -450,14 +451,14 @@ CatchupManagerImpl::tryApplySyncingLedgers() auto const& lcd = it->second; // we still have a missing ledger - if (ledgerHeader.header.ledgerSeq + 1 != lcd.getLedgerSeq()) + if (getLcl().header.ledgerSeq + 1 != lcd.getLedgerSeq()) { break; } mApp.getLedgerManager().closeLedger(lcd); CLOG_INFO(History, "Closed buffered ledger: {}", - LedgerManager::ledgerAbbrev(ledgerHeader)); + LedgerManager::ledgerAbbrev(getLcl())); ++it; } diff --git a/src/herder/TxSetFrame.cpp b/src/herder/TxSetFrame.cpp index e4f951f458..5f8e4479f2 100644 --- a/src/herder/TxSetFrame.cpp +++ b/src/herder/TxSetFrame.cpp @@ -875,7 +875,7 @@ ApplicableTxSetFrame::checkValid(Application& app, uint64_t upperBoundCloseTimeOffset) const { ZoneScoped; - auto& lcl = app.getLedgerManager().getLastClosedLedgerHeader(); + auto const& lcl = app.getLedgerManager().getLastClosedLedgerHeader(); // Start by checking previousLedgerHash if (lcl.hash != mPreviousLedgerHash) diff --git a/src/herder/test/HerderTests.cpp b/src/herder/test/HerderTests.cpp index a1fb07475a..c191703fb6 100644 --- a/src/herder/test/HerderTests.cpp +++ b/src/herder/test/HerderTests.cpp @@ -1870,7 +1870,9 @@ testSCPDriver(uint32 protocolVersion, uint32_t maxTxSetSize, size_t expectedOps) Application::pointer app = createTestApplication(clock, cfg); - auto const& lcl = app->getLedgerManager().getLastClosedLedgerHeader(); + auto getLcl = [&]() { + return app->getLedgerManager().getLastClosedLedgerHeader(); + }; auto root = TestAccount::createRoot(*app); std::vector accounts; @@ -1958,7 +1960,7 @@ testSCPDriver(uint32 protocolVersion, uint32_t maxTxSetSize, size_t expectedOps) std::vector txSetSizes; std::vector txSetOpSizes; std::vector closeTimes; - std::vector baseFees; + std::vector baseFees; auto addCandidateThenTest = [&](CandidateSpec const& spec) { // Create a transaction set using the given parameters, combine @@ -1974,13 +1976,13 @@ testSCPDriver(uint32 protocolVersion, uint32_t maxTxSetSize, size_t expectedOps) auto [txSet, applicableTxSet] = makeTransactions(spec.n, spec.nbOps, spec.feeMulti); txSetHashes.push_back(txSet->getContentsHash()); - txSetSizes.push_back(applicableTxSet->size(lcl.header)); + txSetSizes.push_back(applicableTxSet->size(getLcl().header)); txSetOpSizes.push_back(applicableTxSet->sizeOpTotal()); closeTimes.push_back(spec.closeTime); if (spec.baseFeeIncrement) { auto const baseFee = - lcl.header.baseFee + *spec.baseFeeIncrement; + getLcl().header.baseFee + *spec.baseFeeIncrement; baseFees.push_back(baseFee); LedgerUpgrade ledgerUpgrade; ledgerUpgrade.type(LEDGER_UPGRADE_BASE_FEE); @@ -2143,13 +2145,13 @@ testSCPDriver(uint32 protocolVersion, uint32_t maxTxSetSize, size_t expectedOps) auto& herder = static_cast(app->getHerder()); auto& scp = herder.getHerderSCPDriver(); - auto const lclCloseTime = lcl.header.scpValue.closeTime; + auto const lclCloseTime = getLcl().header.scpValue.closeTime; auto testTxBounds = [&](TimePoint const minTime, TimePoint const maxTime, TimePoint const nextCloseTime, bool const expectValid) { - REQUIRE(nextCloseTime > lcl.header.scpValue.closeTime); + REQUIRE(nextCloseTime > getLcl().header.scpValue.closeTime); // Build a transaction set containing one transaction (which // could be any transaction that is valid in all ways aside from // its time bounds) with the given minTime and maxTime. @@ -4215,8 +4217,8 @@ static void externalize(SecretKey const& sk, LedgerManager& lm, HerderImpl& herder, std::vector const& txs, Application& app) { - auto const& lcl = lm.getLastClosedLedgerHeader(); - auto ledgerSeq = lcl.header.ledgerSeq + 1; + auto getLcl = [&]() { return lm.getLastClosedLedgerHeader(); }; + auto ledgerSeq = getLcl().header.ledgerSeq + 1; auto classicTxs = txs; @@ -4243,7 +4245,7 @@ externalize(SecretKey const& sk, LedgerManager& lm, HerderImpl& herder, herder.getPendingEnvelopes().putTxSet(txSet->getContentsHash(), ledgerSeq, txSet); - auto lastCloseTime = lcl.header.scpValue.closeTime; + auto lastCloseTime = getLcl().header.scpValue.closeTime; StellarValue sv = herder.makeStellarValue(txSet->getContentsHash(), lastCloseTime, diff --git a/src/herder/test/TxSetTests.cpp b/src/herder/test/TxSetTests.cpp index 0f90c62921..f70391ebc4 100644 --- a/src/herder/test/TxSetTests.cpp +++ b/src/herder/test/TxSetTests.cpp @@ -613,10 +613,11 @@ TEST_CASE("generalized tx set XDR conversion", "[txset]") } SECTION("built from transactions") { - auto const& lclHeader = - app->getLedgerManager().getLastClosedLedgerHeader(); + auto getLclHeader = [&]() { + return app->getLedgerManager().getLastClosedLedgerHeader(); + }; std::vector txs = - createTxs(5, lclHeader.header.baseFee, /* isSoroban */ false); + createTxs(5, getLclHeader().header.baseFee, /* isSoroban */ false); std::vector sorobanTxs = createTxs(5, 10'000'000, /* isSoroban */ true); @@ -631,7 +632,7 @@ TEST_CASE("generalized tx set XDR conversion", "[txset]") .phases[0] .v0Components()[0] .txsMaybeDiscountedFee() - .baseFee == lclHeader.header.baseFee); + .baseFee == getLclHeader().header.baseFee); REQUIRE(txSetXdr.v1TxSet() .phases[0] .v0Components()[0] @@ -658,7 +659,7 @@ TEST_CASE("generalized tx set XDR conversion", "[txset]") REQUIRE(phase.v0Components().size() == 1); REQUIRE(*phase.v0Components()[0] .txsMaybeDiscountedFee() - .baseFee == lclHeader.header.baseFee); + .baseFee == getLclHeader().header.baseFee); REQUIRE(phase.v0Components()[0] .txsMaybeDiscountedFee() .txs.size() == 5); @@ -684,7 +685,7 @@ TEST_CASE("generalized tx set XDR conversion", "[txset]") { auto const& phase = txSetXdr.v1TxSet().phases[i]; auto expectedBaseFee = - i == 0 ? lclHeader.header.baseFee + i == 0 ? getLclHeader().header.baseFee : higherFeeSorobanTxs[0]->getInclusionFee(); REQUIRE(phase.v0Components().size() == 1); REQUIRE(*phase.v0Components()[0] diff --git a/src/ledger/LedgerManagerImpl.cpp b/src/ledger/LedgerManagerImpl.cpp index 1f3193e16a..d808c5d8f3 100644 --- a/src/ledger/LedgerManagerImpl.cpp +++ b/src/ledger/LedgerManagerImpl.cpp @@ -40,6 +40,7 @@ #include "util/XDRCereal.h" #include "util/XDRStream.h" #include "work/WorkScheduler.h" +#include "xdrpp/printer.h" #include @@ -301,48 +302,33 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist) // Step 2. Restore LedgerHeader from DB based on the ledger hash derived // earlier, or verify we're at genesis if in no-history mode std::optional latestLedgerHeader; - if (mApp.getConfig().MODE_STORES_HISTORY_LEDGERHEADERS) + if (mRebuildInMemoryState) { - if (mRebuildInMemoryState) + LedgerHeader lh; + CLOG_INFO(Ledger, "Setting empty ledger while core rebuilds state: {}", + ledgerAbbrev(lh)); + setLedgerTxnHeader(lh, mApp); + latestLedgerHeader = lh; + } + else + { + auto currentLedger = + LedgerHeaderUtils::loadByHash(getDatabase(), lastLedgerHash); + if (!currentLedger) { - LedgerHeader lh; - CLOG_INFO(Ledger, - "Setting empty ledger while core rebuilds state: {}", - ledgerAbbrev(lh)); - setLedgerTxnHeader(lh, mApp); - latestLedgerHeader = lh; + throw std::runtime_error("Could not load ledger from database"); } - else + HistoryArchiveState has = getLastClosedLedgerHAS(); + if (currentLedger->ledgerSeq != has.currentLedger) { - auto currentLedger = - LedgerHeaderUtils::loadByHash(getDatabase(), lastLedgerHash); - if (!currentLedger) - { - throw std::runtime_error("Could not load ledger from database"); - } - HistoryArchiveState has = getLastClosedLedgerHAS(); - if (currentLedger->ledgerSeq != has.currentLedger) - { - throw std::runtime_error("Invalid database state: last known " - "ledger does not agree with HAS"); - } - - CLOG_INFO(Ledger, "Loaded LCL header from database: {}", - ledgerAbbrev(*currentLedger)); - setLedgerTxnHeader(*currentLedger, mApp); - latestLedgerHeader = *currentLedger; + throw std::runtime_error("Invalid database state: last known " + "ledger does not agree with HAS"); } - } - else - { - // In no-history mode, this method should only be called when - // the LCL is genesis. - releaseAssertOrThrow(mLastClosedLedger.hash == lastLedgerHash); - releaseAssertOrThrow(mLastClosedLedger.header.ledgerSeq == - GENESIS_LEDGER_SEQ); - CLOG_INFO(Ledger, "LCL is genesis: {}", - ledgerAbbrev(mLastClosedLedger)); - latestLedgerHeader = mLastClosedLedger.header; + + CLOG_INFO(Ledger, "Loaded LCL header from database: {}", + ledgerAbbrev(*currentLedger)); + setLedgerTxnHeader(*currentLedger, mApp); + latestLedgerHeader = *currentLedger; } releaseAssert(latestLedgerHeader.has_value()); @@ -380,7 +366,7 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist) } // Step 4. Restore LedgerManager's internal state - advanceLedgerPointers(*latestLedgerHeader); + advanceReadOnlyLedgerState(*latestLedgerHeader); // Maybe truncate checkpoint files if we're restarting after a crash // in closeLedger (in which case any modifications to the ledger state have @@ -395,6 +381,18 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist) LedgerTxn ltx(mApp.getLedgerTxnRoot()); updateNetworkConfig(ltx); } + + // Now that everything has been loaded, ensure LCL inside the snapshot is + // up-to-date + advanceReadOnlyLedgerState(*latestLedgerHeader); +} + +LastClosedLedger const& +getLastClosedLedger(Application& app) +{ + return app.getLedgerManager() + .getCurrentLedgerStateSnaphot() + ->getLastClosedLedger(); } bool @@ -430,17 +428,13 @@ LedgerManagerImpl::getDatabase() uint32_t LedgerManagerImpl::getLastMaxTxSetSize() const { - return mLastClosedLedger.header.maxTxSetSize; + return getLastClosedLedger(mApp).getMaxTxSetSize(); } uint32_t LedgerManagerImpl::getLastMaxTxSetSizeOps() const { - auto n = mLastClosedLedger.header.maxTxSetSize; - return protocolVersionStartsFrom(mLastClosedLedger.header.ledgerVersion, - ProtocolVersion::V_11) - ? n - : (n * MAX_OPS_PER_TX); + return getLastClosedLedger(mApp).getLastMaxTxSetSizeOps(); } Resource @@ -487,29 +481,29 @@ LedgerManagerImpl::maxSorobanTransactionResources() int64_t LedgerManagerImpl::getLastMinBalance(uint32_t ownerCount) const { - auto const& lh = mLastClosedLedger.header; - if (protocolVersionIsBefore(lh.ledgerVersion, ProtocolVersion::V_9)) - return (2 + ownerCount) * lh.baseReserve; + auto const& lh = getLastClosedLedger(mApp); + if (protocolVersionIsBefore(lh.getProtocolVersion(), ProtocolVersion::V_9)) + return (2 + ownerCount) * lh.getLastReserve(); else - return (2LL + ownerCount) * int64_t(lh.baseReserve); + return (2LL + ownerCount) * int64_t(lh.getLastReserve()); } uint32_t LedgerManagerImpl::getLastReserve() const { - return mLastClosedLedger.header.baseReserve; + return getLastClosedLedger(mApp).getLastReserve(); } uint32_t LedgerManagerImpl::getLastTxFee() const { - return mLastClosedLedger.header.baseFee; + return getLastClosedLedger(mApp).getLastTxFee(); } LedgerHeaderHistoryEntry const& LedgerManagerImpl::getLastClosedLedgerHeader() const { - return mLastClosedLedger; + return getLastClosedLedger(mApp).lhhe; } HistoryArchiveState @@ -527,34 +521,43 @@ LedgerManagerImpl::getLastClosedLedgerHAS() uint32_t LedgerManagerImpl::getLastClosedLedgerNum() const { - return mLastClosedLedger.header.ledgerSeq; -} - -SorobanNetworkConfig& -LedgerManagerImpl::getSorobanNetworkConfigInternal() -{ - releaseAssert(mSorobanNetworkConfig); - return *mSorobanNetworkConfig; + return getLastClosedLedger(mApp).getLedgerSeq(); } SorobanNetworkConfig const& LedgerManagerImpl::getSorobanNetworkConfig() { - return getSorobanNetworkConfigInternal(); + releaseAssert(hasSorobanNetworkConfig()); +#ifdef BUILD_TESTS + if (mApp.getConfig().MODE_USES_IN_MEMORY_LEDGER) + { + return *mSorobanNetworkConfig; + } + else +#endif + return getLastClosedLedger(mApp).getSorobanNetworkConfig().value(); } bool LedgerManagerImpl::hasSorobanNetworkConfig() const { - return mSorobanNetworkConfig.has_value(); +#ifdef BUILD_TESTS + if (mApp.getConfig().MODE_USES_IN_MEMORY_LEDGER) + { + return mSorobanNetworkConfig.has_value(); + } + else +#endif + return getLastClosedLedger(mApp).getSorobanNetworkConfig().has_value(); } #ifdef BUILD_TESTS SorobanNetworkConfig& LedgerManagerImpl::getMutableSorobanNetworkConfig() { - return getSorobanNetworkConfigInternal(); + return *mSorobanNetworkConfig; } + std::vector const& LedgerManagerImpl::getLastClosedLedgerTxMeta() { @@ -678,7 +681,8 @@ void LedgerManagerImpl::closeLedgerIf(LedgerCloseData const& ledgerData) { ZoneScoped; - if (mLastClosedLedger.header.ledgerSeq + 1 == ledgerData.getLedgerSeq()) + auto lastClosedLedger = getLastClosedLedgerHeader(); + if (lastClosedLedger.header.ledgerSeq + 1 == ledgerData.getLedgerSeq()) { auto& cm = mApp.getCatchupManager(); // if catchup work is running, we don't want ledger manager to close @@ -688,19 +692,20 @@ LedgerManagerImpl::closeLedgerIf(LedgerCloseData const& ledgerData) CLOG_INFO( Ledger, "Can't close ledger: {} in LM because catchup is running", - ledgerAbbrev(mLastClosedLedger)); + ledgerAbbrev(lastClosedLedger)); return; } closeLedger(ledgerData); - CLOG_INFO(Ledger, "Closed ledger: {}", ledgerAbbrev(mLastClosedLedger)); + CLOG_INFO(Ledger, "Closed ledger: {}", + ledgerAbbrev(getLastClosedLedgerHeader())); } - else if (ledgerData.getLedgerSeq() <= mLastClosedLedger.header.ledgerSeq) + else if (ledgerData.getLedgerSeq() <= lastClosedLedger.header.ledgerSeq) { CLOG_INFO( Ledger, "Skipping close ledger: local state is {}, more recent than {}", - mLastClosedLedger.header.ledgerSeq, ledgerData.getLedgerSeq()); + lastClosedLedger.header.ledgerSeq, ledgerData.getLedgerSeq()); } else { @@ -709,7 +714,7 @@ LedgerManagerImpl::closeLedgerIf(LedgerCloseData const& ledgerData) // Out of sync, buffer what we just heard and start catchup. CLOG_INFO( Ledger, "Lost sync, local LCL is {}, network closed ledger {}", - mLastClosedLedger.header.ledgerSeq, ledgerData.getLedgerSeq()); + lastClosedLedger.header.ledgerSeq, ledgerData.getLedgerSeq()); } setState(LM_CATCHING_UP_STATE); @@ -797,7 +802,7 @@ LedgerManagerImpl::closeLedger(LedgerCloseData const& ledgerData) auto header = ltx.loadHeader(); auto initialLedgerVers = header.current().ledgerVersion; ++header.current().ledgerSeq; - header.current().previousLedgerHash = mLastClosedLedger.hash; + header.current().previousLedgerHash = getLastClosedLedgerHeader().hash; CLOG_DEBUG(Ledger, "starting closeLedger() on ledgerSeq={}", header.current().ledgerSeq); @@ -975,7 +980,7 @@ LedgerManagerImpl::closeLedger(LedgerCloseData const& ledgerData) ledgerClosed(ltx, ledgerCloseMeta, initialLedgerVers); if (ledgerData.getExpectedHash() && - *ledgerData.getExpectedHash() != mLastClosedLedger.hash) + *ledgerData.getExpectedHash() != getLastClosedLedgerHeader().hash) { throw std::runtime_error("Local node's ledger corrupted during close"); } @@ -983,7 +988,7 @@ LedgerManagerImpl::closeLedger(LedgerCloseData const& ledgerData) if (mMetaStream || mMetaDebugStream) { releaseAssert(ledgerCloseMeta); - ledgerCloseMeta->ledgerHeader() = mLastClosedLedger; + ledgerCloseMeta->ledgerHeader() = getLastClosedLedgerHeader(); // At this point we've got a complete meta and we can store it to the // member variable: if we throw while committing below, we will at worst @@ -1102,7 +1107,7 @@ LedgerManagerImpl::setLastClosedLedger( ltx.commit(); mRebuildInMemoryState = false; - advanceLedgerPointers(lastClosed.header); + advanceReadOnlyLedgerState(lastClosed.header); LedgerTxn ltx2(mApp.getLedgerTxnRoot()); if (protocolVersionStartsFrom(ltx2.loadHeader().current().ledgerVersion, SOROBAN_PROTOCOL_VERSION)) @@ -1120,7 +1125,7 @@ LedgerManagerImpl::manuallyAdvanceLedgerHeader(LedgerHeader const& header) "May only manually advance ledger header sequence number with " "MANUAL_CLOSE and RUN_STANDALONE"); } - advanceLedgerPointers(header, false); + advanceReadOnlyLedgerState(header, false); } void @@ -1269,37 +1274,32 @@ LedgerManagerImpl::getCurrentLedgerStateSnaphot() } void -LedgerManagerImpl::advanceLedgerPointers(LedgerHeader const& header, - bool debugLog) +LedgerManagerImpl::advanceReadOnlyLedgerState(LedgerHeader const& header, + bool debugLog) { auto ledgerHash = xdrSha256(header); if (debugLog) { CLOG_DEBUG(Ledger, "Advancing LCL: {} -> {}", - ledgerAbbrev(mLastClosedLedger), + ledgerAbbrev(getLastClosedLedgerHeader()), ledgerAbbrev(header, ledgerHash)); } - auto prevLedgerSeq = mLastClosedLedger.header.ledgerSeq; - mLastClosedLedger.hash = ledgerHash; - mLastClosedLedger.header = header; - - if (header.ledgerSeq != prevLedgerSeq) - { - auto& bm = mApp.getBucketManager(); - auto lcl = LastClosedLedger(mLastClosedLedger, getLastClosedLedgerHAS(), - mSorobanNetworkConfig); - auto liveSnapshot = std::make_unique>( - bm.getLiveBucketList(), lcl); - auto hotArchiveSnapshot = - std::make_unique>( - bm.getHotArchiveBucketList(), lcl); - bm.getBucketSnapshotManager().updateCurrentSnapshot( - std::move(liveSnapshot), std::move(hotArchiveSnapshot)); - } - // Manually refresh the snapshot now that apply is done - // This has to be done *after* snapshot manager updates current snapshot + LedgerHeaderHistoryEntry lhhe; + lhhe.header = header; + lhhe.hash = ledgerHash; + + auto& bm = mApp.getBucketManager(); + auto lcl = + LastClosedLedger(lhhe, getLastClosedLedgerHAS(), mSorobanNetworkConfig); + auto liveSnapshot = std::make_unique>( + bm.getLiveBucketList(), lcl); + auto hotArchiveSnapshot = + std::make_unique>( + bm.getHotArchiveBucketList(), lcl); + bm.getBucketSnapshotManager().updateCurrentSnapshot( + std::move(liveSnapshot), std::move(hotArchiveSnapshot)); getCurrentLedgerStateSnaphot()->updateSnapshotToLatest(); } @@ -1658,13 +1658,10 @@ LedgerManagerImpl::storeCurrentLedger(LedgerHeader const& header, mApp.getPersistentState().setState(PersistentState::kHistoryArchiveState, has.toString()); - if (mApp.getConfig().MODE_STORES_HISTORY_LEDGERHEADERS && storeHeader) + LedgerHeaderUtils::storeInDatabase(mApp.getDatabase(), header); + if (appendToCheckpoint) { - LedgerHeaderUtils::storeInDatabase(mApp.getDatabase(), header); - if (appendToCheckpoint) - { - mApp.getHistoryManager().appendLedgerHeader(header); - } + mApp.getHistoryManager().appendLedgerHeader(header); } } @@ -1702,8 +1699,9 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList( ltxEvictions.commit(); } - getSorobanNetworkConfigInternal().maybeSnapshotBucketListSize( - lh.ledgerSeq, ltx, mApp); + releaseAssert(mSorobanNetworkConfig); + mSorobanNetworkConfig->maybeSnapshotBucketListSize(lh.ledgerSeq, ltx, + mApp); } ltx.getAllEntries(initEntries, liveEntries, deadEntries); @@ -1751,8 +1749,9 @@ LedgerManagerImpl::ledgerClosed( if (ledgerCloseMeta && protocolVersionStartsFrom(initialLedgerVers, SOROBAN_PROTOCOL_VERSION)) { + releaseAssert(mSorobanNetworkConfig); ledgerCloseMeta->setNetworkConfiguration( - getSorobanNetworkConfig(), + *mSorobanNetworkConfig, mApp.getConfig().EMIT_LEDGER_CLOSE_META_EXT_V1); } @@ -1760,7 +1759,7 @@ LedgerManagerImpl::ledgerClosed( mApp.getBucketManager().snapshotLedger(lh); storeCurrentLedger(lh, /* storeHeader */ true, /* appendToCheckpoint */ true); - advanceLedgerPointers(lh); + advanceReadOnlyLedgerState(lh); }); } } diff --git a/src/ledger/LedgerManagerImpl.h b/src/ledger/LedgerManagerImpl.h index 577a5a9f6c..e76db54ffd 100644 --- a/src/ledger/LedgerManagerImpl.h +++ b/src/ledger/LedgerManagerImpl.h @@ -49,7 +49,6 @@ class LedgerManagerImpl : public LedgerManager std::filesystem::path mMetaDebugPath; private: - LedgerHeaderHistoryEntry mLastClosedLedger; std::optional mSorobanNetworkConfig; SorobanMetrics mSorobanMetrics; @@ -114,8 +113,6 @@ class LedgerManagerImpl : public LedgerManager void emitNextMeta(); - SorobanNetworkConfig& getSorobanNetworkConfigInternal(); - // Publishes soroban metrics, including select network config limits as well // as the actual ledger usage. void publishSorobanMetrics(); @@ -134,8 +131,8 @@ class LedgerManagerImpl : public LedgerManager std::unique_ptr const& ledgerCloseMeta, LedgerHeader lh, uint32_t initialLedgerVers); - void advanceLedgerPointers(LedgerHeader const& header, - bool debugLog = true); + void advanceReadOnlyLedgerState(LedgerHeader const& header, + bool debugLog = true); void logTxApplyMetrics(AbstractLedgerTxn& ltx, size_t numTxs, size_t numOps); diff --git a/src/main/CommandHandler.cpp b/src/main/CommandHandler.cpp index a8602c0973..b24636c36b 100644 --- a/src/main/CommandHandler.cpp +++ b/src/main/CommandHandler.cpp @@ -85,7 +85,7 @@ CommandHandler::CommandHandler(Application& app) : mApp(app) } mServer->add404(std::bind(&CommandHandler::fileNotFound, this, _1, _2)); - if (mApp.getConfig().modeStoresAnyHistory()) + if (mApp.getConfig().modeStoresAllHistory()) { addRoute("maintenance", &CommandHandler::maintenance); } diff --git a/src/main/Config.cpp b/src/main/Config.cpp index 9bbecbad16..216d5c19bf 100644 --- a/src/main/Config.cpp +++ b/src/main/Config.cpp @@ -117,7 +117,6 @@ Config::Config() : NODE_SEED(SecretKey::random()) // non configurable MODE_ENABLES_BUCKETLIST = true; MODE_STORES_HISTORY_MISC = true; - MODE_STORES_HISTORY_LEDGERHEADERS = true; MODE_DOES_CATCHUP = true; MODE_AUTO_STARTS_OVERLAY = true; OP_APPLY_SLEEP_TIME_DURATION_FOR_TESTING = @@ -2354,13 +2353,7 @@ Config::modeDoesCatchupWithBucketList() const bool Config::modeStoresAllHistory() const { - return MODE_STORES_HISTORY_LEDGERHEADERS && MODE_STORES_HISTORY_MISC; -} - -bool -Config::modeStoresAnyHistory() const -{ - return MODE_STORES_HISTORY_LEDGERHEADERS || MODE_STORES_HISTORY_MISC; + return MODE_STORES_HISTORY_MISC; } void diff --git a/src/main/Config.h b/src/main/Config.h index 97d8e6fb9b..7e46a9b518 100644 --- a/src/main/Config.h +++ b/src/main/Config.h @@ -469,9 +469,6 @@ class Config : public std::enable_shared_from_this // fees, and scp history in the database bool MODE_STORES_HISTORY_MISC; - // A config parameter that stores ledger headers in the database - bool MODE_STORES_HISTORY_LEDGERHEADERS; - // A config parameter that controls whether core automatically catches up // when it has buffered enough input; if false an out-of-sync node will // remain out-of-sync, buffering ledgers from the network in memory until @@ -783,7 +780,6 @@ class Config : public std::enable_shared_from_this bool modeDoesCatchupWithBucketList() const; bool isPersistingBucketListDBIndexes() const; bool modeStoresAllHistory() const; - bool modeStoresAnyHistory() const; void logBasicInfo() const; void setNoListen(); void setNoPublish(); diff --git a/src/main/test/ApplicationUtilsTests.cpp b/src/main/test/ApplicationUtilsTests.cpp index 3e56609e37..449c709c67 100644 --- a/src/main/test/ApplicationUtilsTests.cpp +++ b/src/main/test/ApplicationUtilsTests.cpp @@ -91,7 +91,6 @@ class SimulationHelper mTestCfg.FORCE_SCP = false; mTestCfg.INVARIANT_CHECKS = {}; mTestCfg.MODE_AUTO_STARTS_OVERLAY = false; - mTestCfg.MODE_STORES_HISTORY_LEDGERHEADERS = true; mTestCfg.USE_CONFIG_FOR_GENESIS = false; mTestCfg.TESTING_UPGRADE_DATETIME = VirtualClock::from_time_t(0); diff --git a/src/transactions/test/InvokeHostFunctionTests.cpp b/src/transactions/test/InvokeHostFunctionTests.cpp index ee9189b437..5a9985ef87 100644 --- a/src/transactions/test/InvokeHostFunctionTests.cpp +++ b/src/transactions/test/InvokeHostFunctionTests.cpp @@ -3234,7 +3234,7 @@ TEST_CASE("settings upgrade command line utils", "[tx][soroban][upgrades]") closeLedger(*app); } - auto const& lcl = lm.getLastClosedLedgerHeader(); + auto getLcl = [&]() { return lm.getLastClosedLedgerHeader(); }; // The only readWrite key in the invoke op is the one that writes the // ConfigUpgradeSet xdr @@ -3248,7 +3248,8 @@ TEST_CASE("settings upgrade command line utils", "[tx][soroban][upgrades]") LedgerTxn ltx(app->getLedgerTxnRoot()); auto ttl = ltx.load(getTTLKey(proposalKey)); // Expire the entry on the next ledger - ttl.current().data.ttl().liveUntilLedgerSeq = lcl.header.ledgerSeq; + ttl.current().data.ttl().liveUntilLedgerSeq = + getLcl().header.ledgerSeq; ltx.commit(); } @@ -3256,11 +3257,11 @@ TEST_CASE("settings upgrade command line utils", "[tx][soroban][upgrades]") auto ledgerUpgrade = LedgerUpgrade{LEDGER_UPGRADE_CONFIG}; ledgerUpgrade.newConfig() = upgradeSetKey; - auto txSet = TxSetXDRFrame::makeEmpty(lcl); - auto lastCloseTime = lcl.header.scpValue.closeTime; + auto txSet = TxSetXDRFrame::makeEmpty(getLcl()); + auto lastCloseTime = getLcl().header.scpValue.closeTime; app->getHerder().externalizeValue( - txSet, lcl.header.ledgerSeq + 1, lastCloseTime, + txSet, getLcl().header.ledgerSeq + 1, lastCloseTime, {LedgerTestUtils::toUpgradeType(ledgerUpgrade)}); // No upgrade due to expired entry @@ -3279,11 +3280,11 @@ TEST_CASE("settings upgrade command line utils", "[tx][soroban][upgrades]") auto ledgerUpgrade = LedgerUpgrade{LEDGER_UPGRADE_CONFIG}; ledgerUpgrade.newConfig() = upgradeSetKey; - auto txSet = TxSetXDRFrame::makeEmpty(lcl); - auto lastCloseTime = lcl.header.scpValue.closeTime; + auto txSet = TxSetXDRFrame::makeEmpty(getLcl()); + auto lastCloseTime = getLcl().header.scpValue.closeTime; app->getHerder().externalizeValue( - txSet, lcl.header.ledgerSeq + 1, lastCloseTime, + txSet, getLcl().header.ledgerSeq + 1, lastCloseTime, {LedgerTestUtils::toUpgradeType(ledgerUpgrade)}); // No upgrade due to tampered entry From d07a59db9b386b80d85338fc16df71be5630d2ac Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 20 Dec 2024 17:00:00 -0800 Subject: [PATCH 5/8] Update tests --- src/bucket/test/BucketListTests.cpp | 7 +-- src/ledger/LedgerManagerImpl.cpp | 18 +++---- .../test/InvokeHostFunctionTests.cpp | 48 ++++++++++--------- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/bucket/test/BucketListTests.cpp b/src/bucket/test/BucketListTests.cpp index 903432e23b..a4d56983ea 100644 --- a/src/bucket/test/BucketListTests.cpp +++ b/src/bucket/test/BucketListTests.cpp @@ -959,11 +959,8 @@ TEST_CASE_VERSIONS("eviction scan", "[bucketlist]") auto& bm = app->getBucketManager(); auto& bl = bm.getLiveBucketList(); - auto& networkCfg = [&]() -> SorobanNetworkConfig& { - LedgerTxn ltx(app->getLedgerTxnRoot()); - return app->getLedgerManager().getMutableSorobanNetworkConfig(); - }(); - + auto& networkCfg = + app->getLedgerManager().getMutableSorobanNetworkConfig(); auto& stateArchivalSettings = networkCfg.stateArchivalSettings(); auto& evictionIter = networkCfg.evictionIterator(); auto const levelToScan = 3; diff --git a/src/ledger/LedgerManagerImpl.cpp b/src/ledger/LedgerManagerImpl.cpp index d808c5d8f3..e4a510ab6a 100644 --- a/src/ledger/LedgerManagerImpl.cpp +++ b/src/ledger/LedgerManagerImpl.cpp @@ -529,26 +529,20 @@ LedgerManagerImpl::getSorobanNetworkConfig() { releaseAssert(hasSorobanNetworkConfig()); #ifdef BUILD_TESTS - if (mApp.getConfig().MODE_USES_IN_MEMORY_LEDGER) - { - return *mSorobanNetworkConfig; - } - else + return *mSorobanNetworkConfig; +#else + return getLastClosedLedger(mApp).getSorobanNetworkConfig().value(); #endif - return getLastClosedLedger(mApp).getSorobanNetworkConfig().value(); } bool LedgerManagerImpl::hasSorobanNetworkConfig() const { #ifdef BUILD_TESTS - if (mApp.getConfig().MODE_USES_IN_MEMORY_LEDGER) - { - return mSorobanNetworkConfig.has_value(); - } - else + return mSorobanNetworkConfig.has_value(); +#else + return getLastClosedLedger(mApp).getSorobanNetworkConfig().has_value(); #endif - return getLastClosedLedger(mApp).getSorobanNetworkConfig().has_value(); } #ifdef BUILD_TESTS diff --git a/src/transactions/test/InvokeHostFunctionTests.cpp b/src/transactions/test/InvokeHostFunctionTests.cpp index 5a9985ef87..e7de259adb 100644 --- a/src/transactions/test/InvokeHostFunctionTests.cpp +++ b/src/transactions/test/InvokeHostFunctionTests.cpp @@ -2082,8 +2082,10 @@ TEST_CASE("state archival", "[tx][soroban]") cfg.mWriteFee1KBBucketListLow = 20'000; cfg.mWriteFee1KBBucketListHigh = 1'000'000; }); - auto const& stateArchivalSettings = - test.getNetworkCfg().stateArchivalSettings(); + + auto getArchivalSettings = [&]() { + return test.getNetworkCfg().stateArchivalSettings(); + }; auto isSuccess = [](auto resultCode) { return resultCode == INVOKE_HOST_FUNCTION_SUCCESS; }; @@ -2091,7 +2093,7 @@ TEST_CASE("state archival", "[tx][soroban]") SECTION("contract instance and Wasm archival") { uint32_t originalExpectedLiveUntilLedger = - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - 1; + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1; for (uint32_t i = test.getApp().getLedgerManager().getLastClosedLedgerNum(); @@ -2121,7 +2123,7 @@ TEST_CASE("state archival", "[tx][soroban]") 40000 /* two LE-writes */); auto newExpectedLiveUntilLedger = - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - 1; + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1; // Instance should now be useable REQUIRE(isSuccess( @@ -2137,7 +2139,7 @@ TEST_CASE("state archival", "[tx][soroban]") 939 /* rent bump */ + 20000 /* one LE write */); auto newExpectedLiveUntilLedger = - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - 1; + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1; // invocation should fail REQUIRE(client.put("temp", ContractDataDurability::TEMPORARY, 0) == @@ -2155,7 +2157,7 @@ TEST_CASE("state archival", "[tx][soroban]") 943 /* rent bump */ + 20000 /* one LE write */); auto newExpectedLiveUntilLedger = - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - 1; + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1; // invocation should fail REQUIRE(client.put("temp", ContractDataDurability::TEMPORARY, 0) == @@ -2194,7 +2196,7 @@ TEST_CASE("state archival", "[tx][soroban]") REQUIRE(isSuccess( client.put("temp", ContractDataDurability::TEMPORARY, 0))); auto expectedTempLiveUntilLedger = - test.getLCLSeq() + stateArchivalSettings.minTemporaryTTL - 1; + test.getLCLSeq() + getArchivalSettings().minTemporaryTTL - 1; // Check for expected minimum lifetime values REQUIRE( @@ -2274,7 +2276,7 @@ TEST_CASE("state archival", "[tx][soroban]") // Recreated entry should be live REQUIRE(client.getTTL("temp", ContractDataDurability::TEMPORARY) == - test.getLCLSeq() + stateArchivalSettings.minTemporaryTTL - + test.getLCLSeq() + getArchivalSettings().minTemporaryTTL - 1); REQUIRE(isSuccess( client.get("temp", ContractDataDurability::TEMPORARY, 42))); @@ -2329,7 +2331,7 @@ TEST_CASE("state archival", "[tx][soroban]") makeSymbolSCVal("persistent2"), ContractDataDurability::PERSISTENT); uint32_t expectedLiveUntilLedger2 = - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - 1; + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1; REQUIRE(client.getTTL("persistent2", ContractDataDurability::PERSISTENT) == expectedLiveUntilLedger2); @@ -2347,7 +2349,7 @@ TEST_CASE("state archival", "[tx][soroban]") // Check value and TTL of restored entry REQUIRE(client.getTTL("persistent", ContractDataDurability::PERSISTENT) == - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1); REQUIRE(isSuccess(client.get( "persistent", ContractDataDurability::PERSISTENT, 10))); @@ -2432,12 +2434,12 @@ TEST_CASE("state archival", "[tx][soroban]") REQUIRE(isSuccess( client.put("key", ContractDataDurability::PERSISTENT, 0))); uint32_t initialLiveUntilLedger = - test.getLCLSeq() + stateArchivalSettings.minPersistentTTL - 1; + test.getLCLSeq() + getArchivalSettings().minPersistentTTL - 1; REQUIRE(client.getTTL("key", ContractDataDurability::PERSISTENT) == initialLiveUntilLedger); // Try extending entry, but set the threshold 1 ledger below the // current TTL. - uint32_t currentTTL = stateArchivalSettings.minPersistentTTL - 2; + uint32_t currentTTL = getArchivalSettings().minPersistentTTL - 2; REQUIRE( isSuccess(client.extend("key", ContractDataDurability::PERSISTENT, currentTTL - 1, 50'000))); @@ -2467,9 +2469,9 @@ TEST_CASE("state archival", "[tx][soroban]") SECTION("extension op") { // Max TTL includes current ledger, so subtract 1 - test.invokeExtendOp({lk}, stateArchivalSettings.maxEntryTTL - 1); + test.invokeExtendOp({lk}, getArchivalSettings().maxEntryTTL - 1); REQUIRE(test.getTTL(lk) == - test.getLCLSeq() + stateArchivalSettings.maxEntryTTL - 1); + test.getLCLSeq() + getArchivalSettings().maxEntryTTL - 1); } SECTION("extend host function persistent") @@ -2480,14 +2482,14 @@ TEST_CASE("state archival", "[tx][soroban]") REQUIRE(isSuccess(client.extend( "key", ContractDataDurability::PERSISTENT, - stateArchivalSettings.maxEntryTTL + 10, - stateArchivalSettings.maxEntryTTL + 10, + getArchivalSettings().maxEntryTTL + 10, + getArchivalSettings().maxEntryTTL + 10, client.readKeySpec("key", ContractDataDurability::PERSISTENT) .setRefundableResourceFee(80'000)))); // Capped at max (Max TTL includes current ledger, so subtract 1) REQUIRE(test.getTTL(lk) == - test.getLCLSeq() + stateArchivalSettings.maxEntryTTL - 1); + test.getLCLSeq() + getArchivalSettings().maxEntryTTL - 1); } SECTION("extend host function temp") @@ -2498,19 +2500,19 @@ TEST_CASE("state archival", "[tx][soroban]") makeSymbolSCVal("key"), ContractDataDurability::TEMPORARY); uint32_t ledgerSeq = test.getLCLSeq(); REQUIRE(client.extend("key", ContractDataDurability::TEMPORARY, - stateArchivalSettings.maxEntryTTL, - stateArchivalSettings.maxEntryTTL) == + getArchivalSettings().maxEntryTTL, + getArchivalSettings().maxEntryTTL) == INVOKE_HOST_FUNCTION_TRAPPED); REQUIRE(test.getTTL(lkTemp) == - ledgerSeq + stateArchivalSettings.minTemporaryTTL - 1); + ledgerSeq + getArchivalSettings().minTemporaryTTL - 1); // Max TTL includes current ledger, so subtract 1 REQUIRE(isSuccess( client.extend("key", ContractDataDurability::TEMPORARY, - stateArchivalSettings.maxEntryTTL - 1, - stateArchivalSettings.maxEntryTTL - 1))); + getArchivalSettings().maxEntryTTL - 1, + getArchivalSettings().maxEntryTTL - 1))); REQUIRE(test.getTTL(lkTemp) == - test.getLCLSeq() + stateArchivalSettings.maxEntryTTL - 1); + test.getLCLSeq() + getArchivalSettings().maxEntryTTL - 1); } } } From 50785e64263032ba9c66fcc76b8688e5841e1df5 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Thu, 26 Dec 2024 21:59:54 -0800 Subject: [PATCH 6/8] Make bucket snapshots const --- src/bucket/BucketListSnapshotBase.cpp | 16 ++++---------- src/bucket/BucketListSnapshotBase.h | 9 ++++---- src/bucket/BucketManager.cpp | 15 ------------- src/bucket/BucketManager.h | 6 ------ src/bucket/BucketSnapshot.cpp | 2 +- src/bucket/BucketSnapshot.h | 2 +- src/bucket/BucketSnapshotManager.cpp | 31 ++++++++++++--------------- src/bucket/BucketSnapshotManager.h | 8 ++++--- src/bucket/SearchableBucketList.cpp | 25 ++++++--------------- src/bucket/SearchableBucketList.h | 18 +++++++--------- src/bucket/test/BucketIndexTests.cpp | 17 +++++++++++++-- src/bucket/test/BucketListTests.cpp | 6 ++---- src/ledger/LedgerStateSnapshot.cpp | 6 +++--- src/ledger/LedgerStateSnapshot.h | 2 +- src/ledger/LedgerTxn.cpp | 6 +++++- src/ledger/LedgerTxnImpl.h | 6 +++--- src/main/QueryServer.cpp | 11 +++++++++- src/main/QueryServer.h | 4 +++- 18 files changed, 85 insertions(+), 105 deletions(-) diff --git a/src/bucket/BucketListSnapshotBase.cpp b/src/bucket/BucketListSnapshotBase.cpp index bd7f026b55..6e56b6dce0 100644 --- a/src/bucket/BucketListSnapshotBase.cpp +++ b/src/bucket/BucketListSnapshotBase.cpp @@ -51,13 +51,9 @@ BucketListSnapshot::getLedgerSeq() const template LedgerHeader const& -SearchableBucketListSnapshotBase::getLedgerHeader() +SearchableBucketListSnapshotBase::getLedgerHeader() const { releaseAssert(mSnapshot); - if (mAutoUpdate) - { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); - } return mSnapshot->getLedgerHeader(); } @@ -100,7 +96,7 @@ SearchableBucketListSnapshotBase::loopAllBuckets( template std::shared_ptr -SearchableBucketListSnapshotBase::load(LedgerKey const& k) +SearchableBucketListSnapshotBase::load(LedgerKey const& k) const { ZoneScoped; @@ -123,10 +119,6 @@ SearchableBucketListSnapshotBase::load(LedgerKey const& k) } }; - if (mAutoUpdate) - { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); - } if (threadIsMain()) { mSnapshotManager.startPointLoadTimer(); @@ -145,7 +137,8 @@ SearchableBucketListSnapshotBase::load(LedgerKey const& k) template std::optional> SearchableBucketListSnapshotBase::loadKeysFromLedger( - std::set const& inKeys, uint32_t ledgerSeq) + std::set const& inKeys, + uint32_t ledgerSeq) const { return loadKeysInternal(inKeys, /*lkMeter=*/nullptr, ledgerSeq); } @@ -164,7 +157,6 @@ SearchableBucketListSnapshotBase::SearchableBucketListSnapshotBase( , mHistoricalSnapshots() , mAutoUpdate(autoUpdate) { - // Always create a snapshot based on the latest LCL state. mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); } diff --git a/src/bucket/BucketListSnapshotBase.h b/src/bucket/BucketListSnapshotBase.h index d1909330a3..4d02bc0435 100644 --- a/src/bucket/BucketListSnapshotBase.h +++ b/src/bucket/BucketListSnapshotBase.h @@ -177,7 +177,7 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable std::optional> loadKeysInternal(std::set const& inKeys, LedgerKeyMeter* lkMeter, - std::optional ledgerSeq); + std::optional ledgerSeq) const; public: uint32_t @@ -186,8 +186,7 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable return mSnapshot->getLedgerSeq(); } - LedgerHeader const& getLedgerHeader(); - LastClosedLedger const& getLastClosedLedger(); + LedgerHeader const& getLedgerHeader() const; // Loads inKeys from the specified historical snapshot. Returns // load_result_vec if the snapshot for the given ledger is @@ -197,8 +196,8 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable // in the BucketList is N - 1. std::optional> loadKeysFromLedger(std::set const& inKeys, - uint32_t ledgerSeq); + uint32_t ledgerSeq) const; - std::shared_ptr load(LedgerKey const& k); + std::shared_ptr load(LedgerKey const& k) const; }; } \ No newline at end of file diff --git a/src/bucket/BucketManager.cpp b/src/bucket/BucketManager.cpp index a576446fbe..10005a974d 100644 --- a/src/bucket/BucketManager.cpp +++ b/src/bucket/BucketManager.cpp @@ -1580,21 +1580,6 @@ BucketManager::getConfig() const return mConfig; } -std::shared_ptr -BucketManager::getSearchableLiveBucketListSnapshot() -{ - // Any other threads must maintain their own snapshot - releaseAssert(threadIsMain()); - if (!mSearchableBucketListSnapshot) - { - mSearchableBucketListSnapshot = - mSnapshotManager->copySearchableLiveBucketListSnapshot( - /* autoUpdate */ true); - } - - return mSearchableBucketListSnapshot; -} - void BucketManager::reportBucketEntryCountMetrics() { diff --git a/src/bucket/BucketManager.h b/src/bucket/BucketManager.h index a1e3ffbe87..2798abd577 100644 --- a/src/bucket/BucketManager.h +++ b/src/bucket/BucketManager.h @@ -78,8 +78,6 @@ class BucketManager : NonMovableOrCopyable std::unique_ptr mWorkDir; BucketMapT mSharedLiveBuckets; BucketMapT mSharedHotArchiveBuckets; - std::shared_ptr - mSearchableBucketListSnapshot{}; // Lock for managing raw Bucket files or the bucket directory. This lock is // only required for file access, but is not required for logical changes to @@ -381,10 +379,6 @@ class BucketManager : NonMovableOrCopyable Config const& getConfig() const; - // Get bucketlist snapshot - std::shared_ptr - getSearchableLiveBucketListSnapshot(); - void reportBucketEntryCountMetrics(); }; diff --git a/src/bucket/BucketSnapshot.cpp b/src/bucket/BucketSnapshot.cpp index a87c359ad8..7ccb755a5f 100644 --- a/src/bucket/BucketSnapshot.cpp +++ b/src/bucket/BucketSnapshot.cpp @@ -180,7 +180,7 @@ Loop LiveBucketSnapshot::scanForEviction( EvictionIterator& iter, uint32_t& bytesToScan, uint32_t ledgerSeq, std::list& evictableKeys, - SearchableLiveBucketListSnapshot& bl) const + SearchableLiveBucketListSnapshot const& bl) const { ZoneScoped; if (isEmpty() || protocolVersionIsBefore(mBucket->getBucketVersion(), diff --git a/src/bucket/BucketSnapshot.h b/src/bucket/BucketSnapshot.h index 65b00022a1..f3646fcb8a 100644 --- a/src/bucket/BucketSnapshot.h +++ b/src/bucket/BucketSnapshot.h @@ -85,7 +85,7 @@ class LiveBucketSnapshot : public BucketSnapshotBase Loop scanForEviction(EvictionIterator& iter, uint32_t& bytesToScan, uint32_t ledgerSeq, std::list& evictableKeys, - SearchableLiveBucketListSnapshot& bl) const; + SearchableLiveBucketListSnapshot const& bl) const; }; class HotArchiveBucketSnapshot : public BucketSnapshotBase diff --git a/src/bucket/BucketSnapshotManager.cpp b/src/bucket/BucketSnapshotManager.cpp index 46869b8bbc..545ea38ac3 100644 --- a/src/bucket/BucketSnapshotManager.cpp +++ b/src/bucket/BucketSnapshotManager.cpp @@ -52,16 +52,15 @@ BucketSnapshotManager::BucketSnapshotManager( } } -std::shared_ptr -BucketSnapshotManager::copySearchableLiveBucketListSnapshot( - bool autoUpdate) const +std::shared_ptr +BucketSnapshotManager::copySearchableLiveBucketListSnapshot() const { // Can't use std::make_shared due to private constructor return std::shared_ptr( new SearchableLiveBucketListSnapshot(*this, autoUpdate)); } -std::shared_ptr +std::shared_ptr BucketSnapshotManager::copySearchableHotArchiveBucketListSnapshot() const { releaseAssert(mCurrHotArchiveSnapshot); @@ -134,19 +133,10 @@ BucketSnapshotManager::maybeUpdateSnapshotInternal( // snapshot, so use a shared lock. std::shared_lock lock(mSnapshotMutex); - // First update current snapshot - if (!snapshot || - snapshot->getLedgerSeq() != managerSnapshot->getLedgerSeq() || - forceUpdate) - { - // Should only update with a newer snapshot - releaseAssert(!snapshot || - snapshot->getLedgerSeq() < - managerSnapshot->getLedgerSeq() || - forceUpdate); - snapshot = std::make_unique const>( - *managerSnapshot); - } + // Should only update on snapshot creation + releaseAssert(!snapshot); + snapshot = + std::make_unique const>(*managerSnapshot); // Then update historical snapshots (if any exist) if (managerHistoricalSnapshots.empty()) @@ -237,4 +227,11 @@ BucketSnapshotManager::endPointLoadTimer(LedgerEntryType t, iter->second.Update(duration); } } + +uint32_t +BucketSnapshotManager::getCurrentLedgerSeq() const +{ + std::shared_lock lock(mSnapshotMutex); + return mCurrLiveSnapshot->getLedgerSeq(); +} } \ No newline at end of file diff --git a/src/bucket/BucketSnapshotManager.h b/src/bucket/BucketSnapshotManager.h index 530bea2d7a..7475417992 100644 --- a/src/bucket/BucketSnapshotManager.h +++ b/src/bucket/BucketSnapshotManager.h @@ -89,10 +89,10 @@ class BucketSnapshotManager : NonMovableOrCopyable SnapshotPtrT&& hotArchiveSnapshot, uint32_t numHistoricalLedgers); - std::shared_ptr - copySearchableLiveBucketListSnapshot(bool autoUpdate) const; + std::shared_ptr + copySearchableLiveBucketListSnapshot() const; - std::shared_ptr + std::shared_ptr copySearchableHotArchiveBucketListSnapshot() const; // Checks if snapshot is out of date and updates it accordingly @@ -107,5 +107,7 @@ class BucketSnapshotManager : NonMovableOrCopyable void endPointLoadTimer(LedgerEntryType t, bool bloomMiss) const; medida::Timer& recordBulkLoadMetrics(std::string const& label, size_t numEntries) const; + + uint32_t getCurrentLedgerSeq() const; }; } \ No newline at end of file diff --git a/src/bucket/SearchableBucketList.cpp b/src/bucket/SearchableBucketList.cpp index 75f69a91a4..8361453928 100644 --- a/src/bucket/SearchableBucketList.cpp +++ b/src/bucket/SearchableBucketList.cpp @@ -15,7 +15,7 @@ EvictionResult SearchableLiveBucketListSnapshot::scanForEviction( uint32_t ledgerSeq, EvictionCounters& counters, EvictionIterator evictionIter, std::shared_ptr stats, - StateArchivalSettings const& sas) + StateArchivalSettings const& sas) const { releaseAssert(mSnapshot); releaseAssert(stats); @@ -71,7 +71,7 @@ template std::optional> SearchableBucketListSnapshotBase::loadKeysInternal( std::set const& inKeys, - LedgerKeyMeter* lkMeter, std::optional ledgerSeq) + LedgerKeyMeter* lkMeter, std::optional ledgerSeq) const { ZoneScoped; @@ -83,11 +83,6 @@ SearchableBucketListSnapshotBase::loadKeysInternal( return keys.empty() ? Loop::COMPLETE : Loop::INCOMPLETE; }; - if (mAutoUpdate) - { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); - } - if (!ledgerSeq || *ledgerSeq == mSnapshot->getLedgerSeq()) { loopAllBuckets(loadKeysLoop, *mSnapshot); @@ -114,16 +109,12 @@ SearchableBucketListSnapshotBase::loadKeysInternal( // trustlines with the given accountID and poolID from step 1 std::vector SearchableLiveBucketListSnapshot::loadPoolShareTrustLinesByAccountAndAsset( - AccountID const& accountID, Asset const& asset) + AccountID const& accountID, Asset const& asset) const { ZoneScoped; // This query should only be called during TX apply releaseAssert(threadIsMain()); - if (mAutoUpdate) - { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); - } releaseAssert(mSnapshot); LedgerKeySet trustlinesToLoad; @@ -161,13 +152,9 @@ SearchableLiveBucketListSnapshot::loadPoolShareTrustLinesByAccountAndAsset( std::vector SearchableLiveBucketListSnapshot::loadInflationWinners(size_t maxWinners, - int64_t minBalance) + int64_t minBalance) const { ZoneScoped; - if (mAutoUpdate) - { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); - } releaseAssert(mSnapshot); // This is a legacy query, should only be called by main thread during @@ -258,7 +245,7 @@ SearchableLiveBucketListSnapshot::loadInflationWinners(size_t maxWinners, std::vector SearchableLiveBucketListSnapshot::loadKeysWithLimits( std::set const& inKeys, - LedgerKeyMeter* lkMeter) + LedgerKeyMeter* lkMeter) const { if (threadIsMain()) { @@ -290,7 +277,7 @@ SearchableHotArchiveBucketListSnapshot::SearchableHotArchiveBucketListSnapshot( std::vector SearchableHotArchiveBucketListSnapshot::loadKeys( - std::set const& inKeys) + std::set const& inKeys) const { auto op = loadKeysInternal(inKeys, /*lkMeter=*/nullptr, std::nullopt); releaseAssertOrThrow(op); diff --git a/src/bucket/SearchableBucketList.h b/src/bucket/SearchableBucketList.h index fe9349c375..e9e2cbb9ef 100644 --- a/src/bucket/SearchableBucketList.h +++ b/src/bucket/SearchableBucketList.h @@ -19,25 +19,23 @@ class SearchableLiveBucketListSnapshot public: std::vector loadPoolShareTrustLinesByAccountAndAsset(AccountID const& accountID, - Asset const& asset); + Asset const& asset) const; std::vector loadInflationWinners(size_t maxWinners, - int64_t minBalance); + int64_t minBalance) const; std::vector loadKeysWithLimits(std::set const& inKeys, - LedgerKeyMeter* lkMeter); + LedgerKeyMeter* lkMeter) const; EvictionResult scanForEviction(uint32_t ledgerSeq, EvictionCounters& counters, EvictionIterator evictionIter, std::shared_ptr stats, - StateArchivalSettings const& sas); + StateArchivalSettings const& sas) const; - friend std::shared_ptr - BucketSnapshotManager::copySearchableLiveBucketListSnapshot( - bool autoUpdate) const; - void updateSnapshotToLatest(); + friend std::shared_ptr + BucketSnapshotManager::copySearchableLiveBucketListSnapshot() const; }; class SearchableHotArchiveBucketListSnapshot @@ -48,9 +46,9 @@ class SearchableHotArchiveBucketListSnapshot public: std::vector - loadKeys(std::set const& inKeys); + loadKeys(std::set const& inKeys) const; - friend std::shared_ptr + friend std::shared_ptr BucketSnapshotManager::copySearchableHotArchiveBucketListSnapshot() const; }; } \ No newline at end of file diff --git a/src/bucket/test/BucketIndexTests.cpp b/src/bucket/test/BucketIndexTests.cpp index 6950794da0..0246789149 100644 --- a/src/bucket/test/BucketIndexTests.cpp +++ b/src/bucket/test/BucketIndexTests.cpp @@ -803,6 +803,9 @@ TEST_CASE("hot archive bucket lookups", "[bucket][bucketindex][archive]") BucketBase::FIRST_PROTOCOL_SUPPORTING_PERSISTENT_EVICTION); addHotArchiveBatchAndUpdateSnapshot(*app, header, archivedEntries, restoredEntries, deletedEntries); + searchableBL = app->getBucketManager() + .getBucketSnapshotManager() + .copySearchableHotArchiveBucketListSnapshot(); checkResult(); // Add a few batches so that entries are no longer in the top bucket @@ -810,6 +813,9 @@ TEST_CASE("hot archive bucket lookups", "[bucket][bucketindex][archive]") { header.ledgerSeq += 1; addHotArchiveBatchAndUpdateSnapshot(*app, header, {}, {}, {}); + searchableBL = app->getBucketManager() + .getBucketSnapshotManager() + .copySearchableHotArchiveBucketListSnapshot(); } // Shadow entries via liveEntry @@ -819,6 +825,9 @@ TEST_CASE("hot archive bucket lookups", "[bucket][bucketindex][archive]") header.ledgerSeq += 1; addHotArchiveBatchAndUpdateSnapshot(*app, header, {}, {liveShadow1, liveShadow2}, {}); + searchableBL = app->getBucketManager() + .getBucketSnapshotManager() + .copySearchableHotArchiveBucketListSnapshot(); // Point load for (auto const& k : {liveShadow1, liveShadow2}) @@ -838,7 +847,9 @@ TEST_CASE("hot archive bucket lookups", "[bucket][bucketindex][archive]") header.ledgerSeq += 1; addHotArchiveBatchAndUpdateSnapshot(*app, header, {}, {}, {deletedShadow}); - + searchableBL = app->getBucketManager() + .getBucketSnapshotManager() + .copySearchableHotArchiveBucketListSnapshot(); // Point load auto entryPtr = searchableBL->load(deletedShadow); REQUIRE(entryPtr); @@ -859,7 +870,9 @@ TEST_CASE("hot archive bucket lookups", "[bucket][bucketindex][archive]") header.ledgerSeq += 1; addHotArchiveBatchAndUpdateSnapshot(*app, header, {archivedShadow}, {}, {}); - + searchableBL = app->getBucketManager() + .getBucketSnapshotManager() + .copySearchableHotArchiveBucketListSnapshot(); // Point load entryPtr = searchableBL->load(LedgerEntryKey(archivedShadow)); REQUIRE(entryPtr); diff --git a/src/bucket/test/BucketListTests.cpp b/src/bucket/test/BucketListTests.cpp index a4d56983ea..78a9f7eb19 100644 --- a/src/bucket/test/BucketListTests.cpp +++ b/src/bucket/test/BucketListTests.cpp @@ -1401,10 +1401,6 @@ TEST_CASE_VERSIONS("Searchable BucketListDB snapshots", "[bucketlist]") LedgerTestUtils::generateValidLedgerEntryOfType(CLAIMABLE_BALANCE); entry.data.claimableBalance().amount = 0; - auto searchableBL = - bm.getBucketSnapshotManager().copySearchableLiveBucketListSnapshot( - true); - // Update entry every 5 ledgers so we can see bucket merge events for (auto ledgerSeq = 1; ledgerSeq < 101; ++ledgerSeq) { @@ -1420,6 +1416,8 @@ TEST_CASE_VERSIONS("Searchable BucketListDB snapshots", "[bucketlist]") } closeLedger(*app); + auto searchableBL = bm.getBucketSnapshotManager() + .copySearchableLiveBucketListSnapshot(); // Snapshot should automatically update with latest version auto loadedEntry = searchableBL->load(LedgerEntryKey(entry)); diff --git a/src/ledger/LedgerStateSnapshot.cpp b/src/ledger/LedgerStateSnapshot.cpp index 781ba769a8..78be141754 100644 --- a/src/ledger/LedgerStateSnapshot.cpp +++ b/src/ledger/LedgerStateSnapshot.cpp @@ -169,9 +169,9 @@ LedgerTxnReadOnly::executeWithMaybeInnerSnapshot( return f(lsg); } -BucketSnapshotState::BucketSnapshotState( - std::shared_ptr snapshot) - : mSnapshot(snapshot) +BucketSnapshotState::BucketSnapshotState(BucketManager& bm) + : mSnapshot( + bm.getBucketSnapshotManager().copySearchableLiveBucketListSnapshot()) , mLedgerHeader(LedgerHeaderWrapper( std::make_shared(snapshot->getLedgerHeader()))) { diff --git a/src/ledger/LedgerStateSnapshot.h b/src/ledger/LedgerStateSnapshot.h index f6347968fb..0fc5f03d5a 100644 --- a/src/ledger/LedgerStateSnapshot.h +++ b/src/ledger/LedgerStateSnapshot.h @@ -108,7 +108,7 @@ class LedgerTxnReadOnly : public AbstractLedgerStateSnapshot // A concrete implementation of read-only BucketList snapshot wrapper class BucketSnapshotState : public AbstractLedgerStateSnapshot { - std::shared_ptr mSnapshot; + std::shared_ptr const mSnapshot; // Store a copy of the header from mSnapshot. This is needed for // validation flow where for certain validation scenarios the header needs // to be modified diff --git a/src/ledger/LedgerTxn.cpp b/src/ledger/LedgerTxn.cpp index 153df77143..ae1994a5ad 100644 --- a/src/ledger/LedgerTxn.cpp +++ b/src/ledger/LedgerTxn.cpp @@ -2660,6 +2660,9 @@ LedgerTxnRoot::Impl::commitChild(EntryIterator iter, mPrefetchHits = 0; mPrefetchMisses = 0; + + // std::shared_ptr<...>::reset does not throw + mSearchableBucketListSnapshot.reset(); } uint64_t @@ -3054,7 +3057,7 @@ LedgerTxnRoot::Impl::areEntriesMissingInCacheForOffer(OfferEntry const& oe) return false; } -SearchableLiveBucketListSnapshot& +SearchableLiveBucketListSnapshot const& LedgerTxnRoot::Impl::getSearchableLiveBucketListSnapshot() const { if (!mSearchableBucketListSnapshot) @@ -3373,6 +3376,7 @@ LedgerTxnRoot::Impl::rollbackChild() noexcept mChild = nullptr; mPrefetchHits = 0; mPrefetchMisses = 0; + mSearchableBucketListSnapshot.reset(); } std::shared_ptr diff --git a/src/ledger/LedgerTxnImpl.h b/src/ledger/LedgerTxnImpl.h index d9433abdc9..f11df5e182 100644 --- a/src/ledger/LedgerTxnImpl.h +++ b/src/ledger/LedgerTxnImpl.h @@ -616,8 +616,8 @@ class LedgerTxnRoot::Impl mutable BestOffers mBestOffers; mutable uint64_t mPrefetchHits{0}; mutable uint64_t mPrefetchMisses{0}; - mutable std::shared_ptr - mSearchableBucketListSnapshot{}; + mutable std::shared_ptr + mSearchableBucketListSnapshot; size_t mBulkLoadBatchSize; std::unique_ptr mTransaction; @@ -684,7 +684,7 @@ class LedgerTxnRoot::Impl bool areEntriesMissingInCacheForOffer(OfferEntry const& oe); - SearchableLiveBucketListSnapshot& + SearchableLiveBucketListSnapshot const& getSearchableLiveBucketListSnapshot() const; uint32_t prefetchInternal(UnorderedSet const& keys, diff --git a/src/main/QueryServer.cpp b/src/main/QueryServer.cpp index b63184f886..7c190666db 100644 --- a/src/main/QueryServer.cpp +++ b/src/main/QueryServer.cpp @@ -56,6 +56,7 @@ QueryServer::QueryServer(const std::string& address, unsigned short port, int maxClient, size_t threadPoolSize, BucketSnapshotManager& bucketSnapshotManager) : mServer(address, port, maxClient, threadPoolSize) + , mBucketSnapshotManager(bucketSnapshotManager) { LOG_INFO(DEFAULT_LOG, "Listening on {}:{} for Query requests", address, port); @@ -133,7 +134,15 @@ QueryServer::getLedgerEntryRaw(std::string const& params, if (!keys.empty()) { - auto& bl = *mBucketListSnapshots.at(std::this_thread::get_id()); + auto& snapshotPtr = mBucketListSnapshots.at(std::this_thread::get_id()); + if (snapshotPtr->getLedgerSeq() < + mBucketSnapshotManager.getCurrentLedgerSeq()) + { + snapshotPtr = + mBucketSnapshotManager.copySearchableLiveBucketListSnapshot(); + } + + auto& bl = *snapshotPtr; LedgerKeySet orderedKeys; for (auto const& key : keys) diff --git a/src/main/QueryServer.h b/src/main/QueryServer.h index 53ee434087..fc8e10fe45 100644 --- a/src/main/QueryServer.h +++ b/src/main/QueryServer.h @@ -26,9 +26,11 @@ class QueryServer httpThreaded::server::server mServer; std::unordered_map> + std::shared_ptr> mBucketListSnapshots; + BucketSnapshotManager& mBucketSnapshotManager; + bool safeRouter(HandlerRoute route, std::string const& params, std::string const& body, std::string& retStr); From b69ace5eb315718a18eb6e6b6fe9d5e891e5a1e2 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Sat, 28 Dec 2024 11:07:19 -0800 Subject: [PATCH 7/8] rebase fallout --- src/bucket/BucketListSnapshotBase.cpp | 9 ++------- src/bucket/BucketListSnapshotBase.h | 8 ++------ src/bucket/BucketManager.cpp | 3 +-- src/bucket/BucketSnapshotManager.cpp | 2 +- src/bucket/SearchableBucketList.cpp | 13 +++---------- src/bucket/SearchableBucketList.h | 2 +- src/bucket/test/BucketIndexTests.cpp | 10 +++++----- src/ledger/LedgerManager.h | 2 +- src/ledger/LedgerManagerImpl.cpp | 8 +++----- src/ledger/LedgerManagerImpl.h | 4 ++-- src/ledger/LedgerStateSnapshot.cpp | 6 +++--- src/ledger/LedgerStateSnapshot.h | 2 +- src/ledger/LedgerTxn.cpp | 2 +- src/main/QueryServer.cpp | 3 +-- 14 files changed, 27 insertions(+), 47 deletions(-) diff --git a/src/bucket/BucketListSnapshotBase.cpp b/src/bucket/BucketListSnapshotBase.cpp index 6e56b6dce0..ee570f9733 100644 --- a/src/bucket/BucketListSnapshotBase.cpp +++ b/src/bucket/BucketListSnapshotBase.cpp @@ -59,13 +59,9 @@ SearchableBucketListSnapshotBase::getLedgerHeader() const template LastClosedLedger const& -SearchableBucketListSnapshotBase::getLastClosedLedger() +SearchableBucketListSnapshotBase::getLastClosedLedger() const { releaseAssert(mSnapshot); - if (mAutoUpdate) - { - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); - } return mSnapshot->getLastClosedLedger(); } @@ -152,10 +148,9 @@ BucketLevelSnapshot::BucketLevelSnapshot( template SearchableBucketListSnapshotBase::SearchableBucketListSnapshotBase( - BucketSnapshotManager const& snapshotManager, bool autoUpdate) + BucketSnapshotManager const& snapshotManager) : mSnapshotManager(snapshotManager) , mHistoricalSnapshots() - , mAutoUpdate(autoUpdate) { mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots); } diff --git a/src/bucket/BucketListSnapshotBase.h b/src/bucket/BucketListSnapshotBase.h index 4d02bc0435..9285399d97 100644 --- a/src/bucket/BucketListSnapshotBase.h +++ b/src/bucket/BucketListSnapshotBase.h @@ -159,7 +159,6 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable // Snapshot managed by SnapshotManager SnapshotPtrT mSnapshot{}; std::map> mHistoricalSnapshots; - bool const mAutoUpdate; // Loops through all buckets, starting with curr at level 0, then snap at // level 0, etc. Calls f on each bucket. Exits early if function @@ -167,12 +166,8 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable void loopAllBuckets(std::function f, BucketListSnapshot const& snapshot) const; - // If `autoUpdate` is true, the snapshot will keep itself consistent with - // LCL automatically. If not, callers are expected to refresh the snapshot - // manually (this is useful to use cases that a consistent view of the state - // for some arbitrary time) SearchableBucketListSnapshotBase( - BucketSnapshotManager const& snapshotManager, bool autoUpdate); + BucketSnapshotManager const& snapshotManager); std::optional> loadKeysInternal(std::set const& inKeys, @@ -187,6 +182,7 @@ class SearchableBucketListSnapshotBase : public NonMovableOrCopyable } LedgerHeader const& getLedgerHeader() const; + LastClosedLedger const& getLastClosedLedger() const; // Loads inKeys from the specified historical snapshot. Returns // load_result_vec if the snapshot for the given ledger is diff --git a/src/bucket/BucketManager.cpp b/src/bucket/BucketManager.cpp index 10005a974d..60d4b3be12 100644 --- a/src/bucket/BucketManager.cpp +++ b/src/bucket/BucketManager.cpp @@ -1054,8 +1054,7 @@ BucketManager::startBackgroundEvictionScan(uint32_t ledgerSeq) releaseAssert(!mEvictionFuture.valid()); releaseAssert(mEvictionStatistics); - auto searchableBL = mSnapshotManager->copySearchableLiveBucketListSnapshot( - /* autoUpdate */ true); + auto searchableBL = mSnapshotManager->copySearchableLiveBucketListSnapshot(); auto const& cfg = mApp.getLedgerManager().getSorobanNetworkConfig(); auto const& sas = cfg.stateArchivalSettings(); diff --git a/src/bucket/BucketSnapshotManager.cpp b/src/bucket/BucketSnapshotManager.cpp index 545ea38ac3..f8086a5a1a 100644 --- a/src/bucket/BucketSnapshotManager.cpp +++ b/src/bucket/BucketSnapshotManager.cpp @@ -57,7 +57,7 @@ BucketSnapshotManager::copySearchableLiveBucketListSnapshot() const { // Can't use std::make_shared due to private constructor return std::shared_ptr( - new SearchableLiveBucketListSnapshot(*this, autoUpdate)); + new SearchableLiveBucketListSnapshot(*this)); } std::shared_ptr diff --git a/src/bucket/SearchableBucketList.cpp b/src/bucket/SearchableBucketList.cpp index 8361453928..e87eca5cdb 100644 --- a/src/bucket/SearchableBucketList.cpp +++ b/src/bucket/SearchableBucketList.cpp @@ -61,12 +61,6 @@ SearchableLiveBucketListSnapshot::scanForEviction( return result; } -void -SearchableLiveBucketListSnapshot::updateSnapshotToLatest() -{ - mSnapshotManager.maybeUpdateSnapshot(mSnapshot, mHistoricalSnapshots, true); -} - template std::optional> SearchableBucketListSnapshotBase::loadKeysInternal( @@ -263,15 +257,14 @@ SearchableLiveBucketListSnapshot::loadKeysWithLimits( } SearchableLiveBucketListSnapshot::SearchableLiveBucketListSnapshot( - BucketSnapshotManager const& snapshotManager, bool autoUpdate) - : SearchableBucketListSnapshotBase(snapshotManager, autoUpdate) + BucketSnapshotManager const& snapshotManager) + : SearchableBucketListSnapshotBase(snapshotManager) { } SearchableHotArchiveBucketListSnapshot::SearchableHotArchiveBucketListSnapshot( BucketSnapshotManager const& snapshotManager) - : SearchableBucketListSnapshotBase(snapshotManager, - /* autoUpdate */ true) + : SearchableBucketListSnapshotBase(snapshotManager) { } diff --git a/src/bucket/SearchableBucketList.h b/src/bucket/SearchableBucketList.h index e9e2cbb9ef..9ce2fef018 100644 --- a/src/bucket/SearchableBucketList.h +++ b/src/bucket/SearchableBucketList.h @@ -14,7 +14,7 @@ class SearchableLiveBucketListSnapshot : public SearchableBucketListSnapshotBase { SearchableLiveBucketListSnapshot( - BucketSnapshotManager const& snapshotManager, bool autoUpdate); + BucketSnapshotManager const& snapshotManager); public: std::vector diff --git a/src/bucket/test/BucketIndexTests.cpp b/src/bucket/test/BucketIndexTests.cpp index 0246789149..fc8b46b63a 100644 --- a/src/bucket/test/BucketIndexTests.cpp +++ b/src/bucket/test/BucketIndexTests.cpp @@ -133,7 +133,7 @@ class BucketIndexTest auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(true); + .copySearchableLiveBucketListSnapshot(); auto lk = LedgerEntryKey(canonicalEntry); auto currentLoadedEntry = searchableBL->load(lk); @@ -252,7 +252,7 @@ class BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(true); + .copySearchableLiveBucketListSnapshot(); // Test bulk load lookup auto loadResult = @@ -279,7 +279,7 @@ class BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(true); + .copySearchableLiveBucketListSnapshot(); for (size_t i = 0; i < n; ++i) { LedgerKeySet searchSubset; @@ -319,7 +319,7 @@ class BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(true); + .copySearchableLiveBucketListSnapshot(); // Load should return empty vector for keys not in bucket list auto keysNotInBL = @@ -496,7 +496,7 @@ class BucketIndexPoolShareTest : public BucketIndexTest { auto searchableBL = getBM() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(true); + .copySearchableLiveBucketListSnapshot(); auto loadResult = searchableBL->loadPoolShareTrustLinesByAccountAndAsset( mAccountToSearch.accountID, mAssetToSearch); diff --git a/src/ledger/LedgerManager.h b/src/ledger/LedgerManager.h index bff644a201..7a9644731d 100644 --- a/src/ledger/LedgerManager.h +++ b/src/ledger/LedgerManager.h @@ -97,7 +97,7 @@ class LedgerManager getLastClosedLedgerHeader() const = 0; // Get bucketlist snapshot - virtual std::shared_ptr + virtual std::shared_ptr getCurrentLedgerStateSnaphot() = 0; // return the HAS that corresponds to the last closed ledger as persisted in diff --git a/src/ledger/LedgerManagerImpl.cpp b/src/ledger/LedgerManagerImpl.cpp index e4a510ab6a..0464b6693a 100644 --- a/src/ledger/LedgerManagerImpl.cpp +++ b/src/ledger/LedgerManagerImpl.cpp @@ -1252,17 +1252,15 @@ LedgerManagerImpl::maybeResetLedgerCloseMetaDebugStream(uint32_t ledgerSeq) } } -std::shared_ptr +std::shared_ptr LedgerManagerImpl::getCurrentLedgerStateSnaphot() { if (!mReadOnlyLedgerStateSnapshot) { - // Set autoUpdate to false to "freeze" the snapshot - // Update manually at the end of ledger close mReadOnlyLedgerStateSnapshot = mApp.getBucketManager() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(/* autoUpdate */ false); + .copySearchableLiveBucketListSnapshot(); } return mReadOnlyLedgerStateSnapshot; } @@ -1294,7 +1292,7 @@ LedgerManagerImpl::advanceReadOnlyLedgerState(LedgerHeader const& header, bm.getHotArchiveBucketList(), lcl); bm.getBucketSnapshotManager().updateCurrentSnapshot( std::move(liveSnapshot), std::move(hotArchiveSnapshot)); - getCurrentLedgerStateSnaphot()->updateSnapshotToLatest(); + mReadOnlyLedgerStateSnapshot = bm.getBucketSnapshotManager().copySearchableLiveBucketListSnapshot(); } void diff --git a/src/ledger/LedgerManagerImpl.h b/src/ledger/LedgerManagerImpl.h index e76db54ffd..a4a9060f00 100644 --- a/src/ledger/LedgerManagerImpl.h +++ b/src/ledger/LedgerManagerImpl.h @@ -67,7 +67,7 @@ class LedgerManagerImpl : public LedgerManager medida::Timer& mMetaStreamWriteTime; VirtualClock::time_point mLastClose; bool mRebuildInMemoryState{false}; - std::shared_ptr + std::shared_ptr mReadOnlyLedgerStateSnapshot; std::unique_ptr mStartCatchup; @@ -202,7 +202,7 @@ class LedgerManagerImpl : public LedgerManager SorobanMetrics& getSorobanMetrics() override; - std::shared_ptr + std::shared_ptr getCurrentLedgerStateSnaphot() override; }; } diff --git a/src/ledger/LedgerStateSnapshot.cpp b/src/ledger/LedgerStateSnapshot.cpp index 78be141754..97a427dcc5 100644 --- a/src/ledger/LedgerStateSnapshot.cpp +++ b/src/ledger/LedgerStateSnapshot.cpp @@ -169,9 +169,9 @@ LedgerTxnReadOnly::executeWithMaybeInnerSnapshot( return f(lsg); } -BucketSnapshotState::BucketSnapshotState(BucketManager& bm) - : mSnapshot( - bm.getBucketSnapshotManager().copySearchableLiveBucketListSnapshot()) +BucketSnapshotState::BucketSnapshotState( + std::shared_ptr snapshot) + : mSnapshot(snapshot) , mLedgerHeader(LedgerHeaderWrapper( std::make_shared(snapshot->getLedgerHeader()))) { diff --git a/src/ledger/LedgerStateSnapshot.h b/src/ledger/LedgerStateSnapshot.h index 0fc5f03d5a..6dd0ae8abb 100644 --- a/src/ledger/LedgerStateSnapshot.h +++ b/src/ledger/LedgerStateSnapshot.h @@ -116,7 +116,7 @@ class BucketSnapshotState : public AbstractLedgerStateSnapshot public: BucketSnapshotState( - std::shared_ptr snapshot); + std::shared_ptr snapshot); ~BucketSnapshotState() override; LastClosedLedger const& getLastClosedLedger() const override; diff --git a/src/ledger/LedgerTxn.cpp b/src/ledger/LedgerTxn.cpp index ae1994a5ad..500bea8f27 100644 --- a/src/ledger/LedgerTxn.cpp +++ b/src/ledger/LedgerTxn.cpp @@ -3065,7 +3065,7 @@ LedgerTxnRoot::Impl::getSearchableLiveBucketListSnapshot() const mSearchableBucketListSnapshot = mApp.getBucketManager() .getBucketSnapshotManager() - .copySearchableLiveBucketListSnapshot(/* autoUpdate */ true); + .copySearchableLiveBucketListSnapshot(); } return *mSearchableBucketListSnapshot; diff --git a/src/main/QueryServer.cpp b/src/main/QueryServer.cpp index 7c190666db..1830727ce6 100644 --- a/src/main/QueryServer.cpp +++ b/src/main/QueryServer.cpp @@ -68,8 +68,7 @@ QueryServer::QueryServer(const std::string& address, unsigned short port, for (auto pid : workerPids) { mBucketListSnapshots[pid] = std::move( - bucketSnapshotManager.copySearchableLiveBucketListSnapshot( - /* autoUpdate */ true)); + bucketSnapshotManager.copySearchableLiveBucketListSnapshot()); } } From 33b06e203c04dd617b491e6d40fa3325984571d6 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Sat, 28 Dec 2024 15:53:29 -0800 Subject: [PATCH 8/8] Fix ledger close meta: it was broken due to double addBatch in tests in p20 and later --- .../ledger-close-meta-v1-protocol-20.json | 820 +++++++++--------- .../ledger-close-meta-v1-protocol-21.json | 14 +- .../ledger-close-meta-v1-protocol-22.json | 14 +- 3 files changed, 424 insertions(+), 424 deletions(-) diff --git a/src/testdata/ledger-close-meta-v1-protocol-20.json b/src/testdata/ledger-close-meta-v1-protocol-20.json index 046b649d36..4297245de7 100644 --- a/src/testdata/ledger-close-meta-v1-protocol-20.json +++ b/src/testdata/ledger-close-meta-v1-protocol-20.json @@ -6,24 +6,24 @@ "v": 0 }, "ledgerHeader": { - "hash": "a50c06f398679584d4acff68de5130502114df913f41c270a4bce9e1d6cd5c36", + "hash": "96bbf541d371216daf6d52718c6c80c40cbfa67b51e578df821c238af37fcf6b", "header": { "ledgerVersion": 20, - "previousLedgerHash": "ab3ae955a234c8b03bbd42f5a7ba9b98989ea9fa6e380b00d9bb47abc11fd9f7", + "previousLedgerHash": "635da5e96def44947953c1612b480ac47ce81eaa51bf49b10ce705585fef5820", "scpValue": { - "txSetHash": "748fee17bde220a1e44a917ac6ae9cf70bedb749bc2a2bf440fffbe04d7a46cf", + "txSetHash": "d36dc1b5b4eb0bd5adbf019a5ca575fbcf1453668c8c9e8a74b31d85b4044cb8", "closeTime": 0, "upgrades": [], "ext": { "v": "STELLAR_VALUE_SIGNED", "lcValueSignature": { "nodeID": "GDDOUW25MRFLNXQMN3OODP6JQEXSGLMHAFZV4XPQ2D3GA4QFIDMEJG2O", - "signature": "db221f42903acae8fa8f38251516df81257687c301729f00fe8c9f377af298181a8f18b9b5a690f3c6c05f8fe168c30081d1ad0c4b8dcbd34f194300e9aa830a" + "signature": "c1f4dacc73f38778c4a2fa20eef4d10c469dc78eeba64946bd2028a6b0315d3b9a09f311fed3e20b9b4a3446fab3c3ea62c7773b6e826527b1dc48ba22d13a0f" } } }, - "txSetResultHash": "249b974bacf8b5c4a8f0b5598194c1b9eca64af0b5c1506daa871c1533b6baac", - "bucketListHash": "7c28bf01c1eb9bf17fae213218f9cffeea048d5b261b57bb1092ee39a3afe1c3", + "txSetResultHash": "f66233c106977a4cc148e019411ff6ddfaf76c337d004ed9a304a70407b161d0", + "bucketListHash": "69afd589321f0d78146910460d3a54c07213593f39edd7fe95b9e71e53b4b0fc", "ledgerSeq": 7, "totalCoins": 1000000000000000000, "feePool": 800, @@ -49,7 +49,7 @@ "txSet": { "v": 1, "v1TxSet": { - "previousLedgerHash": "ab3ae955a234c8b03bbd42f5a7ba9b98989ea9fa6e380b00d9bb47abc11fd9f7", + "previousLedgerHash": "635da5e96def44947953c1612b480ac47ce81eaa51bf49b10ce705585fef5820", "phases": [ { "v": 0, @@ -185,22 +185,43 @@ "txProcessing": [ { "result": { - "transactionHash": "0db2322d85e9d8ea2421559922bb6107429650ebdad304c907480853d465c10d", + "transactionHash": "324d0628e2a215d367f181f0e3aacbaa26fa638e676e73fb9ad26a360314a7b7", "result": { - "feeCharged": 100, + "feeCharged": 300, "result": { - "code": "txSUCCESS", - "results": [ - { - "code": "opINNER", - "tr": { - "type": "PAYMENT", - "paymentResult": { - "code": "PAYMENT_SUCCESS" - } + "code": "txFEE_BUMP_INNER_SUCCESS", + "innerResultPair": { + "transactionHash": "b28c171f9658320b5ce8d50e4e1a36b74afbb2a92eec7df92a8981067131b025", + "result": { + "feeCharged": 200, + "result": { + "code": "txSUCCESS", + "results": [ + { + "code": "opINNER", + "tr": { + "type": "PAYMENT", + "paymentResult": { + "code": "PAYMENT_SUCCESS" + } + } + }, + { + "code": "opINNER", + "tr": { + "type": "PAYMENT", + "paymentResult": { + "code": "PAYMENT_SUCCESS" + } + } + } + ] + }, + "ext": { + "v": 0 } } - ] + } }, "ext": { "v": 0 @@ -211,13 +232,13 @@ { "type": "LEDGER_ENTRY_STATE", "state": { - "lastModifiedLedgerSeq": 5, + "lastModifiedLedgerSeq": 4, "data": { "type": "ACCOUNT", "account": { - "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", - "balance": 999999998999989700, - "seqNum": 3, + "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", + "balance": 400000000, + "seqNum": 17179869184, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -225,31 +246,7 @@ "thresholds": "01000000", "signers": [], "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 5, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -265,9 +262,9 @@ "data": { "type": "ACCOUNT", "account": { - "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", - "balance": 999999998999989600, - "seqNum": 3, + "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", + "balance": 399999700, + "seqNum": 17179869184, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -275,31 +272,7 @@ "thresholds": "01000000", "signers": [], "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 5, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -323,9 +296,9 @@ "data": { "type": "ACCOUNT", "account": { - "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", - "balance": 999999998999989600, - "seqNum": 3, + "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", + "balance": 399999700, + "seqNum": 17179869184, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -333,31 +306,7 @@ "thresholds": "01000000", "signers": [], "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 5, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -373,9 +322,61 @@ "data": { "type": "ACCOUNT", "account": { - "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", - "balance": 999999998999989600, - "seqNum": 4, + "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", + "balance": 399999700, + "seqNum": 17179869184, + "numSubEntries": 0, + "inflationDest": null, + "flags": 0, + "homeDomain": "", + "thresholds": "01000000", + "signers": [], + "ext": { + "v": 0 + } + } + }, + "ext": { + "v": 0 + } + } + }, + { + "type": "LEDGER_ENTRY_STATE", + "state": { + "lastModifiedLedgerSeq": 5, + "data": { + "type": "ACCOUNT", + "account": { + "accountID": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q", + "balance": 200010000, + "seqNum": 21474836480, + "numSubEntries": 0, + "inflationDest": null, + "flags": 0, + "homeDomain": "", + "thresholds": "01000000", + "signers": [], + "ext": { + "v": 0 + } + } + }, + "ext": { + "v": 0 + } + } + }, + { + "type": "LEDGER_ENTRY_UPDATED", + "updated": { + "lastModifiedLedgerSeq": 7, + "data": { + "type": "ACCOUNT", + "account": { + "accountID": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q", + "balance": 200010000, + "seqNum": 21474836481, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -425,43 +426,18 @@ "state": { "lastModifiedLedgerSeq": 6, "data": { - "type": "ACCOUNT", - "account": { + "type": "TRUSTLINE", + "trustLine": { "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", - "balance": 399999900, - "seqNum": 12884901889, - "numSubEntries": 1, - "inflationDest": null, - "flags": 0, - "homeDomain": "", - "thresholds": "01000000", - "signers": [], + "asset": { + "assetCode": "CUR1", + "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" + }, + "balance": 0, + "limit": 100, + "flags": 1, "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 6, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -475,43 +451,18 @@ "updated": { "lastModifiedLedgerSeq": 7, "data": { - "type": "ACCOUNT", - "account": { + "type": "TRUSTLINE", + "trustLine": { "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", - "balance": 400000900, - "seqNum": 12884901889, - "numSubEntries": 1, - "inflationDest": null, - "flags": 0, - "homeDomain": "", - "thresholds": "01000000", - "signers": [], + "asset": { + "assetCode": "CUR1", + "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" + }, + "balance": 50, + "limit": 100, + "flags": 1, "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 6, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -519,49 +470,28 @@ "v": 0 } } - }, + } + ] + }, + { + "changes": [ { "type": "LEDGER_ENTRY_STATE", "state": { "lastModifiedLedgerSeq": 7, "data": { - "type": "ACCOUNT", - "account": { - "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", - "balance": 999999998999989600, - "seqNum": 4, - "numSubEntries": 0, - "inflationDest": null, - "flags": 0, - "homeDomain": "", - "thresholds": "01000000", - "signers": [], + "type": "TRUSTLINE", + "trustLine": { + "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", + "asset": { + "assetCode": "CUR1", + "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" + }, + "balance": 50, + "limit": 100, + "flags": 1, "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 7, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -575,43 +505,18 @@ "updated": { "lastModifiedLedgerSeq": 7, "data": { - "type": "ACCOUNT", - "account": { - "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", - "balance": 999999998999988600, - "seqNum": 4, - "numSubEntries": 0, - "inflationDest": null, - "flags": 0, - "homeDomain": "", - "thresholds": "01000000", - "signers": [], + "type": "TRUSTLINE", + "trustLine": { + "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", + "asset": { + "assetCode": "CUR1", + "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" + }, + "balance": 100, + "limit": 100, + "flags": 1, "ext": { - "v": 1, - "v1": { - "liabilities": { - "buying": 0, - "selling": 0 - }, - "ext": { - "v": 2, - "v2": { - "numSponsored": 0, - "numSponsoring": 0, - "signerSponsoringIDs": [], - "ext": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "seqLedger": 7, - "seqTime": 0 - } - } - } - } - } + "v": 0 } } }, @@ -630,43 +535,22 @@ }, { "result": { - "transactionHash": "324d0628e2a215d367f181f0e3aacbaa26fa638e676e73fb9ad26a360314a7b7", + "transactionHash": "0db2322d85e9d8ea2421559922bb6107429650ebdad304c907480853d465c10d", "result": { - "feeCharged": 300, + "feeCharged": 100, "result": { - "code": "txFEE_BUMP_INNER_SUCCESS", - "innerResultPair": { - "transactionHash": "b28c171f9658320b5ce8d50e4e1a36b74afbb2a92eec7df92a8981067131b025", - "result": { - "feeCharged": 200, - "result": { - "code": "txSUCCESS", - "results": [ - { - "code": "opINNER", - "tr": { - "type": "PAYMENT", - "paymentResult": { - "code": "PAYMENT_SUCCESS" - } - } - }, - { - "code": "opINNER", - "tr": { - "type": "PAYMENT", - "paymentResult": { - "code": "PAYMENT_SUCCESS" - } - } - } - ] - }, - "ext": { - "v": 0 + "code": "txSUCCESS", + "results": [ + { + "code": "opINNER", + "tr": { + "type": "PAYMENT", + "paymentResult": { + "code": "PAYMENT_SUCCESS" + } } } - } + ] }, "ext": { "v": 0 @@ -677,13 +561,13 @@ { "type": "LEDGER_ENTRY_STATE", "state": { - "lastModifiedLedgerSeq": 4, + "lastModifiedLedgerSeq": 5, "data": { "type": "ACCOUNT", "account": { - "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", - "balance": 400000000, - "seqNum": 17179869184, + "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", + "balance": 999999998999989700, + "seqNum": 3, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -691,7 +575,31 @@ "thresholds": "01000000", "signers": [], "ext": { - "v": 0 + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, + "ext": { + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 5, + "seqTime": 0 + } + } + } + } + } } } }, @@ -707,9 +615,9 @@ "data": { "type": "ACCOUNT", "account": { - "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", - "balance": 399999700, - "seqNum": 17179869184, + "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", + "balance": 999999998999989600, + "seqNum": 3, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -717,85 +625,57 @@ "thresholds": "01000000", "signers": [], "ext": { - "v": 0 - } - } - }, - "ext": { - "v": 0 - } - } - } - ], - "txApplyProcessing": { - "v": 3, - "v3": { - "ext": { - "v": 0 - }, - "txChangesBefore": [ - { - "type": "LEDGER_ENTRY_STATE", - "state": { - "lastModifiedLedgerSeq": 7, - "data": { - "type": "ACCOUNT", - "account": { - "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", - "balance": 399999700, - "seqNum": 17179869184, - "numSubEntries": 0, - "inflationDest": null, - "flags": 0, - "homeDomain": "", - "thresholds": "01000000", - "signers": [], - "ext": { - "v": 0 - } - } - }, - "ext": { - "v": 0 - } - } - }, - { - "type": "LEDGER_ENTRY_UPDATED", - "updated": { - "lastModifiedLedgerSeq": 7, - "data": { - "type": "ACCOUNT", - "account": { - "accountID": "GCAEBM3GKNR6SV6N73FSGBXU6NSMZ2URQVMJQHXFQFY2PJPX6YBCSAKZ", - "balance": 399999700, - "seqNum": 17179869184, - "numSubEntries": 0, - "inflationDest": null, - "flags": 0, - "homeDomain": "", - "thresholds": "01000000", - "signers": [], + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, "ext": { - "v": 0 + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 5, + "seqTime": 0 + } + } + } } } - }, - "ext": { - "v": 0 } } }, + "ext": { + "v": 0 + } + } + } + ], + "txApplyProcessing": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "txChangesBefore": [ { "type": "LEDGER_ENTRY_STATE", "state": { - "lastModifiedLedgerSeq": 5, + "lastModifiedLedgerSeq": 7, "data": { "type": "ACCOUNT", "account": { - "accountID": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q", - "balance": 200010000, - "seqNum": 21474836480, + "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", + "balance": 999999998999989600, + "seqNum": 3, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -803,7 +683,31 @@ "thresholds": "01000000", "signers": [], "ext": { - "v": 0 + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, + "ext": { + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 5, + "seqTime": 0 + } + } + } + } + } } } }, @@ -819,9 +723,9 @@ "data": { "type": "ACCOUNT", "account": { - "accountID": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q", - "balance": 200010000, - "seqNum": 21474836481, + "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", + "balance": 999999998999989600, + "seqNum": 4, "numSubEntries": 0, "inflationDest": null, "flags": 0, @@ -871,18 +775,43 @@ "state": { "lastModifiedLedgerSeq": 6, "data": { - "type": "TRUSTLINE", - "trustLine": { + "type": "ACCOUNT", + "account": { "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", - "asset": { - "assetCode": "CUR1", - "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" - }, - "balance": 0, - "limit": 100, - "flags": 1, + "balance": 399999900, + "seqNum": 12884901889, + "numSubEntries": 1, + "inflationDest": null, + "flags": 0, + "homeDomain": "", + "thresholds": "01000000", + "signers": [], "ext": { - "v": 0 + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, + "ext": { + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 6, + "seqTime": 0 + } + } + } + } + } } } }, @@ -896,18 +825,43 @@ "updated": { "lastModifiedLedgerSeq": 7, "data": { - "type": "TRUSTLINE", - "trustLine": { + "type": "ACCOUNT", + "account": { "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", - "asset": { - "assetCode": "CUR1", - "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" - }, - "balance": 50, - "limit": 100, - "flags": 1, + "balance": 400000900, + "seqNum": 12884901889, + "numSubEntries": 1, + "inflationDest": null, + "flags": 0, + "homeDomain": "", + "thresholds": "01000000", + "signers": [], "ext": { - "v": 0 + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, + "ext": { + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 6, + "seqTime": 0 + } + } + } + } + } } } }, @@ -915,28 +869,49 @@ "v": 0 } } - } - ] - }, - { - "changes": [ + }, { "type": "LEDGER_ENTRY_STATE", "state": { "lastModifiedLedgerSeq": 7, "data": { - "type": "TRUSTLINE", - "trustLine": { - "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", - "asset": { - "assetCode": "CUR1", - "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" - }, - "balance": 50, - "limit": 100, - "flags": 1, + "type": "ACCOUNT", + "account": { + "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", + "balance": 999999998999989600, + "seqNum": 4, + "numSubEntries": 0, + "inflationDest": null, + "flags": 0, + "homeDomain": "", + "thresholds": "01000000", + "signers": [], "ext": { - "v": 0 + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, + "ext": { + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 7, + "seqTime": 0 + } + } + } + } + } } } }, @@ -950,18 +925,43 @@ "updated": { "lastModifiedLedgerSeq": 7, "data": { - "type": "TRUSTLINE", - "trustLine": { - "accountID": "GB6MXQ5262ZJGDQNA6BL4TWE5SADVZXIKLPELFXKUE27X4SQTGQS44ZB", - "asset": { - "assetCode": "CUR1", - "issuer": "GCGE27HU2VYQANKL2VZWLCAOJYMEFST5DXPBWQ7BRRPOHUPK626DNG4Q" - }, - "balance": 100, - "limit": 100, - "flags": 1, + "type": "ACCOUNT", + "account": { + "accountID": "GC4EFXBN6BEENDAX7PBW5PGIIIVH3INMD3OEPQASXOLGOHVVP7ZEMG7X", + "balance": 999999998999988600, + "seqNum": 4, + "numSubEntries": 0, + "inflationDest": null, + "flags": 0, + "homeDomain": "", + "thresholds": "01000000", + "signers": [], "ext": { - "v": 0 + "v": 1, + "v1": { + "liabilities": { + "buying": 0, + "selling": 0 + }, + "ext": { + "v": 2, + "v2": { + "numSponsored": 0, + "numSponsoring": 0, + "signerSponsoringIDs": [], + "ext": { + "v": 3, + "v3": { + "ext": { + "v": 0 + }, + "seqLedger": 7, + "seqTime": 0 + } + } + } + } + } } } }, @@ -981,7 +981,7 @@ ], "upgradesProcessing": [], "scpInfo": [], - "totalByteSizeOfBucketList": 583, + "totalByteSizeOfBucketList": 703, "evictedTemporaryLedgerKeys": [], "evictedPersistentLedgerEntries": [] } diff --git a/src/testdata/ledger-close-meta-v1-protocol-21.json b/src/testdata/ledger-close-meta-v1-protocol-21.json index 1851a23f3e..05dcfb8b09 100644 --- a/src/testdata/ledger-close-meta-v1-protocol-21.json +++ b/src/testdata/ledger-close-meta-v1-protocol-21.json @@ -6,24 +6,24 @@ "v": 0 }, "ledgerHeader": { - "hash": "52f4e92f487154e485346c691585a082a9733ebab749c580734e9b13be42c963", + "hash": "d56f69daf91565e2406a47123f52892e7834185aa0d78a3660ffc32c1036d015", "header": { "ledgerVersion": 21, - "previousLedgerHash": "4d6b671a994888a7276f1bd0ebf844b678284f483258f6e11378fafe7262ea6c", + "previousLedgerHash": "1d27adc177601684904a5bf656515bafcfa2ffce524bc281413623139314ef95", "scpValue": { - "txSetHash": "ecd3150886583d2df7c8e2da0043cdb5cba4f8a9371283bec5f3856e019df40c", + "txSetHash": "9e6dcfc6f718670287c0954be6c0b939b5c8ac20536fb12c5423136a15923414", "closeTime": 0, "upgrades": [], "ext": { "v": "STELLAR_VALUE_SIGNED", "lcValueSignature": { "nodeID": "GDDOUW25MRFLNXQMN3OODP6JQEXSGLMHAFZV4XPQ2D3GA4QFIDMEJG2O", - "signature": "28f38eed1571b69f23307a87c67fdabf7e619bb0cef976bc460bb40aa68f1fa97db858aef8484c35837ce8794e2d2a492bff14ee4ca75b67d4f10646a04e000b" + "signature": "0eef18d50abb7d872f2ac853dfde0ae96d44891ae171e756445e44e8dd358c0377a24829f6ca688e9ca342052793f986836e40982dcfe7d38580994706262104" } } }, "txSetResultHash": "f66233c106977a4cc148e019411ff6ddfaf76c337d004ed9a304a70407b161d0", - "bucketListHash": "ade00de2089f5d22038df58ed0acab53cd53079fc0980d423b8edf61506c6481", + "bucketListHash": "88546625d1d5d78e0ed0045e3c52b5f3672ca5ebc8a5be12901ac1911139973d", "ledgerSeq": 7, "totalCoins": 1000000000000000000, "feePool": 800, @@ -49,7 +49,7 @@ "txSet": { "v": 1, "v1TxSet": { - "previousLedgerHash": "4d6b671a994888a7276f1bd0ebf844b678284f483258f6e11378fafe7262ea6c", + "previousLedgerHash": "1d27adc177601684904a5bf656515bafcfa2ffce524bc281413623139314ef95", "phases": [ { "v": 0, @@ -981,7 +981,7 @@ ], "upgradesProcessing": [], "scpInfo": [], - "totalByteSizeOfBucketList": 788, + "totalByteSizeOfBucketList": 967, "evictedTemporaryLedgerKeys": [], "evictedPersistentLedgerEntries": [] } diff --git a/src/testdata/ledger-close-meta-v1-protocol-22.json b/src/testdata/ledger-close-meta-v1-protocol-22.json index f9e1ff43fe..270ab76ae9 100644 --- a/src/testdata/ledger-close-meta-v1-protocol-22.json +++ b/src/testdata/ledger-close-meta-v1-protocol-22.json @@ -6,24 +6,24 @@ "v": 0 }, "ledgerHeader": { - "hash": "bb89aefaf31b3f03f6f7623c75dd055f4e58773b557eda1118b5a9d2b80b33b9", + "hash": "7bf914c410e40b5786de0a4ace2ea5598d05e60ba1161d307a7e177a811510fa", "header": { "ledgerVersion": 22, - "previousLedgerHash": "7571e5186d594475cfb7107be2ac14b4aa70e6ccf31810dd961eb91168443ac3", + "previousLedgerHash": "ffff85c9cbc23a80ea78a0fe604bbd9f7b7095633404316e6b006897f88b7fb0", "scpValue": { - "txSetHash": "833ee1e2b95263731bc434c06c0878aa93b2466b3ec05cbda1c4c60881249301", + "txSetHash": "f85d6ccae5bd0c965cc8553fbef82fd48b1a69b30cb9fcdd5f1be865411cb64c", "closeTime": 0, "upgrades": [], "ext": { "v": "STELLAR_VALUE_SIGNED", "lcValueSignature": { "nodeID": "GDDOUW25MRFLNXQMN3OODP6JQEXSGLMHAFZV4XPQ2D3GA4QFIDMEJG2O", - "signature": "6d0af8ae88d6cf05d4ef0fbd85e3e0676fc9f5334e8630cced3ca1f9521c34e6f6ae7c4a7ad296a1a1a092bbe9b40802462511ec99e389b7d953ba7695339802" + "signature": "4fd0dc0a9185eec8f1c6dbe5360a7be605cf83e28f0fd603a320b919ae6b80d685a2b684241eecd12e36b0f62cbef3de70e64137fe1321831fb15a1c1388bf0d" } } }, "txSetResultHash": "f66233c106977a4cc148e019411ff6ddfaf76c337d004ed9a304a70407b161d0", - "bucketListHash": "bfe580088e8d44d0f6be8f0dd5d55ffdd22931b66a80c88407b169eeca70aa5c", + "bucketListHash": "8a070de26600d61a4ad4c09455ae13d621b5f53698a9710013bda2932118a474", "ledgerSeq": 7, "totalCoins": 1000000000000000000, "feePool": 800, @@ -49,7 +49,7 @@ "txSet": { "v": 1, "v1TxSet": { - "previousLedgerHash": "7571e5186d594475cfb7107be2ac14b4aa70e6ccf31810dd961eb91168443ac3", + "previousLedgerHash": "ffff85c9cbc23a80ea78a0fe604bbd9f7b7095633404316e6b006897f88b7fb0", "phases": [ { "v": 0, @@ -981,7 +981,7 @@ ], "upgradesProcessing": [], "scpInfo": [], - "totalByteSizeOfBucketList": 1021, + "totalByteSizeOfBucketList": 1267, "evictedTemporaryLedgerKeys": [], "evictedPersistentLedgerEntries": [] }