Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 2 additions & 2 deletions scripts/benchmark_cchain_range.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ set -euo pipefail
# RUNNER_TYPE (optional): Runner type/label to include in benchmark naming.
# LABELS (optional): Comma-separated key=value pairs for metric labels.
# BENCHMARK_OUTPUT_FILE (optional): If set, benchmark output is also written to this file.
# METRICS_SERVER_ENABLED (optional): If set, enables the metrics server.
# METRICS_SERVER_ENABLED (optional, bool): If set, starts HTTP server exposing /metrics endpoint
# METRICS_SERVER_PORT (optional): If set, determines the port the metrics server will listen to.
# METRICS_COLLECTOR_ENABLED (optional): If set, enables the metrics collector.
# METRICS_COLLECTOR_ENABLED (optional, bool): If set, starts Prometheus agent to collect and forward metrics to remote instance

: "${BLOCK_DIR:?BLOCK_DIR must be set}"
: "${CURRENT_STATE_DIR:?CURRENT_STATE_DIR must be set}"
Expand Down
46 changes: 44 additions & 2 deletions tests/reexecute/c/vm_reexecute.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"maps"
"os"
"path/filepath"
"runtime/pprof"
"slices"
"strconv"
"strings"
Expand Down Expand Up @@ -42,6 +43,7 @@ var (
executionTimeout time.Duration
labelsArg string

pprofEnabled bool
metricsServerEnabledArg bool
metricsServerPortArg uint64
metricsCollectorEnabledArg bool
Expand Down Expand Up @@ -92,6 +94,7 @@ func init() {
flag.IntVar(&chanSizeArg, "chan-size", 100, "Size of the channel to use for block processing.")
flag.DurationVar(&executionTimeout, "execution-timeout", 0, "Benchmark execution timeout. After this timeout has elapsed, terminate the benchmark without error. If 0, no timeout is applied.")

flag.BoolVar(&pprofEnabled, "pprof", false, "Enable full suite of pprof profiling.")
flag.BoolVar(&metricsServerEnabledArg, "metrics-server-enabled", false, "Whether to enable the metrics server.")
flag.Uint64Var(&metricsServerPortArg, "metrics-server-port", 0, "The port the metrics server will listen to.")
flag.BoolVar(&metricsCollectorEnabledArg, "metrics-collector-enabled", false, "Whether to enable the metrics collector (if true, then metrics-server-enabled must be true as well).")
Expand Down Expand Up @@ -135,6 +138,10 @@ func main() {
tc.SetDefaultContextParent(context.Background())
defer tc.RecoverAndExit()

if pprofEnabled {
defer setupPprof(tc)()
}

benchmarkName := fmt.Sprintf(
"BenchmarkReexecuteRange/[%d,%d]-Config-%s-Runner-%s",
startBlockArg,
Expand Down Expand Up @@ -209,15 +216,16 @@ func benchmarkReexecuteRange(
zap.String("runner", runnerTypeArg),
zap.String("config", configNameArg),
zap.String("labels", labelsArg),
zap.String("metrics-server-enabled", strconv.FormatBool(metricsServerEnabled)),
zap.Bool("metrics-server-enabled", metricsServerEnabled),
zap.Uint64("metrics-server-port", metricsPort),
zap.String("metrics-collector-enabled", strconv.FormatBool(metricsCollectorEnabled)),
zap.Bool("metrics-collector-enabled", metricsCollectorEnabled),
zap.String("block-dir", blockDir),
zap.String("vm-db-dir", vmDBDir),
zap.String("chain-data-dir", chainDataDir),
zap.Uint64("start-block", startBlock),
zap.Uint64("end-block", endBlock),
zap.Int("chan-size", chanSize),
zap.Bool("pprof-enabled", pprofEnabled),
)

blockChan, err := reexecute.CreateBlockChanFromLevelDB(tc, blockDir, startBlock, endBlock, chanSize)
Expand Down Expand Up @@ -553,3 +561,37 @@ func parseCustomLabels(labelsStr string) (map[string]string, error) {
}
return labels, nil
}

func setupPprof(tc tests.TestContext) func() {
r := require.New(tc)
logger := tests.NewDefaultLogger("pprof")

cwd, err := os.Getwd()
r.NoError(err, "failed to get current working directory")

profileDir := filepath.Join(cwd, "pprof")
r.NoError(os.MkdirAll(profileDir, perms.ReadWriteExecute), "failed to create profile directory")

cpuFile, err := os.Create(filepath.Join(profileDir, "cpu.prof"))
r.NoError(err, "failed to create CPU profile")

r.NoError(pprof.StartCPUProfile(cpuFile), "failed to start CPU profile")

return func() {
pprof.StopCPUProfile()
cpuFile.Close()
logger.Info("CPU profile", zap.String("path", cpuFile.Name()))

memFile, err := os.Create(filepath.Join(profileDir, "mem.prof"))
if err != nil {
logger.Error("failed to create memory profile", zap.Error(err))
return
}
defer memFile.Close()
if err := pprof.WriteHeapProfile(memFile); err != nil {
logger.Error("failed to write memory profile", zap.Error(err))
return
}
logger.Info("memory profile", zap.String("path", memFile.Name()))
}
}