Skip to content

Commit 17eb4cb

Browse files
authoredFeb 13, 2024··
Merge pull request #4166 from marta-lokhova/startup_path
Rewrite state loading path on startup Reviewed-by: dmkozh
2 parents d2e6be1 + b57d301 commit 17eb4cb

12 files changed

+185
-181
lines changed
 

‎src/bucket/BucketManager.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,10 @@ class BucketManager : NonMovableOrCopyable
270270
checkForMissingBucketsFiles(HistoryArchiveState const& has) = 0;
271271

272272
// Assume state from `has` in BucketList: find and attach all buckets in
273-
// `has`, set current BL. Note: Does not restart merging
273+
// `has`, set current BL.
274274
virtual void assumeState(HistoryArchiveState const& has,
275-
uint32_t maxProtocolVersion) = 0;
275+
uint32_t maxProtocolVersion,
276+
bool restartMerges) = 0;
276277

277278
virtual void shutdown() = 0;
278279

‎src/bucket/BucketManagerImpl.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ BucketManagerImpl::checkForMissingBucketsFiles(HistoryArchiveState const& has)
10481048

10491049
void
10501050
BucketManagerImpl::assumeState(HistoryArchiveState const& has,
1051-
uint32_t maxProtocolVersion)
1051+
uint32_t maxProtocolVersion, bool restartMerges)
10521052
{
10531053
ZoneScoped;
10541054
releaseAssertOrThrow(mApp.getConfig().MODE_ENABLES_BUCKETLIST);
@@ -1093,7 +1093,10 @@ BucketManagerImpl::assumeState(HistoryArchiveState const& has,
10931093
mBucketList->getLevel(i).setNext(nextFuture);
10941094
}
10951095

1096-
mBucketList->restartMerges(mApp, maxProtocolVersion, has.currentLedger);
1096+
if (restartMerges)
1097+
{
1098+
mBucketList->restartMerges(mApp, maxProtocolVersion, has.currentLedger);
1099+
}
10971100
cleanupStaleFiles();
10981101
}
10991102

‎src/bucket/BucketManagerImpl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class BucketManagerImpl : public BucketManager
166166
std::vector<std::string>
167167
checkForMissingBucketsFiles(HistoryArchiveState const& has) override;
168168
void assumeState(HistoryArchiveState const& has,
169-
uint32_t maxProtocolVersion) override;
169+
uint32_t maxProtocolVersion, bool restartMerges) override;
170170
void shutdown() override;
171171

172172
bool isShutdown() const override;

‎src/catchup/ApplyBucketsWork.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ ApplyBucketsWork::doWork()
279279
CLOG_INFO(History, "ApplyBuckets : done, assuming state");
280280

281281
// After all buckets applied, spawn assumeState work
282-
addWork<AssumeStateWork>(mApplyState, mMaxProtocolVersion);
282+
addWork<AssumeStateWork>(mApplyState, mMaxProtocolVersion,
283+
/* restartMerges */ true);
283284
mSpawnedAssumeStateWork = true;
284285
}
285286

‎src/catchup/AssumeStateWork.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ namespace stellar
1414
{
1515
AssumeStateWork::AssumeStateWork(Application& app,
1616
HistoryArchiveState const& has,
17-
uint32_t maxProtocolVersion)
17+
uint32_t maxProtocolVersion,
18+
bool restartMerges)
1819
: Work(app, "assume-state", BasicWork::RETRY_NEVER)
1920
, mHas(has)
2021
, mMaxProtocolVersion(maxProtocolVersion)
22+
, mRestartMerges(restartMerges)
2123
{
2224
// Maintain reference to all Buckets in HAS to avoid garbage collection,
2325
// including future buckets that have already finished merging
@@ -68,8 +70,10 @@ AssumeStateWork::doWork()
6870
// Add bucket files to BucketList and restart merges
6971
auto assumeStateCB = [&has = mHas,
7072
maxProtocolVersion = mMaxProtocolVersion,
73+
restartMerges = mRestartMerges,
7174
&buckets = mBuckets](Application& app) {
72-
app.getBucketManager().assumeState(has, maxProtocolVersion);
75+
app.getBucketManager().assumeState(has, maxProtocolVersion,
76+
restartMerges);
7377

7478
// Drop bucket references once assume state complete since buckets
7579
// now referenced by BucketList

‎src/catchup/AssumeStateWork.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ class AssumeStateWork : public Work
1717
HistoryArchiveState const& mHas;
1818
uint32_t const mMaxProtocolVersion;
1919
bool mWorkSpawned{false};
20+
bool const mRestartMerges;
2021

2122
// Keep strong reference to buckets in HAS so they are not garbage
2223
// collected during indexing
2324
std::vector<std::shared_ptr<Bucket>> mBuckets{};
2425

2526
public:
2627
AssumeStateWork(Application& app, HistoryArchiveState const& has,
27-
uint32_t maxProtocolVersion);
28+
uint32_t maxProtocolVersion, bool restartMerges);
2829

2930
protected:
3031
State doWork() override;

‎src/ledger/LedgerManager.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,14 @@ class LedgerManager
147147
// Called by application lifecycle events, system startup.
148148
virtual void startNewLedger() = 0;
149149

150-
// loads the last ledger information from the database
151-
// if handler is set, also loads bucket information and invokes handler.
152-
virtual void loadLastKnownLedger(std::function<void()> handler) = 0;
150+
// loads the last ledger information from the database with the following
151+
// parameters:
152+
// * restoreBucketlist indicates whether to restore the bucket list fully,
153+
// and restart merges
154+
// * isLedgerStateReady indicates whether the ledger state is ready or is
155+
// still being rebuilt (in which case we can't yet load ledger entries)
156+
virtual void loadLastKnownLedger(bool restoreBucketlist,
157+
bool isLedgerStateReady) = 0;
153158

154159
// Return true if core is currently rebuilding in-memory state via local
155160
// catchup

‎src/ledger/LedgerManagerImpl.cpp

+97-80
Original file line numberDiff line numberDiff line change
@@ -333,11 +333,12 @@ setLedgerTxnHeader(LedgerHeader const& lh, Application& app)
333333
}
334334

335335
void
336-
LedgerManagerImpl::loadLastKnownLedger(function<void()> handler)
336+
LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist,
337+
bool isLedgerStateReady)
337338
{
338339
ZoneScoped;
339-
auto ledgerTime = mLedgerClose.TimeScope();
340340

341+
// Step 1. Load LCL state from the DB and extract latest ledger hash
341342
string lastLedger =
342343
mApp.getPersistentState().getState(PersistentState::kLastClosedLedger);
343344

@@ -346,103 +347,119 @@ LedgerManagerImpl::loadLastKnownLedger(function<void()> handler)
346347
throw std::runtime_error(
347348
"No reference in DB to any last closed ledger");
348349
}
349-
else
350-
{
351-
CLOG_INFO(Ledger, "Last closed ledger (LCL) hash is {}", lastLedger);
352-
Hash lastLedgerHash = hexToBin256(lastLedger);
353350

354-
if (mApp.getConfig().MODE_STORES_HISTORY_LEDGERHEADERS)
351+
CLOG_INFO(Ledger, "Last closed ledger (LCL) hash is {}", lastLedger);
352+
Hash lastLedgerHash = hexToBin256(lastLedger);
353+
354+
// Step 2. Restore LedgerHeader from DB based on the ledger hash derived
355+
// earlier, or verify we're at genesis if in no-history mode
356+
std::optional<LedgerHeader> latestLedgerHeader;
357+
if (mApp.getConfig().MODE_STORES_HISTORY_LEDGERHEADERS)
358+
{
359+
if (mRebuildInMemoryState)
355360
{
356-
if (mRebuildInMemoryState)
361+
LedgerHeader lh;
362+
CLOG_INFO(Ledger,
363+
"Setting empty ledger while core rebuilds state: {}",
364+
ledgerAbbrev(lh));
365+
setLedgerTxnHeader(lh, mApp);
366+
latestLedgerHeader = lh;
367+
}
368+
else
369+
{
370+
auto currentLedger =
371+
LedgerHeaderUtils::loadByHash(getDatabase(), lastLedgerHash);
372+
if (!currentLedger)
357373
{
358-
LedgerHeader lh;
359-
CLOG_INFO(Ledger,
360-
"Setting empty ledger while core rebuilds state: {}",
361-
ledgerAbbrev(lh));
362-
setLedgerTxnHeader(lh, mApp);
374+
throw std::runtime_error("Could not load ledger from database");
363375
}
364-
else
376+
HistoryArchiveState has = getLastClosedLedgerHAS();
377+
if (currentLedger->ledgerSeq != has.currentLedger)
365378
{
366-
auto currentLedger = LedgerHeaderUtils::loadByHash(
367-
getDatabase(), lastLedgerHash);
368-
if (!currentLedger)
369-
{
370-
throw std::runtime_error(
371-
"Could not load ledger from database");
372-
}
373-
HistoryArchiveState has = getLastClosedLedgerHAS();
374-
if (currentLedger->ledgerSeq != has.currentLedger)
375-
{
376-
throw std::runtime_error(
377-
"Invalid database state: last known "
378-
"ledger does not agree with HAS");
379-
}
380-
381-
CLOG_INFO(Ledger, "Loaded LCL header from database: {}",
382-
ledgerAbbrev(*currentLedger));
383-
setLedgerTxnHeader(*currentLedger, mApp);
379+
throw std::runtime_error("Invalid database state: last known "
380+
"ledger does not agree with HAS");
384381
}
382+
383+
CLOG_INFO(Ledger, "Loaded LCL header from database: {}",
384+
ledgerAbbrev(*currentLedger));
385+
setLedgerTxnHeader(*currentLedger, mApp);
386+
latestLedgerHeader = *currentLedger;
385387
}
386-
else
388+
}
389+
else
390+
{
391+
// In no-history mode, this method should only be called when
392+
// the LCL is genesis.
393+
releaseAssertOrThrow(mLastClosedLedger.hash == lastLedgerHash);
394+
releaseAssertOrThrow(mLastClosedLedger.header.ledgerSeq ==
395+
GENESIS_LEDGER_SEQ);
396+
CLOG_INFO(Ledger, "LCL is genesis: {}",
397+
ledgerAbbrev(mLastClosedLedger));
398+
latestLedgerHeader = mLastClosedLedger.header;
399+
}
400+
401+
releaseAssert(latestLedgerHeader.has_value());
402+
403+
// Step 3. Restore BucketList if we're doing a full core startup
404+
// (startServices=true), OR when using BucketListDB
405+
if (restoreBucketlist || mApp.getConfig().isUsingBucketListDB())
406+
{
407+
HistoryArchiveState has = getLastClosedLedgerHAS();
408+
auto missing = mApp.getBucketManager().checkForMissingBucketsFiles(has);
409+
auto pubmissing = mApp.getHistoryManager()
410+
.getMissingBucketsReferencedByPublishQueue();
411+
missing.insert(missing.end(), pubmissing.begin(), pubmissing.end());
412+
if (!missing.empty())
387413
{
388-
// In no-history mode, this method should only be called when
389-
// the LCL is genesis.
390-
releaseAssertOrThrow(mLastClosedLedger.hash == lastLedgerHash);
391-
releaseAssertOrThrow(mLastClosedLedger.header.ledgerSeq ==
392-
GENESIS_LEDGER_SEQ);
393-
CLOG_INFO(Ledger, "LCL is genesis: {}",
394-
ledgerAbbrev(mLastClosedLedger));
414+
CLOG_ERROR(Ledger,
415+
"{} buckets are missing from bucket directory '{}'",
416+
missing.size(), mApp.getBucketManager().getBucketDir());
417+
throw std::runtime_error("Bucket directory is corrupt");
395418
}
396419

397-
if (handler)
420+
if (mApp.getConfig().MODE_ENABLES_BUCKETLIST)
398421
{
399-
HistoryArchiveState has = getLastClosedLedgerHAS();
400-
auto missing =
401-
mApp.getBucketManager().checkForMissingBucketsFiles(has);
402-
auto pubmissing = mApp.getHistoryManager()
403-
.getMissingBucketsReferencedByPublishQueue();
404-
missing.insert(missing.end(), pubmissing.begin(), pubmissing.end());
405-
if (!missing.empty())
422+
// Only restart merges in full startup mode. Many modes in core
423+
// (standalone offline commands, in-memory setup) do not need to
424+
// spin up expensive merge processes.
425+
auto assumeStateWork =
426+
mApp.getWorkScheduler().executeWork<AssumeStateWork>(
427+
has, latestLedgerHeader->ledgerVersion, restoreBucketlist);
428+
if (assumeStateWork->getState() == BasicWork::State::WORK_SUCCESS)
406429
{
407-
CLOG_ERROR(
408-
Ledger, "{} buckets are missing from bucket directory '{}'",
409-
missing.size(), mApp.getBucketManager().getBucketDir());
410-
throw std::runtime_error("Bucket directory is corrupt");
430+
CLOG_INFO(Ledger, "Assumed bucket-state for LCL: {}",
431+
ledgerAbbrev(*latestLedgerHeader));
411432
}
412433
else
413434
{
414-
{
415-
LedgerTxn ltx(mApp.getLedgerTxnRoot());
416-
auto header = ltx.loadHeader();
417-
uint32_t ledgerVersion = header.current().ledgerVersion;
418-
if (mApp.getConfig().MODE_ENABLES_BUCKETLIST)
419-
{
420-
auto assumeStateWork =
421-
mApp.getWorkScheduler()
422-
.executeWork<AssumeStateWork>(has,
423-
ledgerVersion);
424-
if (assumeStateWork->getState() ==
425-
BasicWork::State::WORK_SUCCESS)
426-
{
427-
CLOG_INFO(Ledger,
428-
"Assumed bucket-state for LCL: {}",
429-
ledgerAbbrev(header.current()));
430-
}
431-
else
432-
{
433-
// Work should only fail during graceful shutdown
434-
releaseAssert(mApp.isStopping());
435-
}
436-
}
437-
advanceLedgerPointers(header.current());
438-
}
439-
handler();
435+
// Work should only fail during graceful shutdown
436+
releaseAssertOrThrow(mApp.isStopping());
440437
}
441438
}
442-
else
439+
}
440+
441+
// Step 4. Restore LedgerManager's internal state
442+
advanceLedgerPointers(*latestLedgerHeader);
443+
444+
if (protocolVersionStartsFrom(latestLedgerHeader->ledgerVersion,
445+
SOROBAN_PROTOCOL_VERSION))
446+
{
447+
if (isLedgerStateReady)
443448
{
449+
// Step 5. If ledger state is ready and core is in v20, load network
450+
// configs right away
444451
LedgerTxn ltx(mApp.getLedgerTxnRoot());
445-
advanceLedgerPointers(ltx.loadHeader().current());
452+
updateNetworkConfig(ltx);
453+
}
454+
else
455+
{
456+
// In some modes, e.g. in-memory, core's state is rebuilt
457+
// asynchronously via catchup. In this case, we're not able to load
458+
// the network config at this time, and instead must let catchup do
459+
// it when ready.
460+
CLOG_INFO(Ledger,
461+
"Ledger state is being rebuilt, network config will "
462+
"be loaded once the rebuild is done");
446463
}
447464
}
448465
}

‎src/ledger/LedgerManagerImpl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ class LedgerManagerImpl : public LedgerManager
182182

183183
void startNewLedger(LedgerHeader const& genesisLedger);
184184
void startNewLedger() override;
185-
void loadLastKnownLedger(std::function<void()> handler) override;
185+
void loadLastKnownLedger(bool restoreBucketlist,
186+
bool isLedgerStateReady) override;
186187
virtual bool rebuildingInMemoryState() override;
187188
virtual void setupInMemoryStateRebuild() override;
188189

‎src/main/ApplicationImpl.cpp

+43-59
Original file line numberDiff line numberDiff line change
@@ -550,15 +550,8 @@ ApplicationImpl::getJsonInfo(bool verbose)
550550
void
551551
ApplicationImpl::reportInfo(bool verbose)
552552
{
553-
auto loadConfig = [this]() {
554-
LedgerTxn ltx(getLedgerTxnRoot());
555-
if (protocolVersionStartsFrom(ltx.loadHeader().current().ledgerVersion,
556-
SOROBAN_PROTOCOL_VERSION))
557-
{
558-
getLedgerManager().updateNetworkConfig(ltx);
559-
}
560-
};
561-
mLedgerManager->loadLastKnownLedger(loadConfig);
553+
mLedgerManager->loadLastKnownLedger(/* restoreBucketlist */ false,
554+
/* isLedgerStateReady */ true);
562555
LOG_INFO(DEFAULT_LOG, "Reporting application info");
563556
std::cout << getJsonInfo(verbose).toStyledString() << std::endl;
564557
}
@@ -793,67 +786,58 @@ ApplicationImpl::validateAndLogConfig()
793786
}
794787

795788
void
796-
ApplicationImpl::start()
789+
ApplicationImpl::startServices()
797790
{
798-
if (mStarted)
791+
// restores Herder's state before starting overlay
792+
mHerder->start();
793+
// set known cursors before starting maintenance job
794+
ExternalQueue ps(*this);
795+
ps.setInitialCursors(mConfig.KNOWN_CURSORS);
796+
mMaintainer->start();
797+
if (mConfig.MODE_AUTO_STARTS_OVERLAY)
799798
{
800-
CLOG_INFO(Ledger, "Skipping application start up");
801-
return;
799+
mOverlayManager->start();
800+
}
801+
auto npub = mHistoryManager->publishQueuedHistory();
802+
if (npub != 0)
803+
{
804+
CLOG_INFO(Ledger, "Restarted publishing {} queued snapshots", npub);
805+
}
806+
if (mConfig.FORCE_SCP)
807+
{
808+
LOG_INFO(DEFAULT_LOG, "* ");
809+
LOG_INFO(DEFAULT_LOG,
810+
"* Force-starting scp from the current db state.");
811+
LOG_INFO(DEFAULT_LOG, "* ");
812+
813+
mHerder->bootstrap();
814+
}
815+
if (mConfig.AUTOMATIC_SELF_CHECK_PERIOD.count() != 0)
816+
{
817+
scheduleSelfCheck(true);
802818
}
803-
CLOG_INFO(Ledger, "Starting up application");
804-
mStarted = true;
805819

806820
if (mConfig.TESTING_UPGRADE_DATETIME.time_since_epoch().count() != 0)
807821
{
808822
mHerder->setUpgrades(mConfig);
809823
}
824+
}
810825

811-
bool done = false;
812-
mLedgerManager->loadLastKnownLedger([this, &done]() {
813-
// Make sure to load Soroban network config before
814-
// herder starts (tx queue configuration is based on it).
815-
{
816-
LedgerTxn ltx(getLedgerTxnRoot());
817-
if (protocolVersionStartsFrom(
818-
ltx.loadHeader().current().ledgerVersion,
819-
SOROBAN_PROTOCOL_VERSION))
820-
{
821-
getLedgerManager().updateNetworkConfig(ltx);
822-
}
823-
}
824-
// restores Herder's state before starting overlay
825-
mHerder->start();
826-
// set known cursors before starting maintenance job
827-
ExternalQueue ps(*this);
828-
ps.setInitialCursors(mConfig.KNOWN_CURSORS);
829-
mMaintainer->start();
830-
if (mConfig.MODE_AUTO_STARTS_OVERLAY)
831-
{
832-
mOverlayManager->start();
833-
}
834-
auto npub = mHistoryManager->publishQueuedHistory();
835-
if (npub != 0)
836-
{
837-
CLOG_INFO(Ledger, "Restarted publishing {} queued snapshots", npub);
838-
}
839-
if (mConfig.FORCE_SCP)
840-
{
841-
LOG_INFO(DEFAULT_LOG, "* ");
842-
LOG_INFO(DEFAULT_LOG,
843-
"* Force-starting scp from the current db state.");
844-
LOG_INFO(DEFAULT_LOG, "* ");
826+
void
827+
ApplicationImpl::start()
828+
{
829+
if (mStarted)
830+
{
831+
CLOG_INFO(Ledger, "Skipping application start up");
832+
return;
833+
}
845834

846-
mHerder->bootstrap();
847-
}
848-
if (mConfig.AUTOMATIC_SELF_CHECK_PERIOD.count() != 0)
849-
{
850-
scheduleSelfCheck(true);
851-
}
852-
done = true;
853-
});
835+
CLOG_INFO(Ledger, "Starting up application");
836+
mStarted = true;
854837

855-
while (!done && mVirtualClock.crank(true))
856-
;
838+
mLedgerManager->loadLastKnownLedger(/* restoreBucketlist */ true,
839+
/* isLedgerStateReady */ true);
840+
startServices();
857841
}
858842

859843
void

‎src/main/ApplicationImpl.h

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class ApplicationImpl : public Application
8484
std::string jobName) override;
8585

8686
virtual void start() override;
87+
void startServices();
8788

8889
// Stops the worker io_context, which should cause the threads to exit once
8990
// they finish running any work-in-progress. If you want a more abrupt exit

‎src/main/ApplicationUtils.cpp

+15-29
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ setupMinimalDBForInMemoryMode(Config const& cfg, uint32_t startAtLedger)
162162

163163
if (!rebuildDB)
164164
{
165-
app->getLedgerManager().loadLastKnownLedger(nullptr);
165+
// Ledger state is not yet ready during this setup step
166+
app->getLedgerManager().loadLastKnownLedger(
167+
/* restoreBucketlist */ false, /* isLedgerStateReady */ false);
166168
auto lcl = app->getLedgerManager().getLastClosedLedgerNum();
167169
LOG_INFO(DEFAULT_LOG, "Current in-memory state, got LCL: {}", lcl);
168170
rebuildDB =
@@ -195,7 +197,10 @@ setupApp(Config& cfg, VirtualClock& clock, uint32_t startAtLedger,
195197
return nullptr;
196198
}
197199

198-
app->getLedgerManager().loadLastKnownLedger(nullptr);
200+
// With in-memory mode, ledger state is not yet ready during this setup step
201+
app->getLedgerManager().loadLastKnownLedger(
202+
/* restoreBucketlist */ false,
203+
/* isLedgerStateReady */ !cfg.isInMemoryMode());
199204
auto lcl = app->getLedgerManager().getLastClosedLedgerHeader();
200205

201206
if (cfg.isInMemoryMode() &&
@@ -447,15 +452,8 @@ selfCheck(Config cfg)
447452

448453
// We run self-checks from a "loaded but dormant" state where the
449454
// application is not started, but the LM has loaded the LCL.
450-
app->getLedgerManager().loadLastKnownLedger(nullptr);
451-
{
452-
LedgerTxn ltx(app->getLedgerTxnRoot());
453-
if (protocolVersionStartsFrom(ltx.loadHeader().current().ledgerVersion,
454-
SOROBAN_PROTOCOL_VERSION))
455-
{
456-
app->getLedgerManager().updateNetworkConfig(ltx);
457-
}
458-
}
455+
app->getLedgerManager().loadLastKnownLedger(/* restoreBucketlist */ false,
456+
/* isLedgerStateReady */ true);
459457

460458
// First we schedule the cheap, asynchronous "online" checks that get run by
461459
// the HTTP "self-check" endpoint, and crank until they're done.
@@ -533,17 +531,11 @@ mergeBucketList(Config cfg, std::string const& outputDir)
533531
VirtualClock clock;
534532
cfg.setNoListen();
535533
Application::pointer app = Application::create(clock, cfg, false);
536-
app->getLedgerManager().loadLastKnownLedger(nullptr);
537534
auto& lm = app->getLedgerManager();
538-
{
539-
LedgerTxn ltx(app->getLedgerTxnRoot());
540-
if (protocolVersionStartsFrom(ltx.loadHeader().current().ledgerVersion,
541-
SOROBAN_PROTOCOL_VERSION))
542-
{
543-
lm.updateNetworkConfig(ltx);
544-
}
545-
}
546535
auto& bm = app->getBucketManager();
536+
537+
lm.loadLastKnownLedger(/* restoreBucketlist */ false,
538+
/* isLedgerStateReady */ true);
547539
HistoryArchiveState has = lm.getLastClosedLedgerHAS();
548540
auto bucket = bm.mergeBuckets(has);
549541

@@ -578,16 +570,10 @@ dumpLedger(Config cfg, std::string const& outputFile,
578570
VirtualClock clock;
579571
cfg.setNoListen();
580572
Application::pointer app = Application::create(clock, cfg, false);
581-
app->getLedgerManager().loadLastKnownLedger(nullptr);
582573
auto& lm = app->getLedgerManager();
583-
{
584-
LedgerTxn ltx(app->getLedgerTxnRoot());
585-
if (protocolVersionStartsFrom(ltx.loadHeader().current().ledgerVersion,
586-
SOROBAN_PROTOCOL_VERSION))
587-
{
588-
lm.updateNetworkConfig(ltx);
589-
}
590-
}
574+
575+
lm.loadLastKnownLedger(/* restoreBucketlist */ false,
576+
/* isLedgerStateReady */ true);
591577
HistoryArchiveState has = lm.getLastClosedLedgerHAS();
592578
std::optional<uint32_t> minLedger;
593579
if (lastModifiedLedgerCount)

0 commit comments

Comments
 (0)
Please sign in to comment.