Skip to content

eth/tracers: forward V2 state hooks through mux tracer - #34869

Merged
s1na merged 1 commit into
ethereum:masterfrom
rayjun:fix/mux-forward-v2-state-hooks
May 4, 2026
Merged

s1na merged 1 commit into
ethereum:masterfrom
rayjun:fix/mux-forward-v2-state-hooks

Conversation

@rayjun

@rayjun rayjun commented May 4, 2026

Copy link
Copy Markdown
Contributor

The mux tracer never exposed OnNonceChangeV2 or OnCodeChangeV2 on the Hooks struct it returns. A child tracer that only implements the V2 variants (which include a reason parameter - CodeChangeReason / NonceChangeReason) silently received no events when wrapped behind the mux.

Worse, OnCodeChangeV2 had a fanout method defined (added in #33148) but was never wired into the outer Hooks{} literal, so it was dead code. OnNonceChangeV2 had neither the fanout nor the wire.

Mirror the precedence already used in core/state_processor.go and the OnSystemCall fix from #34862: expose only the V2 variants on the Hooks struct, and have the fanout prefer each child's V2 hook, falling back to V1 when only V1 is set. Exposing both V1 and V2 simultaneously would have tripped the "cannot have both" guard in WrapWithJournal and made statedb_hooked pick only V2 (so V1-only children would still lose events).

Callers: a child tracer registered via muxTracer config that tracks nonce changes with NonceChangeReason (e.g. to detect EIP-7702 authorizations vs contract creation) or code changes with CodeChangeReason (e.g. to filter self-destruct from creation) was functionally broken - no events reached the child at all for OnNonceChangeV2, and OnCodeChangeV2 specifically became dead code after #33148.

Add a regression test covering both V2-only and V1-only children.

The mux tracer never exposed OnNonceChangeV2 or OnCodeChangeV2 on the
Hooks struct it returns. A child tracer that only implements the V2
variants (which include a reason parameter - CodeChangeReason /
NonceChangeReason) silently received no events when wrapped behind the
mux.

Worse, OnCodeChangeV2 had a fanout method defined (added in ethereum#33148) but
was never wired into the outer Hooks{} literal, so it was dead code.
OnNonceChangeV2 had neither the fanout nor the wire.

Mirror the precedence already used in core/state_processor.go and the
OnSystemCall fix from ethereum#34862: expose only the V2 variants on the Hooks
struct, and have the fanout prefer each child's V2 hook, falling back
to V1 when only V1 is set. Exposing both V1 and V2 simultaneously would
have tripped the "cannot have both" guard in WrapWithJournal and made
statedb_hooked pick only V2 (so V1-only children would still lose
events).

Callers: a child tracer registered via muxTracer config that tracks
nonce changes with NonceChangeReason (e.g. to detect EIP-7702
authorizations vs contract creation) or code changes with
CodeChangeReason (e.g. to filter self-destruct from creation) was
functionally broken - no events reached the child at all for
OnNonceChangeV2, and OnCodeChangeV2 specifically became dead code
after ethereum#33148.

Add a regression test covering both V2-only and V1-only children.
@rayjun
rayjun requested a review from s1na as a code owner May 4, 2026 13:44

@s1na s1na 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.

LGTM

@s1na s1na added this to the 1.17.3 milestone May 4, 2026
@s1na
s1na merged commit efd6cdc into ethereum:master May 4, 2026
8 of 9 checks passed
@rayjun
rayjun deleted the fix/mux-forward-v2-state-hooks branch May 5, 2026 07:40
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.

2 participants