eth,cmd: set tracer's backend after eth initalized

Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
jsvisa 2024-08-22 03:15:03 +00:00
parent 0f9fe5fda3
commit efbdfbbda3
7 changed files with 46 additions and 13 deletions

View file

@ -2192,7 +2192,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
if ctx.IsSet(VMTraceJsonConfigFlag.Name) { 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) t, _, err := tracers.LiveDirectory.New(name, config)
if err != nil { if err != nil {
Fatalf("Failed to create tracer %q: %v", name, err) Fatalf("Failed to create tracer %q: %v", name, err)
} }

View file

@ -17,11 +17,13 @@
package tracing package tracing
import ( import (
"context"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -68,6 +70,16 @@ type BlockEvent struct {
Safe *types.Header Safe *types.Header
} }
// Backend interface provides the common API services (that are provided by
// both full and light clients) with access to necessary functions.
type Backend interface {
HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error)
}
type ( type (
/* /*
- VM events - - VM events -
@ -171,6 +183,7 @@ type (
) )
type Hooks struct { type Hooks struct {
Backend Backend
// VM events // VM events
OnTxStart TxStartHook OnTxStart TxStartHook
OnTxEnd TxEndHook OnTxEnd TxEndHook
@ -196,6 +209,11 @@ type Hooks struct {
OnLog LogHook OnLog LogHook
} }
// SetBackend sets a backend to the hooks, use this backend to read chain data.
func (h *Hooks) SetBackend(backend Backend) {
h.Backend = backend
}
// BalanceChangeReason is used to indicate the reason for a balance change, useful // BalanceChangeReason is used to indicate the reason for a balance change, useful
// for tracing and reporting. // for tracing and reporting.
type BalanceChangeReason byte type BalanceChangeReason byte

View file

@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state/pruner" "github.com/ethereum/go-ethereum/core/state/pruner"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/blobpool"
"github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/ethereum/go-ethereum/core/txpool/legacypool"
@ -195,17 +196,20 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
StateHistory: config.StateHistory, StateHistory: config.StateHistory,
StateScheme: scheme, StateScheme: scheme,
} }
liveTracer *tracing.Hooks
liveAPIs []rpc.API
) )
if config.VMTrace != "" { if config.VMTrace != "" {
var traceConfig json.RawMessage var traceConfig json.RawMessage
if config.VMTraceJsonConfig != "" { if config.VMTraceJsonConfig != "" {
traceConfig = json.RawMessage(config.VMTraceJsonConfig) traceConfig = json.RawMessage(config.VMTraceJsonConfig)
} }
t, err := tracers.LiveDirectory.New(config.VMTrace, traceConfig) var err error
liveTracer, liveAPIs, err = tracers.LiveDirectory.New(config.VMTrace, traceConfig)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create tracer %s: %v", config.VMTrace, err) return nil, fmt.Errorf("failed to create tracer %s: %v", config.VMTrace, err)
} }
vmConfig.Tracer = t vmConfig.Tracer = liveTracer
} }
// Override the chain config with provided settings. // Override the chain config with provided settings.
var overrides core.ChainOverrides var overrides core.ChainOverrides
@ -268,6 +272,14 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
stack.RegisterProtocols(eth.Protocols()) stack.RegisterProtocols(eth.Protocols())
stack.RegisterLifecycle(eth) stack.RegisterLifecycle(eth)
// Set live tracer's backend and register the live tracer APIs
if liveTracer != nil {
liveTracer.SetBackend(eth.APIBackend)
if liveAPIs != nil {
stack.RegisterAPIs(liveAPIs)
}
}
// Successful startup; push a marker and check previous unclean shutdowns. // Successful startup; push a marker and check previous unclean shutdowns.
eth.shutdownTracker.MarkStartup() eth.shutdownTracker.MarkStartup()

View file

@ -552,7 +552,7 @@ func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockG
traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl") traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl")
// Load supply tracer // Load supply tracer
tracer, err := tracers.LiveDirectory.New("supply", json.RawMessage(fmt.Sprintf(`{"path":"%s"}`, traceOutputPath))) tracer, _, err := tracers.LiveDirectory.New("supply", json.RawMessage(fmt.Sprintf(`{"path":"%s"}`, traceOutputPath)))
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to create call tracer: %v", err) return nil, nil, fmt.Errorf("failed to create call tracer: %v", err)
} }

View file

@ -5,9 +5,10 @@ import (
"errors" "errors"
"github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/rpc"
) )
type ctorFunc func(config json.RawMessage) (*tracing.Hooks, error) type ctorFunc func(config json.RawMessage) (*tracing.Hooks, []rpc.API, error)
// LiveDirectory is the collection of tracers which can be used // LiveDirectory is the collection of tracers which can be used
// during normal block import operations. // during normal block import operations.
@ -23,9 +24,9 @@ func (d *liveDirectory) Register(name string, f ctorFunc) {
} }
// New instantiates a tracer by name. // New instantiates a tracer by name.
func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, error) { func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, []rpc.API, error) {
if f, ok := d.elems[name]; ok { if f, ok := d.elems[name]; ok {
return f(config) return f(config)
} }
return nil, errors.New("not found") return nil, nil, errors.New("not found")
} }

View file

@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
) )
func init() { func init() {
@ -21,7 +22,7 @@ func init() {
// as soon as we have a real live tracer. // as soon as we have a real live tracer.
type noop struct{} type noop struct{}
func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, error) { func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, []rpc.API, error) {
t := &noop{} t := &noop{}
return &tracing.Hooks{ return &tracing.Hooks{
OnTxStart: t.OnTxStart, OnTxStart: t.OnTxStart,
@ -41,7 +42,7 @@ func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, error) {
OnCodeChange: t.OnCodeChange, OnCodeChange: t.OnCodeChange,
OnStorageChange: t.OnStorageChange, OnStorageChange: t.OnStorageChange,
OnLog: t.OnLog, OnLog: t.OnLog,
}, nil }, nil, nil
} }
func (t *noop) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { func (t *noop) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {

View file

@ -15,6 +15,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"gopkg.in/natefinch/lumberjack.v2" "gopkg.in/natefinch/lumberjack.v2"
) )
@ -74,15 +75,15 @@ type supplyTracerConfig struct {
MaxSize int `json:"maxSize"` // MaxSize is the maximum size in megabytes of the tracer log file before it gets rotated. It defaults to 100 megabytes. MaxSize int `json:"maxSize"` // MaxSize is the maximum size in megabytes of the tracer log file before it gets rotated. It defaults to 100 megabytes.
} }
func newSupply(cfg json.RawMessage) (*tracing.Hooks, error) { func newSupply(cfg json.RawMessage) (*tracing.Hooks, []rpc.API, error) {
var config supplyTracerConfig var config supplyTracerConfig
if cfg != nil { if cfg != nil {
if err := json.Unmarshal(cfg, &config); err != nil { if err := json.Unmarshal(cfg, &config); err != nil {
return nil, fmt.Errorf("failed to parse config: %v", err) return nil, nil, fmt.Errorf("failed to parse config: %v", err)
} }
} }
if config.Path == "" { if config.Path == "" {
return nil, errors.New("supply tracer output path is required") return nil, nil, errors.New("supply tracer output path is required")
} }
// Store traces in a rotating file // Store traces in a rotating file
@ -106,7 +107,7 @@ func newSupply(cfg json.RawMessage) (*tracing.Hooks, error) {
OnEnter: t.OnEnter, OnEnter: t.OnEnter,
OnExit: t.OnExit, OnExit: t.OnExit,
OnClose: t.OnClose, OnClose: t.OnClose,
}, nil }, nil, nil
} }
func newSupplyInfo() supplyInfo { func newSupplyInfo() supplyInfo {