@@ -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: \n have %+v\n want %+v" , ret , testspec .expect )
406+ }
407+ }
408+ }
409+ }
410+
308411func 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