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

turbo/jsonrpc: add optional includePrecompiles flag to trace_* apis #10979

Merged
merged 7 commits into from
Jul 4, 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
20 changes: 10 additions & 10 deletions turbo/jsonrpc/call_traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ package jsonrpc

import (
"context"
"github.com/ledgerwatch/erigon-lib/common/hexutil"
"sync"
"testing"

"github.com/holiman/uint256"
jsoniter "github.com/json-iterator/go"
"github.com/ledgerwatch/erigon-lib/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fastjson"

"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/hexutil"
"github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestCallTraceOneByOne(t *testing.T) {
ToBlock: (*hexutil.Uint64)(&toBlock),
ToAddress: []*common.Address{&toAddress1},
}
if err = api.Filter(context.Background(), traceReq1, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq1, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer()))
Expand Down Expand Up @@ -110,7 +110,7 @@ func TestCallTraceUnwind(t *testing.T) {
ToBlock: (*hexutil.Uint64)(&toBlock),
ToAddress: []*common.Address{&toAddress1},
}
if err = api.Filter(context.Background(), traceReq1, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq1, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer()))
Expand All @@ -125,7 +125,7 @@ func TestCallTraceUnwind(t *testing.T) {
ToBlock: (*hexutil.Uint64)(&toBlock),
ToAddress: []*common.Address{&toAddress1},
}
if err = api.Filter(context.Background(), traceReq2, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq2, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{1, 2, 3, 4, 5, 11, 12}, blockNumbersFromTraces(t, stream.Buffer()))
Expand All @@ -141,7 +141,7 @@ func TestCallTraceUnwind(t *testing.T) {
ToBlock: (*hexutil.Uint64)(&toBlock),
ToAddress: []*common.Address{&toAddress1},
}
if err = api.Filter(context.Background(), traceReq3, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq3, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{12, 13, 14, 15, 16, 17, 18, 19, 20}, blockNumbersFromTraces(t, stream.Buffer()))
Expand Down Expand Up @@ -171,7 +171,7 @@ func TestFilterNoAddresses(t *testing.T) {
FromBlock: (*hexutil.Uint64)(&fromBlock),
ToBlock: (*hexutil.Uint64)(&toBlock),
}
if err = api.Filter(context.Background(), traceReq1, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq1, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer()))
Expand Down Expand Up @@ -220,7 +220,7 @@ func TestFilterAddressIntersection(t *testing.T) {
ToAddress: []*common.Address{&m.Address, &toAddress2},
Mode: TraceFilterModeIntersection,
}
if err = api.Filter(context.Background(), traceReq1, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq1, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer()))
Expand All @@ -236,7 +236,7 @@ func TestFilterAddressIntersection(t *testing.T) {
ToAddress: []*common.Address{&toAddress1, &m.Address},
Mode: TraceFilterModeIntersection,
}
if err = api.Filter(context.Background(), traceReq1, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq1, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
assert.Equal(t, []int{1, 2, 3, 4, 5}, blockNumbersFromTraces(t, stream.Buffer()))
Expand All @@ -252,7 +252,7 @@ func TestFilterAddressIntersection(t *testing.T) {
FromAddress: []*common.Address{&toAddress2, &toAddress1, &other},
Mode: TraceFilterModeIntersection,
}
if err = api.Filter(context.Background(), traceReq1, new(bool), stream); err != nil {
if err = api.Filter(context.Background(), traceReq1, new(bool), nil, stream); err != nil {
t.Fatalf("trace_filter failed: %v", err)
}
require.Empty(t, blockNumbersFromTraces(t, stream.Buffer()))
Expand Down
4 changes: 2 additions & 2 deletions turbo/jsonrpc/gen_traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func TestGeneratedTraceApi(t *testing.T) {
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
baseApi := NewBaseApi(nil, stateCache, m.BlockReader, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs)
api := NewTraceAPI(baseApi, m.DB, &httpcfg.HttpCfg{})
traces, err := api.Block(context.Background(), rpc.BlockNumber(1), new(bool))
traces, err := api.Block(context.Background(), rpc.BlockNumber(1), new(bool), nil)
if err != nil {
t.Errorf("trace_block %d: %v", 0, err)
}
Expand Down Expand Up @@ -275,7 +275,7 @@ func TestGeneratedTraceApi(t *testing.T) {
func TestGeneratedTraceApiCollision(t *testing.T) {
m := rpcdaemontest.CreateTestSentryForTracesCollision(t)
api := NewTraceAPI(newBaseApiForTest(m), m.DB, &httpcfg.HttpCfg{})
traces, err := api.Transaction(context.Background(), common.HexToHash("0xb2b9fa4c999c1c8370ce1fbd1c4315a9ce7f8421fe2ebed8a9051ff2e4e7e3da"), new(bool))
traces, err := api.Transaction(context.Background(), common.HexToHash("0xb2b9fa4c999c1c8370ce1fbd1c4315a9ce7f8421fe2ebed8a9051ff2e4e7e3da"), new(bool), nil)
if err != nil {
t.Errorf("trace_block %d: %v", 0, err)
}
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

52 changes: 42 additions & 10 deletions turbo/jsonrpc/trace_adhoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/types/accounts"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/eth/tracers"
"github.com/ledgerwatch/erigon/polygon/tracer"
"github.com/ledgerwatch/erigon/rpc"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
Expand Down Expand Up @@ -224,7 +225,24 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int)
return msg, nil
}

// OpenEthereum-style tracer
func parseOeTracerConfig(traceConfig *tracers.TraceConfig) (OeTracerConfig, error) {
if traceConfig == nil || traceConfig.TracerConfig == nil || *traceConfig.TracerConfig == nil {
return OeTracerConfig{}, nil
}

var config OeTracerConfig
if err := json.Unmarshal(*traceConfig.TracerConfig, &config); err != nil {
return OeTracerConfig{}, err
}

return config, nil
}

type OeTracerConfig struct {
IncludePrecompiles bool `json:"includePrecompiles"` // by default Parity/OpenEthereum format does not include precompiles
}

// OeTracer is an OpenEthereum-style tracer
type OeTracer struct {
r *TraceCallResult
traceAddr []int
Expand All @@ -240,6 +258,7 @@ type OeTracer struct {
lastOffStack *VmTraceOp
vmOpStack []*VmTraceOp // Stack of vmTrace operations as call depth increases
idx []string // Prefix for the "idx" inside operations, for easier navigation
config OeTracerConfig
}

func (ot *OeTracer) CaptureTxStart(gasLimit uint64) {}
Expand Down Expand Up @@ -279,7 +298,9 @@ func (ot *OeTracer) captureStartOrEnter(deep bool, typ vm.OpCode, from libcommon
}
if precompile && deep && (value == nil || value.IsZero()) {
ot.precompile = true
return
if !ot.config.IncludePrecompiles {
return
}
}
if gas > 500000000 {
gas = 500000001 - (0x8000000000000000 - gas)
Expand Down Expand Up @@ -378,7 +399,9 @@ func (ot *OeTracer) captureEndOrExit(deep bool, output []byte, usedGas uint64, e
}
if ot.precompile {
ot.precompile = false
return
if !ot.config.IncludePrecompiles {
return
}
}
if !deep {
ot.r.Output = libcommon.CopyBytes(output)
Expand Down Expand Up @@ -711,7 +734,7 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) {
}
}

func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool) (*TraceCallResult, error) {
func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool, traceConfig *tracers.TraceConfig) (*TraceCallResult, error) {
if gasBailOut == nil {
gasBailOut = new(bool) // false by default
}
Expand Down Expand Up @@ -770,7 +793,7 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon

signer := types.MakeSigner(chainConfig, blockNum, block.Time())
// Returns an array of trace arrays, one trace array for each transaction
traces, _, err := api.callManyTransactions(ctx, tx, block, traceTypes, txnIndex, *gasBailOut, signer, chainConfig)
traces, _, err := api.callManyTransactions(ctx, tx, block, traceTypes, txnIndex, *gasBailOut, signer, chainConfig, traceConfig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -811,7 +834,7 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon
return result, nil
}

func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, traceTypes []string, gasBailOut *bool) ([]*TraceCallResult, error) {
func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, traceTypes []string, gasBailOut *bool, traceConfig *tracers.TraceConfig) ([]*TraceCallResult, error) {
if gasBailOut == nil {
gasBailOut = new(bool) // false by default
}
Expand Down Expand Up @@ -854,7 +877,7 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH

signer := types.MakeSigner(chainConfig, blockNumber, block.Time())
// Returns an array of trace arrays, one trace array for each transaction
traces, _, err := api.callManyTransactions(ctx, tx, block, traceTypes, -1 /* all tx indices */, *gasBailOut, signer, chainConfig)
traces, _, err := api.callManyTransactions(ctx, tx, block, traceTypes, -1 /* all tx indices */, *gasBailOut, signer, chainConfig, traceConfig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -882,7 +905,7 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH
}

// Call implements trace_call.
func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTypes []string, blockNrOrHash *rpc.BlockNumberOrHash) (*TraceCallResult, error) {
func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTypes []string, blockNrOrHash *rpc.BlockNumberOrHash, traceConfig *tracers.TraceConfig) (*TraceCallResult, error) {
tx, err := api.kv.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -952,6 +975,10 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp
traceResult.VmTrace = &VmTrace{Ops: []*VmTraceOp{}}
}
var ot OeTracer
ot.config, err = parseOeTracerConfig(traceConfig)
if err != nil {
return nil, err
}
ot.compat = api.compatibility
if traceTypeTrace || traceTypeVmTrace {
ot.r = traceResult
Expand Down Expand Up @@ -1016,7 +1043,7 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp
}

// CallMany implements trace_callMany.
func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, parentNrOrHash *rpc.BlockNumberOrHash) ([]*TraceCallResult, error) {
func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, parentNrOrHash *rpc.BlockNumberOrHash, traceConfig *tracers.TraceConfig) ([]*TraceCallResult, error) {
dbtx, err := api.kv.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1096,12 +1123,13 @@ func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, pa
return nil, fmt.Errorf("convert callParam to msg: %w", err)
}
}
results, _, err := api.doCallMany(ctx, dbtx, msgs, callParams, parentNrOrHash, nil, true /* gasBailout */, -1 /* all tx indices */)
results, _, err := api.doCallMany(ctx, dbtx, msgs, callParams, parentNrOrHash, nil, true /* gasBailout */, -1 /* all tx indices */, traceConfig)
return results, err
}

func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []types.Message, callParams []TraceCallParam,
parentNrOrHash *rpc.BlockNumberOrHash, header *types.Header, gasBailout bool, txIndexNeeded int,
traceConfig *tracers.TraceConfig,
) ([]*TraceCallResult, *state.IntraBlockState, error) {
chainConfig, err := api.chainConfig(ctx, dbtx)
if err != nil {
Expand Down Expand Up @@ -1184,6 +1212,10 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type
vmConfig := vm.Config{}
if (traceTypeTrace && (txIndexNeeded == -1 || txIndex == txIndexNeeded)) || traceTypeVmTrace {
var ot OeTracer
ot.config, err = parseOeTracerConfig(traceConfig)
if err != nil {
return nil, nil, err
}
ot.compat = api.compatibility
ot.r = traceResult
ot.idx = []string{fmt.Sprintf("%d-", txIndex)}
Expand Down
Loading
Loading