github.com/ethereum/go-ethereum@v1.16.1/ethclient/gethclient/gethclient_test.go (about)

     1  // Copyright 2021 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package gethclient
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"encoding/json"
    23  	"math/big"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/ethereum/go-ethereum"
    28  	"github.com/ethereum/go-ethereum/common"
    29  	"github.com/ethereum/go-ethereum/consensus/ethash"
    30  	"github.com/ethereum/go-ethereum/core"
    31  	"github.com/ethereum/go-ethereum/core/types"
    32  	"github.com/ethereum/go-ethereum/crypto"
    33  	"github.com/ethereum/go-ethereum/eth"
    34  	"github.com/ethereum/go-ethereum/eth/ethconfig"
    35  	"github.com/ethereum/go-ethereum/eth/filters"
    36  	"github.com/ethereum/go-ethereum/eth/tracers"
    37  	"github.com/ethereum/go-ethereum/ethclient"
    38  	"github.com/ethereum/go-ethereum/node"
    39  	"github.com/ethereum/go-ethereum/params"
    40  	"github.com/ethereum/go-ethereum/rpc"
    41  )
    42  
    43  var (
    44  	testKey, _   = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    45  	testAddr     = crypto.PubkeyToAddress(testKey.PublicKey)
    46  	testContract = common.HexToAddress("0xbeef")
    47  	testEmpty    = common.HexToAddress("0xeeee")
    48  	testSlot     = common.HexToHash("0xdeadbeef")
    49  	testValue    = crypto.Keccak256Hash(testSlot[:])
    50  	testBalance  = big.NewInt(2e15)
    51  	testTxHashes []common.Hash
    52  )
    53  
    54  func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
    55  	// Generate test chain.
    56  	genesis, blocks := generateTestChain()
    57  	// Create node
    58  	n, err := node.New(&node.Config{
    59  		HTTPModules: []string{"debug", "eth", "admin"},
    60  	})
    61  	if err != nil {
    62  		t.Fatalf("can't create new node: %v", err)
    63  	}
    64  	// Create Ethereum Service
    65  	config := &ethconfig.Config{Genesis: genesis, RPCGasCap: 1000000}
    66  	ethservice, err := eth.New(n, config)
    67  	if err != nil {
    68  		t.Fatalf("can't create new ethereum service: %v", err)
    69  	}
    70  	n.RegisterAPIs(tracers.APIs(ethservice.APIBackend))
    71  
    72  	filterSystem := filters.NewFilterSystem(ethservice.APIBackend, filters.Config{})
    73  	n.RegisterAPIs([]rpc.API{{
    74  		Namespace: "eth",
    75  		Service:   filters.NewFilterAPI(filterSystem),
    76  	}})
    77  
    78  	// Import the test chain.
    79  	if err := n.Start(); err != nil {
    80  		t.Fatalf("can't start test node: %v", err)
    81  	}
    82  	if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
    83  		t.Fatalf("can't import test blocks: %v", err)
    84  	}
    85  	return n, blocks
    86  }
    87  
    88  func generateTestChain() (*core.Genesis, []*types.Block) {
    89  	genesis := &core.Genesis{
    90  		Config: params.AllEthashProtocolChanges,
    91  		Alloc: types.GenesisAlloc{
    92  			testAddr:     {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
    93  			testContract: {Nonce: 1, Code: []byte{0x13, 0x37}},
    94  			testEmpty:    {Balance: big.NewInt(1)},
    95  		},
    96  		ExtraData: []byte("test genesis"),
    97  		Timestamp: 9000,
    98  	}
    99  	generate := func(i int, g *core.BlockGen) {
   100  		g.OffsetTime(5)
   101  		g.SetExtra([]byte("test"))
   102  
   103  		to := common.BytesToAddress([]byte{byte(i + 1)})
   104  		tx := types.NewTx(&types.LegacyTx{
   105  			Nonce:    uint64(i),
   106  			To:       &to,
   107  			Value:    big.NewInt(int64(2*i + 1)),
   108  			Gas:      params.TxGas,
   109  			GasPrice: big.NewInt(params.InitialBaseFee),
   110  			Data:     nil,
   111  		})
   112  		tx, _ = types.SignTx(tx, types.LatestSignerForChainID(genesis.Config.ChainID), testKey)
   113  		g.AddTx(tx)
   114  		testTxHashes = append(testTxHashes, tx.Hash())
   115  	}
   116  	_, blocks, _ := core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 1, generate)
   117  	blocks = append([]*types.Block{genesis.ToBlock()}, blocks...)
   118  	return genesis, blocks
   119  }
   120  
   121  func TestGethClient(t *testing.T) {
   122  	backend, _ := newTestBackend(t)
   123  	client := backend.Attach()
   124  	defer backend.Close()
   125  	defer client.Close()
   126  
   127  	tests := []struct {
   128  		name string
   129  		test func(t *testing.T)
   130  	}{
   131  		{
   132  			"TestGetProof1",
   133  			func(t *testing.T) { testGetProof(t, client, testAddr) },
   134  		}, {
   135  			"TestGetProof2",
   136  			func(t *testing.T) { testGetProof(t, client, testContract) },
   137  		}, {
   138  			"TestGetProofEmpty",
   139  			func(t *testing.T) { testGetProof(t, client, testEmpty) },
   140  		}, {
   141  			"TestGetProofNonExistent",
   142  			func(t *testing.T) { testGetProofNonExistent(t, client) },
   143  		}, {
   144  			"TestGetProofCanonicalizeKeys",
   145  			func(t *testing.T) { testGetProofCanonicalizeKeys(t, client) },
   146  		}, {
   147  			"TestGCStats",
   148  			func(t *testing.T) { testGCStats(t, client) },
   149  		}, {
   150  			"TestMemStats",
   151  			func(t *testing.T) { testMemStats(t, client) },
   152  		}, {
   153  			"TestGetNodeInfo",
   154  			func(t *testing.T) { testGetNodeInfo(t, client) },
   155  		}, {
   156  			"TestSubscribePendingTxHashes",
   157  			func(t *testing.T) { testSubscribePendingTransactions(t, client) },
   158  		}, {
   159  			"TestCallContract",
   160  			func(t *testing.T) { testCallContract(t, client) },
   161  		}, {
   162  			"TestCallContractWithBlockOverrides",
   163  			func(t *testing.T) { testCallContractWithBlockOverrides(t, client) },
   164  		},
   165  		// The testaccesslist is a bit time-sensitive: the newTestBackend imports
   166  		// one block. The `testAccessList` fails if the miner has not yet created a
   167  		// new pending-block after the import event.
   168  		// Hence: this test should be last, execute the tests serially.
   169  		{
   170  			"TestAccessList",
   171  			func(t *testing.T) { testAccessList(t, client) },
   172  		},
   173  		{
   174  			"TestTraceTransaction",
   175  			func(t *testing.T) { testTraceTransactions(t, client) },
   176  		},
   177  		{
   178  			"TestSetHead",
   179  			func(t *testing.T) { testSetHead(t, client) },
   180  		},
   181  	}
   182  	for _, tt := range tests {
   183  		t.Run(tt.name, tt.test)
   184  	}
   185  }
   186  
   187  func testAccessList(t *testing.T, client *rpc.Client) {
   188  	ec := New(client)
   189  
   190  	for i, tc := range []struct {
   191  		msg       ethereum.CallMsg
   192  		wantGas   uint64
   193  		wantErr   string
   194  		wantVMErr string
   195  		wantAL    string
   196  	}{
   197  		{ // Test transfer
   198  			msg: ethereum.CallMsg{
   199  				From:     testAddr,
   200  				To:       &common.Address{},
   201  				Gas:      21000,
   202  				GasPrice: big.NewInt(875000000),
   203  				Value:    big.NewInt(1),
   204  			},
   205  			wantGas: 21000,
   206  			wantAL:  `[]`,
   207  		},
   208  		{ // Test reverting transaction
   209  			msg: ethereum.CallMsg{
   210  				From:     testAddr,
   211  				To:       nil,
   212  				Gas:      100000,
   213  				GasPrice: big.NewInt(1000000000),
   214  				Value:    big.NewInt(1),
   215  				Data:     common.FromHex("0x608060806080608155fd"),
   216  			},
   217  			wantGas:   77496,
   218  			wantVMErr: "execution reverted",
   219  			wantAL: `[
   220    {
   221      "address": "0xdb7d6ab1f17c6b31909ae466702703daef9269cf",
   222      "storageKeys": [
   223        "0x0000000000000000000000000000000000000000000000000000000000000081"
   224      ]
   225    }
   226  ]`,
   227  		},
   228  		{ // error when gasPrice is less than baseFee
   229  			msg: ethereum.CallMsg{
   230  				From:     testAddr,
   231  				To:       &common.Address{},
   232  				Gas:      21000,
   233  				GasPrice: big.NewInt(1), // less than baseFee
   234  				Value:    big.NewInt(1),
   235  			},
   236  			wantErr: "max fee per gas less than block base fee",
   237  		},
   238  		{ // when gasPrice is not specified
   239  			msg: ethereum.CallMsg{
   240  				From:  testAddr,
   241  				To:    &common.Address{},
   242  				Gas:   21000,
   243  				Value: big.NewInt(1),
   244  			},
   245  			wantGas: 21000,
   246  			wantAL:  `[]`,
   247  		},
   248  	} {
   249  		al, gas, vmErr, err := ec.CreateAccessList(context.Background(), tc.msg)
   250  		if tc.wantErr != "" {
   251  			if !strings.Contains(err.Error(), tc.wantErr) {
   252  				t.Fatalf("test %d: wrong error: %v", i, err)
   253  			}
   254  			continue
   255  		} else if err != nil {
   256  			t.Fatalf("test %d: wrong error: %v", i, err)
   257  		}
   258  		if have, want := vmErr, tc.wantVMErr; have != want {
   259  			t.Fatalf("test %d: vmErr wrong, have %v want %v", i, have, want)
   260  		}
   261  		if have, want := gas, tc.wantGas; have != want {
   262  			t.Fatalf("test %d: gas wrong, have %v want %v", i, have, want)
   263  		}
   264  		haveList, _ := json.MarshalIndent(al, "", "  ")
   265  		if have, want := string(haveList), tc.wantAL; have != want {
   266  			t.Fatalf("test %d: access list wrong, have:\n%v\nwant:\n%v", i, have, want)
   267  		}
   268  	}
   269  }
   270  
   271  func testGetProof(t *testing.T, client *rpc.Client, addr common.Address) {
   272  	ec := New(client)
   273  	ethcl := ethclient.NewClient(client)
   274  	result, err := ec.GetProof(context.Background(), addr, []string{testSlot.String()}, nil)
   275  	if err != nil {
   276  		t.Fatal(err)
   277  	}
   278  	if result.Address != addr {
   279  		t.Fatalf("unexpected address, have: %v want: %v", result.Address, addr)
   280  	}
   281  	// test nonce
   282  	if nonce, _ := ethcl.NonceAt(context.Background(), addr, nil); result.Nonce != nonce {
   283  		t.Fatalf("invalid nonce, want: %v got: %v", nonce, result.Nonce)
   284  	}
   285  	// test balance
   286  	if balance, _ := ethcl.BalanceAt(context.Background(), addr, nil); result.Balance.Cmp(balance) != 0 {
   287  		t.Fatalf("invalid balance, want: %v got: %v", balance, result.Balance)
   288  	}
   289  	// test storage
   290  	if len(result.StorageProof) != 1 {
   291  		t.Fatalf("invalid storage proof, want 1 proof, got %v proof(s)", len(result.StorageProof))
   292  	}
   293  	for _, proof := range result.StorageProof {
   294  		if proof.Key != testSlot.String() {
   295  			t.Fatalf("invalid storage proof key, want: %q, got: %q", testSlot.String(), proof.Key)
   296  		}
   297  		slotValue, _ := ethcl.StorageAt(context.Background(), addr, common.HexToHash(proof.Key), nil)
   298  		if have, want := common.BigToHash(proof.Value), common.BytesToHash(slotValue); have != want {
   299  			t.Fatalf("addr %x, invalid storage proof value: have: %v, want: %v", addr, have, want)
   300  		}
   301  	}
   302  	// test code
   303  	code, _ := ethcl.CodeAt(context.Background(), addr, nil)
   304  	if have, want := result.CodeHash, crypto.Keccak256Hash(code); have != want {
   305  		t.Fatalf("codehash wrong, have %v want %v ", have, want)
   306  	}
   307  }
   308  
   309  func testGetProofCanonicalizeKeys(t *testing.T, client *rpc.Client) {
   310  	ec := New(client)
   311  
   312  	// Tests with non-canon input for storage keys.
   313  	// Here we check that the storage key is canonicalized.
   314  	result, err := ec.GetProof(context.Background(), testAddr, []string{"0x0dEadbeef"}, nil)
   315  	if err != nil {
   316  		t.Fatal(err)
   317  	}
   318  	if result.StorageProof[0].Key != "0xdeadbeef" {
   319  		t.Fatalf("wrong storage key encoding in proof: %q", result.StorageProof[0].Key)
   320  	}
   321  	if result, err = ec.GetProof(context.Background(), testAddr, []string{"0x000deadbeef"}, nil); err != nil {
   322  		t.Fatal(err)
   323  	}
   324  	if result.StorageProof[0].Key != "0xdeadbeef" {
   325  		t.Fatalf("wrong storage key encoding in proof: %q", result.StorageProof[0].Key)
   326  	}
   327  
   328  	// If the requested storage key is 32 bytes long, it will be returned as is.
   329  	hashSizedKey := "0x00000000000000000000000000000000000000000000000000000000deadbeef"
   330  	result, err = ec.GetProof(context.Background(), testAddr, []string{hashSizedKey}, nil)
   331  	if err != nil {
   332  		t.Fatal(err)
   333  	}
   334  	if result.StorageProof[0].Key != hashSizedKey {
   335  		t.Fatalf("wrong storage key encoding in proof: %q", result.StorageProof[0].Key)
   336  	}
   337  }
   338  
   339  func testGetProofNonExistent(t *testing.T, client *rpc.Client) {
   340  	addr := common.HexToAddress("0x0001")
   341  	ec := New(client)
   342  	result, err := ec.GetProof(context.Background(), addr, nil, nil)
   343  	if err != nil {
   344  		t.Fatal(err)
   345  	}
   346  	if result.Address != addr {
   347  		t.Fatalf("unexpected address, have: %v want: %v", result.Address, addr)
   348  	}
   349  	// test nonce
   350  	if result.Nonce != 0 {
   351  		t.Fatalf("invalid nonce, want: %v got: %v", 0, result.Nonce)
   352  	}
   353  	// test balance
   354  	if result.Balance.Sign() != 0 {
   355  		t.Fatalf("invalid balance, want: %v got: %v", 0, result.Balance)
   356  	}
   357  	// test storage
   358  	if have := len(result.StorageProof); have != 0 {
   359  		t.Fatalf("invalid storage proof, want 0 proof, got %v proof(s)", have)
   360  	}
   361  	// test codeHash
   362  	if have, want := result.CodeHash, (common.Hash{}); have != want {
   363  		t.Fatalf("codehash wrong, have %v want %v ", have, want)
   364  	}
   365  	// test codeHash
   366  	if have, want := result.StorageHash, (common.Hash{}); have != want {
   367  		t.Fatalf("storagehash wrong, have %v want %v ", have, want)
   368  	}
   369  }
   370  
   371  func testGCStats(t *testing.T, client *rpc.Client) {
   372  	ec := New(client)
   373  	_, err := ec.GCStats(context.Background())
   374  	if err != nil {
   375  		t.Fatal(err)
   376  	}
   377  }
   378  
   379  func testMemStats(t *testing.T, client *rpc.Client) {
   380  	ec := New(client)
   381  	stats, err := ec.MemStats(context.Background())
   382  	if err != nil {
   383  		t.Fatal(err)
   384  	}
   385  	if stats.Alloc == 0 {
   386  		t.Fatal("Invalid mem stats retrieved")
   387  	}
   388  }
   389  
   390  func testGetNodeInfo(t *testing.T, client *rpc.Client) {
   391  	ec := New(client)
   392  	info, err := ec.GetNodeInfo(context.Background())
   393  	if err != nil {
   394  		t.Fatal(err)
   395  	}
   396  
   397  	if info.Name == "" {
   398  		t.Fatal("Invalid node info retrieved")
   399  	}
   400  }
   401  
   402  func testSetHead(t *testing.T, client *rpc.Client) {
   403  	ec := New(client)
   404  	err := ec.SetHead(context.Background(), big.NewInt(0))
   405  	if err != nil {
   406  		t.Fatal(err)
   407  	}
   408  }
   409  
   410  func testSubscribePendingTransactions(t *testing.T, client *rpc.Client) {
   411  	ec := New(client)
   412  	ethcl := ethclient.NewClient(client)
   413  
   414  	// Subscribe to Transactions
   415  	ch1 := make(chan common.Hash)
   416  	ec.SubscribePendingTransactions(context.Background(), ch1)
   417  
   418  	// Subscribe to Transactions
   419  	ch2 := make(chan *types.Transaction)
   420  	ec.SubscribeFullPendingTransactions(context.Background(), ch2)
   421  
   422  	// Send a transaction
   423  	chainID, err := ethcl.ChainID(context.Background())
   424  	if err != nil {
   425  		t.Fatal(err)
   426  	}
   427  	nonce, err := ethcl.NonceAt(context.Background(), testAddr, nil)
   428  	if err != nil {
   429  		t.Fatal(err)
   430  	}
   431  	// Create transaction
   432  	tx := types.NewTransaction(nonce, common.Address{1}, big.NewInt(1), 22000, big.NewInt(1), nil)
   433  	signer := types.LatestSignerForChainID(chainID)
   434  	signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
   435  	if err != nil {
   436  		t.Fatal(err)
   437  	}
   438  	signedTx, err := tx.WithSignature(signer, signature)
   439  	if err != nil {
   440  		t.Fatal(err)
   441  	}
   442  	// Send transaction
   443  	err = ethcl.SendTransaction(context.Background(), signedTx)
   444  	if err != nil {
   445  		t.Fatal(err)
   446  	}
   447  	// Check that the transaction was sent over the channel
   448  	hash := <-ch1
   449  	if hash != signedTx.Hash() {
   450  		t.Fatalf("Invalid tx hash received, got %v, want %v", hash, signedTx.Hash())
   451  	}
   452  	// Check that the transaction was sent over the channel
   453  	tx = <-ch2
   454  	if tx.Hash() != signedTx.Hash() {
   455  		t.Fatalf("Invalid tx hash received, got %v, want %v", tx.Hash(), signedTx.Hash())
   456  	}
   457  }
   458  
   459  func testCallContract(t *testing.T, client *rpc.Client) {
   460  	ec := New(client)
   461  	msg := ethereum.CallMsg{
   462  		From:     testAddr,
   463  		To:       &common.Address{},
   464  		Gas:      21000,
   465  		GasPrice: big.NewInt(1000000000),
   466  		Value:    big.NewInt(1),
   467  	}
   468  	// CallContract without override
   469  	if _, err := ec.CallContract(context.Background(), msg, big.NewInt(0), nil); err != nil {
   470  		t.Fatalf("unexpected error: %v", err)
   471  	}
   472  	// CallContract with override
   473  	override := OverrideAccount{
   474  		Nonce: 1,
   475  	}
   476  	mapAcc := make(map[common.Address]OverrideAccount)
   477  	mapAcc[testAddr] = override
   478  	if _, err := ec.CallContract(context.Background(), msg, big.NewInt(0), &mapAcc); err != nil {
   479  		t.Fatalf("unexpected error: %v", err)
   480  	}
   481  }
   482  
   483  func testTraceTransactions(t *testing.T, client *rpc.Client) {
   484  	ec := New(client)
   485  	for _, txHash := range testTxHashes {
   486  		// Struct logger
   487  		_, err := ec.TraceTransaction(context.Background(), txHash, nil)
   488  		if err != nil {
   489  			t.Fatal(err)
   490  		}
   491  
   492  		// Struct logger
   493  		_, err = ec.TraceTransaction(context.Background(), txHash,
   494  			&tracers.TraceConfig{},
   495  		)
   496  		if err != nil {
   497  			t.Fatal(err)
   498  		}
   499  	}
   500  }
   501  
   502  func TestOverrideAccountMarshal(t *testing.T) {
   503  	om := map[common.Address]OverrideAccount{
   504  		{0x11}: {
   505  			// Zero-valued nonce is not overridden, but simply dropped by the encoder.
   506  			Nonce: 0,
   507  		},
   508  		{0xaa}: {
   509  			Nonce: 5,
   510  		},
   511  		{0xbb}: {
   512  			Code: []byte{1},
   513  		},
   514  		{0xcc}: {
   515  			// 'code', 'balance', 'state' should be set when input is
   516  			// a non-nil but empty value.
   517  			Code:    []byte{},
   518  			Balance: big.NewInt(0),
   519  			State:   map[common.Hash]common.Hash{},
   520  			// For 'stateDiff' the behavior is different, empty map
   521  			// is ignored because it makes no difference.
   522  			StateDiff: map[common.Hash]common.Hash{},
   523  		},
   524  	}
   525  
   526  	marshalled, err := json.MarshalIndent(&om, "", "  ")
   527  	if err != nil {
   528  		t.Fatalf("unexpected error: %v", err)
   529  	}
   530  
   531  	expected := `{
   532    "0x1100000000000000000000000000000000000000": {},
   533    "0xaa00000000000000000000000000000000000000": {
   534      "nonce": "0x5"
   535    },
   536    "0xbb00000000000000000000000000000000000000": {
   537      "code": "0x01"
   538    },
   539    "0xcc00000000000000000000000000000000000000": {
   540      "code": "0x",
   541      "balance": "0x0",
   542      "state": {}
   543    }
   544  }`
   545  
   546  	if string(marshalled) != expected {
   547  		t.Error("wrong output:", string(marshalled))
   548  		t.Error("want:", expected)
   549  	}
   550  }
   551  
   552  func TestBlockOverridesMarshal(t *testing.T) {
   553  	for i, tt := range []struct {
   554  		bo   BlockOverrides
   555  		want string
   556  	}{
   557  		{
   558  			bo:   BlockOverrides{},
   559  			want: `{}`,
   560  		},
   561  		{
   562  			bo: BlockOverrides{
   563  				Coinbase: common.HexToAddress("0x1111111111111111111111111111111111111111"),
   564  			},
   565  			want: `{"feeRecipient":"0x1111111111111111111111111111111111111111"}`,
   566  		},
   567  		{
   568  			bo: BlockOverrides{
   569  				Number:     big.NewInt(1),
   570  				Difficulty: big.NewInt(2),
   571  				Time:       3,
   572  				GasLimit:   4,
   573  				BaseFee:    big.NewInt(5),
   574  			},
   575  			want: `{"number":"0x1","difficulty":"0x2","time":"0x3","gasLimit":"0x4","baseFeePerGas":"0x5"}`,
   576  		},
   577  	} {
   578  		marshalled, err := json.Marshal(&tt.bo)
   579  		if err != nil {
   580  			t.Fatalf("unexpected error: %v", err)
   581  		}
   582  		if string(marshalled) != tt.want {
   583  			t.Errorf("Testcase #%d failed. expected\n%s\ngot\n%s", i, tt.want, string(marshalled))
   584  		}
   585  	}
   586  }
   587  
   588  func testCallContractWithBlockOverrides(t *testing.T, client *rpc.Client) {
   589  	ec := New(client)
   590  	msg := ethereum.CallMsg{
   591  		From:     testAddr,
   592  		To:       &common.Address{},
   593  		Gas:      50000,
   594  		GasPrice: big.NewInt(1000000000),
   595  		Value:    big.NewInt(1),
   596  	}
   597  	override := OverrideAccount{
   598  		// Returns coinbase address.
   599  		Code: common.FromHex("0x41806000526014600cf3"),
   600  	}
   601  	mapAcc := make(map[common.Address]OverrideAccount)
   602  	mapAcc[common.Address{}] = override
   603  	res, err := ec.CallContract(context.Background(), msg, big.NewInt(0), &mapAcc)
   604  	if err != nil {
   605  		t.Fatalf("unexpected error: %v", err)
   606  	}
   607  	if !bytes.Equal(res, common.FromHex("0x0000000000000000000000000000000000000000")) {
   608  		t.Fatalf("unexpected result: %x", res)
   609  	}
   610  
   611  	// Now test with block overrides
   612  	bo := BlockOverrides{
   613  		Coinbase: common.HexToAddress("0x1111111111111111111111111111111111111111"),
   614  	}
   615  	res, err = ec.CallContractWithBlockOverrides(context.Background(), msg, big.NewInt(0), &mapAcc, bo)
   616  	if err != nil {
   617  		t.Fatalf("unexpected error: %v", err)
   618  	}
   619  	if !bytes.Equal(res, common.FromHex("0x1111111111111111111111111111111111111111")) {
   620  		t.Fatalf("unexpected result: %x", res)
   621  	}
   622  }