Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions doc/missions.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ Simulate Public Network topology and throughput based on user-supplied distribut

Stress test a network of simulated Tier1 topology with classic traffic and report maximum achieved throughput.

### Parameters

- `--disable-trigger-timer`: Disable `EXPERIMENTAL_TRIGGER_TIMER` on all nodes. The trigger timer is enabled by default.

## MissionSorobanLoadGeneration

Test heavy Soroban load on a large network of nodes. This mission mostly focuses on high-bandwidth traffic, and its impact on SCP and overlay. Apply time is simulated to avoid noise from database backends.
Expand Down Expand Up @@ -159,6 +163,21 @@ Find the minimum ledger target close time a simulated Tier1 network can sustain

Same as `MissionMinBlockTimeClassic`, but drives an explicit `MIXED_PREGEN_*` overlay-only loadgen mode with pre-generated classic payments plus a selected synthetic Soroban transaction type.

## MissionTriggerTimerMixConsensus

Tests the `EXPERIMENTAL_TRIGGER_TIMER` feature on a simulated Public Network topology with a configurable mix of nodes that have the flag enabled versus disabled, under configurable clock-drift distributions. It drives the same `MIXED_PREGEN_*` (classic + synthetic Soroban) overlay-only load as `MissionMinBlockTimeMixed`, but instead of binary-searching for a minimum block time it runs a single load pass at a fixed ledger close time and verifies consensus stays healthy (no errors, pairwise-consistent, all nodes in sync). Requires a generated pubnet topology via `--pubnet-data`.

### Parameters

- `--trigger-timer-flag-pct`: Percentage (0-100) of nodes with `EXPERIMENTAL_TRIGGER_TIMER` enabled. Default 100.
- `--drift-pct`: Percentage (0-100) of nodes that receive clock drift. Default 0.
- `--uniform-drift=lower,upper`: Uniform random clock drift, in signed ms, applied to each drifting node (e.g. `--uniform-drift=-2000,+2000`).
- `--bimodal-drift=min1,max1,min2,max2`: Bimodal clock drift, in signed ms — the first half of the drifting nodes draw from `[min1,max1]`, the second half from `[min2,max2]` (e.g. `--bimodal-drift=-5000,-2000,+2000,+5000`).
- `--ledger-close-time-ms`: Target ledger close time in ms, upgraded before load is applied. Default 5000.
- `--min-block-time-mixed-mode`: The `MIXED_PREGEN_*` loadgen mode to drive. Default `mixed_pregen_sac_payment`.
- `--classic-tx-rate`: Classic TPS. Defaults to half of `--tx-rate`.
- `--soroban-tx-rate`: Soroban TPS. Defaults to half of `--tx-rate`.

## MissionMixedNominationLeaderElectionWithOldMajority

Run a network with a mix of nodes running the old and new nomination leader election algorithms. Contains a majority of nodes running the old algorithm.
Expand Down
51 changes: 49 additions & 2 deletions src/App/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ type MissionOptions
maxBlockTimeMs: int,
minBlockTimeMixedMode: string,
minBlockTimeMixedClassicTxRate: int option,
minBlockTimeMixedSorobanTxRate: int option
minBlockTimeMixedSorobanTxRate: int option,
triggerTimerFlagPct: int,
uniformDrift: seq<int>,
bimodalDrift: seq<int>,
driftPct: int,
ledgerCloseTimeMs: int option,
disableTriggerTimer: bool
) =

[<Option('k', "kubeconfig", HelpText = "Kubernetes config file", Required = false, Default = "~/.kube/config")>]
Expand Down Expand Up @@ -631,6 +637,41 @@ type MissionOptions
Required = false)>]
member self.MinBlockTimeMixedSorobanTxRate = minBlockTimeMixedSorobanTxRate

[<Option("trigger-timer-flag-pct",
HelpText = "Percentage (0-100) of nodes with EXPERIMENTAL_TRIGGER_TIMER enabled",
Required = false,
Default = 100)>]
member self.TriggerTimerFlagPct = triggerTimerFlagPct

[<Option("uniform-drift",
Separator = ',',
HelpText = "Uniform clock drift range in signed ms: --uniform-drift=lower,upper (e.g. --uniform-drift=-2000,+2000)",
Required = false)>]
member self.UniformDrift = uniformDrift

[<Option("bimodal-drift",
Separator = ',',
HelpText = "Bimodal clock drift ranges in signed ms: --bimodal-drift=min1,max1,min2,max2 (e.g. --bimodal-drift=-5000,-2000,+2000,+5000)",
Required = false)>]
member self.BimodalDrift = bimodalDrift

[<Option("drift-pct",
HelpText = "Percentage (0-100) of nodes that receive clock drift",
Required = false,
Default = 0)>]
member self.DriftPct = driftPct

[<Option("ledger-close-time-ms",
HelpText = "Target ledger close time (ms) upgraded before applying load in TriggerTimerMixConsensus (default 5000)",
Required = false)>]
member self.LedgerCloseTimeMs = ledgerCloseTimeMs

[<Option("disable-trigger-timer",
HelpText = "Disable EXPERIMENTAL_TRIGGER_TIMER on all nodes in MaxTPSClassic (default: enabled)",
Required = false,
Default = false)>]
member self.DisableTriggerTimer = disableTriggerTimer
Comment on lines +669 to +673

let splitLabel (lab: string) : (string * string option) =
match lab.Split ':' |> Array.toList with
| [ x ] -> x, None
Expand Down Expand Up @@ -869,7 +910,13 @@ let main argv =
minBlockTimeMixedMode = mission.MinBlockTimeMixedMode
minBlockTimeMixedClassicTxRate = mission.MinBlockTimeMixedClassicTxRate
minBlockTimeMixedSorobanTxRate = mission.MinBlockTimeMixedSorobanTxRate
runForMinBlockTime = false }
runForMinBlockTime = false
triggerTimerFlagPct = mission.TriggerTimerFlagPct
uniformDrift = List.ofSeq mission.UniformDrift
bimodalDrift = List.ofSeq mission.BimodalDrift
driftPct = mission.DriftPct
ledgerCloseTimeMs = mission.LedgerCloseTimeMs
enableTriggerTimer = not mission.DisableTriggerTimer }

allMissions.[m] missionContext

Expand Down
8 changes: 7 additions & 1 deletion src/FSLibrary.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,13 @@ let ctx : MissionContext =
minBlockTimeMixedMode = "mixed_pregen_sac_payment"
minBlockTimeMixedClassicTxRate = None
minBlockTimeMixedSorobanTxRate = None
runForMinBlockTime = false }
runForMinBlockTime = false
triggerTimerFlagPct = 100
uniformDrift = []
bimodalDrift = []
driftPct = 0
ledgerCloseTimeMs = None
enableTriggerTimer = true }

let netdata = __SOURCE_DIRECTORY__ + "/../../../data/public-network-data-2024-08-01.json"
let pubkeys = __SOURCE_DIRECTORY__ + "/../../../data/tier1keys.json"
Expand Down
1 change: 1 addition & 0 deletions src/FSLibrary/FSLibrary.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<Compile Include="MinBlockTimeTest.fs" />
<Compile Include="MissionMinBlockTimeClassic.fs" />
<Compile Include="MissionMinBlockTimeMixed.fs" />
<Compile Include="MissionTriggerTimerMixConsensus.fs" />
<Compile Include="StellarMission.fs" />
</ItemGroup>
<ItemGroup>
Expand Down
10 changes: 9 additions & 1 deletion src/FSLibrary/MaxTPSTest.fs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ let upgradeSorobanLedgerLimits
peer.WaitForLedgerMaxTxCount multiplier


let maxTPSTest (context: MissionContext) (baseLoadGen: LoadGen) (setupCfg: LoadGen option) =
let maxTPSTest (context: MissionContext) (baseLoadGen: LoadGen) (setupCfg: LoadGen option) (enableTriggerTimer: bool) =
let allNodes =
if context.pubnetData.IsSome then
FullPubnetCoreSets context true false
Expand All @@ -133,6 +133,14 @@ let maxTPSTest (context: MissionContext) (baseLoadGen: LoadGen) (setupCfg: LoadG
context.image
(if context.flatQuorum.IsSome then context.flatQuorum.Value else false)

let allNodes =
if enableTriggerTimer then
allNodes
|> List.map
(fun (cs: CoreSet) -> { cs with options = { cs.options with experimentalTriggerTimer = Some true } })
else
allNodes

// PayPregenerated requires node restart between failed iterations to ensure validity of the pregenerated transactions
// However, large-scale simulation restarts can be slow, so for now only use the new mode on small networks
let baseLoadGen =
Expand Down
10 changes: 7 additions & 3 deletions src/FSLibrary/MinBlockTimeTest.fs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ let private maxTxSetSizeForTarget (kind: string) (targetMs: int) (txRate: int) =

max (int txSetSize) 100

let private classicMaxTxSetSizeForTarget (targetMs: int) (classicTxRate: int) =
// Exposed for reuse by MissionTriggerTimerMixConsensus, which runs the same
// MIXED_PREGEN_* load without the binary search.
let classicMaxTxSetSizeForTarget (targetMs: int) (classicTxRate: int) =
maxTxSetSizeForTarget "Classic" targetMs classicTxRate

let private sorobanMaxTxSetSizeForTarget (targetMs: int) (sorobanTxRate: int) =
Expand Down Expand Up @@ -139,7 +141,8 @@ let private waitForMixedPregenSorobanLimits (peer: Peer) (limits: MixedPregenSor
&& info.Tx.MaxContractEventsSizeBytes = limits.txMaxContractEventsSizeBytes)
(fun _ -> LogInfo "Waiting for MIXED_PREGEN_* Soroban limits on %s" peer.ShortName.StringName)

let private upgradeMixedPregenSorobanLimits
// Exposed for reuse by MissionTriggerTimerMixConsensus.
let upgradeMixedPregenSorobanLimits
(formation: StellarFormation)
(coreSets: CoreSet list)
(baseLoadGen: LoadGen)
Expand Down Expand Up @@ -227,7 +230,8 @@ let private toggleOverlayOnlyMode (formation: StellarFormation) (coreSets: CoreS
let res = peer.ToggleOverlayOnlyMode()
LogInfo "Toggled overlay-only mode on %s: %s" peer.ShortName.StringName res)

let private withOverlayOnlyMode (formation: StellarFormation) (coreSets: CoreSet list) (f: unit -> unit) =
// Exposed for reuse by MissionTriggerTimerMixConsensus.
let withOverlayOnlyMode (formation: StellarFormation) (coreSets: CoreSet list) (f: unit -> unit) =
LogInfo "Enabling overlay-only mode"
toggleOverlayOnlyMode formation coreSets

Expand Down
2 changes: 1 addition & 1 deletion src/FSLibrary/MissionMaxTPSClassic.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ let maxTPSClassic (context: MissionContext) =
maxfeerate = None
skiplowfeetxs = false }

maxTPSTest context baseLoadGen None
maxTPSTest context baseLoadGen None context.enableTriggerTimer
2 changes: 1 addition & 1 deletion src/FSLibrary/MissionMaxTPSMixed.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ let maxTPSMixed (baseContext: MissionContext) =

let invokeSetupCfg = { baseLoadGen with mode = SorobanInvokeSetup }

maxTPSTest context baseLoadGen (Some invokeSetupCfg)
maxTPSTest context baseLoadGen (Some invokeSetupCfg) false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why disable trigger timer in MaxTPSMixed?

Loading
Loading