Skip to content

Commit

Permalink
Merge pull request #3523 from dessaya/improve-tracer
Browse files Browse the repository at this point in the history
refactor(evm): simplify tracer code
  • Loading branch information
vitaliy-io authored Jan 24, 2025
2 parents 4f65eeb + 471414c commit ec9252d
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 342 deletions.
8 changes: 1 addition & 7 deletions packages/chainutil/evmtrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ func EVMTrace(
aliasOutput *isc.AliasOutputWithID,
blockTime time.Time,
iscRequestsInBlock []isc.Request,
txIndex *uint64,
blockNumber *uint64,
tracer *tracers.Tracer,
) error {
_, err := runISCTask(
Expand All @@ -24,11 +22,7 @@ func EVMTrace(
blockTime,
iscRequestsInBlock,
false,
&isc.EVMTracer{
Tracer: tracer,
TxIndex: txIndex,
BlockNumber: blockNumber,
},
tracer,
)
return err
}
6 changes: 3 additions & 3 deletions packages/chainutil/runvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"errors"
"time"

"go.uber.org/zap"

"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/samber/lo"
"go.uber.org/zap"

"github.com/iotaledger/wasp/packages/chain"
"github.com/iotaledger/wasp/packages/hashing"
Expand All @@ -27,7 +27,7 @@ func runISCTask(
blockTime time.Time,
reqs []isc.Request,
estimateGasMode bool,
evmTracer *isc.EVMTracer,
evmTracer *tracers.Tracer,
) ([]*vm.RequestResult, error) {
store := ch.Store()
migs, err := getMigrationsForBlock(store, aliasOutput)
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/jsonrpc/chainbackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type ChainBackend interface {
EVMSendTransaction(tx *types.Transaction) error
EVMCall(aliasOutput *isc.AliasOutputWithID, callMsg ethereum.CallMsg) ([]byte, error)
EVMEstimateGas(aliasOutput *isc.AliasOutputWithID, callMsg ethereum.CallMsg) (uint64, error)
EVMTrace(aliasOutput *isc.AliasOutputWithID, blockTime time.Time, iscRequestsInBlock []isc.Request, txIndex *uint64, blockNumber *uint64, tracer *tracers.Tracer) error
EVMTrace(aliasOutput *isc.AliasOutputWithID, blockTime time.Time, iscRequestsInBlock []isc.Request, tracer *tracers.Tracer) error
FeePolicy(blockIndex uint32) (*gas.FeePolicy, error)
ISCChainID() *isc.ChainID
ISCCallView(chainState state.State, scName string, funName string, args dict.Dict) (dict.Dict, error)
Expand Down
61 changes: 35 additions & 26 deletions packages/evm/jsonrpc/evmchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,34 +681,45 @@ func (e *EVMChain) traceTransaction(
}

blockNumber := uint64(blockInfo.BlockIndex())

tracer, err := newTracer(tracerType, &tracers.Context{
BlockHash: blockHash,
BlockNumber: new(big.Int).SetUint64(blockNumber),
TxIndex: int(txIndex),
TxHash: tx.Hash(),
}, config.TracerConfig, false, nil)
tracer, err := newTracer(
tracerType,
&tracers.Context{
BlockHash: blockHash,
BlockNumber: new(big.Int).SetUint64(blockNumber),
TxIndex: int(txIndex),
TxHash: tx.Hash(),
},
config.TracerConfig,
)
if err != nil {
return nil, err
}

if evmutil.IsFakeTransaction(tx) {
return tracer.TraceFakeTx(tx)
}

err = e.backend.EVMTrace(
blockInfo.PreviousAliasOutput,
blockInfo.Timestamp,
requestsInBlock,
&txIndex,
&blockNumber,
tracer.Tracer,
tracer,
)
if err != nil {
return nil, err
}

return tracer.GetResult()
res, err := tracer.GetResult()
if err != nil {
return nil, err
}

var txResults []TxTraceResult
err = json.Unmarshal(res, &txResults)
if err != nil {
return nil, err
}

if len(txResults) <= int(txIndex) {
return nil, errors.New("tx trace not found in tracer result")
}
return txResults[int(txIndex)].Result, nil
}

func (e *EVMChain) debugTraceBlock(config *tracers.TraceConfig, block *types.Block) (any, error) {
Expand All @@ -723,13 +734,14 @@ func (e *EVMChain) debugTraceBlock(config *tracers.TraceConfig, block *types.Blo
}

blockNumber := uint64(iscBlock.BlockIndex())

blockTxs := block.Transactions()

tracer, err := newTracer(tracerType, &tracers.Context{
BlockHash: block.Hash(),
BlockNumber: new(big.Int).SetUint64(blockNumber),
}, config.TracerConfig, true, blockTxs)
tracer, err := newTracer(
tracerType,
&tracers.Context{
BlockHash: block.Hash(),
BlockNumber: new(big.Int).SetUint64(blockNumber),
},
config.TracerConfig,
)
if err != nil {
return nil, err
}
Expand All @@ -738,14 +750,11 @@ func (e *EVMChain) debugTraceBlock(config *tracers.TraceConfig, block *types.Blo
iscBlock.PreviousAliasOutput,
iscBlock.Timestamp,
iscRequestsInBlock,
nil,
&blockNumber,
tracer.Tracer,
tracer,
)
if err != nil {
return nil, err
}

return tracer.GetResult()
}

Expand Down
4 changes: 2 additions & 2 deletions packages/evm/jsonrpc/jsonrpctest/jsonrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,15 +592,15 @@ func TestRPCTraceTx(t *testing.T) {

t.Run("prestate", func(t *testing.T) {
accountMap, err := env.traceTransactionWithPrestate(tx1.Hash())
// t.Logf("%s", lo.Must(json.MarshalIndent(accountMap, "", " ")))
require.NoError(t, err)
require.NotEmpty(t, accountMap)
// t.Logf("%s", lo.Must(json.MarshalIndent(accountMap, "", " ")))

diff, err := env.traceTransactionWithPrestateDiff(tx1.Hash())
// t.Logf("%s", lo.Must(json.MarshalIndent(diff, "", " ")))
require.NoError(t, err)
require.NotEmpty(t, diff.Pre)
require.NotEmpty(t, diff.Post)
// t.Logf("%s", lo.Must(json.MarshalIndent(diff, "", " ")))
})
}

Expand Down
64 changes: 12 additions & 52 deletions packages/evm/jsonrpc/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,32 @@ import (
"encoding/json"
"fmt"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/eth/tracers"

"github.com/iotaledger/wasp/packages/evm/evmutil"
)

type Tracer struct {
*tracers.Tracer
TraceFakeTx func(tx *types.Transaction) (json.RawMessage, error)
}

type tracerFactory func(traceCtx *tracers.Context, cfg json.RawMessage, traceBlock bool, initValue any) (*Tracer, error)
type tracerFactory func(traceCtx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error)

var allTracers = map[string]tracerFactory{}

func registerTracer(tracerType string, fn tracerFactory) {
allTracers[tracerType] = fn
}

func newTracer(tracerType string, ctx *tracers.Context, cfg json.RawMessage, traceBlock bool, initValue any) (*Tracer, error) {
func newTracer(
tracerType string,
ctx *tracers.Context,
cfg json.RawMessage,
) (*tracers.Tracer, error) {
fn := allTracers[tracerType]
if fn == nil {
return nil, fmt.Errorf("unsupported tracer type: %s", tracerType)
}
return fn(ctx, cfg, traceBlock, initValue)
return fn(ctx, cfg)
}

func GetTraceResults(
blockTxs []*types.Transaction,
traceBlock bool,
getFakeTxTrace func(tx *types.Transaction) (json.RawMessage, error),
getTxTrace func(tx *types.Transaction) (json.RawMessage, error),
getSingleTxTrace func() (json.RawMessage, error),
reason error,
) (json.RawMessage, error) {
var traceResult []byte
var err error
if traceBlock {
results := make([]TxTraceResult, 0, len(blockTxs))
var jsResult json.RawMessage
for _, tx := range blockTxs {
if evmutil.IsFakeTransaction(tx) {
jsResult, err = getFakeTxTrace(tx)
if err != nil {
return nil, err
}
} else {
jsResult, err = getTxTrace(tx)
if err != nil {
return nil, err
}
}

results = append(results, TxTraceResult{TxHash: tx.Hash(), Result: jsResult})
}

traceResult, err = json.Marshal(results)
if err != nil {
return nil, err
}
} else {
traceResult, err = getSingleTxTrace()
if err != nil {
return nil, err
}
}

return traceResult, reason
type TxTraceResult struct {
TxHash common.Hash `json:"txHash"` // transaction hash
Result json.RawMessage `json:"result,omitempty"` // Trace results produced by the tracer
Error string `json:"error,omitempty"` // Trace failure produced by the tracer
}
Loading

0 comments on commit ec9252d

Please sign in to comment.