Skip to content

execution/stagedsync, execution/exec: dedup exec3 block-task construction and AA execution#22174

Draft
yperbasis wants to merge 2 commits into
mainfrom
yperbasis/exec3-block-tasks
Draft

execution/stagedsync, execution/exec: dedup exec3 block-task construction and AA execution#22174
yperbasis wants to merge 2 commits into
mainfrom
yperbasis/exec3-block-tasks

Conversation

@yperbasis

Copy link
Copy Markdown
Member

Two consolidations in the execution pipeline, one commit each:

  1. execAATxnTxTask.executeAA. The historical trace worker carried a ~70-line copy of the AA-bundle validation/execution logic; it is now an 8-line wrapper over the shared method, with its tracer-specific TraceFroms/TraceTos filling kept at the call site. The single semantic delta between the copies is the "validated AA bundle" log length, fixed separately in cl, db, execution, p2p, cmd: fix copy-paste drift defects #22165 — that line is left byte-identical here so both PRs land conflict-free, after which the fix covers both callers through the shared path. (Pre-existing behavior preserved, worth knowing: the sole execAATxn caller discards the AA path's Logs/TraceFroms — unchanged.)
  2. Shared buildBlockTasks. The serial and parallel executors carried the same ~70-line block-ingest + TxTask-construction loop and had already drifted (the parallel path gained the step-misalignment check; serial didn't). One helper on the embedded txExecutor now builds tasks for both; deliberate per-path differences stay at the call sites, parameterized: getHash closure (serial mutex-wrapped vs parallel per-worker placeholder), BlockStateCache (parallel-only), BAL read (parallel-only), Amsterdam guard + accumulator StartChange (serial-only, still ahead of execution), partial-block tracking (serial-only), step-misalignment check untouched and NOT added to serial. The historical CustomTraceMapReduce copy is not converted (import cycle; structurally different — streams to a queue).

Reorderings are limited to moving pure task construction ahead of side-effect-free reads (verified GetHashFn/NewEVMBlockContext are lazy); execution ordering unchanged.

Net −89 lines. Verified: short + full non-short execution/stagedsync + execution/exec suites green before and after, scoped golangci-lint clean (×2), make erigon integration.

Part of a dedup series; siblings #22165#22173.

yperbasis added 2 commits July 2, 2026 21:59
HistoricalTraceWorker.execAATxn duplicated the AA-bundle validation and
execution logic of TxTask.executeAA line for line. Replace the copy with
a call to executeAA, keeping the TraceFroms/TraceTos filling (success
path only, as before) at the historical call site.

Behavior-preserving except one log-only delta: the historical copy's
'validated AA bundle' log printed endIdx-startIdx+1 while executeAA
still prints startIdx-endIdx; the shared site now wins. That expression
is fixed separately (yperbasis/dedup-audit-fixes, b3b25f8), which
after this dedup fixes both callers at once.
serialExecutor.exec and txExecutor.executeBlocks duplicated the
per-block ingest sequence: read-ahead ping, canonical-hash lookup,
block fetch with readAheader fallback, EVM block context construction,
and the TxTask build loop. Extract txExecutor.buildBlockTasks and call
it from both.

Deliberate deltas parameterized or kept at the call sites:
- getHash fn: serial passes its mutex-wrapped se.getHeader; parallel
  passes the per-worker-overridden placeholder reading via blockTx.
- BlockStateCache: parallel passes a fresh per-block cache; serial nil.
- BAL read/decode/validate stays parallel-only, now after the helper.
- Amsterdam guard and accumulator.StartChange stay serial-only.
- Snapshot step-misalignment check stays parallel-only, untouched.

The helper skips already-executed txns before constructing the task
(parallel's form; serial previously constructed then discarded, with no
side effects from the discarded task) and reports partialBlock, which
serial folds into havePartialBlock. Serial tasks now carry Config and
Engine from construction; executeBlock reassigns the same values before
use. Behavior-preserving.

The similar loop in exec.CustomTraceMapReduce is left alone: package
exec cannot import stagedsync, and it differs structurally (streams
tasks straight to a queue, no readAheader cache or skip logic, inline
hash warming, HistoryExecution always true).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces duplication in the execution pipeline by centralizing (1) AA bundle validation/execution and (2) exec3 block-ingest + TxTask construction so serial and parallel paths share the same task-building logic while keeping intentional per-path differences at the call sites.

Changes:

  • Added (*txExecutor).buildBlockTasks and switched both parallel executeBlocks and the serial executor to use it for block read + TxTask construction.
  • Replaced the historical trace worker’s inlined AA bundle logic with a thin wrapper over TxTask.executeAA, keeping tracer-specific TraceFroms/TraceTos handling at the call site.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
execution/stagedsync/exec3.go Introduces buildBlockTasks and uses it from the parallel exec3 loop to deduplicate per-block task construction.
execution/stagedsync/exec3_serial.go Switches serial exec3 to use the shared buildBlockTasks helper and removes the now-duplicated local task-construction loop.
execution/exec/historical_trace_worker.go Replaces the historical trace worker’s AA execution/validation copy with a wrapper calling TxTask.executeAA.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +257 to +259
aaTxn := txTask.Tx().(*types.AccountAbstractionTransaction) // type cast checked by the caller
result := txTask.executeAA(aaTxn, rw.evm, rw.taskGasPool, rw.ibs, rw.execArgs.ChainConfig)
if result.Err != nil {
if len(result.ValidationResults) == 0 {
result.Err = fmt.Errorf("found RIP-7560 but no remaining validation results, txIndex %d", txTask.TxIndex)
aaTxn := txTask.Tx().(*types.AccountAbstractionTransaction) // type cast checked by the caller
result := txTask.executeAA(aaTxn, rw.evm, rw.taskGasPool, rw.ibs, rw.execArgs.ChainConfig)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants