go-ethereum/eth/tracers/native/mux_test.go
rayoo efd6cdcff1
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
eth/tracers: forward V2 state hooks through mux tracer (#34869)
Fixes the muxTracer to correctly forward events to v2 state
hooks, i.e. `OnCodeChangeV2` and `OnNonceChangeV2`.
2026-05-04 21:36:26 +02:00

87 lines
3.2 KiB
Go

// Copyright 2026 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package native
import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/eth/tracers"
)
// TestMuxForwardsV2StateHooks verifies that the mux tracer fans out the V2
// variants of state-change hooks to child tracers. A child tracer that only
// implements OnCodeChangeV2 / OnNonceChangeV2 must still receive events when
// wrapped behind the mux. The mux must also fall back to the V1 hook when a
// child only implements V1, mirroring the precedence used in
// core/state_processor.go.
func TestMuxForwardsV2StateHooks(t *testing.T) {
var (
codeV2Calls int
nonceV2Calls int
codeV1Calls int
nonceV1Calls int
)
v2Child := &tracers.Tracer{
Hooks: &tracing.Hooks{
OnCodeChangeV2: func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) {
codeV2Calls++
},
OnNonceChangeV2: func(addr common.Address, prev, new uint64, reason tracing.NonceChangeReason) {
nonceV2Calls++
},
},
}
v1Child := &tracers.Tracer{
Hooks: &tracing.Hooks{
OnCodeChange: func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte) {
codeV1Calls++
},
OnNonceChange: func(addr common.Address, prev, new uint64) {
nonceV1Calls++
},
},
}
mux, err := NewMuxTracer([]string{"v2", "v1"}, []*tracers.Tracer{v2Child, v1Child})
if err != nil {
t.Fatalf("NewMuxTracer: %v", err)
}
if mux.Hooks.OnCodeChangeV2 == nil {
t.Fatal("mux does not expose OnCodeChangeV2; V2-only child tracers will miss code changes")
}
if mux.Hooks.OnNonceChangeV2 == nil {
t.Fatal("mux does not expose OnNonceChangeV2; V2-only child tracers will miss nonce changes")
}
mux.Hooks.OnCodeChangeV2(common.Address{}, common.Hash{}, nil, common.Hash{}, nil, tracing.CodeChangeContractCreation)
mux.Hooks.OnNonceChangeV2(common.Address{}, 0, 1, tracing.NonceChangeEoACall)
if codeV2Calls != 1 {
t.Fatalf("V2 child OnCodeChangeV2 got %d calls, want 1", codeV2Calls)
}
if nonceV2Calls != 1 {
t.Fatalf("V2 child OnNonceChangeV2 got %d calls, want 1", nonceV2Calls)
}
if codeV1Calls != 1 {
t.Fatalf("V1 child OnCodeChange got %d calls, want 1 (mux should fall back from V2 to V1)", codeV1Calls)
}
if nonceV1Calls != 1 {
t.Fatalf("V1 child OnNonceChange got %d calls, want 1 (mux should fall back from V2 to V1)", nonceV1Calls)
}
}