Skip to content

Commit

Permalink
Add support for the max number of threads per ledger config setting.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmkozh committed Jul 2, 2024
1 parent 6a987b3 commit 9c1ea65
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 33 deletions.
5 changes: 5 additions & 0 deletions src/herder/Upgrades.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,11 @@ Upgrades::applyVersionUpgrade(Application& app, AbstractLedgerTxn& ltx,
{
SorobanNetworkConfig::createCostTypesForV21(ltx, app);
}
if (needUpgradeToVersion(PARALLEL_SOROBAN_PHASE_PROTOCOL_VERSION,
prevVersion, newVersion))
{
SorobanNetworkConfig::createLedgerEntriesForParallelSoroban(ltx, app);
}
}

void
Expand Down
202 changes: 175 additions & 27 deletions src/herder/test/UpgradesTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,29 @@ getBucketListSizeWindowKey()
return windowKey;
}

#ifdef ENABLE_NEXT_PROTOCOL_VERSION_UNSAFE_FOR_PRODUCTION
LedgerKey
getParallelComputeSettingsLedgerKey()
{
LedgerKey maxContractSizeKey(CONFIG_SETTING);
maxContractSizeKey.configSetting().configSettingID =
CONFIG_SETTING_CONTRACT_PARALLEL_COMPUTE_V0;
return maxContractSizeKey;
}

ConfigUpgradeSetFrameConstPtr
makeParallelComputeUpdgrade(AbstractLedgerTxn& ltx, uint32_t maxParallelThreads)
{
// Make entry for the upgrade
ConfigUpgradeSet configUpgradeSet;
auto& configEntry = configUpgradeSet.updatedEntry.emplace_back();
configEntry.configSettingID(CONFIG_SETTING_CONTRACT_PARALLEL_COMPUTE_V0);
configEntry.contractParallelCompute().ledgerMaxParallelThreads =
maxParallelThreads;
return makeConfigUpgradeSet(ltx, configUpgradeSet);
}
#endif

void
testListUpgrades(VirtualClock::system_time_point preferredUpgradeDatetime,
bool shouldListAny)
Expand Down Expand Up @@ -813,6 +836,55 @@ TEST_CASE("config upgrade validation", "[upgrades]")
}
}

#ifdef ENABLE_NEXT_PROTOCOL_VERSION_UNSAFE_FOR_PRODUCTION
TEST_CASE("config upgrade validation for protocol 22", "[upgrades]")
{
auto runTest = [&](uint32_t protocolVersion,
Upgrades::UpgradeValidity expectedRes) {
VirtualClock clock;
auto cfg = getTestConfig(0);
cfg.TESTING_UPGRADE_LEDGER_PROTOCOL_VERSION = protocolVersion;
auto app = createTestApplication(clock, cfg);

LedgerHeader header;
auto headerTime = VirtualClock::to_time_t(genesis(0, 2));
header.ledgerVersion = protocolVersion;
header.scpValue.closeTime = headerTime;

ConfigUpgradeSetFrameConstPtr configUpgradeSet;

{
Upgrades::UpgradeParameters scheduledUpgrades;
LedgerTxn ltx(app->getLedgerTxnRoot());
configUpgradeSet = makeParallelComputeUpdgrade(ltx, 10);

scheduledUpgrades.mUpgradeTime = genesis(0, 1);
scheduledUpgrades.mConfigUpgradeSetKey = configUpgradeSet->getKey();
app->getHerder().setUpgrades(scheduledUpgrades);
ltx.commit();
}
LedgerTxn ltx(app->getLedgerTxnRoot());
LedgerUpgrade outUpgrade;
REQUIRE(Upgrades::isValidForApply(
toUpgradeType(makeConfigUpgrade(*configUpgradeSet)),
outUpgrade, *app, ltx, header) == expectedRes);
};

SECTION("valid for apply")
{
runTest(static_cast<uint32_t>(PARALLEL_SOROBAN_PHASE_PROTOCOL_VERSION),
Upgrades::UpgradeValidity::VALID);
}

SECTION("unsupported protocol")
{
runTest(static_cast<uint32_t>(PARALLEL_SOROBAN_PHASE_PROTOCOL_VERSION) -
1,
Upgrades::UpgradeValidity::INVALID);
}
}
#endif

TEST_CASE("config upgrades applied to ledger", "[soroban][upgrades]")
{
VirtualClock clock;
Expand Down Expand Up @@ -1659,8 +1731,9 @@ TEST_CASE("upgrade to version 10", "[upgrades]")
" offers that do not satisfy thresholds")
{
// Pay txFee to send 4*baseReserve + 3*txFee for net balance
// decrease of 4*baseReserve + 4*txFee. This matches the balance
// decrease from creating 4 offers as in the next test section.
// decrease of 4*baseReserve + 4*txFee. This matches the
// balance decrease from creating 4 offers as in the next
// test section.
a1.pay(root, 4 * lm.getLastReserve() + 3 * txFee);

std::vector<TestMarketOffer> offers;
Expand Down Expand Up @@ -1797,8 +1870,9 @@ TEST_CASE("upgrade to version 10", "[upgrades]")
" unauthorized offers")
{
// Pay txFee to send 4*baseReserve + 3*txFee for net balance
// decrease of 4*baseReserve + 4*txFee. This matches the balance
// decrease from creating 4 offers as in the next test section.
// decrease of 4*baseReserve + 4*txFee. This matches the
// balance decrease from creating 4 offers as in the next
// test section.
a1.pay(root, 4 * lm.getLastReserve() + 3 * txFee);

std::vector<TestMarketOffer> offers;
Expand Down Expand Up @@ -2009,8 +2083,8 @@ TEST_CASE("upgrade to version 11", "[upgrades]")
// Check several subtle characteristics of the post-upgrade
// environment:
// - Old-protocol merges stop happening (there should have
// been 6 before the upgrade, but we re-use a merge we did at
// ledger 1 for ledger 2 spill, so the counter is at 5)
// been 6 before the upgrade, but we re-use a merge we did
// at ledger 1 for ledger 2 spill, so the counter is at 5)
// - New-protocol merges start happening.
// - At the upgrade (5), we find 1 INITENTRY in lev[0].curr
// - The next two (6, 7), propagate INITENTRYs to lev[0].snap
Expand Down Expand Up @@ -2123,8 +2197,8 @@ TEST_CASE("upgrade to version 12", "[upgrades]")
REQUIRE(getVers(lev1Snap) == oldProto);
REQUIRE(mc.mPostShadowRemovalProtocolMerges == 6);
// One more old-style merge despite the upgrade
// At ledger 8, level 2 spills, and starts an old-style merge,
// as level 1 snap is still of old version
// At ledger 8, level 2 spills, and starts an old-style
// merge, as level 1 snap is still of old version
REQUIRE(mc.mPreShadowRemovalProtocolMerges == 6);
break;
case 7:
Expand Down Expand Up @@ -2308,6 +2382,77 @@ TEST_CASE("configuration initialized in version upgrade", "[upgrades]")
}
}

#ifdef ENABLE_NEXT_PROTOCOL_VERSION_UNSAFE_FOR_PRODUCTION
TEST_CASE("parallel Soroban settings upgrade", "[upgrades]")
{
VirtualClock clock;
auto cfg = getTestConfig(0);
cfg.USE_CONFIG_FOR_GENESIS = false;

auto app = createTestApplication(clock, cfg);

executeUpgrade(*app,
makeProtocolVersionUpgrade(
static_cast<uint32_t>(SOROBAN_PROTOCOL_VERSION) - 1));

for (uint32_t version = static_cast<uint32_t>(SOROBAN_PROTOCOL_VERSION);
version <
static_cast<uint32_t>(PARALLEL_SOROBAN_PHASE_PROTOCOL_VERSION);
++version)
{
executeUpgrade(*app, makeProtocolVersionUpgrade(version));
}

{
LedgerTxn ltx(app->getLedgerTxnRoot());
REQUIRE(!ltx.load(getParallelComputeSettingsLedgerKey()));
}

executeUpgrade(*app, makeProtocolVersionUpgrade(static_cast<uint32_t>(
PARALLEL_SOROBAN_PHASE_PROTOCOL_VERSION)));

// Make sure initial value is correct.
{
LedgerTxn ltx(app->getLedgerTxnRoot());
auto parellelComputeEntry =
ltx.load(getParallelComputeSettingsLedgerKey())
.current()
.data.configSetting();
REQUIRE(parellelComputeEntry.configSettingID() ==
CONFIG_SETTING_CONTRACT_PARALLEL_COMPUTE_V0);
REQUIRE(parellelComputeEntry.contractParallelCompute()
.ledgerMaxParallelThreads ==
InitialSorobanNetworkConfig::LEDGER_MAX_PARALLEL_THREADS);

// Check that BucketList size window initialized with current BL
// size
auto const& networkConfig =
app->getLedgerManager().getSorobanNetworkConfig();
REQUIRE(networkConfig.ledgerMaxParallelThreads() ==
InitialSorobanNetworkConfig::LEDGER_MAX_PARALLEL_THREADS);
}

// Execute an upgrade.
{
LedgerTxn ltx(app->getLedgerTxnRoot());
auto configUpgradeSet = makeParallelComputeUpdgrade(ltx, 5);
ltx.commit();
executeUpgrade(*app, makeConfigUpgrade(*configUpgradeSet));
}

LedgerTxn ltx(app->getLedgerTxnRoot());

REQUIRE(ltx.load(getParallelComputeSettingsLedgerKey())
.current()
.data.configSetting()
.contractParallelCompute()
.ledgerMaxParallelThreads == 5);
REQUIRE(app->getLedgerManager()
.getSorobanNetworkConfig()
.ledgerMaxParallelThreads() == 5);
}
#endif

TEST_CASE_VERSIONS("upgrade base reserve", "[upgrades]")
{
VirtualClock clock;
Expand Down Expand Up @@ -2584,8 +2729,9 @@ TEST_CASE_VERSIONS("upgrade base reserve", "[upgrades]")
createOffers(sponsoredAcc, offers, sponsoredAccPullOffers);
createOffers(sponsoredAcc2, offers, true);

// prepare ops to transfer sponsorship of all sponsoredAcc
// offers and one offer from sponsoredAcc2 to sponsoringAcc
// prepare ops to transfer sponsorship of all
// sponsoredAcc offers and one offer from sponsoredAcc2
// to sponsoringAcc
std::vector<Operation> ops = {
sponsoringAcc.op(
beginSponsoringFutureReserves(sponsoredAcc)),
Expand Down Expand Up @@ -2622,15 +2768,17 @@ TEST_CASE_VERSIONS("upgrade base reserve", "[upgrades]")

if (sponsoredAccPullOffers)
{
// SponsoringAcc is now sponsoring all 12 of sponsoredAcc's
// offers. SponsoredAcc has 4 subentries. It also has enough
// lumens to cover 12 more subentries after the sponsorship
// update. After the upgrade to double the baseReserve, this
// account will need to cover the 4 subEntries, so we only
// need 4 extra baseReserves before the upgrade. Pay out the
// rest (8 reserves) so we can get our orders pulled on
// upgrade. 16(total reserves) - 4(subEntries) -
// 4(base reserve increase) = 8(extra base reserves)
// SponsoringAcc is now sponsoring all 12 of
// sponsoredAcc's offers. SponsoredAcc has 4
// subentries. It also has enough lumens to cover 12
// more subentries after the sponsorship update.
// After the upgrade to double the baseReserve, this
// account will need to cover the 4 subEntries, so
// we only need 4 extra baseReserves before the
// upgrade. Pay out the rest (8 reserves) so we can
// get our orders pulled on upgrade. 16(total
// reserves) - 4(subEntries) - 4(base reserve
// increase) = 8(extra base reserves)

sponsoredAcc.pay(root, baseReserve * 8);
}
Expand All @@ -2644,8 +2792,8 @@ TEST_CASE_VERSIONS("upgrade base reserve", "[upgrades]")
sponsoringAcc.pay(root, 1);
}

// This account needs to lose a base reserve to get its orders
// pulled
// This account needs to lose a base reserve to get its
// orders pulled
sponsoredAcc2.pay(root, baseReserve);

// execute upgrade
Expand Down Expand Up @@ -2714,8 +2862,8 @@ TEST_CASE_VERSIONS("upgrade base reserve", "[upgrades]")
root.create(sponsoredSeed,
lm.getLastMinBalance(14) + 3999 + 15 * txFee);

// This account will have one sponsored offer and will always
// have it's offers pulled.
// This account will have one sponsored offer and will
// always have it's offers pulled.
auto sponsored2 = root.create(
"C", 2 * lm.getLastMinBalance(13) + 3999 + 15 * txFee);

Expand Down Expand Up @@ -2743,8 +2891,8 @@ TEST_CASE_VERSIONS("upgrade base reserve", "[upgrades]")
};

for_versions_from(14, *app, [&] {
// Swap the seeds to test that the ordering of accounts doesn't
// matter when upgrading
// Swap the seeds to test that the ordering of accounts
// doesn't matter when upgrading
SECTION("account A is sponsored")
{
sponsorshipTestsBySeed("B", "A");
Expand Down Expand Up @@ -3261,8 +3409,8 @@ TEST_CASE("upgrade to generalized tx set in network", "[upgrades][overlay]")
Upgrades::UpgradeParameters upgrades;
upgrades.mProtocolVersion = std::make_optional<uint32>(
static_cast<uint32>(SOROBAN_PROTOCOL_VERSION));
// Upgrade to generalized tx set in 3 ledgers (4 ledgers before update
// is applied).
// Upgrade to generalized tx set in 3 ledgers (4 ledgers before
// update is applied).
upgrades.mUpgradeTime =
lclCloseTime + Herder::EXP_LEDGER_TIMESPAN_SECONDS * 3;
node->getHerder().setUpgrades(upgrades);
Expand Down
Loading

0 comments on commit 9c1ea65

Please sign in to comment.