Skip to content

chore(deploy): switch Docker and EC2 defaults to maxperf#103

Closed
panos-xyz wants to merge 5 commits intomainfrom
chore/docker-ec2-maxperf
Closed

chore(deploy): switch Docker and EC2 defaults to maxperf#103
panos-xyz wants to merge 5 commits intomainfrom
chore/docker-ec2-maxperf

Conversation

@panos-xyz
Copy link
Copy Markdown
Contributor

@panos-xyz panos-xyz commented Apr 24, 2026

Summary

Follow-up to #102. Flip the production-deploy defaults from profilingmaxperf so prod nodes capture the full 2–5% runtime gain from fat LTO + single codegen unit.

  • Dockerfile: BUILD_PROFILE=maxperf (was profiling)
  • MakefileEc2.mk: PROFILE ?= maxperf (was profiling)

Kept consistent: both prod artifacts still share the same profile, so S3-deployed EC2 binaries match what the Docker image ships.

Tradeoff

Aspect profiling (previous default in #102) maxperf (this PR)
Runtime throughput baseline +2–5%
Binary size +5–15% (line-table symbols) baseline (stripped)
Link time baseline ~2–3× longer
Flame-graphable in prod yes no (rebuild with profiling on-demand)

Given morph-reth is a throughput-bound L2 execution client and prod incidents are rare, the default tilts toward runtime performance. When a prod incident actually needs symbols, rebuild on-demand:

  • docker build --build-arg BUILD_PROFILE=profiling ...
  • PROFILE=profiling make -f MakefileEc2.mk build-bk-prod-morph-prod-mainnet-to-morph-reth

Stacking

Test plan

  • CI green once chore: port build profile gradient from tempo #102 merges
  • Build one Docker image with this default to confirm link-stage completes in an acceptable window
  • Compare deployed-binary performance (tx/s, block execution time) before/after to measure the realized gain

Summary by CodeRabbit

  • Chores
    • Updated build configuration to support multiple performance profiles with optimized defaults for production deployments.
    • Enhanced CI/CD workflow to allow manual selection of build profiles.
    • Adjusted Docker and build toolchain defaults for improved performance optimization.

Clippy 1.95 reports `storage.sort_by(|(a, _), (b, _)| a.cmp(b))` as
a `clippy::unnecessary_sort_by` (prefer `sort_by_key`) in the
`apply_curie_hard_fork` test. The fix is the clippy-suggested rewrite.

No behavioural change; only the test's sort comparator is reshaped.
morph-reth's root Cargo.toml previously defined no [profile.*] overrides,
so release builds fell back to Cargo defaults (lto=off). Adopt the same
profile shape used by the sibling `tempo` project:

- profile.dev:      line-tables-only debug, unpacked split-debuginfo.
- profile.hivetests: opt-level=3 + lto=thin, inherits test (debug_assert on).
- profile.release:   opt-level=3, lto=thin, strip=symbols, codegen-units=16.
- profile.profiling: release + line-table debug + strip=none + incremental
                     — production binaries that still flamegraph cleanly.
- profile.bench:     inherits profiling.
- profile.maxperf:   release + lto=fat + codegen-units=1 for peak throughput
                     (expect a noticeably longer link stage).
Match the tempo project's convention: production container images default
to the `profiling` profile, which is release-grade (opt-level=3, lto=thin,
codegen-units=16) but keeps line-table debug symbols and skips stripping.
That preserves flame graphs and backtraces in prod at near-zero runtime
cost.

Override with `--build-arg BUILD_PROFILE=maxperf` for peak throughput
(fat LTO + codegen-units=1, much slower link) or `BUILD_PROFILE=release`
for the stripped/symbolless variant.
Previously the release workflow hardcoded `target/<target>/release/` when
packaging tarballs, which coupled it to the Makefile's `release` default
and silently broke if either was overridden.

Changes:
- Add a `profile` workflow_dispatch input (default `profiling`, with
  `maxperf` and `release` as alternatives). Push-tag triggers keep
  defaulting to `maxperf` for peak throughput on public releases.
- Resolve the profile in a dedicated step and thread it through both
  `make build-<target>` (via PROFILE=) and the subsequent `cp` path
  (using the computed `profile_dir`, which handles Cargo's dev→debug
  naming quirk).
- Update `MakefileEc2.mk` default PROFILE to `profiling` so S3-deployed
  EC2 binaries match the Dockerfile default — shipped prod artifacts
  keep line-table symbols for flame graphs.
Follow-up to the profile gradient PR (#102). Flip the production-binary
defaults from `profiling` to `maxperf` to capture the full 2-5% runtime
gain from fat LTO + single codegen unit on prod nodes.

- Dockerfile: `BUILD_PROFILE=maxperf` (was `profiling`)
- MakefileEc2.mk: `PROFILE ?= maxperf` (was `profiling`)

Tradeoff: symbols are stripped, so flame graphs and symbolicated
backtraces require a one-off `--build-arg BUILD_PROFILE=profiling` (or
`PROFILE=profiling make ...`) rebuild. Given the L2 execution client is
throughput-sensitive and prod incidents are rare, the default is tilted
toward runtime performance. Docker image builds will also take ~2-3x
longer at the link stage — a one-time cost per image tag.

Depends on #102 (introduces the `maxperf` profile definition).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

This PR introduces customizable Cargo build profiles and updates the build system to select between them. It adds profiling, maxperf, hivetests, and bench profiles alongside modified dev and release profiles, with different optimization, debug info, and LTO settings. The release workflow now accepts a manual profile selection input, dynamically maps profiles to target directories, and passes the chosen profile to build steps. Dockerfile and MakefileEc2.mk default profiles change from release to maxperf.

Changes

Cohort / File(s) Summary
Build Profile Configuration
Cargo.toml
Introduces 6 Cargo build profiles: dev (reduced debug info), release (opt-level 3, thin LTO, stripping), profiling (release-based with debug symbols), hivetests (optimized test), bench (profiling-based), and maxperf (fat LTO, 1 codegen-unit).
Release Workflow
.github/workflows/release.yml
Adds workflow_dispatch input for profile selection (default: profiling; options: profiling, maxperf, release). Implements dynamic profile_dir resolution with special-case mapping (devdebug) for binary path construction, defaulting to maxperf on tag pushes.
Container Build Defaults
Dockerfile
Changes ARG BUILD_PROFILE default from release to maxperf with expanded inline documentation for profile override behavior.
Makefile Configuration
MakefileEc2.mk
Changes PROFILE default from release to maxperf with added comments describing EC2 deployment and profiling override usage.
Test Refactoring
crates/evm/src/block/curie.rs
Simplifies test storage ordering from explicit sort_by comparator to sort_by_key on U256.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • anylots
  • chengwenxi
  • curryxbo

Poem

🐰 Through profiles we hop, swift maxperf leads the way,
Debug and fat LTO, we optimize today,
From dev to profiling, each build finds its place,
Flexibility blooms—a fast-tuning embrace! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: switching Docker and EC2 deployment defaults to the maxperf Cargo build profile. It accurately reflects the main objective across the modified files (Dockerfile, MakefileEc2.mk).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/docker-ec2-maxperf

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release.yml:
- Around line 15-22: The profile input currently defaults to "profiling" and can
produce artifacts that clash with the canonical maxperf release filename; update
the release artifact naming logic so that when the input profile (the "profile"
choice) is not "maxperf" the profile is embedded into the tarball name (e.g.,
morph-reth-${VERSION}-${{ inputs.profile }}-${{ matrix.arch }}-linux.tar.gz),
and/or alternatively enforce profile="maxperf" when workflow_dispatch is used
with dry_run=false by adding a conditional that overrides the "profile" input
before build; locate references to the "profile" input and the tarball filename
string in the build/upload and draft-release job steps (where the current
morph-reth-${VERSION}-<arch>-linux.tar.gz pattern is formed) and apply the
conditional naming or override accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84c011a5-78b7-495a-a5af-9bb0884020f9

📥 Commits

Reviewing files that changed from the base of the PR and between faec4c8 and 34885ff.

📒 Files selected for processing (5)
  • .github/workflows/release.yml
  • Cargo.toml
  • Dockerfile
  • MakefileEc2.mk
  • crates/evm/src/block/curie.rs

Comment on lines +15 to +22
profile:
description: "Cargo profile for release binaries"
type: choice
default: "profiling"
options:
- profiling
- maxperf
- release
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider whether release artifacts built from a non-maxperf profile should be distinguishable.

When triggered via workflow_dispatch, a user can pick profiling (current default) or release, and the resulting tarball is uploaded with the same filename pattern (morph-reth-${VERSION}-<arch>-linux.tar.gz) as the canonical tag-push maxperf artifact. If that build ever reaches the draft-release job (i.e., dry_run=false), it would be published under the same download URL that users expect to be the maxperf production binary — with measurably different runtime characteristics and, for profiling, unstripped symbols.

Two low-effort mitigations to consider:

  1. Embed the profile into the archive name when it's not maxperf (e.g., morph-reth-${VERSION}-${profile}-x86_64-linux.tar.gz), or
  2. Force profile=maxperf whenever dry_run=false on workflow_dispatch (i.e., only allow non-default profiles for dry runs).

Not a blocker for this PR's scope, but worth thinking through before the next manual release.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 15 - 22, The profile input
currently defaults to "profiling" and can produce artifacts that clash with the
canonical maxperf release filename; update the release artifact naming logic so
that when the input profile (the "profile" choice) is not "maxperf" the profile
is embedded into the tarball name (e.g., morph-reth-${VERSION}-${{
inputs.profile }}-${{ matrix.arch }}-linux.tar.gz), and/or alternatively enforce
profile="maxperf" when workflow_dispatch is used with dry_run=false by adding a
conditional that overrides the "profile" input before build; locate references
to the "profile" input and the tarball filename string in the build/upload and
draft-release job steps (where the current
morph-reth-${VERSION}-<arch>-linux.tar.gz pattern is formed) and apply the
conditional naming or override accordingly.

@panos-xyz
Copy link
Copy Markdown
Contributor Author

Superseded — squashing into a single PR per reviewer preference.

@panos-xyz panos-xyz closed this Apr 24, 2026
@panos-xyz panos-xyz deleted the chore/docker-ec2-maxperf branch April 24, 2026 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant