Skip to content

Commit 73a08a8

Browse files
Merge pull request #383 from marta-lokhova/loadgenSplit
Split load across nodes more evenly, useful for low tps configs
2 parents a19ce86 + 008f5c7 commit 73a08a8

2 files changed

Lines changed: 35 additions & 26 deletions

File tree

src/FSLibrary/MinBlockTimeTest.fs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ let private smallNetworkSize = 10
2222

2323
let private searchThresholdMs = 100
2424

25-
let private protocolMaxBlockTimeMs = 5000
26-
2725
let private timeoutsFor (targetMs: int) : int = max 500 (targetMs / 5)
2826

2927
let private mixedPregenLedgerMultiplier = 15
@@ -315,7 +313,7 @@ let minBlockTimeTest (context: MissionContext) (baseLoadGen: LoadGen) (setupCfg:
315313
formation.ManualClose coreSets
316314
formation.WaitUntilSynced coreSets
317315
formation.UpgradeProtocolToLatest coreSets
318-
formation.UpgradeMaxTxSetSize coreSets (classicTxRateForLimits * 10)
316+
formation.UpgradeMaxTxSetSize coreSets (max (classicTxRateForLimits * mixedPregenLedgerMultiplier) 100)
319317

320318
if isMixedPregenMode baseLoadGen.mode then
321319
upgradeMixedPregenSorobanLimits formation coreSets baseLoadGen
@@ -363,34 +361,26 @@ let minBlockTimeTest (context: MissionContext) (baseLoadGen: LoadGen) (setupCfg:
363361
txs = fixedTxRate * 300
364362
txrate = fixedTxRate }
365363

366-
// Both the SCP upgrade (which runs a small arming loadgen) and
367-
// the measurement load can fail when the network is still
368-
// degraded from a previous iteration; either case is an SLA
369-
// miss, not a crash.
370-
try
371-
applySCPUpgrade targetMs
372-
formation.clearMetrics allNodes
364+
applySCPUpgrade targetMs
365+
formation.clearMetrics allNodes
373366

367+
// A loadgen failure is not an SLA signal — it usually means the
368+
// requested TPS is too high for the network, or that loadgen
369+
// itself lost a tx in the pipeline. Treating it as "SLA missed"
370+
// would mislead the binary search, so fail the mission loudly.
371+
try
374372
if isMixedPregenMode baseLoadGen.mode then
375373
withOverlayOnlyMode
376374
formation
377375
allNodes
378376
(fun () -> formation.RunMultiLoadgen activeLoadGenNodes loadGen)
379377
else
380378
formation.RunMultiLoadgen activeLoadGenNodes loadGen
379+
with e -> failwithf "Loadgen failed at T=%dms; TPS might be too high (%s)" targetMs e.Message
381380

382-
formation.CheckNoErrorsAndPairwiseConsistency()
383-
formation.EnsureAllNodesInSync allNodes
384-
checkLedgerAgeSLA formation allNodes targetMs
385-
with e ->
386-
LogInfo "Run errored at T=%dms: %s" targetMs e.Message
387-
false
388-
389-
if context.maxBlockTimeMs > protocolMaxBlockTimeMs then
390-
failwithf
391-
"--max-block-time-ms=%d exceeds the protocol cap (%d ms); validators will reject such upgrades"
392-
context.maxBlockTimeMs
393-
protocolMaxBlockTimeMs
381+
formation.CheckNoErrorsAndPairwiseConsistency()
382+
formation.EnsureAllNodesInSync allNodes
383+
checkLedgerAgeSLA formation allNodes targetMs
394384

395385
if context.minBlockTimeMs >= context.maxBlockTimeMs then
396386
failwithf

src/FSLibrary/StellarStatefulSets.fs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,16 +409,35 @@ type StellarFormation with
409409
let n = List.length coreSets
410410

411411
let fractionalLoadGen (i: int) : LoadGen =
412-
let getFraction attr = if i + 1 = n then (attr / n + attr % n) else attr / n
412+
// Spread remainder across the first r nodes instead of dumping it
413+
// entirely on the last one, so per-node load stays even.
414+
let getFraction attr =
415+
let q = attr / n
416+
let r = attr % n
417+
if i < r then q + 1 else q
418+
413419
let getOptionalFraction attr = Option.map getFraction attr
414420

421+
let classicShare = getOptionalFraction fullLoadGen.classicTxRate
422+
let sorobanShare = getOptionalFraction fullLoadGen.sorobanTxRate
423+
424+
// In mixed mode derive txrate from the component rates so that
425+
// txrate, classicTxRate, and sorobanTxRate stay consistent on
426+
// every peer (independent splits would diverge by 1 per slice).
427+
let txrateShare =
428+
match classicShare, sorobanShare with
429+
| Some c, Some s -> c + s
430+
| Some c, None -> c
431+
| None, Some s -> s
432+
| None, None -> getFraction fullLoadGen.txrate
433+
415434
{ fullLoadGen with
416435
accounts = fullLoadGen.accounts / n
417436
txs = fullLoadGen.txs / n
418437
spikesize = getFraction fullLoadGen.spikesize
419-
txrate = getFraction fullLoadGen.txrate
420-
classicTxRate = getOptionalFraction fullLoadGen.classicTxRate
421-
sorobanTxRate = getOptionalFraction fullLoadGen.sorobanTxRate }
438+
txrate = txrateShare
439+
classicTxRate = classicShare
440+
sorobanTxRate = sorobanShare }
422441

423442
let hasNonZeroRate (loadGen: LoadGen) =
424443
match loadGen.classicTxRate, loadGen.sorobanTxRate with

0 commit comments

Comments
 (0)