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