From dba6fc7e7ab944d72888b890c25fd4256a067950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ste=CC=81phane=20Duchesneau?= Date: Mon, 29 Jun 2026 13:59:39 -0400 Subject: [PATCH 1/2] Advertise finalized head as LIB on engine-API path The cloned OpFirehoseEngineValidator started the Firehose block tracer with `finalized = None`, so live engine-API blocks carried no finalized reference and downstream LIB (last irreversible block) never advanced. Read the finalized head from the node provider via `finalized_block_num_hash()` (adding a `BlockIdReader` bound) and pass it as the block's `FinalizedBlockRef`, mirroring the reth fork's `runner.rs` ExEx path. --- CHANGELOG.sf.md | 11 ++++++++++ rust/op-reth/CHANGELOG.sf.md | 8 +++++++ .../crates/firehose/src/engine_validator.rs | 22 ++++++++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.sf.md b/CHANGELOG.sf.md index ff2e536e779..441bb1a7b0a 100644 --- a/CHANGELOG.sf.md +++ b/CHANGELOG.sf.md @@ -9,6 +9,17 @@ The `sf-release.yml` workflow publishes the top-most version section here as the GitHub release notes (via `sfreleaser changelog extract-section`), so keep the most recent release at the top. +## v2.3.3-fh-1 + +### Fixed + +- LIB (last irreversible / finalized block) was never advertised on the live + engine-API path: the cloned `OpFirehoseEngineValidator` started the block + tracer with `finalized = None`, so emitted blocks carried no finalized ref and + downstream LIB never advanced. It now reads the finalized head from the node + provider (`finalized_block_num_hash()`) and passes it as the block's + `FinalizedBlockRef`, mirroring the reth fork's `runner.rs` ExEx path. + ## v2.3.3-fh Bumps the SF op-reth fork to upstream `op-reth/v2.3.3` (the intervening diff --git a/rust/op-reth/CHANGELOG.sf.md b/rust/op-reth/CHANGELOG.sf.md index 22cfe450a30..14fb0fec4aa 100644 --- a/rust/op-reth/CHANGELOG.sf.md +++ b/rust/op-reth/CHANGELOG.sf.md @@ -6,6 +6,14 @@ This changelog tracks changes that the StreamingFast fork applies on top of upst ## Unreleased +### Fixed + +- LIB (finalized block) was never advanced on the live engine-API path: the cloned + `OpFirehoseEngineValidator` started the block tracer with `finalized = None`. It now reads the + finalized head via `self.provider.finalized_block_num_hash()` (requiring a `BlockIdReader` bound + on the provider) and passes it as the block's `FinalizedBlockRef`, mirroring the reth fork's + `runner.rs`. + ### Changed - Merged upstream `op-reth/v2.3.3` into the Firehose branch. No reth/revm/alloy version bump diff --git a/rust/op-reth/crates/firehose/src/engine_validator.rs b/rust/op-reth/crates/firehose/src/engine_validator.rs index 499cb6087f7..c9cf2292c6d 100644 --- a/rust/op-reth/crates/firehose/src/engine_validator.rs +++ b/rust/op-reth/crates/firehose/src/engine_validator.rs @@ -55,10 +55,10 @@ use reth_primitives_traits::{ }; use reth_provider::{ providers::{OverlayBuilder, OverlayStateProviderFactory}, - BlockExecutionOutput, BlockNumReader, BlockReader, ChangeSetReader, DatabaseProviderFactory, - DatabaseProviderROFactory, HashedPostStateProvider, ProviderError, PruneCheckpointReader, - StageCheckpointReader, StateProvider, StateProviderBox, StateProviderFactory, StateReader, - StorageChangeSetReader, StorageSettingsCache, + BlockExecutionOutput, BlockIdReader, BlockNumReader, BlockReader, ChangeSetReader, + DatabaseProviderFactory, DatabaseProviderROFactory, HashedPostStateProvider, ProviderError, + PruneCheckpointReader, StageCheckpointReader, StateProvider, StateProviderBox, + StateProviderFactory, StateReader, StorageChangeSetReader, StorageSettingsCache, }; use reth_revm::{ database::StateProviderDatabase, @@ -152,6 +152,7 @@ where > + BlockReader
+ ChangeSetReader + BlockNumReader + + BlockIdReader + StateProviderFactory + StateReader + HashedPostStateProvider @@ -533,7 +534,18 @@ where Ok(sealed) => sealed, Err(e) => return Err(e.into()), }; - let tracer = FirehoseBlockTracer::start::(&sealed, None); + // Advertise the current finalized head as the block's LIB (last + // irreversible block). Mirrors the reth fork's `runner.rs`, which passes + // `to_finalized_ref(ctx.provider().finalized_block_num_hash())`; here we read + // it from the validator's provider. `to_finalized_ref` is crate-private in + // `reth-firehose`, so the conversion is inlined. + let finalized = self.provider.finalized_block_num_hash().ok().flatten().map(|num_hash| { + firehose_tracer::types::FinalizedBlockRef { + number: num_hash.number, + hash: Some(num_hash.hash), + } + }); + let tracer = FirehoseBlockTracer::start::(&sealed, finalized); let is_genesis = tracer.is_genesis(); firehose_tracer::firehose_debug!( "validator: firehose tracer initialized (block={}, is_genesis={})", From d4ccb09b7f83fc1bca9d7e36a57d71f047156172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ste=CC=81phane=20Duchesneau?= Date: Mon, 29 Jun 2026 14:36:32 -0400 Subject: [PATCH 2/2] Speed up image CI: GHA layer cache + fast-build on PRs Cold builds took ~32m (no layer cache; maxperf LTO). Cache the cargo-chef dependency layer across runs (type=gha) and use the fast-build profile for PR builds, keeping maxperf for branch/tag releases. Mirrors build-images.yaml. --- .github/workflows/sf-release.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/sf-release.yml b/.github/workflows/sf-release.yml index 4a9b196e256..4ebf16c37ba 100644 --- a/.github/workflows/sf-release.yml +++ b/.github/workflows/sf-release.yml @@ -122,9 +122,18 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} provenance: false + # Cache the cargo-chef dependency layer across runs (ephemeral runners + # otherwise cold-rebuild all deps every time, ~13m). Keyed per profile by + # buildx, so PR (fast-build) and tag (maxperf) caches stay separate. + cache-from: type=gha + cache-to: type=gha,mode=max build-args: | VERSION=${{ steps.extract-version.outputs.VERSION }} FIREHOSE_ETHEREUM=${{ inputs.firehose_ethereum || 'latest' }} + # Full LTO `maxperf` is only worth its ~19m link tail for shippable + # builds (tags); PRs use `fast-build` (no LTO) to validate the build + # faster. Mirrors upstream build-images.yaml. + BUILD_PROFILE=${{ github.event_name == 'pull_request' && 'fast-build' || 'maxperf' }} release: if: startsWith(github.ref, 'refs/tags/')