From 94daed85daf2cd922312cadeec10fe91d8d6b0ad Mon Sep 17 00:00:00 2001 From: Julian Meyer Date: Tue, 24 Feb 2026 17:32:00 +0000 Subject: [PATCH] fix: flashblock and block time settings --- benchmark/flags/flags.go | 36 +++++++++--------- runner/benchmark/benchmark.go | 7 ++-- runner/benchmark/definition.go | 28 ++++++++++++++ runner/benchmark/matrix.go | 6 +++ runner/benchmark/matrix_test.go | 11 +++--- runner/clients/builder/client.go | 7 ++++ runner/clients/types/types.go | 10 +++-- runner/network/configutil/rollup_config.go | 6 +-- .../network/consensus/sequencer_consensus.go | 1 + runner/network/fault_proof_benchmark.go | 4 +- runner/network/network_benchmark.go | 38 ++++++++++--------- runner/network/sequencer_benchmark.go | 3 +- runner/network/validator_benchmark.go | 3 +- runner/service.go | 6 +-- 14 files changed, 108 insertions(+), 58 deletions(-) diff --git a/benchmark/flags/flags.go b/benchmark/flags/flags.go index 8f86508b..d719daaf 100644 --- a/benchmark/flags/flags.go +++ b/benchmark/flags/flags.go @@ -15,16 +15,16 @@ func prefixEnvVars(name string) []string { } const ( - ConfigFlagName = "config" - RootDirFlagName = "root-dir" - OutputDirFlagName = "output-dir" - TxFuzzBinFlagName = "tx-fuzz-bin" - ProxyPortFlagName = "proxy-port" - BenchmarkRunIDFlagName = "benchmark-run-id" - MachineTypeFlagName = "machine-type" - MachineProviderFlagName = "machine-provider" - MachineRegionFlagName = "machine-region" - FileSystemFlagName = "file-system" + ConfigFlagName = "config" + RootDirFlagName = "root-dir" + OutputDirFlagName = "output-dir" + TxFuzzBinFlagName = "tx-fuzz-bin" + ProxyPortFlagName = "proxy-port" + BenchmarkRunIDFlagName = "benchmark-run-id" + MachineTypeFlagName = "machine-type" + MachineProviderFlagName = "machine-provider" + MachineRegionFlagName = "machine-region" + FileSystemFlagName = "file-system" ParallelTxBatchesFlagName = "parallel-tx-batches" ) @@ -42,17 +42,17 @@ var ( } RootDirFlag = &cli.StringFlag{ - Name: RootDirFlagName, - Usage: "Root Directory", - EnvVars: prefixEnvVars("ROOT_DIR"), - Required: true, + Name: RootDirFlagName, + Usage: "Root Directory", + EnvVars: prefixEnvVars("ROOT_DIR"), + Value: "./data-dir", } OutputDirFlag = &cli.StringFlag{ - Name: OutputDirFlagName, - Usage: "Output Directory", - EnvVars: prefixEnvVars("OUTPUT_DIR"), - Required: true, + Name: OutputDirFlagName, + Usage: "Output Directory", + Value: "./output", + EnvVars: prefixEnvVars("OUTPUT_DIR"), } TxFuzzBinFlag = &cli.StringFlag{ diff --git a/runner/benchmark/benchmark.go b/runner/benchmark/benchmark.go index 135e5463..3af1efcd 100644 --- a/runner/benchmark/benchmark.go +++ b/runner/benchmark/benchmark.go @@ -7,7 +7,6 @@ import ( "os" "strings" "sync/atomic" - "time" "github.com/base/base-bench/runner/network/types" "github.com/ethereum/go-ethereum/core" @@ -29,9 +28,9 @@ const ( ) var DefaultParams = &types.RunParams{ - NodeType: "geth", - GasLimit: 50e9, - BlockTime: 1 * time.Second, + NodeType: "geth", + GasLimit: 50e9, + // BlockTime is set from the top-level block_time config in ResolveTestRunsFromMatrix. } // NewParamsFromValues constructs a new benchmark params given a config and a set of transaction payloads to run. diff --git a/runner/benchmark/definition.go b/runner/benchmark/definition.go index 0b869747..e255c94d 100644 --- a/runner/benchmark/definition.go +++ b/runner/benchmark/definition.go @@ -8,6 +8,7 @@ import ( "path" "path/filepath" "strings" + "time" "github.com/base/base-bench/runner/payload" ) @@ -87,13 +88,40 @@ func (s SnapshotDefinition) CreateSnapshot(nodeType string, outputDir string) er return cmd.Run() } +// FlashblocksConfig holds top-level flashblocks configuration. +type FlashblocksConfig struct { + BlockTime string `yaml:"block_time"` +} + +const DefaultFlashblocksBlockTime = "250ms" +const DefaultBlockTime = "1s" + type BenchmarkConfig struct { Name string `yaml:"name"` Description *string `yaml:"description"` + BlockTime *string `yaml:"block_time"` + Flashblocks *FlashblocksConfig `yaml:"flashblocks"` Benchmarks []TestDefinition `yaml:"benchmarks"` TransactionPayloads []payload.Definition `yaml:"payloads"` } +// GetBlockTime returns the configured block time as a duration, or the default (1s). +func (bc *BenchmarkConfig) GetBlockTime() (time.Duration, error) { + raw := DefaultBlockTime + if bc.BlockTime != nil && *bc.BlockTime != "" { + raw = *bc.BlockTime + } + return time.ParseDuration(raw) +} + +// FlashblocksBlockTime returns the configured flashblocks block time, or the default. +func (bc *BenchmarkConfig) FlashblocksBlockTime() string { + if bc.Flashblocks != nil && bc.Flashblocks.BlockTime != "" { + return bc.Flashblocks.BlockTime + } + return DefaultFlashblocksBlockTime +} + type DatadirConfig struct { Sequencer *string `yaml:"sequencer"` Validator *string `yaml:"validator"` diff --git a/runner/benchmark/matrix.go b/runner/benchmark/matrix.go index bfdc8d6c..430aa892 100644 --- a/runner/benchmark/matrix.go +++ b/runner/benchmark/matrix.go @@ -47,6 +47,11 @@ func NewTestPlanFromConfig(c TestDefinition, testFileName string, config *Benchm // ResolveTestRunsFromMatrix constructs a new ParamsMatrix from a config. func ResolveTestRunsFromMatrix(c TestDefinition, testFileName string, config *BenchmarkConfig) ([]TestRun, error) { + blockTime, err := config.GetBlockTime() + if err != nil { + return nil, fmt.Errorf("invalid block_time: %w", err) + } + seenParams := make(map[string]bool) // Multiple payloads can run in a single benchmark. @@ -107,6 +112,7 @@ func ResolveTestRunsFromMatrix(c TestDefinition, testFileName string, config *Be return nil, err } + params.BlockTime = blockTime params.Name = config.Name if config.Description != nil { params.Description = *config.Description diff --git a/runner/benchmark/matrix_test.go b/runner/benchmark/matrix_test.go index d4d822aa..5440dccf 100644 --- a/runner/benchmark/matrix_test.go +++ b/runner/benchmark/matrix_test.go @@ -2,6 +2,7 @@ package benchmark_test import ( "testing" + "time" "github.com/base/base-bench/runner/benchmark" "github.com/base/base-bench/runner/network/types" @@ -31,7 +32,7 @@ func TestResolveTestRunsFromMatrix(t *testing.T) { NodeType: "geth", PayloadID: "simple", GasLimit: benchmark.DefaultParams.GasLimit, - BlockTime: benchmark.DefaultParams.BlockTime, + BlockTime: 1 * time.Second, }, }, }, @@ -57,7 +58,7 @@ func TestResolveTestRunsFromMatrix(t *testing.T) { NodeType: "geth", GasLimit: benchmark.DefaultParams.GasLimit, PayloadID: "simple", - BlockTime: benchmark.DefaultParams.BlockTime, + BlockTime: 1 * time.Second, }, }, { @@ -65,7 +66,7 @@ func TestResolveTestRunsFromMatrix(t *testing.T) { NodeType: "erigon", GasLimit: benchmark.DefaultParams.GasLimit, PayloadID: "simple", - BlockTime: benchmark.DefaultParams.BlockTime, + BlockTime: 1 * time.Second, }, }, { @@ -73,7 +74,7 @@ func TestResolveTestRunsFromMatrix(t *testing.T) { NodeType: "geth", GasLimit: benchmark.DefaultParams.GasLimit, PayloadID: "complex", - BlockTime: benchmark.DefaultParams.BlockTime, + BlockTime: 1 * time.Second, }, }, { @@ -81,7 +82,7 @@ func TestResolveTestRunsFromMatrix(t *testing.T) { NodeType: "erigon", GasLimit: benchmark.DefaultParams.GasLimit, PayloadID: "complex", - BlockTime: benchmark.DefaultParams.BlockTime, + BlockTime: 1 * time.Second, }, }, }, diff --git a/runner/clients/builder/client.go b/runner/clients/builder/client.go index 660b41a1..578947a6 100644 --- a/runner/clients/builder/client.go +++ b/runner/clients/builder/client.go @@ -49,6 +49,13 @@ func (r *BuilderClient) Run(ctx context.Context, cfg *types.RuntimeConfig) error cfg2 := *cfg cfg2.Args = append(cfg2.Args, "--flashblocks.port", fmt.Sprintf("%d", r.websocketPort)) + cfg2.Args = append(cfg2.Args, "--flashblocks.fixed") + if cfg.FlashblocksBlockTime != "" { + cfg2.Args = append(cfg2.Args, "--flashblocks.block-time", cfg.FlashblocksBlockTime) + } + if cfg.BlockTimeMs > 0 { + cfg2.Args = append(cfg2.Args, "--rollup.chain-block-time", fmt.Sprintf("%d", cfg.BlockTimeMs)) + } err := r.elClient.Run(ctx, &cfg2) if err != nil { return err diff --git a/runner/clients/types/types.go b/runner/clients/types/types.go index f7f7e882..00cd6efc 100644 --- a/runner/clients/types/types.go +++ b/runner/clients/types/types.go @@ -10,10 +10,12 @@ import ( ) type RuntimeConfig struct { - Stdout io.WriteCloser - Stderr io.WriteCloser - Args []string - FlashblocksURL *string // Optional URL for flashblocks websocket server (only used by clients that support it) + Stdout io.WriteCloser + Stderr io.WriteCloser + Args []string + FlashblocksURL *string // Optional URL for flashblocks websocket server (only used by clients that support it) + FlashblocksBlockTime string // Block time for flashblocks (e.g. "250ms") + BlockTimeMs uint64 // L2 block time in milliseconds } // ExecutionClient is an abstraction over the different clients that can be used to run the chain like diff --git a/runner/network/configutil/rollup_config.go b/runner/network/configutil/rollup_config.go index ea55c767..150f172e 100644 --- a/runner/network/configutil/rollup_config.go +++ b/runner/network/configutil/rollup_config.go @@ -12,8 +12,8 @@ import ( "github.com/ethereum/go-ethereum/params" ) -// GetRollupConfig creates a rollup configuration for the given genesis and chain -func GetRollupConfig(genesis *core.Genesis, chain fakel1.L1Chain, batcherAddr common.Address) *rollup.Config { +// GetRollupConfig creates a rollup configuration for the given genesis, chain, and block time (in seconds). +func GetRollupConfig(genesis *core.Genesis, chain fakel1.L1Chain, batcherAddr common.Address, blockTimeSec uint64) *rollup.Config { var eipParams eth.Bytes8 copy(eipParams[:], eip1559.EncodeHolocene1559Params(50, 1)) @@ -50,7 +50,7 @@ func GetRollupConfig(genesis *core.Genesis, chain fakel1.L1Chain, batcherAddr co }), }, }, - BlockTime: 1, + BlockTime: blockTimeSec, MaxSequencerDrift: 20, SeqWindowSize: 24, L1ChainID: big.NewInt(1), diff --git a/runner/network/consensus/sequencer_consensus.go b/runner/network/consensus/sequencer_consensus.go index 6b62f967..661bb5fa 100644 --- a/runner/network/consensus/sequencer_consensus.go +++ b/runner/network/consensus/sequencer_consensus.go @@ -289,6 +289,7 @@ func (f *SequencerConsensusClient) Propose(ctx context.Context, blockMetrics *me blockMetrics.AddExecutionMetric(networktypes.UpdateForkChoiceLatencyMetric, duration) f.currentPayloadID = payloadID + f.log.Info("Waiting for block time", "block_time", f.options.BlockTime) // wait block time time.Sleep(f.options.BlockTime) diff --git a/runner/network/fault_proof_benchmark.go b/runner/network/fault_proof_benchmark.go index b762ad99..7f1625ac 100644 --- a/runner/network/fault_proof_benchmark.go +++ b/runner/network/fault_proof_benchmark.go @@ -43,8 +43,8 @@ type opProgramBenchmark struct { rollupCfg *rollup.Config } -func NewOPProgramBenchmark(genesis *core.Genesis, log log.Logger, opProgramBin string, l2RPCURL string, l1Chain fakel1.L1Chain, batcherKey *ecdsa.PrivateKey) ProofProgramBenchmark { - rollupCfg := configutil.GetRollupConfig(genesis, l1Chain, crypto.PubkeyToAddress(batcherKey.PublicKey)) +func NewOPProgramBenchmark(genesis *core.Genesis, log log.Logger, opProgramBin string, l2RPCURL string, l1Chain fakel1.L1Chain, batcherKey *ecdsa.PrivateKey, blockTimeSec uint64) ProofProgramBenchmark { + rollupCfg := configutil.GetRollupConfig(genesis, l1Chain, crypto.PubkeyToAddress(batcherKey.PublicKey), blockTimeSec) batcher := proofprogram.NewBatcher(rollupCfg, batcherKey, l1Chain) return &opProgramBenchmark{ diff --git a/runner/network/network_benchmark.go b/runner/network/network_benchmark.go index 53246b3f..2bf13775 100644 --- a/runner/network/network_benchmark.go +++ b/runner/network/network_benchmark.go @@ -44,20 +44,22 @@ type NetworkBenchmark struct { testConfig *benchtypes.TestConfig proofConfig *benchmark.ProofProgramOptions - transactionPayload payload.Definition - ports portmanager.PortManager + transactionPayload payload.Definition + ports portmanager.PortManager + flashblocksBlockTime string } // NewNetworkBenchmark creates a new network benchmark and initializes the payload worker and consensus client -func NewNetworkBenchmark(config *benchtypes.TestConfig, log log.Logger, sequencerOptions *config.InternalClientOptions, validatorOptions *config.InternalClientOptions, proofConfig *benchmark.ProofProgramOptions, transactionPayload payload.Definition, ports portmanager.PortManager) (*NetworkBenchmark, error) { +func NewNetworkBenchmark(config *benchtypes.TestConfig, log log.Logger, sequencerOptions *config.InternalClientOptions, validatorOptions *config.InternalClientOptions, proofConfig *benchmark.ProofProgramOptions, transactionPayload payload.Definition, ports portmanager.PortManager, flashblocksBlockTime string) (*NetworkBenchmark, error) { return &NetworkBenchmark{ - log: log, - sequencerOptions: sequencerOptions, - validatorOptions: validatorOptions, - testConfig: config, - proofConfig: proofConfig, - transactionPayload: transactionPayload, - ports: ports, + log: log, + sequencerOptions: sequencerOptions, + validatorOptions: validatorOptions, + testConfig: config, + proofConfig: proofConfig, + transactionPayload: transactionPayload, + ports: ports, + flashblocksBlockTime: flashblocksBlockTime, }, nil } @@ -88,7 +90,7 @@ func (nb *NetworkBenchmark) Run(ctx context.Context) error { } func (nb *NetworkBenchmark) benchmarkSequencer(ctx context.Context, l1Chain *l1Chain) (*benchtypes.PayloadResult, uint64, types.ExecutionClient, error) { - sequencerClient, err := setupNode(ctx, nb.log, nb.testConfig.Params.NodeType, nb.testConfig.Params, nb.sequencerOptions, nb.ports, "") + sequencerClient, err := setupNode(ctx, nb.log, nb.testConfig.Params.NodeType, nb.testConfig.Params, nb.sequencerOptions, nb.ports, "", nb.flashblocksBlockTime) if err != nil { return nil, 0, nil, fmt.Errorf("failed to setup sequencer node: %w", err) } @@ -158,7 +160,7 @@ func (nb *NetworkBenchmark) benchmarkValidator(ctx context.Context, payloadResul validatorNodeType = nb.testConfig.Params.NodeType } - validatorClient, err := setupNode(ctx, nb.log, validatorNodeType, nb.testConfig.Params, nb.validatorOptions, nb.ports, flashblockServerURL) + validatorClient, err := setupNode(ctx, nb.log, validatorNodeType, nb.testConfig.Params, nb.validatorOptions, nb.ports, flashblockServerURL, nb.flashblocksBlockTime) if err != nil { sequencerClient.Stop() return fmt.Errorf("failed to setup validator node: %w", err) @@ -253,7 +255,7 @@ func (nb *NetworkBenchmark) GetResult() (*benchmark.RunResult, error) { }, nil } -func setupNode(ctx context.Context, l log.Logger, nodeTypeStr string, params benchtypes.RunParams, options *config.InternalClientOptions, portManager portmanager.PortManager, flashblockServerURL string) (types.ExecutionClient, error) { +func setupNode(ctx context.Context, l log.Logger, nodeTypeStr string, params benchtypes.RunParams, options *config.InternalClientOptions, portManager portmanager.PortManager, flashblockServerURL string, flashblocksBlockTime string) (types.ExecutionClient, error) { if options == nil { return nil, errors.New("client options cannot be nil") } @@ -293,10 +295,12 @@ func setupNode(ctx context.Context, l log.Logger, nodeTypeStr string, params ben } runtimeConfig := &types.RuntimeConfig{ - Stdout: stdoutLogger, - Stderr: stderrLogger, - Args: args, - FlashblocksURL: flashblocksURLPtr, + Stdout: stdoutLogger, + Stderr: stderrLogger, + Args: args, + FlashblocksURL: flashblocksURLPtr, + FlashblocksBlockTime: flashblocksBlockTime, + BlockTimeMs: uint64(params.BlockTime.Milliseconds()), } if err := client.Run(ctx, runtimeConfig); err != nil { diff --git a/runner/network/sequencer_benchmark.go b/runner/network/sequencer_benchmark.go index 536ad1aa..19f3c781 100644 --- a/runner/network/sequencer_benchmark.go +++ b/runner/network/sequencer_benchmark.go @@ -259,7 +259,8 @@ func (nb *sequencerBenchmark) Run(ctx context.Context, metricsCollector metrics. return } - time.Sleep(1000 * time.Millisecond) + log.Info("Sleeping for block time", "block_time", params.BlockTime) + time.Sleep(time.Duration(params.BlockTime) * time.Second) err = metricsCollector.Collect(benchmarkCtx, blockMetrics) if err != nil { diff --git a/runner/network/validator_benchmark.go b/runner/network/validator_benchmark.go index cf5e5880..b3e397fb 100644 --- a/runner/network/validator_benchmark.go +++ b/runner/network/validator_benchmark.go @@ -53,7 +53,8 @@ func (vb *validatorBenchmark) benchmarkFaultProofProgram(ctx context.Context, pa return fmt.Errorf("proof program binary does not exist at %s", binaryPath) } - opProgramBenchmark := NewOPProgramBenchmark(&vb.config.Genesis, vb.log, binaryPath, vb.validatorClient.ClientURL(), l1Chain, batcherKey) + blockTimeSec := uint64(vb.config.Params.BlockTime.Seconds()) + opProgramBenchmark := NewOPProgramBenchmark(&vb.config.Genesis, vb.log, binaryPath, vb.validatorClient.ClientURL(), l1Chain, batcherKey, blockTimeSec) return opProgramBenchmark.Run(ctx, payloads, lastSetupBlock) } diff --git a/runner/service.go b/runner/service.go index 7be227f9..473a7a7f 100644 --- a/runner/service.go +++ b/runner/service.go @@ -320,7 +320,7 @@ func (s *service) setupBlobsDir(workingDir string) error { return nil } -func (s *service) runTest(ctx context.Context, params types.RunParams, workingDir string, outputDir string, snapshotConfig *benchmark.SnapshotDefinition, proofConfig *benchmark.ProofProgramOptions, transactionPayload payload.Definition, datadirsConfig *benchmark.DatadirConfig) (*benchmark.RunResult, error) { +func (s *service) runTest(ctx context.Context, params types.RunParams, workingDir string, outputDir string, snapshotConfig *benchmark.SnapshotDefinition, proofConfig *benchmark.ProofProgramOptions, transactionPayload payload.Definition, datadirsConfig *benchmark.DatadirConfig, flashblocksBlockTime string) (*benchmark.RunResult, error) { s.log.Info(fmt.Sprintf("Running benchmark with params: %+v", params)) @@ -384,7 +384,7 @@ func (s *service) runTest(ctx context.Context, params types.RunParams, workingDi } // Run benchmark - benchmark, err := network.NewNetworkBenchmark(config, s.log, sequencerOptions, validatorOptions, proofConfig, transactionPayload, s.portState) + benchmark, err := network.NewNetworkBenchmark(config, s.log, sequencerOptions, validatorOptions, proofConfig, transactionPayload, s.portState, flashblocksBlockTime) if err != nil { return nil, errors.Wrap(err, "failed to create network benchmark") } @@ -566,7 +566,7 @@ outerLoop: return errors.Wrap(err, "failed to create output directory") } - metricSummary, err := s.runTest(ctx, c.Params, s.config.DataDir(), outputDir, testPlan.Snapshot, testPlan.ProofProgram, transactionPayloads[c.Params.PayloadID], testPlan.Datadir) + metricSummary, err := s.runTest(ctx, c.Params, s.config.DataDir(), outputDir, testPlan.Snapshot, testPlan.ProofProgram, transactionPayloads[c.Params.PayloadID], testPlan.Datadir, config.FlashblocksBlockTime()) if err != nil { log.Error("Failed to run test", "err", err) metricSummary = &benchmark.RunResult{