Skip to content

Commit f25405b

Browse files
Ensure unique preimages during loadgen upgrade setup (#4425)
Currently, loadgen can produce duplicate preimages during `SOROBAN_UPGRADE_SETUP` if metrics have been cleared between `SOROBAN_UPGRADE_SETUP` calls. This scenario causes the setup to fail. This change fixes this by using an internal counter as part of the preimage instead of using medida metrics. # Checklist - [x] Reviewed the [contributing](https://github.com/stellar/stellar-core/blob/master/CONTRIBUTING.md#submitting-changes) document - [x] Rebased on top of master (no merge commits) - [x] Ran `clang-format` v8.0.0 (via `make format` or the Visual Studio extension) - [x] Compiles - [x] Ran all tests - [ ] If change impacts performance, include supporting evidence per the [performance document](https://github.com/stellar/stellar-core/blob/master/performance-eval/performance-eval.md)
2 parents 3c7fb22 + 70f2a87 commit f25405b

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

src/simulation/LoadGenerator.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -1260,11 +1260,8 @@ LoadGenerator::createContractTransaction(uint32_t ledgerNum, uint64_t accountId,
12601260
createResources.readBytes = mContactOverheadBytes;
12611261
createResources.writeBytes = 300;
12621262

1263-
auto salt = sha256(
1264-
std::to_string(mContractInstanceKeys.size()) + "run" +
1265-
std::to_string(mApp.getMetrics()
1266-
.NewMeter({"loadgen", "run", "complete"}, "run")
1267-
.count()));
1263+
auto salt = sha256("upgrade" +
1264+
std::to_string(++mNumCreateContractTransactionCalls));
12681265
auto contractIDPreimage = makeContractIDPreimage(*account, salt);
12691266

12701267
auto tx = makeSorobanCreateContractTx(

src/simulation/LoadGenerator.h

+4
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ class LoadGenerator
327327
int64_t mPreLoadgenApplySorobanSuccess = 0;
328328
int64_t mPreLoadgenApplySorobanFailure = 0;
329329

330+
// Number of times `createContractTransaction` has been called. Used to
331+
// ensure unique preimages for all `SOROBAN_UPGRADE_SETUP` runs.
332+
uint32_t mNumCreateContractTransactionCalls = 0;
333+
330334
bool mFailed{false};
331335
bool mStarted{false};
332336
bool mInitialAccountsCreated{false};

src/simulation/test/LoadGeneratorTests.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -716,3 +716,48 @@ TEST_CASE("Multi-op mixed transactions are valid", "[loadgen]")
716716
REQUIRE(dexOps > 0);
717717
REQUIRE(dexOps + nonDexOps == 3 * 100);
718718
}
719+
720+
TEST_CASE("Upgrade setup with metrics reset", "[loadgen]")
721+
{
722+
// Create a simulation with two nodes
723+
Simulation::pointer sim = Topologies::pair(
724+
Simulation::OVER_LOOPBACK, sha256(getTestConfig().NETWORK_PASSPHRASE));
725+
sim->startAllNodes();
726+
sim->crankUntil([&]() { return sim->haveAllExternalized(3, 1); },
727+
2 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false);
728+
729+
Application::pointer app = sim->getNodes().front();
730+
LoadGenerator& loadgen = app->getLoadGenerator();
731+
medida::Meter& runsComplete =
732+
app->getMetrics().NewMeter({"loadgen", "run", "complete"}, "run");
733+
medida::Meter& runsFailed =
734+
app->getMetrics().NewMeter({"loadgen", "run", "failed"}, "run");
735+
736+
// Add an account
737+
loadgen.generateLoad(GeneratedLoadConfig::createAccountsLoad(
738+
/* nAccounts */ 1, /* txRate */ 1));
739+
sim->crankUntil([&]() { return runsComplete.count() == 1; },
740+
5 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false);
741+
742+
// Clear metrics to reset run count
743+
app->clearMetrics("");
744+
745+
// Setup a soroban limit upgrade that must succeed
746+
GeneratedLoadConfig upgradeSetupCfg =
747+
GeneratedLoadConfig::createSorobanUpgradeSetupLoad();
748+
upgradeSetupCfg.setMinSorobanPercentSuccess(100);
749+
loadgen.generateLoad(upgradeSetupCfg);
750+
sim->crankUntil([&]() { return runsComplete.count() == 1; },
751+
5 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false);
752+
REQUIRE(runsFailed.count() == 0);
753+
754+
// Clear metrics again to reset run count
755+
app->clearMetrics("");
756+
757+
// Setup again. This should succeed even though it's the same account with
758+
// the same `runsComplete` value performing the setup
759+
loadgen.generateLoad(upgradeSetupCfg);
760+
sim->crankUntil([&]() { return runsComplete.count() == 1; },
761+
5 * Herder::EXP_LEDGER_TIMESPAN_SECONDS, false);
762+
REQUIRE(runsFailed.count() == 0);
763+
}

0 commit comments

Comments
 (0)