diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index cbf0ef6a9b..dcfcf917f4 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -384,6 +384,7 @@ var (
VMTraceJsonConfigFlag = &cli.StringFlag{
Name: "vmtrace-config",
Usage: "Tracer configuration (JSON)",
+ Value: "{}",
Category: flags.VMCategory,
}
@@ -1673,13 +1674,8 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// VM tracing config.
if ctx.IsSet(VMTraceFlag.Name) {
if name := ctx.String(VMTraceFlag.Name); name != "" {
- var config string
- if ctx.IsSet(VMTraceJsonConfigFlag.Name) {
- config = ctx.String(VMTraceJsonConfigFlag.Name)
- }
-
cfg.VMTrace = name
- cfg.VMTraceJsonConfig = config
+ cfg.VMTraceJsonConfig = ctx.String(VMTraceJsonConfigFlag.Name)
}
}
}
@@ -1862,10 +1858,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (chain *core.B
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}
if ctx.IsSet(VMTraceFlag.Name) {
if name := ctx.String(VMTraceFlag.Name); name != "" {
- var config json.RawMessage
- if ctx.IsSet(VMTraceJsonConfigFlag.Name) {
- config = json.RawMessage(ctx.String(VMTraceJsonConfigFlag.Name))
- }
+ config := json.RawMessage(ctx.String(VMTraceJsonConfigFlag.Name))
t, err := tracers.LiveDirectory.New(name, config)
if err != nil {
Fatalf("Failed to create tracer %q: %v", name, err)
diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go
index 91c753a6a6..ff1e2764ef 100644
--- a/core/tracing/hooks.go
+++ b/core/tracing/hooks.go
@@ -53,9 +53,8 @@ type VMContext struct {
Time uint64
Random *common.Hash
// Effective tx gas price
- GasPrice *big.Int
- ChainConfig *params.ChainConfig
- StateDB StateDB
+ GasPrice *big.Int
+ StateDB StateDB
}
// BlockEvent is emitted upon tracing an incoming block.
diff --git a/core/vm/evm.go b/core/vm/evm.go
index c2e822a7e8..ffe6d99f89 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -557,7 +557,6 @@ func (evm *EVM) GetVMContext() *tracing.VMContext {
Time: evm.Context.Time,
Random: evm.Context.Random,
GasPrice: evm.TxContext.GasPrice,
- ChainConfig: evm.ChainConfig(),
StateDB: evm.StateDB,
}
}
diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go
index 80639f87a3..7ee253e804 100644
--- a/core/vm/runtime/runtime_test.go
+++ b/core/vm/runtime/runtime_test.go
@@ -828,7 +828,7 @@ func TestRuntimeJSTracer(t *testing.T) {
statedb.SetCode(common.HexToAddress("0xee"), calleeCode)
statedb.SetCode(common.HexToAddress("0xff"), suicideCode)
- tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
+ tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil, params.TestChainConfig)
if err != nil {
t.Fatal(err)
}
@@ -863,7 +863,7 @@ func TestJSTracerCreateTx(t *testing.T) {
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
- tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
+ tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil, params.TestChainConfig)
if err != nil {
t.Fatal(err)
}
diff --git a/eth/backend.go b/eth/backend.go
index dd67bf0efc..964a0359c2 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -187,7 +187,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
}
)
if config.VMTrace != "" {
- var traceConfig json.RawMessage
+ traceConfig := json.RawMessage("{}")
if config.VMTraceJsonConfig != "" {
traceConfig = json.RawMessage(config.VMTraceJsonConfig)
}
diff --git a/eth/tracers/api.go b/eth/tracers/api.go
index 84fab25b1f..a4920b6ac1 100644
--- a/eth/tracers/api.go
+++ b/eth/tracers/api.go
@@ -856,7 +856,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
Stop: logger.Stop,
}
} else {
- tracer, err = DefaultDirectory.New(*config.Tracer, txctx, config.TracerConfig)
+ tracer, err = DefaultDirectory.New(*config.Tracer, txctx, config.TracerConfig, api.backend.ChainConfig())
if err != nil {
return nil, err
}
diff --git a/eth/tracers/dir.go b/eth/tracers/dir.go
index f5d41c9953..43cdfdd508 100644
--- a/eth/tracers/dir.go
+++ b/eth/tracers/dir.go
@@ -22,6 +22,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core/tracing"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// Context contains some contextual infos for a transaction execution that is not
@@ -44,8 +45,8 @@ type Tracer struct {
Stop func(err error)
}
-type ctorFn func(*Context, json.RawMessage) (*Tracer, error)
-type jsCtorFn func(string, *Context, json.RawMessage) (*Tracer, error)
+type ctorFn func(*Context, json.RawMessage, *params.ChainConfig) (*Tracer, error)
+type jsCtorFn func(string, *Context, json.RawMessage, *params.ChainConfig) (*Tracer, error)
type elem struct {
ctor ctorFn
@@ -78,12 +79,15 @@ func (d *directory) RegisterJSEval(f jsCtorFn) {
// New returns a new instance of a tracer, by iterating through the
// registered lookups. Name is either name of an existing tracer
// or an arbitrary JS code.
-func (d *directory) New(name string, ctx *Context, cfg json.RawMessage) (*Tracer, error) {
+func (d *directory) New(name string, ctx *Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*Tracer, error) {
+ if len(cfg) == 0 {
+ cfg = json.RawMessage("{}")
+ }
if elem, ok := d.elems[name]; ok {
- return elem.ctor(ctx, cfg)
+ return elem.ctor(ctx, cfg, chainConfig)
}
// Assume JS code
- return d.jsEval(name, ctx, cfg)
+ return d.jsEval(name, ctx, cfg, chainConfig)
}
// IsJS will return true if the given tracer will evaluate
diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go
index ac859805ec..9e8b311d16 100644
--- a/eth/tracers/internal/tracetest/calltrace_test.go
+++ b/eth/tracers/internal/tracetest/calltrace_test.go
@@ -129,7 +129,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc)
)
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
+ tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig, test.Genesis.Config)
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
@@ -227,7 +227,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil)
+ tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil, test.Genesis.Config)
if err != nil {
b.Fatalf("failed to create call tracer: %v", err)
}
@@ -264,7 +264,7 @@ func TestInternals(t *testing.T) {
}
)
mkTracer := func(name string, cfg json.RawMessage) *tracers.Tracer {
- tr, err := tracers.DefaultDirectory.New(name, nil, cfg)
+ tr, err := tracers.DefaultDirectory.New(name, nil, cfg, config)
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
@@ -448,7 +448,7 @@ func testContractTracer(tracerName string, dirPath string, t *testing.T) {
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc)
)
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
+ tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig, nil)
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go
index a3bfd1ae30..2983518593 100644
--- a/eth/tracers/internal/tracetest/flat_calltrace_test.go
+++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go
@@ -96,7 +96,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc)
// Create the tracer, the EVM environment and run it
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
+ tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig, test.Genesis.Config)
if err != nil {
return fmt.Errorf("failed to create call tracer: %v", err)
}
diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go
index 646f6ade8e..ee8368a0e5 100644
--- a/eth/tracers/internal/tracetest/prestate_test.go
+++ b/eth/tracers/internal/tracetest/prestate_test.go
@@ -105,7 +105,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc)
)
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
+ tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig, test.Genesis.Config)
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go
index e96a672244..d38918b3f8 100644
--- a/eth/tracers/js/goja.go
+++ b/eth/tracers/js/goja.go
@@ -33,6 +33,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
"github.com/XinFinOrg/XDPoSChain/eth/tracers/internal"
jsassets "github.com/XinFinOrg/XDPoSChain/eth/tracers/js/internal/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
"github.com/dop251/goja"
"github.com/holiman/uint256"
)
@@ -46,10 +47,10 @@ func init() {
if err != nil {
panic(err)
}
- type ctorFn = func(*tracers.Context, json.RawMessage) (*tracers.Tracer, error)
+ type ctorFn = func(*tracers.Context, json.RawMessage, *params.ChainConfig) (*tracers.Tracer, error)
lookup := func(code string) ctorFn {
- return func(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
- return newJsTracer(code, ctx, cfg)
+ return func(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
+ return newJsTracer(code, ctx, cfg, chainConfig)
}
}
for name, code := range assetTracers {
@@ -110,6 +111,7 @@ func fromBuf(vm *goja.Runtime, bufType goja.Value, buf goja.Value, allowString b
type jsTracer struct {
vm *goja.Runtime
env *tracing.VMContext
+ chainConfig *params.ChainConfig
toBig toBigFn // Converts a hex string into a JS bigint
toBuf toBufFn // Converts a []byte into a JS buffer
fromBuf fromBufFn // Converts an array, hex string or Uint8Array to a []byte
@@ -146,13 +148,14 @@ type jsTracer struct {
// The methods `result` and `fault` are required to be present.
// The methods `step`, `enter`, and `exit` are optional, but note that
// `enter` and `exit` always go together.
-func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
+func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
vm := goja.New()
// By default field names are exported to JS as is, i.e. capitalized.
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
t := &jsTracer{
- vm: vm,
- ctx: make(map[string]goja.Value),
+ vm: vm,
+ ctx: make(map[string]goja.Value),
+ chainConfig: chainConfig,
}
t.setTypeConverters()
@@ -252,7 +255,7 @@ func (t *jsTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from
db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf}
t.dbValue = db.setupObject()
// Update list of precompiles based on current block
- rules := env.ChainConfig.Rules(env.BlockNumber)
+ rules := t.chainConfig.Rules(env.BlockNumber)
t.activePrecompiles = vm.ActivePrecompiles(rules)
t.ctx["block"] = t.vm.ToValue(t.env.BlockNumber.Uint64())
t.ctx["gas"] = t.vm.ToValue(tx.Gas())
diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go
index 3a9cc3596e..c688e20c96 100644
--- a/eth/tracers/js/tracer_test.go
+++ b/eth/tracers/js/tracer_test.go
@@ -89,11 +89,12 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo
func TestTracer(t *testing.T) {
execTracer := func(code string, contract []byte) ([]byte, string) {
t.Helper()
- tracer, err := newJsTracer(code, nil, nil)
+ chainConfig := params.TestChainConfig
+ tracer, err := newJsTracer(code, nil, nil, chainConfig)
if err != nil {
t.Fatal(err)
}
- ret, err := runTrace(tracer, testCtx(), params.TestChainConfig, contract)
+ ret, err := runTrace(tracer, testCtx(), chainConfig, contract)
if err != nil {
return nil, err.Error() // Stringify to allow comparison without nil checks
}
@@ -166,7 +167,8 @@ func TestTracer(t *testing.T) {
func TestHalt(t *testing.T) {
timeout := errors.New("stahp")
- tracer, err := newJsTracer("{step: function() { while(1); }, result: function() { return null; }, fault: function(){}}", nil, nil)
+ chainConfig := params.TestChainConfig
+ tracer, err := newJsTracer("{step: function() { while(1); }, result: function() { return null; }, fault: function(){}}", nil, nil, chainConfig)
if err != nil {
t.Fatal(err)
}
@@ -174,20 +176,21 @@ func TestHalt(t *testing.T) {
time.Sleep(1 * time.Second)
tracer.Stop(timeout)
}()
- if _, err = runTrace(tracer, testCtx(), params.TestChainConfig, nil); !strings.Contains(err.Error(), "stahp") {
+ if _, err = runTrace(tracer, testCtx(), chainConfig, nil); !strings.Contains(err.Error(), "stahp") {
t.Errorf("Expected timeout error, got %v", err)
}
}
func TestHaltBetweenSteps(t *testing.T) {
- tracer, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }}", nil, nil)
+ chainConfig := params.TestChainConfig
+ tracer, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }}", nil, nil, chainConfig)
if err != nil {
t.Fatal(err)
}
scope := &vm.ScopeContext{
Contract: vm.NewContract(&account{}, &account{}, big.NewInt(0), 0),
}
- env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, nil, params.TestChainConfig, vm.Config{Tracer: tracer.Hooks})
+ env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, nil, chainConfig, vm.Config{Tracer: tracer.Hooks})
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 0, big.NewInt(0))
tracer.OnOpcode(0, 0, 0, 0, scope, nil, 0, nil)
@@ -205,11 +208,12 @@ func TestHaltBetweenSteps(t *testing.T) {
func TestNoStepExec(t *testing.T) {
execTracer := func(code string) []byte {
t.Helper()
- tracer, err := newJsTracer(code, nil, nil)
+ chainConfig := params.TestChainConfig
+ tracer, err := newJsTracer(code, nil, nil, chainConfig)
if err != nil {
t.Fatal(err)
}
- env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, nil, params.TestChainConfig, vm.Config{Tracer: tracer.Hooks})
+ env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, nil, chainConfig, vm.Config{Tracer: tracer.Hooks})
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 1000, big.NewInt(0))
tracer.OnExit(0, nil, 0, nil, false)
@@ -256,8 +260,7 @@ func TestIsPrecompile(t *testing.T) {
chaincfg.IstanbulBlock = big.NewInt(200)
chaincfg.BerlinBlock = big.NewInt(300)
txCtx := vm.TxContext{GasPrice: big.NewInt(100000)}
-
- tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil)
+ tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil, chaincfg)
if err != nil {
t.Fatal(err)
}
@@ -271,7 +274,7 @@ func TestIsPrecompile(t *testing.T) {
t.Errorf("tracer should not consider blake2f as precompile in byzantium")
}
- tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil)
+ tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil, chaincfg)
blockCtx = vm.BlockContext{BlockNumber: big.NewInt(250)}
res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg, nil)
if err != nil {
@@ -283,16 +286,17 @@ func TestIsPrecompile(t *testing.T) {
}
func TestEnterExit(t *testing.T) {
+ chainConfig := params.TestChainConfig
// test that either both or none of enter() and exit() are defined
- if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}", new(tracers.Context), nil); err == nil {
+ if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}", new(tracers.Context), nil, chainConfig); err == nil {
t.Fatal("tracer creation should've failed without exit() definition")
}
- if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}", new(tracers.Context), nil); err != nil {
+ if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}", new(tracers.Context), nil, chainConfig); err != nil {
t.Fatal(err)
}
// test that the enter and exit method are correctly invoked and the values passed
- tracer, err := newJsTracer("{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}", new(tracers.Context), nil)
+ tracer, err := newJsTracer("{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}", new(tracers.Context), nil, chainConfig)
if err != nil {
t.Fatal(err)
}
@@ -314,7 +318,8 @@ func TestEnterExit(t *testing.T) {
func TestSetup(t *testing.T) {
// Test empty config
- _, err := newJsTracer(`{setup: function(cfg) { if (cfg !== "{}") { throw("invalid empty config") } }, fault: function() {}, result: function() {}}`, new(tracers.Context), nil)
+ chainConfig := params.TestChainConfig
+ _, err := newJsTracer(`{setup: function(cfg) { if (cfg !== "{}") { throw("invalid empty config") } }, fault: function() {}, result: function() {}}`, new(tracers.Context), nil, chainConfig)
if err != nil {
t.Error(err)
}
@@ -324,12 +329,12 @@ func TestSetup(t *testing.T) {
t.Fatal(err)
}
// Test no setup func
- _, err = newJsTracer(`{fault: function() {}, result: function() {}}`, new(tracers.Context), cfg)
+ _, err = newJsTracer(`{fault: function() {}, result: function() {}}`, new(tracers.Context), cfg, chainConfig)
if err != nil {
t.Fatal(err)
}
// Test config value
- tracer, err := newJsTracer("{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}", new(tracers.Context), cfg)
+ tracer, err := newJsTracer("{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}", new(tracers.Context), cfg, chainConfig)
if err != nil {
t.Fatal(err)
}
diff --git a/eth/tracers/live.go b/eth/tracers/live.go
index 06e323b13b..253b91663b 100644
--- a/eth/tracers/live.go
+++ b/eth/tracers/live.go
@@ -1,3 +1,19 @@
+// Copyright 2024 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 .
+
package tracers
import (
@@ -24,6 +40,9 @@ func (d *liveDirectory) Register(name string, f ctorFunc) {
// New instantiates a tracer by name.
func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, error) {
+ if len(config) == 0 {
+ config = json.RawMessage("{}")
+ }
if f, ok := d.elems[name]; ok {
return f(config)
}
diff --git a/eth/tracers/live/noop.go b/eth/tracers/live/noop.go
index 2a4fdcc410..78e576353d 100644
--- a/eth/tracers/live/noop.go
+++ b/eth/tracers/live/noop.go
@@ -1,3 +1,19 @@
+// Copyright 2024 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 .
+
package live
import (
diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go
index 4f7fdd2389..4f9796ebd8 100644
--- a/eth/tracers/native/4byte.go
+++ b/eth/tracers/native/4byte.go
@@ -27,6 +27,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func init() {
@@ -48,17 +49,19 @@ func init() {
// 0xc281d19e-0: 1
// }
type fourByteTracer struct {
- ids map[string]int // ids aggregates the 4byte ids found
- interrupt atomic.Bool // Atomic flag to signal execution interruption
- reason error // Textual reason for the interruption
+ ids map[string]int // ids aggregates the 4byte ids found
+ interrupt atomic.Bool // Atomic flag to signal execution interruption
+ reason error // Textual reason for the interruption
+ chainConfig *params.ChainConfig
activePrecompiles []common.Address // Updated on tx start based on given rules
}
// newFourByteTracer returns a native go tracer which collects
// 4 byte-identifiers of a tx, and implements vm.EVMLogger.
-func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) {
+func newFourByteTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
t := &fourByteTracer{
- ids: make(map[string]int),
+ ids: make(map[string]int),
+ chainConfig: chainConfig,
}
return &tracers.Tracer{
Hooks: &tracing.Hooks{
@@ -88,7 +91,7 @@ func (t *fourByteTracer) store(id []byte, size int) {
func (t *fourByteTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
// Update list of precompiles based on current block
- rules := env.ChainConfig.Rules(env.BlockNumber)
+ rules := t.chainConfig.Rules(env.BlockNumber)
t.activePrecompiles = vm.ActivePrecompiles(rules)
}
diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go
index d9530c0582..6fb0b7a6e4 100644
--- a/eth/tracers/native/call.go
+++ b/eth/tracers/native/call.go
@@ -29,6 +29,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
//go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe_json.go
@@ -125,7 +126,7 @@ type callTracerConfig struct {
// newCallTracer returns a native go tracer which tracks
// call frames of a tx, and implements vm.EVMLogger.
-func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
+func newCallTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
t, err := newCallTracerObject(ctx, cfg)
if err != nil {
return nil, err
@@ -145,10 +146,8 @@ func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer,
func newCallTracerObject(ctx *tracers.Context, cfg json.RawMessage) (*callTracer, error) {
var config callTracerConfig
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
+ if err := json.Unmarshal(cfg, &config); err != nil {
+ return nil, err
}
// First callframe contains tx context info
// and is populated on start and end.
diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go
index b15bd273fa..74a188bc14 100644
--- a/eth/tracers/native/call_flat.go
+++ b/eth/tracers/native/call_flat.go
@@ -31,6 +31,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
//go:generate go run github.com/fjl/gencodec -type flatCallAction -field-override flatCallActionMarshaling -out gen_flatcallaction_json.go
@@ -115,6 +116,7 @@ type flatCallResultMarshaling struct {
type flatCallTracer struct {
tracer *callTracer
config flatCallTracerConfig
+ chainConfig *params.ChainConfig
ctx *tracers.Context // Holds tracer context data
interrupt atomic.Bool // Atomic flag to signal execution interruption
activePrecompiles []common.Address // Updated on tx start based on given rules
@@ -126,22 +128,20 @@ type flatCallTracerConfig struct {
}
// newFlatCallTracer returns a new flatCallTracer.
-func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
+func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
var config flatCallTracerConfig
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
+ if err := json.Unmarshal(cfg, &config); err != nil {
+ return nil, err
}
// Create inner call tracer with default configuration, don't forward
// the OnlyTopCall or WithLog to inner for now
- t, err := newCallTracerObject(ctx, nil)
+ t, err := newCallTracerObject(ctx, json.RawMessage("{}"))
if err != nil {
return nil, err
}
- ft := &flatCallTracer{tracer: t, ctx: ctx, config: config}
+ ft := &flatCallTracer{tracer: t, ctx: ctx, config: config, chainConfig: chainConfig}
return &tracers.Tracer{
Hooks: &tracing.Hooks{
OnTxStart: ft.OnTxStart,
@@ -207,7 +207,7 @@ func (t *flatCallTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction
}
t.tracer.OnTxStart(env, tx, from)
// Update list of precompiles based on current block
- rules := env.ChainConfig.Rules(env.BlockNumber)
+ rules := t.chainConfig.Rules(env.BlockNumber)
t.activePrecompiles = vm.ActivePrecompiles(rules)
}
diff --git a/eth/tracers/native/call_flat_test.go b/eth/tracers/native/call_flat_test.go
index db922586ad..08df47b37d 100644
--- a/eth/tracers/native/call_flat_test.go
+++ b/eth/tracers/native/call_flat_test.go
@@ -31,7 +31,7 @@ import (
)
func TestCallFlatStop(t *testing.T) {
- tracer, err := tracers.DefaultDirectory.New("flatCallTracer", &tracers.Context{}, nil)
+ tracer, err := tracers.DefaultDirectory.New("flatCallTracer", &tracers.Context{}, nil, params.MainnetChainConfig)
require.NoError(t, err)
// this error should be returned by GetResult
@@ -47,9 +47,7 @@ func TestCallFlatStop(t *testing.T) {
Data: nil,
})
- tracer.OnTxStart(&tracing.VMContext{
- ChainConfig: params.MainnetChainConfig,
- }, tx, common.Address{})
+ tracer.OnTxStart(&tracing.VMContext{}, tx, common.Address{})
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, nil, 0, big.NewInt(0))
diff --git a/eth/tracers/native/contract.go b/eth/tracers/native/contract.go
index 7c8585c132..18a225a28c 100644
--- a/eth/tracers/native/contract.go
+++ b/eth/tracers/native/contract.go
@@ -12,6 +12,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func init() {
@@ -30,7 +31,7 @@ type contractTracerConfig struct {
}
// NewContractTracer returns a native go tracer which tracks the contractor was created
-func NewContractTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
+func NewContractTracer(ctx *tracers.Context, cfg json.RawMessage, _ *params.ChainConfig) (*tracers.Tracer, error) {
var config contractTracerConfig
if cfg != nil {
if err := json.Unmarshal(cfg, &config); err != nil {
diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go
index dc33a13090..c9ddb0ca1d 100644
--- a/eth/tracers/native/mux.go
+++ b/eth/tracers/native/mux.go
@@ -24,6 +24,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/tracing"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func init() {
@@ -38,17 +39,15 @@ type muxTracer struct {
}
// newMuxTracer returns a new mux tracer.
-func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
+func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
var config map[string]json.RawMessage
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
+ if err := json.Unmarshal(cfg, &config); err != nil {
+ return nil, err
}
objects := make([]*tracers.Tracer, 0, len(config))
names := make([]string, 0, len(config))
for k, v := range config {
- t, err := tracers.DefaultDirectory.New(k, ctx, v)
+ t, err := tracers.DefaultDirectory.New(k, ctx, v, chainConfig)
if err != nil {
return nil, err
}
diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go
index c5545487cc..15cd4e85d0 100644
--- a/eth/tracers/native/noop.go
+++ b/eth/tracers/native/noop.go
@@ -24,6 +24,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/tracing"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func init() {
@@ -33,7 +34,7 @@ func init() {
type noopTracer struct{}
// newNoopTracer returns a new noop tracer.
-func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) {
+func newNoopTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
t := &noopTracer{}
return &tracers.Tracer{
Hooks: &tracing.Hooks{
diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go
index 02fe19eb82..067bee7124 100644
--- a/eth/tracers/native/prestate.go
+++ b/eth/tracers/native/prestate.go
@@ -31,6 +31,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
"github.com/XinFinOrg/XDPoSChain/eth/tracers/internal"
"github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
//go:generate go run github.com/fjl/gencodec -type account -field-override accountMarshaling -out gen_account_json.go
@@ -76,12 +77,10 @@ type prestateTracerConfig struct {
DisableStorage bool `json:"disableStorage"` // If true, this tracer will not return the contract storage
}
-func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
+func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
var config prestateTracerConfig
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
+ if err := json.Unmarshal(cfg, &config); err != nil {
+ return nil, err
}
t := &prestateTracer{
pre: stateMap{},