Skip to content

Commit dbad62e

Browse files
committed
Maintain read-only Soroban config accessible by main thread only
1 parent ab76585 commit dbad62e

31 files changed

+174
-150
lines changed

src/herder/HerderImpl.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -2101,7 +2101,8 @@ HerderImpl::maybeHandleUpgrade()
21012101
// no-op on any earlier protocol
21022102
return;
21032103
}
2104-
auto const& conf = mApp.getLedgerManager().getSorobanNetworkConfig();
2104+
auto const& conf =
2105+
mApp.getLedgerManager().getSorobanNetworkConfigReadOnly();
21052106

21062107
auto maybeNewMaxTxSize =
21072108
conf.txMaxSizeBytes() + getFlowControlExtraBuffer();
@@ -2153,7 +2154,7 @@ HerderImpl::start()
21532154
if (protocolVersionStartsFrom(version, SOROBAN_PROTOCOL_VERSION))
21542155
{
21552156
auto const& conf =
2156-
mApp.getLedgerManager().getSorobanNetworkConfig();
2157+
mApp.getLedgerManager().getSorobanNetworkConfigReadOnly();
21572158
mMaxTxSize = std::max(mMaxTxSize, conf.txMaxSizeBytes() +
21582159
getFlowControlExtraBuffer());
21592160
}

src/herder/TransactionQueue.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ TransactionQueue::canAdd(
381381
auto txResult = tx->createSuccessResult();
382382
if (!tx->checkSorobanResourceAndSetError(
383383
mApp.getAppConnector(),
384+
mApp.getLedgerManager()
385+
.getSorobanNetworkConfigReadOnly(),
384386
mApp.getLedgerManager()
385387
.getLastClosedLedgerHeader()
386388
.header.ledgerVersion,

src/herder/test/HerderTests.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,8 @@ TEST_CASE("tx set hits overlay byte limit during construction",
10071007
cfg.mLedgerMaxInstructions = max;
10081008
});
10091009

1010-
auto const& conf = app->getLedgerManager().getSorobanNetworkConfig();
1010+
auto const& conf =
1011+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
10111012
uint32_t maxContractSize = 0;
10121013
maxContractSize = conf.maxContractSizeBytes();
10131014

@@ -1162,7 +1163,7 @@ TEST_CASE("surge pricing", "[herder][txset][soroban]")
11621163
auto tx = makeMultiPayment(acc1, root, 1, 100, 0, 1);
11631164

11641165
SorobanNetworkConfig conf =
1165-
app->getLedgerManager().getSorobanNetworkConfig();
1166+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
11661167

11671168
uint32_t const baseFee = 10'000'000;
11681169
SorobanResources resources;
@@ -3361,7 +3362,7 @@ TEST_CASE("soroban txs accepted by the network",
33613362
for (auto node : nodes)
33623363
{
33633364
REQUIRE(node->getLedgerManager()
3364-
.getSorobanNetworkConfig()
3365+
.getSorobanNetworkConfigReadOnly()
33653366
.ledgerMaxTxCount() == ledgerWideLimit * 10);
33663367
}
33673368

src/herder/test/TransactionQueueTests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,7 @@ TEST_CASE("Soroban TransactionQueue limits",
12591259
auto account2 = root.create("a2", minBalance2);
12601260

12611261
SorobanNetworkConfig conf =
1262-
app->getLedgerManager().getSorobanNetworkConfig();
1262+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
12631263

12641264
SorobanResources resources;
12651265
resources.instructions = 2'000'000;

src/herder/test/TxSetTests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ TEST_CASE("txset nomination", "[txset]")
10871087
});
10881088

10891089
auto const& sorobanConfig =
1090-
app->getLedgerManager().getSorobanNetworkConfig();
1090+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
10911091
stellar::uniform_int_distribution<> txReadEntriesDistr(
10921092
1, sorobanConfig.txMaxReadLedgerEntries());
10931093

src/herder/test/UpgradesTests.cpp

+10-8
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ makeBucketListSizeWindowSampleSizeTestUpgrade(Application& app,
251251
{
252252
// Modify window size
253253
auto sas = app.getLedgerManager()
254-
.getSorobanNetworkConfig()
254+
.getSorobanNetworkConfigReadOnly()
255255
.stateArchivalSettings();
256256
sas.bucketListSizeWindowSampleSize = newWindowSize;
257257

@@ -837,7 +837,7 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
837837
executeUpgrade(*app, makeProtocolVersionUpgrade(
838838
static_cast<uint32_t>(SOROBAN_PROTOCOL_VERSION)));
839839
auto const& sorobanConfig =
840-
app->getLedgerManager().getSorobanNetworkConfig();
840+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
841841
SECTION("unknown config upgrade set is ignored")
842842
{
843843
auto contractID = autocheck::generator<Hash>()(5);
@@ -905,7 +905,7 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
905905
auto const newSize = 20;
906906
populateValuesAndUpgradeSize(newSize);
907907
auto const& cfg2 =
908-
app->getLedgerManager().getSorobanNetworkConfig();
908+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
909909

910910
// Verify that we popped the 10 oldest values
911911
auto sum = 0;
@@ -927,7 +927,7 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
927927
auto const newSize = 40;
928928
populateValuesAndUpgradeSize(newSize);
929929
auto const& cfg2 =
930-
app->getLedgerManager().getSorobanNetworkConfig();
930+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
931931

932932
// Verify that we backfill 10 copies of the oldest value
933933
auto sum = 0;
@@ -957,7 +957,7 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
957957
LedgerTxn ltx2(app->getLedgerTxnRoot());
958958

959959
auto const& cfg =
960-
app->getLedgerManager().getSorobanNetworkConfig();
960+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
961961
initialSize =
962962
cfg.mStateArchivalSettings.bucketListSizeWindowSampleSize;
963963
initialWindow = cfg.mBucketListSizeSnapshots;
@@ -972,7 +972,8 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
972972
REQUIRE(configUpgradeSet);
973973
executeUpgrade(*app, makeConfigUpgrade(*configUpgradeSet));
974974

975-
auto const& cfg = app->getLedgerManager().getSorobanNetworkConfig();
975+
auto const& cfg =
976+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
976977
REQUIRE(cfg.mStateArchivalSettings.bucketListSizeWindowSampleSize ==
977978
initialSize);
978979
REQUIRE(cfg.mBucketListSizeSnapshots == initialWindow);
@@ -1086,7 +1087,7 @@ TEST_CASE("Soroban max tx set size upgrade applied to ledger",
10861087
static_cast<uint32_t>(SOROBAN_PROTOCOL_VERSION)));
10871088

10881089
auto const& sorobanConfig =
1089-
app->getLedgerManager().getSorobanNetworkConfig();
1090+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
10901091

10911092
executeUpgrade(*app, makeMaxSorobanTxSizeUpgrade(123));
10921093
REQUIRE(sorobanConfig.ledgerMaxTxCount() == 123);
@@ -2245,7 +2246,8 @@ TEST_CASE("configuration initialized in version upgrade", "[upgrades]")
22452246
InitialSorobanNetworkConfig::MAX_CONTRACT_SIZE);
22462247

22472248
// Check that BucketList size window initialized with current BL size
2248-
auto& networkConfig = app->getLedgerManager().getSorobanNetworkConfig();
2249+
auto& networkConfig =
2250+
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
22492251
REQUIRE(networkConfig.getAverageBucketListSize() == blSize);
22502252

22512253
// Check in memory window

src/ledger/LedgerManager.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ class LedgerManager
9797
getLastClosedLedgerHeader() const = 0;
9898

9999
// Get bucketlist snapshot
100-
virtual std::shared_ptr<SearchableLiveBucketListSnapshot const>
101-
getCurrentLedgerStateSnaphot() = 0;
100+
virtual SearchableSnapshotConstPtr getCurrentLedgerStateSnaphot() = 0;
102101

103102
// return the HAS that corresponds to the last closed ledger as persisted in
104103
// the database
@@ -132,7 +131,9 @@ class LedgerManager
132131
// The config is automatically refreshed on protocol upgrades.
133132
// Ledger txn here is needed for the sake of lazy load; it won't be
134133
// used most of the time.
135-
virtual SorobanNetworkConfig const& getSorobanNetworkConfig() = 0;
134+
virtual SorobanNetworkConfig const& getSorobanNetworkConfigReadOnly() = 0;
135+
virtual SorobanNetworkConfig const& getSorobanNetworkConfigForApply() = 0;
136+
136137
virtual bool hasSorobanNetworkConfig() const = 0;
137138

138139
#ifdef BUILD_TESTS

src/ledger/LedgerManagerImpl.cpp

+45-47
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist)
394394
// configs right away
395395
LedgerTxn ltx(mApp.getLedgerTxnRoot());
396396
updateNetworkConfig(ltx);
397+
mSorobanNetworkConfigReadOnly = mSorobanNetworkConfigForApply;
397398
}
398399
}
399400

@@ -452,7 +453,7 @@ LedgerManagerImpl::maxLedgerResources(bool isSoroban)
452453

453454
if (isSoroban)
454455
{
455-
auto conf = getSorobanNetworkConfig();
456+
auto conf = getSorobanNetworkConfigReadOnly();
456457
std::vector<int64_t> limits = {conf.ledgerMaxTxCount(),
457458
conf.ledgerMaxInstructions(),
458459
conf.ledgerMaxTransactionSizesBytes(),
@@ -474,7 +475,8 @@ LedgerManagerImpl::maxSorobanTransactionResources()
474475
{
475476
ZoneScoped;
476477

477-
auto const& conf = mApp.getLedgerManager().getSorobanNetworkConfig();
478+
auto const& conf =
479+
mApp.getLedgerManager().getSorobanNetworkConfigReadOnly();
478480
int64_t const opCount = 1;
479481
std::vector<int64_t> limits = {opCount,
480482
conf.txMaxInstructions(),
@@ -538,35 +540,37 @@ LedgerManagerImpl::getLastClosedLedgerNum() const
538540
return mLastClosedLedger.header.ledgerSeq;
539541
}
540542

541-
SorobanNetworkConfig&
542-
LedgerManagerImpl::getSorobanNetworkConfigInternal()
543+
SorobanNetworkConfig const&
544+
LedgerManagerImpl::getSorobanNetworkConfigReadOnly()
543545
{
544546
releaseAssert(threadIsMain());
545-
releaseAssert(mSorobanNetworkConfig);
546-
return *mSorobanNetworkConfig;
547+
releaseAssert(hasSorobanNetworkConfig());
548+
return *mSorobanNetworkConfigReadOnly;
547549
}
548550

549551
SorobanNetworkConfig const&
550-
LedgerManagerImpl::getSorobanNetworkConfig()
552+
LedgerManagerImpl::getSorobanNetworkConfigForApply()
551553
{
552-
releaseAssert(threadIsMain());
553-
return getSorobanNetworkConfigInternal();
554+
// Must be called from ledger close thread only
555+
releaseAssert(mSorobanNetworkConfigForApply);
556+
return *mSorobanNetworkConfigForApply;
554557
}
555558

556559
bool
557560
LedgerManagerImpl::hasSorobanNetworkConfig() const
558561
{
559562
releaseAssert(threadIsMain());
560-
return mSorobanNetworkConfig.has_value();
563+
return static_cast<bool>(mSorobanNetworkConfigReadOnly);
561564
}
562565

563566
#ifdef BUILD_TESTS
564567
SorobanNetworkConfig&
565568
LedgerManagerImpl::getMutableSorobanNetworkConfig()
566569
{
567570
releaseAssert(threadIsMain());
568-
return getSorobanNetworkConfigInternal();
571+
return *mSorobanNetworkConfigForApply;
569572
}
573+
570574
std::vector<TransactionMetaFrame> const&
571575
LedgerManagerImpl::getLastClosedLedgerTxMeta()
572576
{
@@ -589,48 +593,41 @@ LedgerManagerImpl::getSorobanMetrics()
589593
void
590594
LedgerManagerImpl::publishSorobanMetrics()
591595
{
592-
releaseAssert(mSorobanNetworkConfig);
596+
auto const& conf = getSorobanNetworkConfigForApply();
593597
// first publish the network config limits
594598
mSorobanMetrics.mConfigContractDataKeySizeBytes.set_count(
595-
mSorobanNetworkConfig->maxContractDataKeySizeBytes());
599+
conf.maxContractDataKeySizeBytes());
596600
mSorobanMetrics.mConfigMaxContractDataEntrySizeBytes.set_count(
597-
mSorobanNetworkConfig->maxContractDataEntrySizeBytes());
601+
conf.maxContractDataEntrySizeBytes());
598602
mSorobanMetrics.mConfigMaxContractSizeBytes.set_count(
599-
mSorobanNetworkConfig->maxContractSizeBytes());
600-
mSorobanMetrics.mConfigTxMaxSizeByte.set_count(
601-
mSorobanNetworkConfig->txMaxSizeBytes());
602-
mSorobanMetrics.mConfigTxMaxCpuInsn.set_count(
603-
mSorobanNetworkConfig->txMaxInstructions());
604-
mSorobanMetrics.mConfigTxMemoryLimitBytes.set_count(
605-
mSorobanNetworkConfig->txMemoryLimit());
603+
conf.maxContractSizeBytes());
604+
mSorobanMetrics.mConfigTxMaxSizeByte.set_count(conf.txMaxSizeBytes());
605+
mSorobanMetrics.mConfigTxMaxCpuInsn.set_count(conf.txMaxInstructions());
606+
mSorobanMetrics.mConfigTxMemoryLimitBytes.set_count(conf.txMemoryLimit());
606607
mSorobanMetrics.mConfigTxMaxReadLedgerEntries.set_count(
607-
mSorobanNetworkConfig->txMaxReadLedgerEntries());
608-
mSorobanMetrics.mConfigTxMaxReadBytes.set_count(
609-
mSorobanNetworkConfig->txMaxReadBytes());
608+
conf.txMaxReadLedgerEntries());
609+
mSorobanMetrics.mConfigTxMaxReadBytes.set_count(conf.txMaxReadBytes());
610610
mSorobanMetrics.mConfigTxMaxWriteLedgerEntries.set_count(
611-
mSorobanNetworkConfig->txMaxWriteLedgerEntries());
612-
mSorobanMetrics.mConfigTxMaxWriteBytes.set_count(
613-
mSorobanNetworkConfig->txMaxWriteBytes());
611+
conf.txMaxWriteLedgerEntries());
612+
mSorobanMetrics.mConfigTxMaxWriteBytes.set_count(conf.txMaxWriteBytes());
614613
mSorobanMetrics.mConfigMaxContractEventsSizeBytes.set_count(
615-
mSorobanNetworkConfig->txMaxContractEventsSizeBytes());
616-
mSorobanMetrics.mConfigLedgerMaxTxCount.set_count(
617-
mSorobanNetworkConfig->ledgerMaxTxCount());
614+
conf.txMaxContractEventsSizeBytes());
615+
mSorobanMetrics.mConfigLedgerMaxTxCount.set_count(conf.ledgerMaxTxCount());
618616
mSorobanMetrics.mConfigLedgerMaxInstructions.set_count(
619-
mSorobanNetworkConfig->ledgerMaxInstructions());
617+
conf.ledgerMaxInstructions());
620618
mSorobanMetrics.mConfigLedgerMaxTxsSizeByte.set_count(
621-
mSorobanNetworkConfig->ledgerMaxTransactionSizesBytes());
619+
conf.ledgerMaxTransactionSizesBytes());
622620
mSorobanMetrics.mConfigLedgerMaxReadLedgerEntries.set_count(
623-
mSorobanNetworkConfig->ledgerMaxReadLedgerEntries());
621+
conf.ledgerMaxReadLedgerEntries());
624622
mSorobanMetrics.mConfigLedgerMaxReadBytes.set_count(
625-
mSorobanNetworkConfig->ledgerMaxReadBytes());
623+
conf.ledgerMaxReadBytes());
626624
mSorobanMetrics.mConfigLedgerMaxWriteEntries.set_count(
627-
mSorobanNetworkConfig->ledgerMaxWriteLedgerEntries());
625+
conf.ledgerMaxWriteLedgerEntries());
628626
mSorobanMetrics.mConfigLedgerMaxWriteBytes.set_count(
629-
mSorobanNetworkConfig->ledgerMaxWriteBytes());
627+
conf.ledgerMaxWriteBytes());
630628
mSorobanMetrics.mConfigBucketListTargetSizeByte.set_count(
631-
mSorobanNetworkConfig->bucketListTargetSizeBytes());
632-
mSorobanMetrics.mConfigFeeWrite1KB.set_count(
633-
mSorobanNetworkConfig->feeWrite1KB());
629+
conf.bucketListTargetSizeBytes());
630+
mSorobanMetrics.mConfigFeeWrite1KB.set_count(conf.feeWrite1KB());
634631

635632
// then publish the actual ledger usage
636633
mSorobanMetrics.publishAndResetLedgerWideMetrics();
@@ -1265,7 +1262,7 @@ LedgerManagerImpl::maybeResetLedgerCloseMetaDebugStream(uint32_t ledgerSeq)
12651262
}
12661263
}
12671264

1268-
std::shared_ptr<SearchableLiveBucketListSnapshot const>
1265+
SearchableSnapshotConstPtr
12691266
LedgerManagerImpl::getCurrentLedgerStateSnaphot()
12701267
{
12711268
if (!mReadOnlyLedgerStateSnapshot)
@@ -1293,9 +1290,9 @@ LedgerManagerImpl::advanceLedgerPointers(LedgerHeader const& header,
12931290

12941291
// NB: with parallel ledger close, this will have to be called strictly from
12951292
// the main thread,
1296-
auto prevLedgerSeq = mLastClosedLedger.header.ledgerSeq;
12971293
mLastClosedLedger.hash = ledgerHash;
12981294
mLastClosedLedger.header = header;
1295+
mSorobanNetworkConfigReadOnly = mSorobanNetworkConfigForApply;
12991296

13001297
auto& bm = mApp.getBucketManager();
13011298
auto liveSnapshot = std::make_unique<BucketListSnapshot<LiveBucket>>(
@@ -1322,11 +1319,12 @@ LedgerManagerImpl::updateNetworkConfig(AbstractLedgerTxn& rootLtx)
13221319

13231320
if (protocolVersionStartsFrom(ledgerVersion, SOROBAN_PROTOCOL_VERSION))
13241321
{
1325-
if (!mSorobanNetworkConfig)
1322+
if (!mSorobanNetworkConfigForApply)
13261323
{
1327-
mSorobanNetworkConfig = std::make_optional<SorobanNetworkConfig>();
1324+
mSorobanNetworkConfigForApply =
1325+
std::make_shared<SorobanNetworkConfig>();
13281326
}
1329-
mSorobanNetworkConfig->loadFromLedger(
1327+
mSorobanNetworkConfigForApply->loadFromLedger(
13301328
rootLtx, mApp.getConfig().CURRENT_LEDGER_PROTOCOL_VERSION,
13311329
ledgerVersion);
13321330
publishSorobanMetrics();
@@ -1712,8 +1710,8 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList(
17121710
ltxEvictions.commit();
17131711
}
17141712

1715-
getSorobanNetworkConfigInternal().maybeSnapshotBucketListSize(
1716-
lh.ledgerSeq, ltx, mApp);
1713+
mSorobanNetworkConfigForApply->maybeSnapshotBucketListSize(lh.ledgerSeq,
1714+
ltx, mApp);
17171715
}
17181716

17191717
ltx.getAllEntries(initEntries, liveEntries, deadEntries);
@@ -1762,7 +1760,7 @@ LedgerManagerImpl::ledgerClosed(
17621760
protocolVersionStartsFrom(initialLedgerVers, SOROBAN_PROTOCOL_VERSION))
17631761
{
17641762
ledgerCloseMeta->setNetworkConfiguration(
1765-
getSorobanNetworkConfig(),
1763+
getSorobanNetworkConfigReadOnly(),
17661764
mApp.getConfig().EMIT_LEDGER_CLOSE_META_EXT_V1);
17671765
}
17681766

0 commit comments

Comments
 (0)