@@ -20,6 +20,7 @@ import (
20
20
"bytes"
21
21
"context"
22
22
"crypto/ecdsa"
23
+ "encoding/json"
23
24
"errors"
24
25
"fmt"
25
26
"math/big"
@@ -305,6 +306,108 @@ func TestTraceCall(t *testing.T) {
305
306
}
306
307
}
307
308
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
+
308
411
func TestTraceTransaction (t * testing.T ) {
309
412
t .Parallel ()
310
413
@@ -469,3 +572,29 @@ func newAccounts(n int) (accounts Accounts) {
469
572
sort .Sort (accounts )
470
573
return accounts
471
574
}
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