Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix logs in trace stream API #180

Merged
merged 3 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 19 additions & 35 deletions eth/filters/trace_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)

var defaultTxTraceOpts = blocknative.TracerOpts{
var txTraceOpts = blocknative.TracerOpts{
Logs: true,
}

var defaultBlockTraceOpts = blocknative.TracerOpts{
var blockTraceOpts = blocknative.TracerOpts{
DisableBlockContext: true,
Logs: true,
}

// TraceNewPendingTransactions creates a subscription that is triggered each time a
// transaction enters the transaction pool. The tx is traced and sent to the client.
func (api *FilterAPI) NewPendingTransactionsWithTrace(ctx context.Context, tracerOptsJSON *[]byte) (*rpc.Subscription, error) {
func (api *FilterAPI) NewPendingTransactionsWithTrace(ctx context.Context) (*rpc.Subscription, error) {
notifier, supported := rpc.NotifierFromContext(ctx)
if !supported {
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
Expand All @@ -48,12 +48,6 @@ func (api *FilterAPI) NewPendingTransactionsWithTrace(ctx context.Context, trace
pendingTxSub := api.events.SubscribePendingTxs(txs)
defer pendingTxSub.Unsubscribe()

tracerOpts, err := getTracerOpts(tracerOptsJSON, defaultTxTraceOpts)
if err != nil {
log.Error("failed to parse tracer options", "err", err)
return
}

var (
txIndex = hexutil.Uint64(0)
msg *core.Message
Expand Down Expand Up @@ -141,7 +135,7 @@ func (api *FilterAPI) NewPendingTransactionsWithTrace(ctx context.Context, trace
startTime := time.Now()

traceCtx.TxHash = tx.Hash
tx.Trace, err = traceTx(txs[i], msg, traceCtx, blockCtx, chainConfig, sDB.Copy(), tracerOpts)
tx.Trace, err = traceTx(txs[i], msg, traceCtx, blockCtx, chainConfig, sDB.Copy())
if err != nil {
log.Info("failed to trace tx", "err", err, "tx", tx.Hash)
metricsPendingTxsTraceFailed.Inc(1)
Expand All @@ -167,7 +161,7 @@ func (api *FilterAPI) NewPendingTransactionsWithTrace(ctx context.Context, trace

// TraceNewFullBlocks creates a subscription that is triggered each time a
// block is added to the chain. The block is traced and sent to the client.
func (api *FilterAPI) NewFullBlocksWithTrace(ctx context.Context, tracerOptsJSON *[]byte) (*rpc.Subscription, error) {
func (api *FilterAPI) NewFullBlocksWithTrace(ctx context.Context) (*rpc.Subscription, error) {
notifier, supported := rpc.NotifierFromContext(ctx)
if !supported {
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
Expand All @@ -184,12 +178,6 @@ func (api *FilterAPI) NewFullBlocksWithTrace(ctx context.Context, tracerOptsJSON
defer reorgSub.Unsubscribe()
chainConfig := api.sys.backend.ChainConfig()

tracerOpts, err := getTracerOpts(tracerOptsJSON, defaultBlockTraceOpts)
if err != nil {
log.Error("failed to parse tracer options", "err", err)
return
}

metricsBlocksNew.Inc(1)
defer metricsBlocksEnd.Inc(1)

Expand Down Expand Up @@ -235,7 +223,7 @@ func (api *FilterAPI) NewFullBlocksWithTrace(ctx context.Context, tracerOptsJSON
continue
}

trace, err := traceBlock(block, chainConfig, api.sys.chain, tracerOpts)
trace, err := traceBlock(block, chainConfig, api.sys.chain)
if err != nil {
log.Info("failure in block trace", "err", err, "hash", hash, "block", block.Number())
metricsBlocksTraceFailed.Inc(1)
Expand Down Expand Up @@ -283,17 +271,21 @@ func (api *FilterAPI) NewFullBlocksWithTrace(ctx context.Context, tracerOptsJSON
}

// traceTx traces a transaction with the given contexts.
func traceTx(tx *types.Transaction, message *core.Message, txCtx *tracers.Context, vmctx vm.BlockContext, chainConfig *params.ChainConfig, statedb *state.StateDB, tracerOpts blocknative.TracerOpts) (*blocknative.Trace, error) {
tracer, err := blocknative.NewTracer(tracerOpts)
func traceTx(tx *types.Transaction, message *core.Message, txCtx *tracers.Context, vmctx vm.BlockContext, chainConfig *params.ChainConfig, statedb *state.StateDB) (*blocknative.Trace, error) {
tracer, err := blocknative.NewTracer(txTraceOpts)
if err != nil {
return nil, err
}

hooks := tracer.Hooks()

vmenv := vm.NewEVM(vmctx, core.NewEVMTxContext(message), statedb, chainConfig, vm.Config{Tracer: hooks, NoBaseFee: true})

// Set the transaction context for the state db so logs are correctly indexed.
statedb.SetTxContext(txCtx.TxHash, txCtx.TxIndex)
statedb.SetLogger(hooks)

// Begin tracing and calling hooks
hooks.BlockNativeInitHook(vmenv)
hooks.OnTxStart(vmenv.GetVMContext(), tx, message.From)
result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit))
Expand Down Expand Up @@ -322,8 +314,12 @@ func traceBlockTx(tx *types.Transaction, message *core.Message, txCtx *tracers.C
hooks := tracer.Hooks()

vmenv := vm.NewEVM(vmctx, core.NewEVMTxContext(message), statedb, chainConfig, vm.Config{Tracer: hooks, NoBaseFee: false})

// Set the transaction context for the state db so logs are correctly indexed.
statedb.SetTxContext(txCtx.TxHash, txCtx.TxIndex)
statedb.SetLogger(hooks)

// Begin tracing and calling hooks
hooks.BlockNativeInitHook(vmenv)
hooks.OnTxStart(vmenv.GetVMContext(), tx, message.From)
result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit))
Expand All @@ -341,7 +337,7 @@ func traceBlockTx(tx *types.Transaction, message *core.Message, txCtx *tracers.C
}

// traceBlock traces all transactions in a block.
func traceBlock(block *types.Block, chainConfig *params.ChainConfig, chain *core.BlockChain, tracerOpts blocknative.TracerOpts) ([]*blocknative.Trace, error) {
func traceBlock(block *types.Block, chainConfig *params.ChainConfig, chain *core.BlockChain) ([]*blocknative.Trace, error) {
parent := chain.GetBlockByHash(block.ParentHash())
if parent == nil {
return nil, errors.New("parent block not found")
Expand Down Expand Up @@ -375,13 +371,13 @@ func traceBlock(block *types.Block, chainConfig *params.ChainConfig, chain *core
TxIndex: i,
TxHash: tx.Hash(),
}
results2[i], results[i], err = traceBlockTx(tx, msg, txCtx, blockCtx, chainConfig, statedb, tracerOpts)
results2[i], results[i], err = traceBlockTx(tx, msg, txCtx, blockCtx, chainConfig, statedb, blockTraceOpts)
if results2[i] != nil {
results2[i].Hash = tx.Hash()
}
if err != nil {
cconf, _ := json.Marshal(chainConfig)
topts, _ := json.Marshal(tracerOpts)
topts, _ := json.Marshal(blockTraceOpts)
exec, _ := json.Marshal(results2)
log.Error("failed to trace block in tx config",
"err", err,
Expand All @@ -398,15 +394,3 @@ func traceBlock(block *types.Block, chainConfig *params.ChainConfig, chain *core

return results, nil
}

// getTracerOpts parses the tracer options from the given JSON and applies them
// on top of the default options.
func getTracerOpts(optsJSON *[]byte, defaults blocknative.TracerOpts) (blocknative.TracerOpts, error) {
opts := defaults
if optsJSON != nil {
if err := json.Unmarshal(*optsJSON, &opts); err != nil {
return blocknative.TracerOpts{}, err
}
}
return opts, nil
}
10 changes: 4 additions & 6 deletions eth/tracers/blocknative/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ type Tracer struct {
evm *vm.EVM
decoder *decoder.Decoder

vmCtx *tracing.VMContext
origin common.Address
tx *types.Transaction
txHash common.Hash
txIndex int
vmCtx *tracing.VMContext
origin common.Address
tx *types.Transaction

trace Trace
startTime time.Time
Expand Down Expand Up @@ -146,7 +144,7 @@ func (t *Tracer) onTxEnd(receipt *types.Receipt, _ error) {

// onLog is called when a log is emitted.
func (t *Tracer) onLog(log *types.Log) {
if !t.opts.Logs || (t.opts.PerHashLogs && log.TxHash != t.txHash) {
if !t.opts.Logs || (t.opts.PerHashLogs && log.TxHash != t.tx.Hash()) {
return
}
t.trace.Logs = append(t.trace.Logs, CallLog{
Expand Down
Loading