Skip to content

Commit a47370e

Browse files
committed
eth/tracer: extend call tracer ethereum#22245
1 parent 3f18c97 commit a47370e

File tree

2 files changed

+130
-1
lines changed

2 files changed

+130
-1
lines changed

eth/tracers/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex
667667
owner := common.Address{}
668668
result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner)
669669
if err != nil {
670-
return nil, fmt.Errorf("tracing failed: %v", err)
670+
return nil, fmt.Errorf("tracing failed: %w", err)
671671
}
672672

673673
// Depending on the tracer type, format and return the output

eth/tracers/api_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"bytes"
2121
"context"
2222
"crypto/ecdsa"
23+
"encoding/json"
2324
"errors"
2425
"fmt"
2526
"math/big"
@@ -305,6 +306,108 @@ func TestTraceCall(t *testing.T) {
305306
}
306307
}
307308

309+
func TestOverridenTraceCall(t *testing.T) {
310+
t.Parallel()
311+
312+
// Initialize test accounts
313+
accounts := newAccounts(3)
314+
genesis := &core.Genesis{
315+
Alloc: types.GenesisAlloc{
316+
accounts[0].addr: {Balance: big.NewInt(9000000000000000000)},
317+
accounts[1].addr: {Balance: big.NewInt(9000000000000000000)},
318+
accounts[2].addr: {Balance: big.NewInt(9000000000000000000)},
319+
},
320+
}
321+
genBlocks := 10
322+
signer := types.HomesteadSigner{}
323+
api := NewAPI(newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
324+
// Transfer from account[0] to account[1]
325+
// value: 1000 wei
326+
// fee: 0 wei
327+
tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
328+
b.AddTx(tx)
329+
}))
330+
randomAccounts, tracer := newAccounts(3), "callTracer"
331+
332+
var testSuite = []struct {
333+
blockNumber rpc.BlockNumber
334+
call ethapi.TransactionArgs
335+
config *TraceCallConfig
336+
expectErr error
337+
expect *callTrace
338+
}{
339+
// Succcessful call with state overriding
340+
{
341+
blockNumber: rpc.LatestBlockNumber,
342+
call: ethapi.TransactionArgs{
343+
From: &randomAccounts[0].addr,
344+
To: &randomAccounts[1].addr,
345+
Value: (*hexutil.Big)(big.NewInt(1000)),
346+
},
347+
config: &TraceCallConfig{
348+
TraceConfig: TraceConfig{Tracer: &tracer},
349+
StateOverrides: &ethapi.StateOverride{
350+
randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(big.NewInt(9000000000000000000))},
351+
},
352+
},
353+
expectErr: nil,
354+
expect: &callTrace{
355+
Type: "CALL",
356+
From: randomAccounts[0].addr,
357+
To: randomAccounts[1].addr,
358+
Gas: newRPCUint64(24979000),
359+
GasUsed: newRPCUint64(0),
360+
Value: (*hexutil.Big)(big.NewInt(1000)),
361+
},
362+
},
363+
// Invalid call without state overriding
364+
{
365+
blockNumber: rpc.LatestBlockNumber,
366+
call: ethapi.TransactionArgs{
367+
From: &randomAccounts[0].addr,
368+
To: &randomAccounts[1].addr,
369+
Value: (*hexutil.Big)(big.NewInt(1000)),
370+
},
371+
config: &TraceCallConfig{
372+
TraceConfig: TraceConfig{Tracer: &tracer},
373+
StateOverrides: &ethapi.StateOverride{
374+
randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(big.NewInt(1250000000000000000))},
375+
},
376+
},
377+
expectErr: core.ErrInsufficientFunds,
378+
expect: nil,
379+
},
380+
}
381+
for _, testspec := range testSuite {
382+
result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config)
383+
if testspec.expectErr != nil {
384+
if err == nil {
385+
t.Errorf("Expect error %v, get nothing", testspec.expectErr)
386+
continue
387+
}
388+
if !errors.Is(err, testspec.expectErr) {
389+
t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
390+
}
391+
} else {
392+
if err != nil {
393+
t.Errorf("Expect no error, get %v", err)
394+
continue
395+
}
396+
ret := new(callTrace)
397+
if err := json.Unmarshal(result.(json.RawMessage), ret); err != nil {
398+
t.Fatalf("failed to unmarshal trace result: %v", err)
399+
}
400+
if !jsonEqual(ret, testspec.expect) {
401+
// uncomment this for easier debugging
402+
//have, _ := json.MarshalIndent(ret, "", " ")
403+
//want, _ := json.MarshalIndent(testspec.expect, "", " ")
404+
//t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", string(have), string(want))
405+
t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, testspec.expect)
406+
}
407+
}
408+
}
409+
}
410+
308411
func TestTraceTransaction(t *testing.T) {
309412
t.Parallel()
310413

@@ -469,3 +572,29 @@ func newAccounts(n int) (accounts Accounts) {
469572
sort.Sort(accounts)
470573
return accounts
471574
}
575+
576+
func newRPCBalance(balance *big.Int) **hexutil.Big {
577+
rpcBalance := (*hexutil.Big)(balance)
578+
return &rpcBalance
579+
}
580+
581+
func newRPCUint64(number uint64) *hexutil.Uint64 {
582+
rpcUint64 := hexutil.Uint64(number)
583+
return &rpcUint64
584+
}
585+
586+
func newRPCBytes(bytes []byte) *hexutil.Bytes {
587+
rpcBytes := hexutil.Bytes(bytes)
588+
return &rpcBytes
589+
}
590+
591+
func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.Hash {
592+
if len(keys) != len(vals) {
593+
panic("invalid input")
594+
}
595+
m := make(map[common.Hash]common.Hash)
596+
for i := 0; i < len(keys); i++ {
597+
m[keys[i]] = vals[i]
598+
}
599+
return &m
600+
}

0 commit comments

Comments
 (0)