Repository navigation
Bump Base to v1.5.4 - #41
Merged
Merged
Conversation
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* chore(proof): bump SP1 to 6.10.0 Bump host and guest SP1 crates and the cargo-prove Docker tag to v6.10.0, sp1-cluster to v2.9.0, kzg-rs to 0.2.9, and the sp1-patches guest patches to their 6.10.0 tags. Co-authored-by: Cursor <cursoragent@cursor.com> (cherry picked from commit 510820c) * ci: bump SP1 setup actions to v6.10.0 Update the sp1-version default and SP1UP_REF in the GitHub and Depot setup actions so CI installs cargo-prove v6.10.0, matching etc/just/succinct.just. Co-authored-by: Cursor <cursoragent@cursor.com> (cherry picked from commit b1272d6) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…oning the submitted batch to v1.5.2 (base#6223) * fix(txpool): store each validity predicate once by partitioning the submitted batch Compiled conditions cloned balance, nonce, and storage predicates out of the submitted batch while keeping the full batch for forwarding, roughly doubling the heap attributed to validity transactions. Move each predicate into exactly one partition and re-combine them when forwarding to a builder. Co-authored-by: Toshi <toshi-noreply@coinbase.com> (cherry picked from commit cece5ad) * bench(payload): measure validity condition memory and evaluation with interleaved timing predicates Co-authored-by: Toshi <toshi-noreply@coinbase.com> (cherry picked from commit e68ab19) Co-authored-by: Toshi <toshi-noreply@coinbase.com> --------- Co-authored-by: Toshi <toshi-noreply@coinbase.com>
…hblocks on follower nodes to v1.5.2 (base#6220) * fix(txpool): expire validity transactions at received flashblocks on follower nodes Validity transactions are evicted at their inclusive flashblock deadline as soon as the builder publishes that flashblock, so an unbumped same-nonce replacement can be admitted mid-block. That expiry only ran on the builder. Transaction ingress is mempool-node first, and those nodes only expired on block commit, so the stale predecessor kept its nonce slot and the replacement was rejected as underpriced for the rest of the block. Add `FlashblockExpiry::expire_published` to record a flashblock observed from the builder's stream under the admission lock, and have the flashblocks node extension route every received flashblock through the local pool before the pending-state processor. A node-level regression test submits a validity transaction through `base_sendRawTransactionValidity`, feeds its deadline flashblock through the follower, and asserts the unbumped replacement is admitted via `eth_sendRawTransaction` before the block commits. Linear: CHAIN-6241 Co-authored-by: Toshi <toshi-noreply@coinbase.com> * fix(txpool): bound follower-recorded flashblock position to the canonical tip A follower records the published position from the websocket stream, which is not authoritative for the pool: a stream for another network, a corrupt frame, or a misbehaving proxy could record a position far ahead of the chain, drain every validity transaction behind it, and reject every later deadline until a reorg. Ignore received flashblocks that are already canonical or more than `RECEIVED_FLASHBLOCK_MAX_LEAD` blocks ahead of the pool's last seen block; block commit still expires those deadlines. Linear: CHAIN-6241 Co-authored-by: Toshi <toshi-noreply@coinbase.com> * Revert "fix(txpool): bound follower-recorded flashblock position to the canonical tip" This reverts commit e03d9c7. * chore(docs): restamp flashblocks-node README in the docs index The release branch still carries the committed docs index; the README gained a pool deadline expiry section, so its summary and digest need refreshing. Co-authored-by: Toshi <toshi-noreply@coinbase.com> --------- Co-authored-by: Toshi <toshi-noreply@coinbase.com>
…e#6222) Keep the resting-predicate index between payload jobs so a validity transaction found unsatisfied in one block is not re-evaluated in the next until a commit or pre-block write changes the state its predicate reads. Today the first flashblock of every block re-evaluates every resting transaction; after Denim every one-shot native block would. - Move the resting set into base-execution-payload-builder as RestingPredicates and RestingPredicateStore, shared by the flashblocks and native builders. - Carry members only when the next block builds on the block this builder finished; wake members from pre-block system calls and deposits through the block-start TransitionState; always release block-number blockers; drop members not yielded for 10-20 blocks. - Extend the existing --builder.resting-predicates mode instead of adding a flag: the flashblocks builder carries the set across flashblocks and blocks, and the native builder carries it across blocks from Denim on. - Move the resting parked and shadow-mismatch counters to the shared validity metrics, and add carry-over metrics. Backport to v1.5.2. The benchmarks from the main change are left out because their scaffolding is not on this branch, and the validity evaluation counters keep this branch's string labels.
…base#6239) * test(consensus): reproduce startup reset cancellation by admin queries Add an intentionally failing regression test using the real sequencer actor and queued engine client. Hold the startup reset response while servicing read-only admin queries, then assert the response receiver survives and no replacement reset is submitted. Amp-Thread-ID: https://ampcode.com/threads/T-daeea7bf-86c0-43de-a2d5-3430dbf84abe Co-authored-by: Julian Meyer <julian.meyer@coinbase.com> * fix(consensus): retain startup reset across admin queries Pin each startup reset attempt across the admin-query select loop so read-only queries cannot drop its response receiver and cause replacement resets. Preserve shutdown, takeover, shadow gating, and deferred-reset backoff behavior. Amp-Thread-ID: https://ampcode.com/threads/T-daeea7bf-86c0-43de-a2d5-3430dbf84abe Co-authored-by: Julian Meyer <julian.meyer@coinbase.com> --------- Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit dadb34f) Adapted for releases/v1.5.2: the new test no longer sets `schedule_delay`, which base#5560 added on main only; this branch has no such field. Co-authored-by: Julian Meyer <julian.meyer@coinbase.com>
… builder (base#6241) Backport of base#6184 to releases/v1.5.2. The schedule flag previously reached only the standalone execution node's native payload builder; base-builder and base sequencer (the unified binary) built the native payload config from `ResourceMeteringConfig::default()`, so a mounted schedule had no effect. `base_builder_cli::Args` now carries `--payload.resource-metering-schedule` (`PAYLOAD_RESOURCE_METERING_SCHEDULE`), builds `ResourceMeteringConfig` through `from_parts`, and `MultiplexingServiceBuilder::native_payload_config` copies the resulting config instead of overriding it with the default. `--builder.enable-resource-metering` is the single switch for both the Flashblocks metering store and native schedule evaluation. Adaptation to releases/v1.5.2: only the import list in `crates/builder/cli/src/args.rs` conflicted, because the release branch still carries `ShadowValidityConfig`; both imports are kept. Every other file applies with byte-identical hunks. Added `sequencer_schedule_wiring_feeds_the_multiplexed_native_payload_builder` to cover the unified binary's CLI-to-multiplexer path, which the original PR only covered up to `BuilderConfig`. (cherry picked from commit e6f58f8)
…flashblocks block-start path to v1.5.2 (base#6278) * fix(builder): sweep unseen resting validity transactions off the block-start path `RestingPredicates::begin_block` walked the whole resting set every `RESTING_UNSEEN_RETAINED_BLOCKS` blocks to drop members no build had yielded. The flashblocks builder calls it between the forkchoice update and `calculate_flashblocks`, so on those blocks the whole flashblock schedule started late by however long the sweep took. With a large resting set that is long enough to cost several flashblocks, every tenth block. - Move the sweep out of `begin_block`. `RestingPredicateStore::finish` runs it when a sweep block finishes, on a named reth task-executor worker, so it overlaps the state root and the leeway. `take` waits for an unfinished sweep and records the wait. - Derive the flashblock schedule before carrying the resting set, and anchor the flashblock timer to that instant, so block-start work can only shorten the first flashblock. - Add `resting_predicate_begin_block_duration`, `resting_predicate_sweep_duration`, `resting_predicate_sweep_wait_duration` and `flashblocks_schedule_delay`, plus `resting_begin_block` and `resting_unseen_sweep` debug spans. - Add `resting_carry`, `native_resting_sweep` and `flashblocks_resting_sweep` benches that carry a large resting set. * perf(payload): sweep resting validity transactions by generation every block The unseen sweep walked every member every 10 blocks. Off the flashblocks block-start path it overlaps the leeway, but the native post-Denim builder has no leeway: the next build waits for any sweep that outlasts the state root, and the cost arrives as a spike every 10 blocks. File each member under the block that rested it and sweep, at the end of every block, only the generation that is `RESTING_UNSEEN_RETAINED_BLOCKS` old: members not seen since are dropped and the rest are re-filed under the block that last saw them. `hold` is unchanged, so the selection loop does no extra work. A member now leaves the set exactly `RESTING_UNSEEN_RETAINED_BLOCKS` blocks after it was last seen, instead of between one and two windows. ABBA against the previous behaviour, `native_resting_sweep` (100k live resting transactions, 4.8k churned per block, 4 runs each): with the next block starting as soon as the last one finishes, the 29-31ms carry on one block in ten becomes a 3.3-4.5ms sweep wait on every block. With 20ms between blocks for the state root, carry is under 0.02ms on every block, against 32-54ms on one block in ten before. * fix(builder): take only the resting carry out of the first flashblock Anchoring the flashblock timer to the moment the schedule was derived also took the fallback build, the payload send and the index-0 publish out of the first flashblock on every block. When those outlast a short first offset, the first tick is already in the past and missed ticks fire back to back, cancelling flashblocks before they build anything. Start the timer where it started before and shorten only the first tick by the resting carry, capped at the whole first flashblock so the first tick is never in the past. `RestingPredicates::rest` also listed a member in the current generation again when it rested twice in one block. The sweep skipped the duplicate, but it cost memory and sweep time per call rather than per member. * fix(payload): drop stale resting generations when the set empties `finish` skipped an empty set before the sweep, so generation entries for members removed by inclusion, wakeups or rescans stayed listed. A builder whose resting transactions all clear before the block finishes would pile them up, and the next sweep over a non-empty set would walk the whole backlog at once. With no members left every entry is stale, so clear them. * fix(payload): bound the wait for the previous block's resting sweep `take` runs before the fallback build and before the native selection loop, so waiting without limit for a slow sweep could delay the payload itself. Wait at most `RESTING_SWEEP_WAIT_LIMIT` (25ms), then start with an empty set, which only means re-evaluating every validity transaction as after a reset. The sweep finishes on its worker and drops the set there. Count give-ups in `resting_predicate_sweep_wait_timeouts_total`. Also update the `resting_predicate_begin_block_duration` description, which still placed the carry before flashblock scheduling. * fix(builder): wait up to one flashblock interval for the resting sweep The flashblocks builder gave up on the previous block's sweep after the same 25ms as the native builder. Its sweep has already overlapped the state root and the leeway, and starting with an empty set means evaluating every validity transaction again in the first flashblock, so a longer wait pays off there. Make the wait limit a `take` argument: the flashblocks builder waits up to one flashblock interval, so a slow sweep costs at most about one flashblock, and the native builder keeps 25ms.
…on flow to v1.5.2 (base#6330) * feat(txpool-tracing): label inclusion metrics by transaction flow Validity transactions can wait in the pool until their predicates hold, so mixing them with standard transactions makes the slow-inclusion share and latency quantiles hard to read. Resolve each transaction's flow from its validity conditions when it enters the pending or queued pool, and label the inclusion duration, healthy/slow inclusion and end-to-end inclusion metrics with `flow` (`standard` or `validity`), matching the builder's flow label. * docs: refresh txpool-tracing docs index summary
…celled (base#6395) The flashblocks and native selection loops returned straight out of the loop when the build was cancelled, skipping every metric recorded after it: `validity_predicate_eval_duration_per_block`, `validity_predicate_candidates_evaluated_per_build`, `validity_candidate_handling_duration`, `predicate_bucket_depth`, `resting_predicate_parked_total` and the payload builder histograms. A flashblock whose selection loop runs until the deadline is the build where validity handling costs the most, so these series went silent exactly when they mattered. On mainnet on 2026-11-02, every flashblock build hit the deadline from about 12:15 UTC and the predicate dashboards dropped to 0 while per-transaction counters kept climbing. Break out of the loop instead, so the post-loop recording runs for cancelled builds too. The flashblocks builder still reports the build as cancelled through `FlashblockDiagnostics::cancelled` and the `flashblock_selection_total{outcome="cancelled"}` counter, and the native builder still returns `Some(())` for a cancelled scan.
…se#6398) Adds a txpool.validity.predicates_per_tx histogram recorded alongside txpool.validity.admitted at every pool admission site, so dashboards can read the average and distribution of predicates per validity transaction.
…se at their target to v1.5.2 (base#6396) * fix(batcher): flush the compression stream so channels close at their target (base#6393) * fix(batcher): flush the compression stream so channels close at their target Brotli holds up to about one window (4 MiB) of input before it emits anything. CompressionStream never flushed, so output_size(), which drives the channel soft target, stayed at zero until Brotli emitted about 1.17 MB at once, and any compressed_size_target below that closed the channel at about 1.17 MB. Flush the encoder once 512 KiB of input has been appended since the last flush. A flush keeps the window, so it only adds a meta-block boundary. The trigger counts input bytes, not blocks: block sizes vary widely across chains, and a fixed block count of large blocks can exceed the window. * fix(batcher): derive the compression flush interval from the size target With a fixed 512 KiB flush interval, the emitted bytes the target is checked against can trail the real compressed size by up to 512 KiB of input, so a target well below that, such as 150 KB, cannot be honored. Flush every quarter of the target instead, so the lag and the overshoot stay small relative to any target, at a constant few flushes per channel. Channels without a target no longer flush. (cherry picked from commit e3507dd) * chore(docs): restamp docs index for batcher READMEs * fix(batcher): count flush overhead in the compression-size bound Each flush ends a Brotli meta-block early, which costs one more meta-block header and up to two bytes of padding, so max_output_size() could undercount streams with a short flush interval. Charge 6 bytes per possible flush, at most one per flush interval of input, and cover a one-byte interval in the bound test. * fix(batcher): make a zero compression flush interval unrepresentable CompressionStream::new took the flush interval as Option<usize>, so a caller passing Some(0) made max_output_size divide by zero. Take Option<NonZeroUsize> instead, and have Channel::flush_interval return None for a zero target. Co-authored-by: Toshi <toshi-noreply@coinbase.com> --------- Co-authored-by: Toshi <toshi-noreply@coinbase.com>
…er a failed forward to v1.5.2 (base#6402) * [backport] perf(tx-forwarding): resend validity transactions only after a failed forward to v1.5.2 Backport of base#6401. * docs: restamp tx-forwarding and transaction-events docs index entries * perf(tx-forwarding): count resends per fill and record them once * fix(tx-forwarding): share the already-imported check with the builder and floor the validity hold
…ol iterator to v1.5.2 (base#6403) * perf(txpool): park resting validity transactions in the pool iterator (base#6256) Backport of base#6256 to releases/v1.5.2, adapted to the release tree, which lacks base#6251/base#6252 and already carries the base#6277 resting sweep. (cherry picked from commit b65abe2) * fix(txpool): interrupt held resting walks when the build is cancelled Since base#6256 the pool iterator parks resting validity transactions itself, so one `next` call can advance past the whole resting set without returning to the build loop. The build loop used to check cancellation, and the native builder finalization requests, before each of those members; with 120k resting members the walk takes about 100ms of a flashblock and could not be interrupted. `BestTransactionsHold::is_interrupted` lets a hold end the walk. The parking iterator checks it every `HOLD_INTERRUPT_INTERVAL` (256) holds and returns without a source head, and the build loop then observes the same interruption. The flashblocks builder interrupts on the flashblock's cancellation token. The native builder interrupts once the job is cancelled or asked to finalize, observing its `CancelOnDrop` through a weak reference so the hold never owns a clone whose drop would cancel the job. Also: - `native_resting_sweep` installs the hold, as the production builder does. It measured the build loop evaluating every resting member instead. - The native builder records the hold's time as `resting_predicate_hold_duration`; it was measured and discarded. * fix(builder): report interrupted flashblock selection as cancelled An interrupted resting hold ends the pool iterator with `None`, so the selection loop exits before its per-candidate cancellation check and the flashblock was labelled `pool_drained`/`pool_empty`. Re-check the token after the loop. Also makes `flashblock_hold` a public, re-exported function, per CLAUDE.md. --------- Co-authored-by: Haardik H <haardik.haardik@coinbase.com>
…idity pool to v1.5.2 (base#6400) * feat(txpool): hold validity transactions in a separate validity pool Backport of base#6253 to releases/v1.5.2, re-implemented on the release's transaction pool. Every transaction carrying validity predicates (protocol-nonce and EIP-8130 channel or nonce-free) is admitted to a dedicated, separately bounded validity pool instead of reth's pending/queued subpools, so validity transactions that rest on hot state can no longer crowd out standard transactions, and a standard flood cannot evict validity transactions. Validity lanes keyed on the protocol nonce follow reth's pending prefix for the same sender, protocol-nonce slots stay exclusive across stores under the price bump, and the builder merges the stores by tip without yielding a nonce before its predecessor. New flags: --rollup.validity-pool-max-count, --rollup.validity-pool-max-size, --rollup.validity-pool-max-account-slots. Release adaptations: the EIP-8130 sidecar keeps this release's uncapped limits; tip backing, allowlisted payers, best-transaction holds, guard replacement checks and state-diff nonce advances are main-only and are not ported. Benchmarks are omitted because the release has no bench harness. * fix(txpool): drop unused test imports and restamp the txpool docs summary * fix(txpool): drop block-expiry entries of evicted lane-store transactions * fix(txpool): reject EIP-7702 delegation on validity transactions Validity transactions live in their own pool, which does not enforce reth's in-flight limits for delegated accounts and pending authorizations. Rather than share those limits across pools, a transaction with validity predicates is rejected when it is an EIP-7702 transaction or its sender is delegated, and a state diff that changes an account's code drops that account's validity transactions.
…fter Denim to v1.5.2 (base#6422) * fix(txpool): reject flashblock-index validity predicates after Denim After Denim the sequencer builds native 200ms blocks without flashblocks, and the native builder skips every transaction that carries a flashblock-index predicate. Ingress still admitted them, so submitters got a transaction hash back for a transaction that could never be included. It then sat in the validity pool, counting toward the resting set and the pool cap, until its block expiry. On Base Sepolia, which has Denim active, a validity transaction with `flashblock_index >= 1` was accepted through the public endpoint, forwarded to the sequencer, evaluated as `unsupported` in every block and never included. Reject these submissions in `base_sendRawTransactionValidity` with an invalid-params error once the block being built is a Denim block, using the same transition check as the expiry window. The mempool nodes run this same ingress, so the submitter sees the error directly. * fix(txpool): reject flashblock-index predicates before forwarding Run the post-Denim flashblock-index rejection before a forwarding node proxies the request upstream, so the submitter gets the error from the first node it reaches. A forwarding node that cannot read its head defers to the upstream node, which runs the same check.
…ow-ups) (base#6416) * fix(deps): pin reth backport of eth_getLogs blocking-pool fixes for v1.5.2 Co-authored-by: Toshi <toshi-noreply@coinbase.com> * chore(deps): pin reth to base-v2.5.2.10 --------- Co-authored-by: Toshi <toshi-noreply@coinbase.com> Co-authored-by: William Law <williamlaw.wtl@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Carries base/reth#39, the trie node iterator seek-boundary fix, on the releases/v1.5.3 line. Generated with Claude Code Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…v1.5.4 backport) (base#6321) * [backport] fix(consensus): size sequencer catch-up buffer for fast block times to v1.5.2 (base#6320) Co-authored-by: Toshi <toshi-noreply@coinbase.com> * test(consensus): cover regular gossip gap against catch-up window Co-authored-by: Toshi <toshi-noreply@coinbase.com> * test(actions): pass catch-up batch limit in shadow sequencer action test Co-authored-by: Toshi <toshi-noreply@coinbase.com> --------- Co-authored-by: Toshi <toshi-noreply@coinbase.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a1ad1b-e2c2-7664-98fe-17d17fd22c09 (cherry picked from commit 2d12988) Co-authored-by: Amp <amp@ampcode.com>
….5.4) (base#6464) * fix(reth-cli): scale engine persistence defaults for 200ms blocks * docs: restamp reth-cli README in docs index
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merges upstream Base
v1.5.4(withv1.5.2andv1.5.3) intorelease/1.x. Tagv1.5.4-fh3.1once merged.Upstream recommends this release for synchronization and block propagation at 200 ms block times. It also raises the engine persistence defaults (
--engine.persistence-threshold7 → 70,--engine.memory-block-buffer-target5 → 70,--engine.persistence-backpressure-threshold16 → 160); set them explicitly to keep the old values.Merge and tag streamingfast/reth#89 first. Upstream moves its reth pin from
base-v2.5.2.8tobase-v2.5.2.11, so this PR pinsstreamingfast/rethbase-v2.5.2.11-fh3.1, which streamingfast/reth#89 releases. Until that tag exists, this branch does not build.Cargo.lockrecords that PR's head commit (9f9f5efa1) under the tag; it stays reachable from the tag as long as base#89 is merged with a merge commit. After tagging,cargo update -p reth-firehosemoves the lock to the tagged commit (same tree).firehose-tracerstays on 5.7.0 and the Firehose block model is unchanged, so the tag keepsfh3.1.Besides the merge:
Cargo.toml(reth pins; kept our extra crates and moved everybase/rethpin tobase-v2.5.2.11and everystreamingfast/rethpin tobase-v2.5.2.11-fh3.1),crates/execution/payload/src/builder.rs(kept the Firehose trace of blocks built from payload attributes alone with the newbuild_payloadclosure),crates/builder/multiplex/src/service_builder.rs(keptOpFirehoseEvmConfigwith upstream's imports),Cargo.lock(upstream's lock plus our Firehose crates; no other version changed).ACTIVATIONS.md: Denim active on Base mainnet, statuses refreshed againstv1.5.4.CHANGELOG
Test Execution Summary
Branch
bump/base-1.5.4:release/1.xatv1.5.1-fh3.1+git merge v1.5.4. Built and tested againststreamingfast/rethbump/base-v2.5.2.11at9f9f5efa1, served locally as thebase-v2.5.2.11-fh3.1tag through aurl.<local mirror>.insteadOfgit redirect (CARGO_NET_GIT_FETCH_WITH_CLI=true). The tag does not exist on GitHub yet.Build Status
cargo build --release --package base-reth-node --bin base-reth-node --package base-consensus --bin base-consensus(same command asDockerfile.sf): PASSED (5 min 18 s)cargo test --no-run -p base-execution-firehose -p base-firehose-tests -p base-firehose-flashblocks -p base-reth-node -p base-execution-chainspec -p base-common-genesis -p base-common-chains -p base-execution-payload-builder -p base-builder-multiplex -p base-reth-cli: PASSEDcargo clippy -p base-reth-node -p base-builder-multiplex -p base-execution-payload-builder --tests: PASSED. No warning in a file this merge touches; the warnings left are incrates/firehose-flashblocks/src/processor.rs,crates/execution/firehoseandcrates/execution/flashblocks/src/traits.rs, which this merge does not change.base-reth-node node --chain base --datadir <empty dir> --disable-discoveryfor 60 s: PASSED. PrintsFIRE INIT 3.1 reth base-1.5.4and the genesisFIRE BLOCK 0, listsDenim @1793901600;node --helpshows--engine.persistence-thresholddefaulting to 70.Unit Tests
cargo test -p base-firehose-testscargo test -p base-firehose-flashblockscargo test -p base-reth-nodecargo test -p base-execution-firehosecargo test -p base-execution-chainspeccargo test -p base-common-genesiscargo test -p base-common-chainscargo test -p base-execution-payload-builderbuilder.rscargo test -p base-reth-clicargo test -p base-builder-multiplexin_process_smoke::payload_builder_modes_match_flashblocks_baselinereturnsInvalid payload attributes(-38003). It fails the same way on pure upstreamv1.5.4and onrelease/1.x(v1.5.1-fh3.1), so it is not caused by this mergecargo test -p reth-firehose -p reth-firehose-tests(instreamingfast/rethbump/base-v2.5.2.11)cargo test -p reth-engine-tree --test firehose_live_tracing --test firehose_live_tracing_bal(same checkout)cargo test -p reth-trie --lib node_iter(same checkout)base-v2.5.2.11Integration Tests
RUSTFLAGS="-C debug-assertions=off" RUST_MIN_STACK=33554432 cargo test -p base-system-tests --test firehose_denim --test firehose_b20 --test firehose_cobalt_b20, Docker-backed (afterforge soldeer install && forge buildincrates/utilities/test-utils/contracts):firehose_b20::b20_transfer_is_tracedfirehose_cobalt_b20::cobalt_b20_surfaces_are_tracedfirehose_denim::denim_activation_block_traces_base_time_installBattlefield Tests
streamingfast/battlefield-ethereumat879ea9a(origin/HEAD),op-reth-devnetsuite with this branch's releasebase-reth-node(1.5.4) as the Firehose node:./scripts/optimism/run_optimism_devnet.sh(withop-nodebuilt fromstreamingfast/optimismrelease/op-reth-2.x), thenOP_RETH_BINARY=<base>/target/release/base-reth-node RUST_MIN_STACK=33554432 ./scripts/run_firehose_op_reth_devnet.sh, thenpnpm test:fh3.0:op-reth-devnet. All snapshots matched; none changed.Header corresponds to RPCandCompare blocks: Firehose blocks match RPC blockspassed. NoERRORor panic in the node log (304 blocks).builder-playgroundwith--keepand wait for theop-gethcontainer as well asop-nodebefore reading its name (it raced and exited once). Itsbproxycontainer also exited once becauseop-rbuilderdid not resolve yet.Firehose bug patterns
BuiltBlock::tracefor blocks built from payload attributes alone is kept after thebuild_payloadsignature change. None found.crates/execution/consensusor engine validation. The base reth bump changes the trie iterator seek, which runs during state root validation beforemark_verified()prints the block. The new persistence defaults (70 / 70 / 160 blocks) only mean that after an unclean shutdown the node executes and prints again up to about 14 s of blocks it held in memory. None found.BaseUpgradeand no schedule change incrates/commonbetweenv1.5.1andv1.5.4. Denim is now active on Base mainnet (first Denim block 53_556_127 at1_793_901_601). Everest stays unscheduled: no timestamp in code, andgetSchedule()on the configured L1protocol_versions_addressreverts on both L1s.ACTIVATIONS.mdrefreshed.crates/common(consensus types, RPC types) in the range, and no change to the reth mapper. None found.Open questions
in_process_smokeinbase-builder-multiplex.payload_builder_modes_match_flashblocks_baselinefails withInvalid payload attributeshere, on pure upstreamv1.5.4and onv1.5.1-fh3.1alike. I left it alone since it is not caused by this merge; someone may want to check whether it also fails in upstream CI.Cargo.lockafter tagging. I kept the lock on fix: logging inconsistencies base/base#89's head commit rather than leaving the reth entries stale. If fix: logging inconsistencies base/base#89 is squash- or rebase-merged, runcargo update -p reth-firehoseonce the tag exists before merging this one.