Skip to content

Commit

Permalink
Maintain read-only Soroban config accessible by main thread only
Browse files Browse the repository at this point in the history
  • Loading branch information
marta-lokhova committed Jan 3, 2025
1 parent ab76585 commit dbad62e
Show file tree
Hide file tree
Showing 31 changed files with 174 additions and 150 deletions.
5 changes: 3 additions & 2 deletions src/herder/HerderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2101,7 +2101,8 @@ HerderImpl::maybeHandleUpgrade()
// no-op on any earlier protocol
return;
}
auto const& conf = mApp.getLedgerManager().getSorobanNetworkConfig();
auto const& conf =
mApp.getLedgerManager().getSorobanNetworkConfigReadOnly();

auto maybeNewMaxTxSize =
conf.txMaxSizeBytes() + getFlowControlExtraBuffer();
Expand Down Expand Up @@ -2153,7 +2154,7 @@ HerderImpl::start()
if (protocolVersionStartsFrom(version, SOROBAN_PROTOCOL_VERSION))
{
auto const& conf =
mApp.getLedgerManager().getSorobanNetworkConfig();
mApp.getLedgerManager().getSorobanNetworkConfigReadOnly();
mMaxTxSize = std::max(mMaxTxSize, conf.txMaxSizeBytes() +
getFlowControlExtraBuffer());
}
Expand Down
2 changes: 2 additions & 0 deletions src/herder/TransactionQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ TransactionQueue::canAdd(
auto txResult = tx->createSuccessResult();
if (!tx->checkSorobanResourceAndSetError(
mApp.getAppConnector(),
mApp.getLedgerManager()
.getSorobanNetworkConfigReadOnly(),
mApp.getLedgerManager()
.getLastClosedLedgerHeader()
.header.ledgerVersion,
Expand Down
7 changes: 4 additions & 3 deletions src/herder/test/HerderTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,8 @@ TEST_CASE("tx set hits overlay byte limit during construction",
cfg.mLedgerMaxInstructions = max;
});

auto const& conf = app->getLedgerManager().getSorobanNetworkConfig();
auto const& conf =
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
uint32_t maxContractSize = 0;
maxContractSize = conf.maxContractSizeBytes();

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

SorobanNetworkConfig conf =
app->getLedgerManager().getSorobanNetworkConfig();
app->getLedgerManager().getSorobanNetworkConfigReadOnly();

uint32_t const baseFee = 10'000'000;
SorobanResources resources;
Expand Down Expand Up @@ -3361,7 +3362,7 @@ TEST_CASE("soroban txs accepted by the network",
for (auto node : nodes)
{
REQUIRE(node->getLedgerManager()
.getSorobanNetworkConfig()
.getSorobanNetworkConfigReadOnly()
.ledgerMaxTxCount() == ledgerWideLimit * 10);
}

Expand Down
2 changes: 1 addition & 1 deletion src/herder/test/TransactionQueueTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,7 @@ TEST_CASE("Soroban TransactionQueue limits",
auto account2 = root.create("a2", minBalance2);

SorobanNetworkConfig conf =
app->getLedgerManager().getSorobanNetworkConfig();
app->getLedgerManager().getSorobanNetworkConfigReadOnly();

SorobanResources resources;
resources.instructions = 2'000'000;
Expand Down
2 changes: 1 addition & 1 deletion src/herder/test/TxSetTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ TEST_CASE("txset nomination", "[txset]")
});

auto const& sorobanConfig =
app->getLedgerManager().getSorobanNetworkConfig();
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
stellar::uniform_int_distribution<> txReadEntriesDistr(
1, sorobanConfig.txMaxReadLedgerEntries());

Expand Down
18 changes: 10 additions & 8 deletions src/herder/test/UpgradesTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ makeBucketListSizeWindowSampleSizeTestUpgrade(Application& app,
{
// Modify window size
auto sas = app.getLedgerManager()
.getSorobanNetworkConfig()
.getSorobanNetworkConfigReadOnly()
.stateArchivalSettings();
sas.bucketListSizeWindowSampleSize = newWindowSize;

Expand Down Expand Up @@ -837,7 +837,7 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
executeUpgrade(*app, makeProtocolVersionUpgrade(
static_cast<uint32_t>(SOROBAN_PROTOCOL_VERSION)));
auto const& sorobanConfig =
app->getLedgerManager().getSorobanNetworkConfig();
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
SECTION("unknown config upgrade set is ignored")
{
auto contractID = autocheck::generator<Hash>()(5);
Expand Down Expand Up @@ -905,7 +905,7 @@ TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
auto const newSize = 20;
populateValuesAndUpgradeSize(newSize);
auto const& cfg2 =
app->getLedgerManager().getSorobanNetworkConfig();
app->getLedgerManager().getSorobanNetworkConfigReadOnly();

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

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

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

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

auto const& sorobanConfig =
app->getLedgerManager().getSorobanNetworkConfig();
app->getLedgerManager().getSorobanNetworkConfigReadOnly();

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

// Check that BucketList size window initialized with current BL size
auto& networkConfig = app->getLedgerManager().getSorobanNetworkConfig();
auto& networkConfig =
app->getLedgerManager().getSorobanNetworkConfigReadOnly();
REQUIRE(networkConfig.getAverageBucketListSize() == blSize);

// Check in memory window
Expand Down
7 changes: 4 additions & 3 deletions src/ledger/LedgerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ class LedgerManager
getLastClosedLedgerHeader() const = 0;

// Get bucketlist snapshot
virtual std::shared_ptr<SearchableLiveBucketListSnapshot const>
getCurrentLedgerStateSnaphot() = 0;
virtual SearchableSnapshotConstPtr getCurrentLedgerStateSnaphot() = 0;

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

virtual bool hasSorobanNetworkConfig() const = 0;

#ifdef BUILD_TESTS
Expand Down
92 changes: 45 additions & 47 deletions src/ledger/LedgerManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ LedgerManagerImpl::loadLastKnownLedger(bool restoreBucketlist)
// configs right away
LedgerTxn ltx(mApp.getLedgerTxnRoot());
updateNetworkConfig(ltx);
mSorobanNetworkConfigReadOnly = mSorobanNetworkConfigForApply;
}
}

Expand Down Expand Up @@ -452,7 +453,7 @@ LedgerManagerImpl::maxLedgerResources(bool isSoroban)

if (isSoroban)
{
auto conf = getSorobanNetworkConfig();
auto conf = getSorobanNetworkConfigReadOnly();
std::vector<int64_t> limits = {conf.ledgerMaxTxCount(),
conf.ledgerMaxInstructions(),
conf.ledgerMaxTransactionSizesBytes(),
Expand All @@ -474,7 +475,8 @@ LedgerManagerImpl::maxSorobanTransactionResources()
{
ZoneScoped;

auto const& conf = mApp.getLedgerManager().getSorobanNetworkConfig();
auto const& conf =
mApp.getLedgerManager().getSorobanNetworkConfigReadOnly();
int64_t const opCount = 1;
std::vector<int64_t> limits = {opCount,
conf.txMaxInstructions(),
Expand Down Expand Up @@ -538,35 +540,37 @@ LedgerManagerImpl::getLastClosedLedgerNum() const
return mLastClosedLedger.header.ledgerSeq;
}

SorobanNetworkConfig&
LedgerManagerImpl::getSorobanNetworkConfigInternal()
SorobanNetworkConfig const&
LedgerManagerImpl::getSorobanNetworkConfigReadOnly()
{
releaseAssert(threadIsMain());
releaseAssert(mSorobanNetworkConfig);
return *mSorobanNetworkConfig;
releaseAssert(hasSorobanNetworkConfig());
return *mSorobanNetworkConfigReadOnly;
}

SorobanNetworkConfig const&
LedgerManagerImpl::getSorobanNetworkConfig()
LedgerManagerImpl::getSorobanNetworkConfigForApply()
{
releaseAssert(threadIsMain());
return getSorobanNetworkConfigInternal();
// Must be called from ledger close thread only
releaseAssert(mSorobanNetworkConfigForApply);
return *mSorobanNetworkConfigForApply;
}

bool
LedgerManagerImpl::hasSorobanNetworkConfig() const
{
releaseAssert(threadIsMain());
return mSorobanNetworkConfig.has_value();
return static_cast<bool>(mSorobanNetworkConfigReadOnly);
}

#ifdef BUILD_TESTS
SorobanNetworkConfig&
LedgerManagerImpl::getMutableSorobanNetworkConfig()
{
releaseAssert(threadIsMain());
return getSorobanNetworkConfigInternal();
return *mSorobanNetworkConfigForApply;
}

std::vector<TransactionMetaFrame> const&
LedgerManagerImpl::getLastClosedLedgerTxMeta()
{
Expand All @@ -589,48 +593,41 @@ LedgerManagerImpl::getSorobanMetrics()
void
LedgerManagerImpl::publishSorobanMetrics()
{
releaseAssert(mSorobanNetworkConfig);
auto const& conf = getSorobanNetworkConfigForApply();
// first publish the network config limits
mSorobanMetrics.mConfigContractDataKeySizeBytes.set_count(
mSorobanNetworkConfig->maxContractDataKeySizeBytes());
conf.maxContractDataKeySizeBytes());
mSorobanMetrics.mConfigMaxContractDataEntrySizeBytes.set_count(
mSorobanNetworkConfig->maxContractDataEntrySizeBytes());
conf.maxContractDataEntrySizeBytes());
mSorobanMetrics.mConfigMaxContractSizeBytes.set_count(
mSorobanNetworkConfig->maxContractSizeBytes());
mSorobanMetrics.mConfigTxMaxSizeByte.set_count(
mSorobanNetworkConfig->txMaxSizeBytes());
mSorobanMetrics.mConfigTxMaxCpuInsn.set_count(
mSorobanNetworkConfig->txMaxInstructions());
mSorobanMetrics.mConfigTxMemoryLimitBytes.set_count(
mSorobanNetworkConfig->txMemoryLimit());
conf.maxContractSizeBytes());
mSorobanMetrics.mConfigTxMaxSizeByte.set_count(conf.txMaxSizeBytes());
mSorobanMetrics.mConfigTxMaxCpuInsn.set_count(conf.txMaxInstructions());
mSorobanMetrics.mConfigTxMemoryLimitBytes.set_count(conf.txMemoryLimit());
mSorobanMetrics.mConfigTxMaxReadLedgerEntries.set_count(
mSorobanNetworkConfig->txMaxReadLedgerEntries());
mSorobanMetrics.mConfigTxMaxReadBytes.set_count(
mSorobanNetworkConfig->txMaxReadBytes());
conf.txMaxReadLedgerEntries());
mSorobanMetrics.mConfigTxMaxReadBytes.set_count(conf.txMaxReadBytes());
mSorobanMetrics.mConfigTxMaxWriteLedgerEntries.set_count(
mSorobanNetworkConfig->txMaxWriteLedgerEntries());
mSorobanMetrics.mConfigTxMaxWriteBytes.set_count(
mSorobanNetworkConfig->txMaxWriteBytes());
conf.txMaxWriteLedgerEntries());
mSorobanMetrics.mConfigTxMaxWriteBytes.set_count(conf.txMaxWriteBytes());
mSorobanMetrics.mConfigMaxContractEventsSizeBytes.set_count(
mSorobanNetworkConfig->txMaxContractEventsSizeBytes());
mSorobanMetrics.mConfigLedgerMaxTxCount.set_count(
mSorobanNetworkConfig->ledgerMaxTxCount());
conf.txMaxContractEventsSizeBytes());
mSorobanMetrics.mConfigLedgerMaxTxCount.set_count(conf.ledgerMaxTxCount());
mSorobanMetrics.mConfigLedgerMaxInstructions.set_count(
mSorobanNetworkConfig->ledgerMaxInstructions());
conf.ledgerMaxInstructions());
mSorobanMetrics.mConfigLedgerMaxTxsSizeByte.set_count(
mSorobanNetworkConfig->ledgerMaxTransactionSizesBytes());
conf.ledgerMaxTransactionSizesBytes());
mSorobanMetrics.mConfigLedgerMaxReadLedgerEntries.set_count(
mSorobanNetworkConfig->ledgerMaxReadLedgerEntries());
conf.ledgerMaxReadLedgerEntries());
mSorobanMetrics.mConfigLedgerMaxReadBytes.set_count(
mSorobanNetworkConfig->ledgerMaxReadBytes());
conf.ledgerMaxReadBytes());
mSorobanMetrics.mConfigLedgerMaxWriteEntries.set_count(
mSorobanNetworkConfig->ledgerMaxWriteLedgerEntries());
conf.ledgerMaxWriteLedgerEntries());
mSorobanMetrics.mConfigLedgerMaxWriteBytes.set_count(
mSorobanNetworkConfig->ledgerMaxWriteBytes());
conf.ledgerMaxWriteBytes());
mSorobanMetrics.mConfigBucketListTargetSizeByte.set_count(
mSorobanNetworkConfig->bucketListTargetSizeBytes());
mSorobanMetrics.mConfigFeeWrite1KB.set_count(
mSorobanNetworkConfig->feeWrite1KB());
conf.bucketListTargetSizeBytes());
mSorobanMetrics.mConfigFeeWrite1KB.set_count(conf.feeWrite1KB());

// then publish the actual ledger usage
mSorobanMetrics.publishAndResetLedgerWideMetrics();
Expand Down Expand Up @@ -1265,7 +1262,7 @@ LedgerManagerImpl::maybeResetLedgerCloseMetaDebugStream(uint32_t ledgerSeq)
}
}

std::shared_ptr<SearchableLiveBucketListSnapshot const>
SearchableSnapshotConstPtr
LedgerManagerImpl::getCurrentLedgerStateSnaphot()
{
if (!mReadOnlyLedgerStateSnapshot)
Expand Down Expand Up @@ -1293,9 +1290,9 @@ LedgerManagerImpl::advanceLedgerPointers(LedgerHeader const& header,

// NB: with parallel ledger close, this will have to be called strictly from
// the main thread,
auto prevLedgerSeq = mLastClosedLedger.header.ledgerSeq;
mLastClosedLedger.hash = ledgerHash;
mLastClosedLedger.header = header;
mSorobanNetworkConfigReadOnly = mSorobanNetworkConfigForApply;

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

if (protocolVersionStartsFrom(ledgerVersion, SOROBAN_PROTOCOL_VERSION))
{
if (!mSorobanNetworkConfig)
if (!mSorobanNetworkConfigForApply)
{
mSorobanNetworkConfig = std::make_optional<SorobanNetworkConfig>();
mSorobanNetworkConfigForApply =
std::make_shared<SorobanNetworkConfig>();
}
mSorobanNetworkConfig->loadFromLedger(
mSorobanNetworkConfigForApply->loadFromLedger(
rootLtx, mApp.getConfig().CURRENT_LEDGER_PROTOCOL_VERSION,
ledgerVersion);
publishSorobanMetrics();
Expand Down Expand Up @@ -1712,8 +1710,8 @@ LedgerManagerImpl::transferLedgerEntriesToBucketList(
ltxEvictions.commit();
}

getSorobanNetworkConfigInternal().maybeSnapshotBucketListSize(
lh.ledgerSeq, ltx, mApp);
mSorobanNetworkConfigForApply->maybeSnapshotBucketListSize(lh.ledgerSeq,
ltx, mApp);
}

ltx.getAllEntries(initEntries, liveEntries, deadEntries);
Expand Down Expand Up @@ -1762,7 +1760,7 @@ LedgerManagerImpl::ledgerClosed(
protocolVersionStartsFrom(initialLedgerVers, SOROBAN_PROTOCOL_VERSION))
{
ledgerCloseMeta->setNetworkConfiguration(
getSorobanNetworkConfig(),
getSorobanNetworkConfigReadOnly(),
mApp.getConfig().EMIT_LEDGER_CLOSE_META_EXT_V1);
}

Expand Down
Loading

0 comments on commit dbad62e

Please sign in to comment.