github.com/ethereum/go-ethereum@v1.16.1/internal/ethapi/api_test.go (about)

     1  // Copyright 2023 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 ethapi
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"crypto/ecdsa"
    23  	"crypto/sha256"
    24  	"encoding/json"
    25  	"errors"
    26  	"fmt"
    27  	"math"
    28  	"math/big"
    29  	"os"
    30  	"path/filepath"
    31  	"reflect"
    32  	"slices"
    33  	"strings"
    34  	"testing"
    35  	"time"
    36  
    37  	"github.com/ethereum/go-ethereum/accounts/abi"
    38  	"github.com/ethereum/go-ethereum/internal/ethapi/override"
    39  
    40  	"github.com/ethereum/go-ethereum"
    41  	"github.com/ethereum/go-ethereum/accounts"
    42  	"github.com/ethereum/go-ethereum/accounts/keystore"
    43  	"github.com/ethereum/go-ethereum/common"
    44  	"github.com/ethereum/go-ethereum/common/hexutil"
    45  	"github.com/ethereum/go-ethereum/consensus"
    46  	"github.com/ethereum/go-ethereum/consensus/beacon"
    47  	"github.com/ethereum/go-ethereum/consensus/ethash"
    48  	"github.com/ethereum/go-ethereum/core"
    49  	"github.com/ethereum/go-ethereum/core/filtermaps"
    50  	"github.com/ethereum/go-ethereum/core/rawdb"
    51  	"github.com/ethereum/go-ethereum/core/state"
    52  	"github.com/ethereum/go-ethereum/core/types"
    53  	"github.com/ethereum/go-ethereum/core/vm"
    54  	"github.com/ethereum/go-ethereum/crypto"
    55  	"github.com/ethereum/go-ethereum/crypto/kzg4844"
    56  	"github.com/ethereum/go-ethereum/ethdb"
    57  	"github.com/ethereum/go-ethereum/event"
    58  	"github.com/ethereum/go-ethereum/internal/blocktest"
    59  	"github.com/ethereum/go-ethereum/params"
    60  	"github.com/ethereum/go-ethereum/rpc"
    61  	"github.com/holiman/uint256"
    62  	"github.com/stretchr/testify/require"
    63  )
    64  
    65  func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainConfig) {
    66  	var (
    67  		signer = types.LatestSigner(config)
    68  		key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    69  	)
    70  
    71  	for i, tt := range tests {
    72  		var tx2 types.Transaction
    73  		tx, err := types.SignNewTx(key, signer, tt.Tx)
    74  		if err != nil {
    75  			t.Fatalf("test %d: signing failed: %v", i, err)
    76  		}
    77  		// Regular transaction
    78  		if data, err := json.Marshal(tx); err != nil {
    79  			t.Fatalf("test %d: marshalling failed; %v", i, err)
    80  		} else if err = tx2.UnmarshalJSON(data); err != nil {
    81  			t.Fatalf("test %d: sunmarshal failed: %v", i, err)
    82  		} else if want, have := tx.Hash(), tx2.Hash(); want != have {
    83  			t.Fatalf("test %d: stx changed, want %x have %x", i, want, have)
    84  		}
    85  
    86  		// rpcTransaction
    87  		rpcTx := newRPCTransaction(tx, common.Hash{}, 0, 0, 0, nil, config)
    88  		if data, err := json.Marshal(rpcTx); err != nil {
    89  			t.Fatalf("test %d: marshalling failed; %v", i, err)
    90  		} else if err = tx2.UnmarshalJSON(data); err != nil {
    91  			t.Fatalf("test %d: unmarshal failed: %v", i, err)
    92  		} else if want, have := tx.Hash(), tx2.Hash(); want != have {
    93  			t.Fatalf("test %d: tx changed, want %x have %x", i, want, have)
    94  		} else {
    95  			want, have := tt.Want, string(data)
    96  			require.JSONEqf(t, want, have, "test %d: rpc json not match, want %s have %s", i, want, have)
    97  		}
    98  	}
    99  }
   100  
   101  func TestTransaction_RoundTripRpcJSON(t *testing.T) {
   102  	t.Parallel()
   103  
   104  	var (
   105  		config = params.AllEthashProtocolChanges
   106  		tests  = allTransactionTypes(common.Address{0xde, 0xad}, config)
   107  	)
   108  	testTransactionMarshal(t, tests, config)
   109  }
   110  
   111  func TestTransactionBlobTx(t *testing.T) {
   112  	t.Parallel()
   113  
   114  	config := *params.TestChainConfig
   115  	config.ShanghaiTime = new(uint64)
   116  	config.CancunTime = new(uint64)
   117  	tests := allBlobTxs(common.Address{0xde, 0xad}, &config)
   118  
   119  	testTransactionMarshal(t, tests, &config)
   120  }
   121  
   122  type txData struct {
   123  	Tx   types.TxData
   124  	Want string
   125  }
   126  
   127  func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txData {
   128  	return []txData{
   129  		{
   130  			Tx: &types.LegacyTx{
   131  				Nonce:    5,
   132  				GasPrice: big.NewInt(6),
   133  				Gas:      7,
   134  				To:       &addr,
   135  				Value:    big.NewInt(8),
   136  				Data:     []byte{0, 1, 2, 3, 4},
   137  				V:        big.NewInt(9),
   138  				R:        big.NewInt(10),
   139  				S:        big.NewInt(11),
   140  			},
   141  			Want: `{
   142  				"blockHash": null,
   143  				"blockNumber": null,
   144  				"from": "0x71562b71999873db5b286df957af199ec94617f7",
   145  				"gas": "0x7",
   146  				"gasPrice": "0x6",
   147  				"hash": "0x5f3240454cd09a5d8b1c5d651eefae7a339262875bcd2d0e6676f3d989967008",
   148  				"input": "0x0001020304",
   149  				"nonce": "0x5",
   150  				"to": "0xdead000000000000000000000000000000000000",
   151  				"transactionIndex": null,
   152  				"value": "0x8",
   153  				"type": "0x0",
   154  				"chainId": "0x539",
   155  				"v": "0xa96",
   156  				"r": "0xbc85e96592b95f7160825d837abb407f009df9ebe8f1b9158a4b8dd093377f75",
   157  				"s": "0x1b55ea3af5574c536967b039ba6999ef6c89cf22fc04bcb296e0e8b0b9b576f5"
   158  			}`,
   159  		}, {
   160  			Tx: &types.LegacyTx{
   161  				Nonce:    5,
   162  				GasPrice: big.NewInt(6),
   163  				Gas:      7,
   164  				To:       nil,
   165  				Value:    big.NewInt(8),
   166  				Data:     []byte{0, 1, 2, 3, 4},
   167  				V:        big.NewInt(32),
   168  				R:        big.NewInt(10),
   169  				S:        big.NewInt(11),
   170  			},
   171  			Want: `{
   172  				"blockHash": null,
   173  				"blockNumber": null,
   174  				"from": "0x71562b71999873db5b286df957af199ec94617f7",
   175  				"gas": "0x7",
   176  				"gasPrice": "0x6",
   177  				"hash": "0x806e97f9d712b6cb7e781122001380a2837531b0fc1e5f5d78174ad4cb699873",
   178  				"input": "0x0001020304",
   179  				"nonce": "0x5",
   180  				"to": null,
   181  				"transactionIndex": null,
   182  				"value": "0x8",
   183  				"type": "0x0",
   184  				"chainId": "0x539",
   185  				"v": "0xa96",
   186  				"r": "0x9dc28b267b6ad4e4af6fe9289668f9305c2eb7a3241567860699e478af06835a",
   187  				"s": "0xa0b51a071aa9bed2cd70aedea859779dff039e3630ea38497d95202e9b1fec7"
   188  			}`,
   189  		},
   190  		{
   191  			Tx: &types.AccessListTx{
   192  				ChainID:  config.ChainID,
   193  				Nonce:    5,
   194  				GasPrice: big.NewInt(6),
   195  				Gas:      7,
   196  				To:       &addr,
   197  				Value:    big.NewInt(8),
   198  				Data:     []byte{0, 1, 2, 3, 4},
   199  				AccessList: types.AccessList{
   200  					types.AccessTuple{
   201  						Address:     common.Address{0x2},
   202  						StorageKeys: []common.Hash{types.EmptyRootHash},
   203  					},
   204  				},
   205  				V: big.NewInt(32),
   206  				R: big.NewInt(10),
   207  				S: big.NewInt(11),
   208  			},
   209  			Want: `{
   210  				"blockHash": null,
   211  				"blockNumber": null,
   212  				"from": "0x71562b71999873db5b286df957af199ec94617f7",
   213  				"gas": "0x7",
   214  				"gasPrice": "0x6",
   215  				"hash": "0x121347468ee5fe0a29f02b49b4ffd1c8342bc4255146bb686cd07117f79e7129",
   216  				"input": "0x0001020304",
   217  				"nonce": "0x5",
   218  				"to": "0xdead000000000000000000000000000000000000",
   219  				"transactionIndex": null,
   220  				"value": "0x8",
   221  				"type": "0x1",
   222  				"accessList": [
   223  					{
   224  						"address": "0x0200000000000000000000000000000000000000",
   225  						"storageKeys": [
   226  							"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
   227  						]
   228  					}
   229  				],
   230  				"chainId": "0x539",
   231  				"v": "0x0",
   232  				"r": "0xf372ad499239ae11d91d34c559ffc5dab4daffc0069e03afcabdcdf231a0c16b",
   233  				"s": "0x28573161d1f9472fa0fd4752533609e72f06414f7ab5588699a7141f65d2abf",
   234  				"yParity": "0x0"
   235  			}`,
   236  		}, {
   237  			Tx: &types.AccessListTx{
   238  				ChainID:  config.ChainID,
   239  				Nonce:    5,
   240  				GasPrice: big.NewInt(6),
   241  				Gas:      7,
   242  				To:       nil,
   243  				Value:    big.NewInt(8),
   244  				Data:     []byte{0, 1, 2, 3, 4},
   245  				AccessList: types.AccessList{
   246  					types.AccessTuple{
   247  						Address:     common.Address{0x2},
   248  						StorageKeys: []common.Hash{types.EmptyRootHash},
   249  					},
   250  				},
   251  				V: big.NewInt(32),
   252  				R: big.NewInt(10),
   253  				S: big.NewInt(11),
   254  			},
   255  			Want: `{
   256  				"blockHash": null,
   257  				"blockNumber": null,
   258  				"from": "0x71562b71999873db5b286df957af199ec94617f7",
   259  				"gas": "0x7",
   260  				"gasPrice": "0x6",
   261  				"hash": "0x067c3baebede8027b0f828a9d933be545f7caaec623b00684ac0659726e2055b",
   262  				"input": "0x0001020304",
   263  				"nonce": "0x5",
   264  				"to": null,
   265  				"transactionIndex": null,
   266  				"value": "0x8",
   267  				"type": "0x1",
   268  				"accessList": [
   269  					{
   270  						"address": "0x0200000000000000000000000000000000000000",
   271  						"storageKeys": [
   272  							"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
   273  						]
   274  					}
   275  				],
   276  				"chainId": "0x539",
   277  				"v": "0x1",
   278  				"r": "0x542981b5130d4613897fbab144796cb36d3cb3d7807d47d9c7f89ca7745b085c",
   279  				"s": "0x7425b9dd6c5deaa42e4ede35d0c4570c4624f68c28d812c10d806ffdf86ce63",
   280  				"yParity": "0x1"
   281  			}`,
   282  		}, {
   283  			Tx: &types.DynamicFeeTx{
   284  				ChainID:   config.ChainID,
   285  				Nonce:     5,
   286  				GasTipCap: big.NewInt(6),
   287  				GasFeeCap: big.NewInt(9),
   288  				Gas:       7,
   289  				To:        &addr,
   290  				Value:     big.NewInt(8),
   291  				Data:      []byte{0, 1, 2, 3, 4},
   292  				AccessList: types.AccessList{
   293  					types.AccessTuple{
   294  						Address:     common.Address{0x2},
   295  						StorageKeys: []common.Hash{types.EmptyRootHash},
   296  					},
   297  				},
   298  				V: big.NewInt(32),
   299  				R: big.NewInt(10),
   300  				S: big.NewInt(11),
   301  			},
   302  			Want: `{
   303  				"blockHash": null,
   304  				"blockNumber": null,
   305  				"from": "0x71562b71999873db5b286df957af199ec94617f7",
   306  				"gas": "0x7",
   307  				"gasPrice": "0x9",
   308  				"maxFeePerGas": "0x9",
   309  				"maxPriorityFeePerGas": "0x6",
   310  				"hash": "0xb63e0b146b34c3e9cb7fbabb5b3c081254a7ded6f1b65324b5898cc0545d79ff",
   311  				"input": "0x0001020304",
   312  				"nonce": "0x5",
   313  				"to": "0xdead000000000000000000000000000000000000",
   314  				"transactionIndex": null,
   315  				"value": "0x8",
   316  				"type": "0x2",
   317  				"accessList": [
   318  					{
   319  						"address": "0x0200000000000000000000000000000000000000",
   320  						"storageKeys": [
   321  							"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
   322  						]
   323  					}
   324  				],
   325  				"chainId": "0x539",
   326  				"v": "0x1",
   327  				"r": "0x3b167e05418a8932cd53d7578711fe1a76b9b96c48642402bb94978b7a107e80",
   328  				"s": "0x22f98a332d15ea2cc80386c1ebaa31b0afebfa79ebc7d039a1e0074418301fef",
   329  				"yParity": "0x1"
   330  			}`,
   331  		}, {
   332  			Tx: &types.DynamicFeeTx{
   333  				ChainID:    config.ChainID,
   334  				Nonce:      5,
   335  				GasTipCap:  big.NewInt(6),
   336  				GasFeeCap:  big.NewInt(9),
   337  				Gas:        7,
   338  				To:         nil,
   339  				Value:      big.NewInt(8),
   340  				Data:       []byte{0, 1, 2, 3, 4},
   341  				AccessList: types.AccessList{},
   342  				V:          big.NewInt(32),
   343  				R:          big.NewInt(10),
   344  				S:          big.NewInt(11),
   345  			},
   346  			Want: `{
   347  				"blockHash": null,
   348  				"blockNumber": null,
   349  				"from": "0x71562b71999873db5b286df957af199ec94617f7",
   350  				"gas": "0x7",
   351  				"gasPrice": "0x9",
   352  				"maxFeePerGas": "0x9",
   353  				"maxPriorityFeePerGas": "0x6",
   354  				"hash": "0xcbab17ee031a9d5b5a09dff909f0a28aedb9b295ac0635d8710d11c7b806ec68",
   355  				"input": "0x0001020304",
   356  				"nonce": "0x5",
   357  				"to": null,
   358  				"transactionIndex": null,
   359  				"value": "0x8",
   360  				"type": "0x2",
   361  				"accessList": [],
   362  				"chainId": "0x539",
   363  				"v": "0x0",
   364  				"r": "0x6446b8a682db7e619fc6b4f6d1f708f6a17351a41c7fbd63665f469bc78b41b9",
   365  				"s": "0x7626abc15834f391a117c63450047309dbf84c5ce3e8e609b607062641e2de43",
   366  				"yParity": "0x0"
   367  			}`,
   368  		},
   369  	}
   370  }
   371  
   372  func allBlobTxs(addr common.Address, config *params.ChainConfig) []txData {
   373  	return []txData{
   374  		{
   375  			Tx: &types.BlobTx{
   376  				Nonce:      6,
   377  				GasTipCap:  uint256.NewInt(1),
   378  				GasFeeCap:  uint256.NewInt(5),
   379  				Gas:        6,
   380  				To:         addr,
   381  				BlobFeeCap: uint256.NewInt(1),
   382  				BlobHashes: []common.Hash{{1}},
   383  				Value:      new(uint256.Int),
   384  				V:          uint256.NewInt(32),
   385  				R:          uint256.NewInt(10),
   386  				S:          uint256.NewInt(11),
   387  			},
   388  			Want: `{
   389                  "blockHash": null,
   390                  "blockNumber": null,
   391                  "from": "0x71562b71999873db5b286df957af199ec94617f7",
   392                  "gas": "0x6",
   393                  "gasPrice": "0x5",
   394                  "maxFeePerGas": "0x5",
   395                  "maxPriorityFeePerGas": "0x1",
   396                  "maxFeePerBlobGas": "0x1",
   397                  "hash": "0x1f2b59a20e61efc615ad0cbe936379d6bbea6f938aafaf35eb1da05d8e7f46a3",
   398                  "input": "0x",
   399                  "nonce": "0x6",
   400                  "to": "0xdead000000000000000000000000000000000000",
   401                  "transactionIndex": null,
   402                  "value": "0x0",
   403                  "type": "0x3",
   404                  "accessList": [],
   405                  "chainId": "0x1",
   406                  "blobVersionedHashes": [
   407                      "0x0100000000000000000000000000000000000000000000000000000000000000"
   408                  ],
   409                  "v": "0x0",
   410                  "r": "0x618be8908e0e5320f8f3b48042a079fe5a335ebd4ed1422a7d2207cd45d872bc",
   411                  "s": "0x27b2bc6c80e849a8e8b764d4549d8c2efac3441e73cf37054eb0a9b9f8e89b27",
   412                  "yParity": "0x0"
   413              }`,
   414  		},
   415  	}
   416  }
   417  
   418  func newTestAccountManager(t *testing.T) (*accounts.Manager, accounts.Account) {
   419  	var (
   420  		dir        = t.TempDir()
   421  		am         = accounts.NewManager(nil)
   422  		b          = keystore.NewKeyStore(dir, 2, 1)
   423  		testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   424  	)
   425  	acc, err := b.ImportECDSA(testKey, "")
   426  	if err != nil {
   427  		t.Fatalf("failed to create test account: %v", err)
   428  	}
   429  	if err := b.Unlock(acc, ""); err != nil {
   430  		t.Fatalf("failed to unlock account: %v\n", err)
   431  	}
   432  	am.AddBackend(b)
   433  	return am, acc
   434  }
   435  
   436  type testBackend struct {
   437  	db      ethdb.Database
   438  	chain   *core.BlockChain
   439  	pending *types.Block
   440  	accman  *accounts.Manager
   441  	acc     accounts.Account
   442  }
   443  
   444  func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.Engine, generator func(i int, b *core.BlockGen)) *testBackend {
   445  	options := core.DefaultConfig().WithArchive(true)
   446  	options.TxLookupLimit = 0 // index all txs
   447  
   448  	accman, acc := newTestAccountManager(t)
   449  	gspec.Alloc[acc.Address] = types.Account{Balance: big.NewInt(params.Ether)}
   450  
   451  	// Generate blocks for testing
   452  	db, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator)
   453  
   454  	chain, err := core.NewBlockChain(db, gspec, engine, options)
   455  	if err != nil {
   456  		t.Fatalf("failed to create tester chain: %v", err)
   457  	}
   458  	if n, err := chain.InsertChain(blocks); err != nil {
   459  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
   460  	}
   461  
   462  	backend := &testBackend{db: db, chain: chain, accman: accman, acc: acc}
   463  	return backend
   464  }
   465  
   466  func (b *testBackend) setPendingBlock(block *types.Block) {
   467  	b.pending = block
   468  }
   469  
   470  func (b testBackend) SyncProgress(ctx context.Context) ethereum.SyncProgress {
   471  	return ethereum.SyncProgress{}
   472  }
   473  func (b testBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
   474  	return big.NewInt(0), nil
   475  }
   476  func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) {
   477  	return nil, nil, nil, nil, nil, nil, nil
   478  }
   479  func (b testBackend) BlobBaseFee(ctx context.Context) *big.Int { return new(big.Int) }
   480  func (b testBackend) ChainDb() ethdb.Database                  { return b.db }
   481  func (b testBackend) AccountManager() *accounts.Manager        { return b.accman }
   482  func (b testBackend) ExtRPCEnabled() bool                      { return false }
   483  func (b testBackend) RPCGasCap() uint64                        { return 10000000 }
   484  func (b testBackend) RPCEVMTimeout() time.Duration             { return time.Second }
   485  func (b testBackend) RPCTxFeeCap() float64                     { return 0 }
   486  func (b testBackend) UnprotectedAllowed() bool                 { return false }
   487  func (b testBackend) SetHead(number uint64)                    {}
   488  func (b testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
   489  	if number == rpc.LatestBlockNumber {
   490  		return b.chain.CurrentBlock(), nil
   491  	}
   492  	if number == rpc.PendingBlockNumber && b.pending != nil {
   493  		return b.pending.Header(), nil
   494  	}
   495  	return b.chain.GetHeaderByNumber(uint64(number)), nil
   496  }
   497  func (b testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
   498  	return b.chain.GetHeaderByHash(hash), nil
   499  }
   500  func (b testBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) {
   501  	if blockNr, ok := blockNrOrHash.Number(); ok {
   502  		return b.HeaderByNumber(ctx, blockNr)
   503  	}
   504  	if blockHash, ok := blockNrOrHash.Hash(); ok {
   505  		return b.HeaderByHash(ctx, blockHash)
   506  	}
   507  	panic("unknown type rpc.BlockNumberOrHash")
   508  }
   509  
   510  func (b testBackend) CurrentHeader() *types.Header { return b.chain.CurrentHeader() }
   511  func (b testBackend) CurrentBlock() *types.Header  { return b.chain.CurrentBlock() }
   512  func (b testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
   513  	if number == rpc.LatestBlockNumber {
   514  		head := b.chain.CurrentBlock()
   515  		return b.chain.GetBlock(head.Hash(), head.Number.Uint64()), nil
   516  	}
   517  	if number == rpc.PendingBlockNumber {
   518  		return b.pending, nil
   519  	}
   520  	if number == rpc.EarliestBlockNumber {
   521  		number = 0
   522  	}
   523  	return b.chain.GetBlockByNumber(uint64(number)), nil
   524  }
   525  
   526  func (b testBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
   527  	return b.chain.GetBlockByHash(hash), nil
   528  }
   529  func (b testBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) {
   530  	if blockNr, ok := blockNrOrHash.Number(); ok {
   531  		return b.BlockByNumber(ctx, blockNr)
   532  	}
   533  	if blockHash, ok := blockNrOrHash.Hash(); ok {
   534  		return b.BlockByHash(ctx, blockHash)
   535  	}
   536  	panic("unknown type rpc.BlockNumberOrHash")
   537  }
   538  func (b testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
   539  	return b.chain.GetBlock(hash, uint64(number.Int64())).Body(), nil
   540  }
   541  func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
   542  	if number == rpc.PendingBlockNumber {
   543  		panic("pending state not implemented")
   544  	}
   545  	header, err := b.HeaderByNumber(ctx, number)
   546  	if err != nil {
   547  		return nil, nil, err
   548  	}
   549  	if header == nil {
   550  		return nil, nil, errors.New("header not found")
   551  	}
   552  	stateDb, err := b.chain.StateAt(header.Root)
   553  	return stateDb, header, err
   554  }
   555  func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
   556  	if blockNr, ok := blockNrOrHash.Number(); ok {
   557  		return b.StateAndHeaderByNumber(ctx, blockNr)
   558  	}
   559  	panic("only implemented for number")
   560  }
   561  func (b testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { panic("implement me") }
   562  func (b testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
   563  	header, err := b.HeaderByHash(ctx, hash)
   564  	if header == nil || err != nil {
   565  		return nil, err
   566  	}
   567  	receipts := rawdb.ReadReceipts(b.db, hash, header.Number.Uint64(), header.Time, b.chain.Config())
   568  	return receipts, nil
   569  }
   570  func (b testBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM {
   571  	if vmConfig == nil {
   572  		vmConfig = b.chain.GetVMConfig()
   573  	}
   574  	context := core.NewEVMBlockContext(header, b.chain, nil)
   575  	if blockContext != nil {
   576  		context = *blockContext
   577  	}
   578  	return vm.NewEVM(context, state, b.chain.Config(), *vmConfig)
   579  }
   580  func (b testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
   581  	panic("implement me")
   582  }
   583  func (b testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
   584  	panic("implement me")
   585  }
   586  func (b testBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
   587  	panic("implement me")
   588  }
   589  func (b testBackend) GetCanonicalTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) {
   590  	tx, blockHash, blockNumber, index := rawdb.ReadCanonicalTransaction(b.db, txHash)
   591  	return tx != nil, tx, blockHash, blockNumber, index
   592  }
   593  func (b testBackend) GetCanonicalReceipt(tx *types.Transaction, blockHash common.Hash, blockNumber, blockIndex uint64) (*types.Receipt, error) {
   594  	return b.chain.GetCanonicalReceipt(tx, blockHash, blockNumber, blockIndex)
   595  }
   596  func (b testBackend) TxIndexDone() bool {
   597  	return true
   598  }
   599  func (b testBackend) GetPoolTransactions() (types.Transactions, error)         { panic("implement me") }
   600  func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") }
   601  func (b testBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
   602  	return 0, nil
   603  }
   604  func (b testBackend) Stats() (pending int, queued int) { panic("implement me") }
   605  func (b testBackend) TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
   606  	panic("implement me")
   607  }
   608  func (b testBackend) TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) {
   609  	panic("implement me")
   610  }
   611  func (b testBackend) SubscribeNewTxsEvent(events chan<- core.NewTxsEvent) event.Subscription {
   612  	panic("implement me")
   613  }
   614  func (b testBackend) ChainConfig() *params.ChainConfig { return b.chain.Config() }
   615  func (b testBackend) Engine() consensus.Engine         { return b.chain.Engine() }
   616  func (b testBackend) GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) {
   617  	panic("implement me")
   618  }
   619  func (b testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
   620  	panic("implement me")
   621  }
   622  func (b testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
   623  	panic("implement me")
   624  }
   625  func (b testBackend) CurrentView() *filtermaps.ChainView {
   626  	panic("implement me")
   627  }
   628  func (b testBackend) NewMatcherBackend() filtermaps.MatcherBackend {
   629  	panic("implement me")
   630  }
   631  
   632  func (b testBackend) HistoryPruningCutoff() uint64 {
   633  	bn, _ := b.chain.HistoryPruningCutoff()
   634  	return bn
   635  }
   636  
   637  func TestEstimateGas(t *testing.T) {
   638  	t.Parallel()
   639  	// Initialize test accounts
   640  	var (
   641  		accounts = newAccounts(4)
   642  		genesis  = &core.Genesis{
   643  			Config: params.MergedTestChainConfig,
   644  			Alloc: types.GenesisAlloc{
   645  				accounts[0].addr: {Balance: big.NewInt(params.Ether)},
   646  				accounts[1].addr: {Balance: big.NewInt(params.Ether)},
   647  				accounts[2].addr: {Balance: big.NewInt(params.Ether), Code: append(types.DelegationPrefix, accounts[3].addr.Bytes()...)},
   648  			},
   649  		}
   650  		genBlocks      = 10
   651  		signer         = types.HomesteadSigner{}
   652  		randomAccounts = newAccounts(2)
   653  	)
   654  	packRevert := func(revertMessage string) []byte {
   655  		var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
   656  		stringType, _ := abi.NewType("string", "", nil)
   657  		args := abi.Arguments{
   658  			{Type: stringType},
   659  		}
   660  		encodedMessage, _ := args.Pack(revertMessage)
   661  
   662  		return append(revertSelector, encodedMessage...)
   663  	}
   664  
   665  	api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
   666  		// Transfer from account[0] to account[1]
   667  		//    value: 1000 wei
   668  		//    fee:   0 wei
   669  		tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, accounts[0].key)
   670  		b.AddTx(tx)
   671  		b.SetPoS()
   672  	}))
   673  
   674  	setCodeAuthorization, _ := types.SignSetCode(accounts[0].key, types.SetCodeAuthorization{
   675  		Address: accounts[0].addr,
   676  		Nonce:   uint64(genBlocks + 1),
   677  	})
   678  
   679  	var testSuite = []struct {
   680  		blockNumber    rpc.BlockNumber
   681  		call           TransactionArgs
   682  		overrides      override.StateOverride
   683  		blockOverrides override.BlockOverrides
   684  		expectErr      error
   685  		want           uint64
   686  	}{
   687  		//simple transfer on latest block
   688  		{
   689  			blockNumber: rpc.LatestBlockNumber,
   690  			call: TransactionArgs{
   691  				From:  &accounts[0].addr,
   692  				To:    &accounts[1].addr,
   693  				Value: (*hexutil.Big)(big.NewInt(1000)),
   694  			},
   695  			expectErr: nil,
   696  			want:      21000,
   697  		},
   698  		// simple transfer with insufficient funds on latest block
   699  		{
   700  			blockNumber: rpc.LatestBlockNumber,
   701  			call: TransactionArgs{
   702  				From:  &randomAccounts[0].addr,
   703  				To:    &accounts[1].addr,
   704  				Value: (*hexutil.Big)(big.NewInt(1000)),
   705  			},
   706  			expectErr: core.ErrInsufficientFunds,
   707  			want:      21000,
   708  		},
   709  		// empty create
   710  		{
   711  			blockNumber: rpc.LatestBlockNumber,
   712  			call:        TransactionArgs{},
   713  			expectErr:   nil,
   714  			want:        53000,
   715  		},
   716  		{
   717  			blockNumber: rpc.LatestBlockNumber,
   718  			call:        TransactionArgs{},
   719  			overrides: override.StateOverride{
   720  				randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
   721  			},
   722  			expectErr: nil,
   723  			want:      53000,
   724  		},
   725  		{
   726  			blockNumber: rpc.LatestBlockNumber,
   727  			call: TransactionArgs{
   728  				From:  &randomAccounts[0].addr,
   729  				To:    &randomAccounts[1].addr,
   730  				Value: (*hexutil.Big)(big.NewInt(1000)),
   731  			},
   732  			overrides: override.StateOverride{
   733  				randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
   734  			},
   735  			expectErr: core.ErrInsufficientFunds,
   736  		},
   737  		// Test for a bug where the gas price was set to zero but the basefee non-zero
   738  		//
   739  		// contract BasefeeChecker {
   740  		//    constructor() {
   741  		//        require(tx.gasprice >= block.basefee);
   742  		//        if (tx.gasprice > 0) {
   743  		//            require(block.basefee > 0);
   744  		//        }
   745  		//    }
   746  		//}
   747  		{
   748  			blockNumber: rpc.LatestBlockNumber,
   749  			call: TransactionArgs{
   750  				From:     &accounts[0].addr,
   751  				Input:    hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
   752  				GasPrice: (*hexutil.Big)(big.NewInt(1_000_000_000)), // Legacy as pricing
   753  			},
   754  			expectErr: nil,
   755  			want:      67617,
   756  		},
   757  		{
   758  			blockNumber: rpc.LatestBlockNumber,
   759  			call: TransactionArgs{
   760  				From:         &accounts[0].addr,
   761  				Input:        hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
   762  				MaxFeePerGas: (*hexutil.Big)(big.NewInt(1_000_000_000)), // 1559 gas pricing
   763  			},
   764  			expectErr: nil,
   765  			want:      67617,
   766  		},
   767  		{
   768  			blockNumber: rpc.LatestBlockNumber,
   769  			call: TransactionArgs{
   770  				From:         &accounts[0].addr,
   771  				Input:        hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
   772  				GasPrice:     nil, // No legacy gas pricing
   773  				MaxFeePerGas: nil, // No 1559 gas pricing
   774  			},
   775  			expectErr: nil,
   776  			want:      67595,
   777  		},
   778  		// Blobs should have no effect on gas estimate
   779  		{
   780  			blockNumber: rpc.LatestBlockNumber,
   781  			call: TransactionArgs{
   782  				From:       &accounts[0].addr,
   783  				To:         &accounts[1].addr,
   784  				Value:      (*hexutil.Big)(big.NewInt(1)),
   785  				BlobHashes: []common.Hash{{0x01, 0x22}},
   786  				BlobFeeCap: (*hexutil.Big)(big.NewInt(1)),
   787  			},
   788  			want: 21000,
   789  		},
   790  		// // SPDX-License-Identifier: GPL-3.0
   791  		//pragma solidity >=0.8.2 <0.9.0;
   792  		//
   793  		//contract BlockOverridesTest {
   794  		//    function call() public view returns (uint256) {
   795  		//        return block.number;
   796  		//    }
   797  		//
   798  		//    function estimate() public view {
   799  		//        revert(string.concat("block ", uint2str(block.number)));
   800  		//    }
   801  		//
   802  		//    function uint2str(uint256 _i) internal pure returns (string memory str) {
   803  		//        if (_i == 0) {
   804  		//            return "0";
   805  		//        }
   806  		//        uint256 j = _i;
   807  		//        uint256 length;
   808  		//        while (j != 0) {
   809  		//            length++;
   810  		//            j /= 10;
   811  		//        }
   812  		//        bytes memory bstr = new bytes(length);
   813  		//        uint256 k = length;
   814  		//        j = _i;
   815  		//        while (j != 0) {
   816  		//            bstr[--k] = bytes1(uint8(48 + (j % 10)));
   817  		//            j /= 10;
   818  		//        }
   819  		//        str = string(bstr);
   820  		//    }
   821  		//}
   822  		{
   823  			blockNumber: rpc.LatestBlockNumber,
   824  			call: TransactionArgs{
   825  				From: &accounts[0].addr,
   826  				To:   &accounts[1].addr,
   827  				Data: hex2Bytes("0x3592d016"), //estimate
   828  			},
   829  			overrides: override.StateOverride{
   830  				accounts[1].addr: override.OverrideAccount{
   831  					Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"),
   832  				},
   833  			},
   834  			blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
   835  			expectErr:      newRevertError(packRevert("block 11")),
   836  		},
   837  		// Should be able to send to an EIP-7702 delegated account.
   838  		{
   839  			blockNumber: rpc.LatestBlockNumber,
   840  			call: TransactionArgs{
   841  				From:  &accounts[0].addr,
   842  				To:    &accounts[2].addr,
   843  				Value: (*hexutil.Big)(big.NewInt(1)),
   844  			},
   845  			want: 21000,
   846  		},
   847  		// Should be able to send as EIP-7702 delegated account.
   848  		{
   849  			blockNumber: rpc.LatestBlockNumber,
   850  			call: TransactionArgs{
   851  				From:  &accounts[2].addr,
   852  				To:    &accounts[1].addr,
   853  				Value: (*hexutil.Big)(big.NewInt(1)),
   854  			},
   855  			want: 21000,
   856  		},
   857  		// Should be able to estimate SetCodeTx.
   858  		{
   859  			blockNumber: rpc.LatestBlockNumber,
   860  			call: TransactionArgs{
   861  				From:              &accounts[0].addr,
   862  				To:                &accounts[1].addr,
   863  				Value:             (*hexutil.Big)(big.NewInt(0)),
   864  				AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
   865  			},
   866  			want: 46000,
   867  		},
   868  		// Should retrieve the code of 0xef0001 || accounts[0].addr and return an invalid opcode error.
   869  		{
   870  			blockNumber: rpc.LatestBlockNumber,
   871  			call: TransactionArgs{
   872  				From:              &accounts[0].addr,
   873  				To:                &accounts[0].addr,
   874  				Value:             (*hexutil.Big)(big.NewInt(0)),
   875  				AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
   876  			},
   877  			expectErr: errors.New("invalid opcode: opcode 0xef not defined"),
   878  		},
   879  		// SetCodeTx with empty authorization list should fail.
   880  		{
   881  			blockNumber: rpc.LatestBlockNumber,
   882  			call: TransactionArgs{
   883  				From:              &accounts[0].addr,
   884  				To:                &common.Address{},
   885  				Value:             (*hexutil.Big)(big.NewInt(0)),
   886  				AuthorizationList: []types.SetCodeAuthorization{},
   887  			},
   888  			expectErr: core.ErrEmptyAuthList,
   889  		},
   890  		// SetCodeTx with nil `to` should fail.
   891  		{
   892  			blockNumber: rpc.LatestBlockNumber,
   893  			call: TransactionArgs{
   894  				From:              &accounts[0].addr,
   895  				To:                nil,
   896  				Value:             (*hexutil.Big)(big.NewInt(0)),
   897  				AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
   898  			},
   899  			expectErr: core.ErrSetCodeTxCreate,
   900  		},
   901  	}
   902  	for i, tc := range testSuite {
   903  		result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
   904  		if tc.expectErr != nil {
   905  			if err == nil {
   906  				t.Errorf("test %d: want error %v, have nothing", i, tc.expectErr)
   907  				continue
   908  			}
   909  			if !errors.Is(err, tc.expectErr) {
   910  				if err.Error() != tc.expectErr.Error() {
   911  					t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
   912  				}
   913  			}
   914  			continue
   915  		}
   916  		if err != nil {
   917  			t.Errorf("test %d: want no error, have %v", i, err)
   918  			continue
   919  		}
   920  		if float64(result) > float64(tc.want)*(1+estimateGasErrorRatio) {
   921  			t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, uint64(result), tc.want)
   922  		}
   923  	}
   924  }
   925  
   926  func TestCall(t *testing.T) {
   927  	t.Parallel()
   928  
   929  	// Initialize test accounts
   930  	var (
   931  		accounts = newAccounts(3)
   932  		dad      = common.HexToAddress("0x0000000000000000000000000000000000000dad")
   933  		genesis  = &core.Genesis{
   934  			Config: params.MergedTestChainConfig,
   935  			Alloc: types.GenesisAlloc{
   936  				accounts[0].addr: {Balance: big.NewInt(params.Ether)},
   937  				accounts[1].addr: {Balance: big.NewInt(params.Ether)},
   938  				accounts[2].addr: {Balance: big.NewInt(params.Ether)},
   939  				dad: {
   940  					Balance: big.NewInt(params.Ether),
   941  					Nonce:   1,
   942  					Storage: map[common.Hash]common.Hash{
   943  						common.Hash{}: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"),
   944  					},
   945  				},
   946  			},
   947  		}
   948  		genBlocks = 10
   949  		signer    = types.HomesteadSigner{}
   950  	)
   951  	api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
   952  		// Transfer from account[0] to account[1]
   953  		//    value: 1000 wei
   954  		//    fee:   0 wei
   955  		tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, accounts[0].key)
   956  		b.AddTx(tx)
   957  		b.SetPoS()
   958  	}))
   959  	randomAccounts := newAccounts(3)
   960  	var testSuite = []struct {
   961  		name           string
   962  		blockNumber    rpc.BlockNumber
   963  		overrides      override.StateOverride
   964  		call           TransactionArgs
   965  		blockOverrides override.BlockOverrides
   966  		expectErr      error
   967  		want           string
   968  	}{
   969  		// transfer on genesis
   970  		{
   971  			name:        "transfer-on-genesis",
   972  			blockNumber: rpc.BlockNumber(0),
   973  			call: TransactionArgs{
   974  				From:  &accounts[0].addr,
   975  				To:    &accounts[1].addr,
   976  				Value: (*hexutil.Big)(big.NewInt(1000)),
   977  			},
   978  			expectErr: nil,
   979  			want:      "0x",
   980  		},
   981  		// transfer on the head
   982  		{
   983  			name:        "transfer-on-the-head",
   984  			blockNumber: rpc.BlockNumber(genBlocks),
   985  			call: TransactionArgs{
   986  				From:  &accounts[0].addr,
   987  				To:    &accounts[1].addr,
   988  				Value: (*hexutil.Big)(big.NewInt(1000)),
   989  			},
   990  			expectErr: nil,
   991  			want:      "0x",
   992  		},
   993  		// transfer on a non-existent block, error expects
   994  		{
   995  			name:        "transfer-non-existent-block",
   996  			blockNumber: rpc.BlockNumber(genBlocks + 1),
   997  			call: TransactionArgs{
   998  				From:  &accounts[0].addr,
   999  				To:    &accounts[1].addr,
  1000  				Value: (*hexutil.Big)(big.NewInt(1000)),
  1001  			},
  1002  			expectErr: errors.New("header not found"),
  1003  		},
  1004  		// transfer on the latest block
  1005  		{
  1006  			name:        "transfer-latest-block",
  1007  			blockNumber: rpc.LatestBlockNumber,
  1008  			call: TransactionArgs{
  1009  				From:  &accounts[0].addr,
  1010  				To:    &accounts[1].addr,
  1011  				Value: (*hexutil.Big)(big.NewInt(1000)),
  1012  			},
  1013  			expectErr: nil,
  1014  			want:      "0x",
  1015  		},
  1016  		// Call which can only succeed if state is state overridden
  1017  		{
  1018  			name:        "state-override-success",
  1019  			blockNumber: rpc.LatestBlockNumber,
  1020  			call: TransactionArgs{
  1021  				From:  &randomAccounts[0].addr,
  1022  				To:    &randomAccounts[1].addr,
  1023  				Value: (*hexutil.Big)(big.NewInt(1000)),
  1024  			},
  1025  			overrides: override.StateOverride{
  1026  				randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
  1027  			},
  1028  			want: "0x",
  1029  		},
  1030  		// Invalid call without state overriding
  1031  		{
  1032  			name:        "insufficient-funds-simple",
  1033  			blockNumber: rpc.LatestBlockNumber,
  1034  			call: TransactionArgs{
  1035  				From:  &randomAccounts[0].addr,
  1036  				To:    &randomAccounts[1].addr,
  1037  				Value: (*hexutil.Big)(big.NewInt(1000)),
  1038  			},
  1039  			expectErr: core.ErrInsufficientFunds,
  1040  		},
  1041  		// Successful simple contract call
  1042  		//
  1043  		// // SPDX-License-Identifier: GPL-3.0
  1044  		//
  1045  		//  pragma solidity >=0.7.0 <0.8.0;
  1046  		//
  1047  		//  /**
  1048  		//   * @title Storage
  1049  		//   * @dev Store & retrieve value in a variable
  1050  		//   */
  1051  		//  contract Storage {
  1052  		//      uint256 public number;
  1053  		//      constructor() {
  1054  		//          number = block.number;
  1055  		//      }
  1056  		//  }
  1057  		{
  1058  			name:        "simple-contract-call",
  1059  			blockNumber: rpc.LatestBlockNumber,
  1060  			call: TransactionArgs{
  1061  				From: &randomAccounts[0].addr,
  1062  				To:   &randomAccounts[2].addr,
  1063  				Data: hex2Bytes("8381f58a"), // call number()
  1064  			},
  1065  			overrides: override.StateOverride{
  1066  				randomAccounts[2].addr: override.OverrideAccount{
  1067  					Code:      hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033"),
  1068  					StateDiff: map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))},
  1069  				},
  1070  			},
  1071  			want: "0x000000000000000000000000000000000000000000000000000000000000007b",
  1072  		},
  1073  		// // SPDX-License-Identifier: GPL-3.0
  1074  		//pragma solidity >=0.8.2 <0.9.0;
  1075  		//
  1076  		//contract BlockOverridesTest {
  1077  		//    function call() public view returns (uint256) {
  1078  		//        return block.number;
  1079  		//    }
  1080  		//
  1081  		//    function estimate() public view {
  1082  		//        revert(string.concat("block ", uint2str(block.number)));
  1083  		//    }
  1084  		//
  1085  		//    function uint2str(uint256 _i) internal pure returns (string memory str) {
  1086  		//        if (_i == 0) {
  1087  		//            return "0";
  1088  		//        }
  1089  		//        uint256 j = _i;
  1090  		//        uint256 length;
  1091  		//        while (j != 0) {
  1092  		//            length++;
  1093  		//            j /= 10;
  1094  		//        }
  1095  		//        bytes memory bstr = new bytes(length);
  1096  		//        uint256 k = length;
  1097  		//        j = _i;
  1098  		//        while (j != 0) {
  1099  		//            bstr[--k] = bytes1(uint8(48 + (j % 10)));
  1100  		//            j /= 10;
  1101  		//        }
  1102  		//        str = string(bstr);
  1103  		//    }
  1104  		//}
  1105  		{
  1106  			name:        "block-override-with-state-override",
  1107  			blockNumber: rpc.LatestBlockNumber,
  1108  			call: TransactionArgs{
  1109  				From: &accounts[1].addr,
  1110  				To:   &accounts[2].addr,
  1111  				Data: hex2Bytes("0x28b5e32b"), //call
  1112  			},
  1113  			overrides: override.StateOverride{
  1114  				accounts[2].addr: override.OverrideAccount{
  1115  					Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"),
  1116  				},
  1117  			},
  1118  			blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
  1119  			want:           "0x000000000000000000000000000000000000000000000000000000000000000b",
  1120  		},
  1121  		// Clear storage trie
  1122  		{
  1123  			name:        "clear-storage-trie",
  1124  			blockNumber: rpc.LatestBlockNumber,
  1125  			call: TransactionArgs{
  1126  				From: &accounts[1].addr,
  1127  				// Yul:
  1128  				// object "Test" {
  1129  				//    code {
  1130  				//        let dad := 0x0000000000000000000000000000000000000dad
  1131  				//        if eq(balance(dad), 0) {
  1132  				//            revert(0, 0)
  1133  				//        }
  1134  				//        let slot := sload(0)
  1135  				//        mstore(0, slot)
  1136  				//        return(0, 32)
  1137  				//    }
  1138  				// }
  1139  				Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"),
  1140  			},
  1141  			overrides: override.StateOverride{
  1142  				dad: override.OverrideAccount{
  1143  					State: map[common.Hash]common.Hash{},
  1144  				},
  1145  			},
  1146  			want: "0x0000000000000000000000000000000000000000000000000000000000000000",
  1147  		},
  1148  		// Invalid blob tx
  1149  		{
  1150  			name:        "invalid-blob-tx",
  1151  			blockNumber: rpc.LatestBlockNumber,
  1152  			call: TransactionArgs{
  1153  				From:       &accounts[1].addr,
  1154  				Input:      &hexutil.Bytes{0x00},
  1155  				BlobHashes: []common.Hash{},
  1156  			},
  1157  			expectErr: core.ErrBlobTxCreate,
  1158  		},
  1159  		// BLOBHASH opcode
  1160  		{
  1161  			name:        "blobhash-opcode",
  1162  			blockNumber: rpc.LatestBlockNumber,
  1163  			call: TransactionArgs{
  1164  				From:       &accounts[1].addr,
  1165  				To:         &randomAccounts[2].addr,
  1166  				BlobHashes: []common.Hash{{0x01, 0x22}},
  1167  				BlobFeeCap: (*hexutil.Big)(big.NewInt(1)),
  1168  			},
  1169  			overrides: override.StateOverride{
  1170  				randomAccounts[2].addr: {
  1171  					Code: hex2Bytes("60004960005260206000f3"),
  1172  				},
  1173  			},
  1174  			want: "0x0122000000000000000000000000000000000000000000000000000000000000",
  1175  		},
  1176  		// Clear the entire storage set
  1177  		{
  1178  			blockNumber: rpc.LatestBlockNumber,
  1179  			call: TransactionArgs{
  1180  				From: &accounts[1].addr,
  1181  				// Yul:
  1182  				// object "Test" {
  1183  				//    code {
  1184  				//        let dad := 0x0000000000000000000000000000000000000dad
  1185  				//        if eq(balance(dad), 0) {
  1186  				//            revert(0, 0)
  1187  				//        }
  1188  				//        let slot := sload(0)
  1189  				//        mstore(0, slot)
  1190  				//        return(0, 32)
  1191  				//    }
  1192  				// }
  1193  				Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"),
  1194  			},
  1195  			overrides: override.StateOverride{
  1196  				dad: override.OverrideAccount{
  1197  					State: map[common.Hash]common.Hash{},
  1198  				},
  1199  			},
  1200  			want: "0x0000000000000000000000000000000000000000000000000000000000000000",
  1201  		},
  1202  		{
  1203  			name:        "unsupported block override beaconRoot",
  1204  			blockNumber: rpc.LatestBlockNumber,
  1205  			call:        TransactionArgs{},
  1206  			blockOverrides: override.BlockOverrides{
  1207  				BeaconRoot: &common.Hash{0, 1, 2},
  1208  			},
  1209  			expectErr: errors.New(`block override "beaconRoot" is not supported for this RPC method`),
  1210  		},
  1211  		{
  1212  			name:        "unsupported block override withdrawals",
  1213  			blockNumber: rpc.LatestBlockNumber,
  1214  			call:        TransactionArgs{},
  1215  			blockOverrides: override.BlockOverrides{
  1216  				Withdrawals: &types.Withdrawals{},
  1217  			},
  1218  			expectErr: errors.New(`block override "withdrawals" is not supported for this RPC method`),
  1219  		},
  1220  	}
  1221  	for _, tc := range testSuite {
  1222  		result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
  1223  		if tc.expectErr != nil {
  1224  			if err == nil {
  1225  				t.Errorf("test %s: want error %v, have nothing", tc.name, tc.expectErr)
  1226  				continue
  1227  			}
  1228  			if !errors.Is(err, tc.expectErr) {
  1229  				// Second try
  1230  				if !reflect.DeepEqual(err, tc.expectErr) {
  1231  					t.Errorf("test %s: error mismatch, want %v, have %v", tc.name, tc.expectErr, err)
  1232  				}
  1233  			}
  1234  			continue
  1235  		}
  1236  		if err != nil {
  1237  			t.Errorf("test %s: want no error, have %v", tc.name, err)
  1238  			continue
  1239  		}
  1240  		if !reflect.DeepEqual(result.String(), tc.want) {
  1241  			t.Errorf("test %s, result mismatch, have\n%v\n, want\n%v\n", tc.name, result.String(), tc.want)
  1242  		}
  1243  	}
  1244  }
  1245  
  1246  func TestSimulateV1(t *testing.T) {
  1247  	t.Parallel()
  1248  	// Initialize test accounts
  1249  	var (
  1250  		accounts     = newAccounts(3)
  1251  		fixedAccount = newTestAccount()
  1252  		genBlocks    = 10
  1253  		signer       = types.HomesteadSigner{}
  1254  		cac          = common.HexToAddress("0x0000000000000000000000000000000000000cac")
  1255  		bab          = common.HexToAddress("0x0000000000000000000000000000000000000bab")
  1256  		coinbase     = "0x000000000000000000000000000000000000ffff"
  1257  		genesis      = &core.Genesis{
  1258  			Config: params.TestChainConfig,
  1259  			Alloc: types.GenesisAlloc{
  1260  				accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  1261  				accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  1262  				accounts[2].addr: {Balance: big.NewInt(params.Ether)},
  1263  				// Yul:
  1264  				// object "Test" {
  1265  				//     code {
  1266  				//         let dad := 0x0000000000000000000000000000000000000dad
  1267  				//         selfdestruct(dad)
  1268  				//     }
  1269  				// }
  1270  				cac: {Balance: big.NewInt(params.Ether), Code: common.Hex2Bytes("610dad80ff")},
  1271  				bab: {
  1272  					Balance: big.NewInt(1),
  1273  					// object "Test" {
  1274  					//    code {
  1275  					//        let value1 := sload(1)
  1276  					//        let value2 := sload(2)
  1277  					//
  1278  					//        // Shift value1 by 128 bits to the left by multiplying it with 2^128
  1279  					//        value1 := mul(value1, 0x100000000000000000000000000000000)
  1280  					//
  1281  					//        // Concatenate value1 and value2
  1282  					//        let concatenatedValue := add(value1, value2)
  1283  					//
  1284  					//        // Store the result in memory and return it
  1285  					//        mstore(0, concatenatedValue)
  1286  					//        return(0, 0x20)
  1287  					//    }
  1288  					// }
  1289  					Code: common.FromHex("0x600154600254700100000000000000000000000000000000820291508082018060005260206000f3"),
  1290  					Storage: map[common.Hash]common.Hash{
  1291  						common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(10)),
  1292  						common.BigToHash(big.NewInt(2)): common.BigToHash(big.NewInt(12)),
  1293  					},
  1294  				},
  1295  			},
  1296  		}
  1297  		sha256Address = common.BytesToAddress([]byte{0x02})
  1298  	)
  1299  	api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) {
  1300  		b.SetCoinbase(common.HexToAddress(coinbase))
  1301  		// Transfer from account[0] to account[1]
  1302  		//    value: 1000 wei
  1303  		//    fee:   0 wei
  1304  		tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
  1305  			Nonce:    uint64(i),
  1306  			To:       &accounts[1].addr,
  1307  			Value:    big.NewInt(1000),
  1308  			Gas:      params.TxGas,
  1309  			GasPrice: b.BaseFee(),
  1310  			Data:     nil,
  1311  		}), signer, accounts[0].key)
  1312  		b.AddTx(tx)
  1313  	}))
  1314  	var (
  1315  		randomAccounts   = newAccounts(4)
  1316  		latest           = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
  1317  		includeTransfers = true
  1318  		validation       = true
  1319  	)
  1320  	type log struct {
  1321  		Address     common.Address `json:"address"`
  1322  		Topics      []common.Hash  `json:"topics"`
  1323  		Data        hexutil.Bytes  `json:"data"`
  1324  		BlockNumber hexutil.Uint64 `json:"blockNumber"`
  1325  		// Skip txHash
  1326  		//TxHash common.Hash `json:"transactionHash" gencodec:"required"`
  1327  		TxIndex hexutil.Uint `json:"transactionIndex"`
  1328  		//BlockHash common.Hash  `json:"blockHash"`
  1329  		Index hexutil.Uint `json:"logIndex"`
  1330  	}
  1331  	type callErr struct {
  1332  		Message string
  1333  		Code    int
  1334  	}
  1335  	type callRes struct {
  1336  		ReturnValue string `json:"returnData"`
  1337  		Error       callErr
  1338  		Logs        []log
  1339  		GasUsed     string
  1340  		Status      string
  1341  	}
  1342  	type blockRes struct {
  1343  		Number string
  1344  		//Hash   string
  1345  		// Ignore timestamp
  1346  		GasLimit      string
  1347  		GasUsed       string
  1348  		Miner         string
  1349  		BaseFeePerGas string
  1350  		Calls         []callRes
  1351  	}
  1352  	var testSuite = []struct {
  1353  		name             string
  1354  		blocks           []simBlock
  1355  		tag              rpc.BlockNumberOrHash
  1356  		includeTransfers *bool
  1357  		validation       *bool
  1358  		expectErr        error
  1359  		want             []blockRes
  1360  	}{
  1361  		// State build-up over calls:
  1362  		// First value transfer OK after state override.
  1363  		// Second one should succeed because of first transfer.
  1364  		{
  1365  			name: "simple",
  1366  			tag:  latest,
  1367  			blocks: []simBlock{{
  1368  				StateOverrides: &override.StateOverride{
  1369  					randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))},
  1370  				},
  1371  				Calls: []TransactionArgs{{
  1372  					From:  &randomAccounts[0].addr,
  1373  					To:    &randomAccounts[1].addr,
  1374  					Value: (*hexutil.Big)(big.NewInt(1000)),
  1375  				}, {
  1376  					From:  &randomAccounts[1].addr,
  1377  					To:    &randomAccounts[2].addr,
  1378  					Value: (*hexutil.Big)(big.NewInt(1000)),
  1379  				}, {
  1380  					To: &randomAccounts[3].addr,
  1381  				}},
  1382  			}},
  1383  			want: []blockRes{{
  1384  				Number:        "0xb",
  1385  				GasLimit:      "0x47e7c4",
  1386  				GasUsed:       "0xf618",
  1387  				Miner:         coinbase,
  1388  				BaseFeePerGas: "0x0",
  1389  				Calls: []callRes{{
  1390  					ReturnValue: "0x",
  1391  					GasUsed:     "0x5208",
  1392  					Logs:        []log{},
  1393  					Status:      "0x1",
  1394  				}, {
  1395  					ReturnValue: "0x",
  1396  					GasUsed:     "0x5208",
  1397  					Logs:        []log{},
  1398  					Status:      "0x1",
  1399  				}, {
  1400  					ReturnValue: "0x",
  1401  					GasUsed:     "0x5208",
  1402  					Logs:        []log{},
  1403  					Status:      "0x1",
  1404  				}},
  1405  			}},
  1406  		}, {
  1407  			// State build-up over blocks.
  1408  			name: "simple-multi-block",
  1409  			tag:  latest,
  1410  			blocks: []simBlock{{
  1411  				StateOverrides: &override.StateOverride{
  1412  					randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))},
  1413  				},
  1414  				Calls: []TransactionArgs{
  1415  					{
  1416  						From:  &randomAccounts[0].addr,
  1417  						To:    &randomAccounts[1].addr,
  1418  						Value: (*hexutil.Big)(big.NewInt(1000)),
  1419  					}, {
  1420  						From:  &randomAccounts[0].addr,
  1421  						To:    &randomAccounts[3].addr,
  1422  						Value: (*hexutil.Big)(big.NewInt(1000)),
  1423  					},
  1424  				},
  1425  			}, {
  1426  				StateOverrides: &override.StateOverride{
  1427  					randomAccounts[3].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
  1428  				},
  1429  				Calls: []TransactionArgs{
  1430  					{
  1431  						From:  &randomAccounts[1].addr,
  1432  						To:    &randomAccounts[2].addr,
  1433  						Value: (*hexutil.Big)(big.NewInt(1000)),
  1434  					},
  1435  				},
  1436  			}},
  1437  			want: []blockRes{{
  1438  				Number:        "0xb",
  1439  				GasLimit:      "0x47e7c4",
  1440  				GasUsed:       "0xa410",
  1441  				Miner:         coinbase,
  1442  				BaseFeePerGas: "0x0",
  1443  				Calls: []callRes{{
  1444  					ReturnValue: "0x",
  1445  					GasUsed:     "0x5208",
  1446  					Logs:        []log{},
  1447  					Status:      "0x1",
  1448  				}, {
  1449  					ReturnValue: "0x",
  1450  					GasUsed:     "0x5208",
  1451  					Logs:        []log{},
  1452  					Status:      "0x1",
  1453  				}},
  1454  			}, {
  1455  				Number:        "0xc",
  1456  				GasLimit:      "0x47e7c4",
  1457  				GasUsed:       "0x5208",
  1458  				Miner:         coinbase,
  1459  				BaseFeePerGas: "0x0",
  1460  				Calls: []callRes{{
  1461  					ReturnValue: "0x",
  1462  					GasUsed:     "0x5208",
  1463  					Logs:        []log{},
  1464  					Status:      "0x1",
  1465  				}},
  1466  			}},
  1467  		}, {
  1468  			// insufficient funds
  1469  			name: "insufficient-funds",
  1470  			tag:  latest,
  1471  			blocks: []simBlock{{
  1472  				Calls: []TransactionArgs{{
  1473  					From:  &randomAccounts[0].addr,
  1474  					To:    &randomAccounts[1].addr,
  1475  					Value: (*hexutil.Big)(big.NewInt(1000)),
  1476  				}},
  1477  			}},
  1478  			want:      nil,
  1479  			expectErr: &invalidTxError{Message: fmt.Sprintf("err: insufficient funds for gas * price + value: address %s have 0 want 1000 (supplied gas 4712388)", randomAccounts[0].addr.String()), Code: errCodeInsufficientFunds},
  1480  		}, {
  1481  			// EVM error
  1482  			name: "evm-error",
  1483  			tag:  latest,
  1484  			blocks: []simBlock{{
  1485  				StateOverrides: &override.StateOverride{
  1486  					randomAccounts[2].addr: override.OverrideAccount{Code: hex2Bytes("f3")},
  1487  				},
  1488  				Calls: []TransactionArgs{{
  1489  					From: &randomAccounts[0].addr,
  1490  					To:   &randomAccounts[2].addr,
  1491  				}},
  1492  			}},
  1493  			want: []blockRes{{
  1494  				Number:        "0xb",
  1495  				GasLimit:      "0x47e7c4",
  1496  				GasUsed:       "0x47e7c4",
  1497  				Miner:         coinbase,
  1498  				BaseFeePerGas: "0x0",
  1499  				Calls: []callRes{{
  1500  					ReturnValue: "0x",
  1501  					Error:       callErr{Message: "stack underflow (0 <=> 2)", Code: errCodeVMError},
  1502  					GasUsed:     "0x47e7c4",
  1503  					Logs:        []log{},
  1504  					Status:      "0x0",
  1505  				}},
  1506  			}},
  1507  		}, {
  1508  			// Block overrides should work, each call is simulated on a different block number
  1509  			name: "block-overrides",
  1510  			tag:  latest,
  1511  			blocks: []simBlock{{
  1512  				BlockOverrides: &override.BlockOverrides{
  1513  					Number:       (*hexutil.Big)(big.NewInt(11)),
  1514  					FeeRecipient: &cac,
  1515  				},
  1516  				Calls: []TransactionArgs{
  1517  					{
  1518  						From: &accounts[0].addr,
  1519  						Input: &hexutil.Bytes{
  1520  							0x43,             // NUMBER
  1521  							0x60, 0x00, 0x52, // MSTORE offset 0
  1522  							0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN
  1523  						},
  1524  					},
  1525  				},
  1526  			}, {
  1527  				BlockOverrides: &override.BlockOverrides{
  1528  					Number: (*hexutil.Big)(big.NewInt(12)),
  1529  				},
  1530  				Calls: []TransactionArgs{{
  1531  					From: &accounts[1].addr,
  1532  					Input: &hexutil.Bytes{
  1533  						0x43,             // NUMBER
  1534  						0x60, 0x00, 0x52, // MSTORE offset 0
  1535  						0x60, 0x20, 0x60, 0x00, 0xf3,
  1536  					},
  1537  				}},
  1538  			}},
  1539  			want: []blockRes{{
  1540  				Number:        "0xb",
  1541  				GasLimit:      "0x47e7c4",
  1542  				GasUsed:       "0xe891",
  1543  				Miner:         strings.ToLower(cac.String()),
  1544  				BaseFeePerGas: "0x0",
  1545  				Calls: []callRes{{
  1546  					ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000b",
  1547  					GasUsed:     "0xe891",
  1548  					Logs:        []log{},
  1549  					Status:      "0x1",
  1550  				}},
  1551  			}, {
  1552  				Number:        "0xc",
  1553  				GasLimit:      "0x47e7c4",
  1554  				GasUsed:       "0xe891",
  1555  				Miner:         strings.ToLower(cac.String()),
  1556  				BaseFeePerGas: "0x0",
  1557  				Calls: []callRes{{
  1558  					ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000c",
  1559  					GasUsed:     "0xe891",
  1560  					Logs:        []log{},
  1561  					Status:      "0x1",
  1562  				}},
  1563  			}},
  1564  		},
  1565  		// Block numbers must be in order.
  1566  		{
  1567  			name: "block-number-order",
  1568  			tag:  latest,
  1569  			blocks: []simBlock{{
  1570  				BlockOverrides: &override.BlockOverrides{
  1571  					Number: (*hexutil.Big)(big.NewInt(12)),
  1572  				},
  1573  				Calls: []TransactionArgs{{
  1574  					From: &accounts[1].addr,
  1575  					Input: &hexutil.Bytes{
  1576  						0x43,             // NUMBER
  1577  						0x60, 0x00, 0x52, // MSTORE offset 0
  1578  						0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN
  1579  					},
  1580  				}},
  1581  			}, {
  1582  				BlockOverrides: &override.BlockOverrides{
  1583  					Number: (*hexutil.Big)(big.NewInt(11)),
  1584  				},
  1585  				Calls: []TransactionArgs{{
  1586  					From: &accounts[0].addr,
  1587  					Input: &hexutil.Bytes{
  1588  						0x43,             // NUMBER
  1589  						0x60, 0x00, 0x52, // MSTORE offset 0
  1590  						0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN
  1591  					},
  1592  				}},
  1593  			}},
  1594  			want:      []blockRes{},
  1595  			expectErr: &invalidBlockNumberError{message: "block numbers must be in order: 11 <= 12"},
  1596  		},
  1597  		// Test on solidity storage example. Set value in one call, read in next.
  1598  		{
  1599  			name: "storage-contract",
  1600  			tag:  latest,
  1601  			blocks: []simBlock{{
  1602  				StateOverrides: &override.StateOverride{
  1603  					randomAccounts[2].addr: override.OverrideAccount{
  1604  						Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"),
  1605  					},
  1606  				},
  1607  				Calls: []TransactionArgs{{
  1608  					// Set value to 5
  1609  					From:  &randomAccounts[0].addr,
  1610  					To:    &randomAccounts[2].addr,
  1611  					Input: hex2Bytes("6057361d0000000000000000000000000000000000000000000000000000000000000005"),
  1612  				}, {
  1613  					// Read value
  1614  					From:  &randomAccounts[0].addr,
  1615  					To:    &randomAccounts[2].addr,
  1616  					Input: hex2Bytes("2e64cec1"),
  1617  				},
  1618  				},
  1619  			}},
  1620  			want: []blockRes{{
  1621  				Number:        "0xb",
  1622  				GasLimit:      "0x47e7c4",
  1623  				GasUsed:       "0x10683",
  1624  				Miner:         coinbase,
  1625  				BaseFeePerGas: "0x0",
  1626  				Calls: []callRes{{
  1627  					ReturnValue: "0x",
  1628  					GasUsed:     "0xaacc",
  1629  					Logs:        []log{},
  1630  					Status:      "0x1",
  1631  				}, {
  1632  					ReturnValue: "0x0000000000000000000000000000000000000000000000000000000000000005",
  1633  					GasUsed:     "0x5bb7",
  1634  					Logs:        []log{},
  1635  					Status:      "0x1",
  1636  				}},
  1637  			}},
  1638  		},
  1639  		// Test logs output.
  1640  		{
  1641  			name: "logs",
  1642  			tag:  latest,
  1643  			blocks: []simBlock{{
  1644  				StateOverrides: &override.StateOverride{
  1645  					randomAccounts[2].addr: override.OverrideAccount{
  1646  						// Yul code:
  1647  						// object "Test" {
  1648  						//    code {
  1649  						//        let hash:u256 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  1650  						//        log1(0, 0, hash)
  1651  						//        return (0, 0)
  1652  						//    }
  1653  						// }
  1654  						Code: hex2Bytes("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3"),
  1655  					},
  1656  				},
  1657  				Calls: []TransactionArgs{{
  1658  					From: &randomAccounts[0].addr,
  1659  					To:   &randomAccounts[2].addr,
  1660  				}},
  1661  			}},
  1662  			want: []blockRes{{
  1663  				Number:        "0xb",
  1664  				GasLimit:      "0x47e7c4",
  1665  				GasUsed:       "0x5508",
  1666  				Miner:         coinbase,
  1667  				BaseFeePerGas: "0x0",
  1668  				Calls: []callRes{{
  1669  					ReturnValue: "0x",
  1670  					Logs: []log{{
  1671  						Address:     randomAccounts[2].addr,
  1672  						Topics:      []common.Hash{common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")},
  1673  						BlockNumber: hexutil.Uint64(11),
  1674  						Data:        hexutil.Bytes{},
  1675  					}},
  1676  					GasUsed: "0x5508",
  1677  					Status:  "0x1",
  1678  				}},
  1679  			}},
  1680  		},
  1681  		// Test ecrecover override
  1682  		{
  1683  			name: "ecrecover-override",
  1684  			tag:  latest,
  1685  			blocks: []simBlock{{
  1686  				StateOverrides: &override.StateOverride{
  1687  					randomAccounts[2].addr: override.OverrideAccount{
  1688  						// Yul code that returns ecrecover(0, 0, 0, 0).
  1689  						// object "Test" {
  1690  						//    code {
  1691  						//        // Free memory pointer
  1692  						//        let free_ptr := mload(0x40)
  1693  						//
  1694  						//        // Initialize inputs with zeros
  1695  						//        mstore(free_ptr, 0)  // Hash
  1696  						//        mstore(add(free_ptr, 0x20), 0)  // v
  1697  						//        mstore(add(free_ptr, 0x40), 0)  // r
  1698  						//        mstore(add(free_ptr, 0x60), 0)  // s
  1699  						//
  1700  						//        // Call ecrecover precompile (at address 1) with all 0 inputs
  1701  						//        let success := staticcall(gas(), 1, free_ptr, 0x80, free_ptr, 0x20)
  1702  						//
  1703  						//        // Check if the call was successful
  1704  						//        if eq(success, 0) {
  1705  						//            revert(0, 0)
  1706  						//        }
  1707  						//
  1708  						//        // Return the recovered address
  1709  						//        return(free_ptr, 0x14)
  1710  						//    }
  1711  						// }
  1712  						Code: hex2Bytes("6040516000815260006020820152600060408201526000606082015260208160808360015afa60008103603157600080fd5b601482f3"),
  1713  					},
  1714  					common.BytesToAddress([]byte{0x01}): override.OverrideAccount{
  1715  						// Yul code that returns the address of the caller.
  1716  						// object "Test" {
  1717  						//    code {
  1718  						//        let c := caller()
  1719  						//        mstore(0, c)
  1720  						//        return(0xc, 0x14)
  1721  						//    }
  1722  						// }
  1723  						Code: hex2Bytes("33806000526014600cf3"),
  1724  					},
  1725  				},
  1726  				Calls: []TransactionArgs{{
  1727  					From: &randomAccounts[0].addr,
  1728  					To:   &randomAccounts[2].addr,
  1729  				}},
  1730  			}},
  1731  			want: []blockRes{{
  1732  				Number:        "0xb",
  1733  				GasLimit:      "0x47e7c4",
  1734  				GasUsed:       "0x52f6",
  1735  				Miner:         coinbase,
  1736  				BaseFeePerGas: "0x0",
  1737  				Calls: []callRes{{
  1738  					// Caller is in this case the contract that invokes ecrecover.
  1739  					ReturnValue: strings.ToLower(randomAccounts[2].addr.String()),
  1740  					GasUsed:     "0x52f6",
  1741  					Logs:        []log{},
  1742  					Status:      "0x1",
  1743  				}},
  1744  			}},
  1745  		},
  1746  		// Test moving the sha256 precompile.
  1747  		{
  1748  			name: "precompile-move",
  1749  			tag:  latest,
  1750  			blocks: []simBlock{{
  1751  				StateOverrides: &override.StateOverride{
  1752  					sha256Address: override.OverrideAccount{
  1753  						// Yul code that returns the calldata.
  1754  						// object "Test" {
  1755  						//    code {
  1756  						//        let size := calldatasize() // Get the size of the calldata
  1757  						//
  1758  						//        // Allocate memory to store the calldata
  1759  						//        let memPtr := msize()
  1760  						//
  1761  						//        // Copy calldata to memory
  1762  						//        calldatacopy(memPtr, 0, size)
  1763  						//
  1764  						//        // Return the calldata from memory
  1765  						//        return(memPtr, size)
  1766  						//    }
  1767  						// }
  1768  						Code:             hex2Bytes("365981600082378181f3"),
  1769  						MovePrecompileTo: &randomAccounts[2].addr,
  1770  					},
  1771  				},
  1772  				Calls: []TransactionArgs{{
  1773  					From:  &randomAccounts[0].addr,
  1774  					To:    &randomAccounts[2].addr,
  1775  					Input: hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
  1776  				}, {
  1777  					From:  &randomAccounts[0].addr,
  1778  					To:    &sha256Address,
  1779  					Input: hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
  1780  				}},
  1781  			}},
  1782  			want: []blockRes{{
  1783  				Number:        "0xb",
  1784  				GasLimit:      "0x47e7c4",
  1785  				GasUsed:       "0xa58c",
  1786  				Miner:         coinbase,
  1787  				BaseFeePerGas: "0x0",
  1788  				Calls: []callRes{{
  1789  					ReturnValue: "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5",
  1790  					GasUsed:     "0x52dc",
  1791  					Logs:        []log{},
  1792  					Status:      "0x1",
  1793  				}, {
  1794  					ReturnValue: "0x0000000000000000000000000000000000000000000000000000000000000001",
  1795  					GasUsed:     "0x52b0",
  1796  					Logs:        []log{},
  1797  					Status:      "0x1",
  1798  				}},
  1799  			}},
  1800  		},
  1801  		// Test ether transfers.
  1802  		{
  1803  			name: "transfer-logs",
  1804  			tag:  latest,
  1805  			blocks: []simBlock{{
  1806  				StateOverrides: &override.StateOverride{
  1807  					randomAccounts[0].addr: override.OverrideAccount{
  1808  						Balance: newRPCBalance(big.NewInt(100)),
  1809  						// Yul code that transfers 100 wei to address passed in calldata:
  1810  						// object "Test" {
  1811  						//    code {
  1812  						//        let recipient := shr(96, calldataload(0))
  1813  						//        let value := 100
  1814  						//        let success := call(gas(), recipient, value, 0, 0, 0, 0)
  1815  						//        if eq(success, 0) {
  1816  						//            revert(0, 0)
  1817  						//        }
  1818  						//    }
  1819  						// }
  1820  						Code: hex2Bytes("60003560601c606460008060008084865af160008103601d57600080fd5b505050"),
  1821  					},
  1822  				},
  1823  				Calls: []TransactionArgs{{
  1824  					From:  &accounts[0].addr,
  1825  					To:    &randomAccounts[0].addr,
  1826  					Value: (*hexutil.Big)(big.NewInt(50)),
  1827  					Input: hex2Bytes(strings.TrimPrefix(fixedAccount.addr.String(), "0x")),
  1828  				}},
  1829  			}},
  1830  			includeTransfers: &includeTransfers,
  1831  			want: []blockRes{{
  1832  				Number:        "0xb",
  1833  				GasLimit:      "0x47e7c4",
  1834  				GasUsed:       "0x77dc",
  1835  				Miner:         coinbase,
  1836  				BaseFeePerGas: "0x0",
  1837  				Calls: []callRes{{
  1838  					ReturnValue: "0x",
  1839  					GasUsed:     "0x77dc",
  1840  					Logs: []log{{
  1841  						Address: transferAddress,
  1842  						Topics: []common.Hash{
  1843  							transferTopic,
  1844  							addressToHash(accounts[0].addr),
  1845  							addressToHash(randomAccounts[0].addr),
  1846  						},
  1847  						Data:        hexutil.Bytes(common.BigToHash(big.NewInt(50)).Bytes()),
  1848  						BlockNumber: hexutil.Uint64(11),
  1849  					}, {
  1850  						Address: transferAddress,
  1851  						Topics: []common.Hash{
  1852  							transferTopic,
  1853  							addressToHash(randomAccounts[0].addr),
  1854  							addressToHash(fixedAccount.addr),
  1855  						},
  1856  						Data:        hexutil.Bytes(common.BigToHash(big.NewInt(100)).Bytes()),
  1857  						BlockNumber: hexutil.Uint64(11),
  1858  						Index:       hexutil.Uint(1),
  1859  					}},
  1860  					Status: "0x1",
  1861  				}},
  1862  			}},
  1863  		},
  1864  		// Tests selfdestructed contract.
  1865  		{
  1866  			name: "selfdestruct",
  1867  			tag:  latest,
  1868  			blocks: []simBlock{{
  1869  				Calls: []TransactionArgs{{
  1870  					From: &accounts[0].addr,
  1871  					To:   &cac,
  1872  				}, {
  1873  					From: &accounts[0].addr,
  1874  					// Check that cac is selfdestructed and balance transferred to dad.
  1875  					// object "Test" {
  1876  					//    code {
  1877  					//        let cac := 0x0000000000000000000000000000000000000cac
  1878  					//        let dad := 0x0000000000000000000000000000000000000dad
  1879  					//        if gt(balance(cac), 0) {
  1880  					//            revert(0, 0)
  1881  					//        }
  1882  					//        if gt(extcodesize(cac), 0) {
  1883  					//            revert(0, 0)
  1884  					//        }
  1885  					//        if eq(balance(dad), 0) {
  1886  					//            revert(0, 0)
  1887  					//        }
  1888  					//    }
  1889  					// }
  1890  					Input: hex2Bytes("610cac610dad600082311115601357600080fd5b6000823b1115602157600080fd5b6000813103602e57600080fd5b5050"),
  1891  				}},
  1892  			}, {
  1893  				Calls: []TransactionArgs{{
  1894  					From:  &accounts[0].addr,
  1895  					Input: hex2Bytes("610cac610dad600082311115601357600080fd5b6000823b1115602157600080fd5b6000813103602e57600080fd5b5050"),
  1896  				}},
  1897  			}},
  1898  			want: []blockRes{{
  1899  				Number:        "0xb",
  1900  				GasLimit:      "0x47e7c4",
  1901  				GasUsed:       "0x1b83f",
  1902  				Miner:         coinbase,
  1903  				BaseFeePerGas: "0x0",
  1904  				Calls: []callRes{{
  1905  					ReturnValue: "0x",
  1906  					GasUsed:     "0xd166",
  1907  					Logs:        []log{},
  1908  					Status:      "0x1",
  1909  				}, {
  1910  					ReturnValue: "0x",
  1911  					GasUsed:     "0xe6d9",
  1912  					Logs:        []log{},
  1913  					Status:      "0x1",
  1914  				}},
  1915  			}, {
  1916  				Number:        "0xc",
  1917  				GasLimit:      "0x47e7c4",
  1918  				GasUsed:       "0xe6d9",
  1919  				Miner:         coinbase,
  1920  				BaseFeePerGas: "0x0",
  1921  				Calls: []callRes{{
  1922  					ReturnValue: "0x",
  1923  					GasUsed:     "0xe6d9",
  1924  					Logs:        []log{},
  1925  					Status:      "0x1",
  1926  				}},
  1927  			}},
  1928  		},
  1929  		// Enable validation checks.
  1930  		{
  1931  			name: "validation-checks",
  1932  			tag:  latest,
  1933  			blocks: []simBlock{{
  1934  				Calls: []TransactionArgs{{
  1935  					From:  &accounts[2].addr,
  1936  					To:    &cac,
  1937  					Nonce: newUint64(2),
  1938  				}},
  1939  			}},
  1940  			validation: &validation,
  1941  			want:       nil,
  1942  			expectErr:  &invalidTxError{Message: fmt.Sprintf("err: nonce too high: address %s, tx: 2 state: 0 (supplied gas 4712388)", accounts[2].addr), Code: errCodeNonceTooHigh},
  1943  		},
  1944  		// Contract sends tx in validation mode.
  1945  		{
  1946  			name: "validation-checks-from-contract",
  1947  			tag:  latest,
  1948  			blocks: []simBlock{{
  1949  				StateOverrides: &override.StateOverride{
  1950  					randomAccounts[2].addr: override.OverrideAccount{
  1951  						Balance: newRPCBalance(big.NewInt(2098640803896784)),
  1952  						Code:    hex2Bytes("00"),
  1953  						Nonce:   newUint64(1),
  1954  					},
  1955  				},
  1956  				Calls: []TransactionArgs{{
  1957  					From:                 &randomAccounts[2].addr,
  1958  					To:                   &cac,
  1959  					Nonce:                newUint64(1),
  1960  					MaxFeePerGas:         newInt(233138868),
  1961  					MaxPriorityFeePerGas: newInt(1),
  1962  				}},
  1963  			}},
  1964  			validation: &validation,
  1965  			want: []blockRes{{
  1966  				Number:        "0xb",
  1967  				GasLimit:      "0x47e7c4",
  1968  				GasUsed:       "0xd166",
  1969  				Miner:         coinbase,
  1970  				BaseFeePerGas: "0xde56ab3",
  1971  				Calls: []callRes{{
  1972  					ReturnValue: "0x",
  1973  					GasUsed:     "0xd166",
  1974  					Logs:        []log{},
  1975  					Status:      "0x1",
  1976  				}},
  1977  			}},
  1978  		},
  1979  		// Successful validation
  1980  		{
  1981  			name: "validation-checks-success",
  1982  			tag:  latest,
  1983  			blocks: []simBlock{{
  1984  				BlockOverrides: &override.BlockOverrides{
  1985  					BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)),
  1986  				},
  1987  				StateOverrides: &override.StateOverride{
  1988  					randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(10000000))},
  1989  				},
  1990  				Calls: []TransactionArgs{{
  1991  					From:         &randomAccounts[0].addr,
  1992  					To:           &randomAccounts[1].addr,
  1993  					Value:        (*hexutil.Big)(big.NewInt(1000)),
  1994  					MaxFeePerGas: (*hexutil.Big)(big.NewInt(2)),
  1995  				}},
  1996  			}},
  1997  			validation: &validation,
  1998  			want: []blockRes{{
  1999  				Number:        "0xb",
  2000  				GasLimit:      "0x47e7c4",
  2001  				GasUsed:       "0x5208",
  2002  				Miner:         coinbase,
  2003  				BaseFeePerGas: "0x1",
  2004  				Calls: []callRes{{
  2005  					ReturnValue: "0x",
  2006  					GasUsed:     "0x5208",
  2007  					Logs:        []log{},
  2008  					Status:      "0x1",
  2009  				}},
  2010  			}},
  2011  		},
  2012  		// Clear storage.
  2013  		{
  2014  			name: "clear-storage",
  2015  			tag:  latest,
  2016  			blocks: []simBlock{{
  2017  				StateOverrides: &override.StateOverride{
  2018  					randomAccounts[2].addr: {
  2019  						Code: newBytes(genesis.Alloc[bab].Code),
  2020  						StateDiff: map[common.Hash]common.Hash{
  2021  							common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(2)),
  2022  							common.BigToHash(big.NewInt(2)): common.BigToHash(big.NewInt(3)),
  2023  						},
  2024  					},
  2025  					bab: {
  2026  						State: map[common.Hash]common.Hash{
  2027  							common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(1)),
  2028  						},
  2029  					},
  2030  				},
  2031  				Calls: []TransactionArgs{{
  2032  					From: &accounts[0].addr,
  2033  					To:   &randomAccounts[2].addr,
  2034  				}, {
  2035  					From: &accounts[0].addr,
  2036  					To:   &bab,
  2037  				}},
  2038  			}, {
  2039  				StateOverrides: &override.StateOverride{
  2040  					randomAccounts[2].addr: {
  2041  						State: map[common.Hash]common.Hash{
  2042  							common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(5)),
  2043  						},
  2044  					},
  2045  				},
  2046  				Calls: []TransactionArgs{{
  2047  					From: &accounts[0].addr,
  2048  					To:   &randomAccounts[2].addr,
  2049  				}},
  2050  			}},
  2051  			want: []blockRes{{
  2052  				Number:        "0xb",
  2053  				GasLimit:      "0x47e7c4",
  2054  				GasUsed:       "0xc542",
  2055  				Miner:         coinbase,
  2056  				BaseFeePerGas: "0x0",
  2057  				Calls: []callRes{{
  2058  					ReturnValue: "0x0000000000000000000000000000000200000000000000000000000000000003",
  2059  					GasUsed:     "0x62a1",
  2060  					Logs:        []log{},
  2061  					Status:      "0x1",
  2062  				}, {
  2063  					ReturnValue: "0x0000000000000000000000000000000100000000000000000000000000000000",
  2064  					GasUsed:     "0x62a1",
  2065  					Logs:        []log{},
  2066  					Status:      "0x1",
  2067  				}},
  2068  			}, {
  2069  				Number:        "0xc",
  2070  				GasLimit:      "0x47e7c4",
  2071  				GasUsed:       "0x62a1",
  2072  				Miner:         coinbase,
  2073  				BaseFeePerGas: "0x0",
  2074  				Calls: []callRes{{
  2075  					ReturnValue: "0x0000000000000000000000000000000500000000000000000000000000000000",
  2076  					GasUsed:     "0x62a1",
  2077  					Logs:        []log{},
  2078  					Status:      "0x1",
  2079  				}},
  2080  			}},
  2081  		},
  2082  		{
  2083  			name: "blockhash-opcode",
  2084  			tag:  latest,
  2085  			blocks: []simBlock{{
  2086  				BlockOverrides: &override.BlockOverrides{
  2087  					Number: (*hexutil.Big)(big.NewInt(12)),
  2088  				},
  2089  				StateOverrides: &override.StateOverride{
  2090  					randomAccounts[2].addr: {
  2091  						Code: hex2Bytes("600035804060008103601057600080fd5b5050"),
  2092  					},
  2093  				},
  2094  				Calls: []TransactionArgs{{
  2095  					From: &accounts[0].addr,
  2096  					To:   &randomAccounts[2].addr,
  2097  					// Phantom block after base.
  2098  					Input: uint256ToBytes(uint256.NewInt(11)),
  2099  				}, {
  2100  					From: &accounts[0].addr,
  2101  					To:   &randomAccounts[2].addr,
  2102  					// Canonical block.
  2103  					Input: uint256ToBytes(uint256.NewInt(8)),
  2104  				}, {
  2105  					From: &accounts[0].addr,
  2106  					To:   &randomAccounts[2].addr,
  2107  					// base block.
  2108  					Input: uint256ToBytes(uint256.NewInt(10)),
  2109  				}},
  2110  			}, {
  2111  				BlockOverrides: &override.BlockOverrides{
  2112  					Number: (*hexutil.Big)(big.NewInt(16)),
  2113  				},
  2114  				Calls: []TransactionArgs{{
  2115  					From: &accounts[0].addr,
  2116  					To:   &randomAccounts[2].addr,
  2117  					// blocks[0]
  2118  					Input: uint256ToBytes(uint256.NewInt(12)),
  2119  				}, {
  2120  					From: &accounts[0].addr,
  2121  					To:   &randomAccounts[2].addr,
  2122  					// Phantom after blocks[0]
  2123  					Input: uint256ToBytes(uint256.NewInt(13)),
  2124  				}},
  2125  			}},
  2126  			want: []blockRes{{
  2127  				Number:        "0xb",
  2128  				GasLimit:      "0x47e7c4",
  2129  				GasUsed:       "0x0",
  2130  				Miner:         coinbase,
  2131  				BaseFeePerGas: "0x0",
  2132  				Calls:         []callRes{},
  2133  			}, {
  2134  				Number:        "0xc",
  2135  				GasLimit:      "0x47e7c4",
  2136  				GasUsed:       "0xf864",
  2137  				Miner:         coinbase,
  2138  				BaseFeePerGas: "0x0",
  2139  				Calls: []callRes{{
  2140  					ReturnValue: "0x",
  2141  					GasUsed:     "0x52cc",
  2142  					Logs:        []log{},
  2143  					Status:      "0x1",
  2144  				}, {
  2145  					ReturnValue: "0x",
  2146  					GasUsed:     "0x52cc",
  2147  					Logs:        []log{},
  2148  					Status:      "0x1",
  2149  				}, {
  2150  
  2151  					ReturnValue: "0x",
  2152  					GasUsed:     "0x52cc",
  2153  					Logs:        []log{},
  2154  					Status:      "0x1",
  2155  				}},
  2156  			}, {
  2157  				Number:        "0xd",
  2158  				GasLimit:      "0x47e7c4",
  2159  				GasUsed:       "0x0",
  2160  				Miner:         coinbase,
  2161  				BaseFeePerGas: "0x0",
  2162  				Calls:         []callRes{},
  2163  			}, {
  2164  				Number:        "0xe",
  2165  				GasLimit:      "0x47e7c4",
  2166  				GasUsed:       "0x0",
  2167  				Miner:         coinbase,
  2168  				BaseFeePerGas: "0x0",
  2169  				Calls:         []callRes{},
  2170  			}, {
  2171  				Number:        "0xf",
  2172  				GasLimit:      "0x47e7c4",
  2173  				GasUsed:       "0x0",
  2174  				Miner:         coinbase,
  2175  				BaseFeePerGas: "0x0",
  2176  				Calls:         []callRes{},
  2177  			}, {
  2178  				Number:        "0x10",
  2179  				GasLimit:      "0x47e7c4",
  2180  				GasUsed:       "0xa598",
  2181  				Miner:         coinbase,
  2182  				BaseFeePerGas: "0x0",
  2183  				Calls: []callRes{{
  2184  					ReturnValue: "0x",
  2185  					GasUsed:     "0x52cc",
  2186  					Logs:        []log{},
  2187  					Status:      "0x1",
  2188  				}, {
  2189  
  2190  					ReturnValue: "0x",
  2191  					GasUsed:     "0x52cc",
  2192  					Logs:        []log{},
  2193  					Status:      "0x1",
  2194  				}},
  2195  			}},
  2196  		},
  2197  		{
  2198  			name: "basefee-non-validation",
  2199  			tag:  latest,
  2200  			blocks: []simBlock{{
  2201  				StateOverrides: &override.StateOverride{
  2202  					randomAccounts[2].addr: {
  2203  						// Yul code:
  2204  						// object "Test" {
  2205  						//    code {
  2206  						//        // Get the gas price from the transaction
  2207  						//        let gasPrice := gasprice()
  2208  						//
  2209  						//        // Get the base fee from the block
  2210  						//        let baseFee := basefee()
  2211  						//
  2212  						//        // Store gasPrice and baseFee in memory
  2213  						//        mstore(0x0, gasPrice)
  2214  						//        mstore(0x20, baseFee)
  2215  						//
  2216  						//        // Return the data
  2217  						//        return(0x0, 0x40)
  2218  						//    }
  2219  						// }
  2220  						Code: hex2Bytes("3a489060005260205260406000f3"),
  2221  					},
  2222  				},
  2223  				Calls: []TransactionArgs{{
  2224  					From: &accounts[0].addr,
  2225  					To:   &randomAccounts[2].addr,
  2226  					// 0 gas price
  2227  				}, {
  2228  					From: &accounts[0].addr,
  2229  					To:   &randomAccounts[2].addr,
  2230  					// non-zero gas price
  2231  					MaxPriorityFeePerGas: newInt(1),
  2232  					MaxFeePerGas:         newInt(2),
  2233  				},
  2234  				},
  2235  			}, {
  2236  				BlockOverrides: &override.BlockOverrides{
  2237  					BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)),
  2238  				},
  2239  				Calls: []TransactionArgs{{
  2240  					From: &accounts[0].addr,
  2241  					To:   &randomAccounts[2].addr,
  2242  					// 0 gas price
  2243  				}, {
  2244  					From: &accounts[0].addr,
  2245  					To:   &randomAccounts[2].addr,
  2246  					// non-zero gas price
  2247  					MaxPriorityFeePerGas: newInt(1),
  2248  					MaxFeePerGas:         newInt(2),
  2249  				},
  2250  				},
  2251  			}, {
  2252  				// Base fee should be 0 to zero even if it was set in previous block.
  2253  				Calls: []TransactionArgs{{
  2254  					From: &accounts[0].addr,
  2255  					To:   &randomAccounts[2].addr,
  2256  				}},
  2257  			}},
  2258  			want: []blockRes{{
  2259  				Number:        "0xb",
  2260  				GasLimit:      "0x47e7c4",
  2261  				GasUsed:       "0xa44e",
  2262  				Miner:         coinbase,
  2263  				BaseFeePerGas: "0x0",
  2264  				Calls: []callRes{{
  2265  					ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  2266  					GasUsed:     "0x5227",
  2267  					Logs:        []log{},
  2268  					Status:      "0x1",
  2269  				}, {
  2270  					ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000",
  2271  					GasUsed:     "0x5227",
  2272  					Logs:        []log{},
  2273  					Status:      "0x1",
  2274  				}},
  2275  			}, {
  2276  				Number:        "0xc",
  2277  				GasLimit:      "0x47e7c4",
  2278  				GasUsed:       "0xa44e",
  2279  				Miner:         coinbase,
  2280  				BaseFeePerGas: "0x1",
  2281  				Calls: []callRes{{
  2282  					ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  2283  					GasUsed:     "0x5227",
  2284  					Logs:        []log{},
  2285  					Status:      "0x1",
  2286  				}, {
  2287  					ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001",
  2288  					GasUsed:     "0x5227",
  2289  					Logs:        []log{},
  2290  					Status:      "0x1",
  2291  				}},
  2292  			}, {
  2293  				Number:        "0xd",
  2294  				GasLimit:      "0x47e7c4",
  2295  				GasUsed:       "0x5227",
  2296  				Miner:         coinbase,
  2297  				BaseFeePerGas: "0x0",
  2298  				Calls: []callRes{{
  2299  					ReturnValue: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  2300  					GasUsed:     "0x5227",
  2301  					Logs:        []log{},
  2302  					Status:      "0x1",
  2303  				}},
  2304  			}},
  2305  		}, {
  2306  			name: "basefee-validation-mode",
  2307  			tag:  latest,
  2308  			blocks: []simBlock{{
  2309  				StateOverrides: &override.StateOverride{
  2310  					randomAccounts[2].addr: {
  2311  						// Yul code:
  2312  						// object "Test" {
  2313  						//    code {
  2314  						//        // Get the gas price from the transaction
  2315  						//        let gasPrice := gasprice()
  2316  						//
  2317  						//        // Get the base fee from the block
  2318  						//        let baseFee := basefee()
  2319  						//
  2320  						//        // Store gasPrice and baseFee in memory
  2321  						//        mstore(0x0, gasPrice)
  2322  						//        mstore(0x20, baseFee)
  2323  						//
  2324  						//        // Return the data
  2325  						//        return(0x0, 0x40)
  2326  						//    }
  2327  						// }
  2328  						Code: hex2Bytes("3a489060005260205260406000f3"),
  2329  					},
  2330  				},
  2331  				Calls: []TransactionArgs{{
  2332  					From:                 &accounts[0].addr,
  2333  					To:                   &randomAccounts[2].addr,
  2334  					MaxFeePerGas:         newInt(233138868),
  2335  					MaxPriorityFeePerGas: newInt(1),
  2336  				}},
  2337  			}},
  2338  			validation: &validation,
  2339  			want: []blockRes{{
  2340  				Number:        "0xb",
  2341  				GasLimit:      "0x47e7c4",
  2342  				GasUsed:       "0x5227",
  2343  				Miner:         coinbase,
  2344  				BaseFeePerGas: "0xde56ab3",
  2345  				Calls: []callRes{{
  2346  					ReturnValue: "0x000000000000000000000000000000000000000000000000000000000de56ab4000000000000000000000000000000000000000000000000000000000de56ab3",
  2347  					GasUsed:     "0x5227",
  2348  					Logs:        []log{},
  2349  					Status:      "0x1",
  2350  				}},
  2351  			}},
  2352  		},
  2353  	}
  2354  
  2355  	for _, tc := range testSuite {
  2356  		t.Run(tc.name, func(t *testing.T) {
  2357  			opts := simOpts{BlockStateCalls: tc.blocks}
  2358  			if tc.includeTransfers != nil && *tc.includeTransfers {
  2359  				opts.TraceTransfers = true
  2360  			}
  2361  			if tc.validation != nil && *tc.validation {
  2362  				opts.Validation = true
  2363  			}
  2364  			result, err := api.SimulateV1(context.Background(), opts, &tc.tag)
  2365  			if tc.expectErr != nil {
  2366  				if err == nil {
  2367  					t.Fatalf("test %s: want error %v, have nothing", tc.name, tc.expectErr)
  2368  				}
  2369  				if !errors.Is(err, tc.expectErr) {
  2370  					// Second try
  2371  					if !reflect.DeepEqual(err, tc.expectErr) {
  2372  						t.Errorf("test %s: error mismatch, want %v, have %v", tc.name, tc.expectErr, err)
  2373  					}
  2374  				}
  2375  				return
  2376  			}
  2377  			if err != nil {
  2378  				t.Fatalf("test %s: want no error, have %v", tc.name, err)
  2379  			}
  2380  			// Turn result into res-struct
  2381  			var have []blockRes
  2382  			resBytes, _ := json.Marshal(result)
  2383  			if err := json.Unmarshal(resBytes, &have); err != nil {
  2384  				t.Fatalf("failed to unmarshal result: %v", err)
  2385  			}
  2386  			if !reflect.DeepEqual(have, tc.want) {
  2387  				t.Log(string(resBytes))
  2388  				t.Errorf("test %s, result mismatch, have\n%v\n, want\n%v\n", tc.name, have, tc.want)
  2389  			}
  2390  		})
  2391  	}
  2392  }
  2393  
  2394  func TestSimulateV1ChainLinkage(t *testing.T) {
  2395  	var (
  2396  		acc          = newTestAccount()
  2397  		sender       = acc.addr
  2398  		contractAddr = common.Address{0xaa, 0xaa}
  2399  		recipient    = common.Address{0xbb, 0xbb}
  2400  		gspec        = &core.Genesis{
  2401  			Config: params.MergedTestChainConfig,
  2402  			Alloc: types.GenesisAlloc{
  2403  				sender:       {Balance: big.NewInt(params.Ether)},
  2404  				contractAddr: {Code: common.Hex2Bytes("5f35405f8114600f575f5260205ff35b5f80fd")},
  2405  			},
  2406  		}
  2407  		signer = types.LatestSigner(params.MergedTestChainConfig)
  2408  	)
  2409  	backend := newTestBackend(t, 1, gspec, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
  2410  		tx := types.MustSignNewTx(acc.key, signer, &types.LegacyTx{
  2411  			Nonce:    uint64(i),
  2412  			GasPrice: b.BaseFee(),
  2413  			Gas:      params.TxGas,
  2414  			To:       &recipient,
  2415  			Value:    big.NewInt(500),
  2416  		})
  2417  		b.AddTx(tx)
  2418  	})
  2419  
  2420  	ctx := context.Background()
  2421  	stateDB, baseHeader, err := backend.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber))
  2422  	if err != nil {
  2423  		t.Fatalf("failed to get state and header: %v", err)
  2424  	}
  2425  
  2426  	sim := &simulator{
  2427  		b:              backend,
  2428  		state:          stateDB,
  2429  		base:           baseHeader,
  2430  		chainConfig:    backend.ChainConfig(),
  2431  		gp:             new(core.GasPool).AddGas(math.MaxUint64),
  2432  		traceTransfers: false,
  2433  		validate:       false,
  2434  		fullTx:         false,
  2435  	}
  2436  
  2437  	var (
  2438  		call1 = TransactionArgs{
  2439  			From:  &sender,
  2440  			To:    &recipient,
  2441  			Value: (*hexutil.Big)(big.NewInt(1000)),
  2442  		}
  2443  		call2 = TransactionArgs{
  2444  			From:  &sender,
  2445  			To:    &recipient,
  2446  			Value: (*hexutil.Big)(big.NewInt(2000)),
  2447  		}
  2448  		call3a = TransactionArgs{
  2449  			From:  &sender,
  2450  			To:    &contractAddr,
  2451  			Input: uint256ToBytes(uint256.NewInt(baseHeader.Number.Uint64() + 1)),
  2452  			Gas:   newUint64(1000000),
  2453  		}
  2454  		call3b = TransactionArgs{
  2455  			From:  &sender,
  2456  			To:    &contractAddr,
  2457  			Input: uint256ToBytes(uint256.NewInt(baseHeader.Number.Uint64() + 2)),
  2458  			Gas:   newUint64(1000000),
  2459  		}
  2460  		blocks = []simBlock{
  2461  			{Calls: []TransactionArgs{call1}},
  2462  			{Calls: []TransactionArgs{call2}},
  2463  			{Calls: []TransactionArgs{call3a, call3b}},
  2464  		}
  2465  	)
  2466  
  2467  	results, err := sim.execute(ctx, blocks)
  2468  	if err != nil {
  2469  		t.Fatalf("simulation execution failed: %v", err)
  2470  	}
  2471  	require.Equal(t, 3, len(results), "expected 3 simulated blocks")
  2472  
  2473  	// Check linkages of simulated blocks:
  2474  	// Verify that block2's parent hash equals block1's hash.
  2475  	block1 := results[0].Block
  2476  	block2 := results[1].Block
  2477  	block3 := results[2].Block
  2478  	require.Equal(t, block1.ParentHash(), baseHeader.Hash(), "parent hash of block1 should equal hash of base block")
  2479  	require.Equal(t, block1.Hash(), block2.Header().ParentHash, "parent hash of block2 should equal hash of block1")
  2480  	require.Equal(t, block2.Hash(), block3.Header().ParentHash, "parent hash of block3 should equal hash of block2")
  2481  
  2482  	// In block3, two calls were executed to our contract.
  2483  	// The first call in block3 should return the blockhash for block1 (i.e. block1.Hash()),
  2484  	// whereas the second call should return the blockhash for block2 (i.e. block2.Hash()).
  2485  	require.Equal(t, block1.Hash().Bytes(), []byte(results[2].Calls[0].ReturnValue), "returned blockhash for block1 does not match")
  2486  	require.Equal(t, block2.Hash().Bytes(), []byte(results[2].Calls[1].ReturnValue), "returned blockhash for block2 does not match")
  2487  }
  2488  
  2489  func TestSimulateV1TxSender(t *testing.T) {
  2490  	var (
  2491  		sender    = common.Address{0xaa, 0xaa}
  2492  		sender2   = common.Address{0xaa, 0xab}
  2493  		sender3   = common.Address{0xaa, 0xac}
  2494  		recipient = common.Address{0xbb, 0xbb}
  2495  		gspec     = &core.Genesis{
  2496  			Config: params.MergedTestChainConfig,
  2497  			Alloc: types.GenesisAlloc{
  2498  				sender:  {Balance: big.NewInt(params.Ether)},
  2499  				sender2: {Balance: big.NewInt(params.Ether)},
  2500  				sender3: {Balance: big.NewInt(params.Ether)},
  2501  			},
  2502  		}
  2503  		ctx = context.Background()
  2504  	)
  2505  	backend := newTestBackend(t, 0, gspec, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {})
  2506  	stateDB, baseHeader, err := backend.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber))
  2507  	if err != nil {
  2508  		t.Fatalf("failed to get state and header: %v", err)
  2509  	}
  2510  
  2511  	sim := &simulator{
  2512  		b:              backend,
  2513  		state:          stateDB,
  2514  		base:           baseHeader,
  2515  		chainConfig:    backend.ChainConfig(),
  2516  		gp:             new(core.GasPool).AddGas(math.MaxUint64),
  2517  		traceTransfers: false,
  2518  		validate:       false,
  2519  		fullTx:         true,
  2520  	}
  2521  
  2522  	results, err := sim.execute(ctx, []simBlock{
  2523  		{Calls: []TransactionArgs{
  2524  			{From: &sender, To: &recipient, Value: (*hexutil.Big)(big.NewInt(1000))},
  2525  			{From: &sender2, To: &recipient, Value: (*hexutil.Big)(big.NewInt(2000))},
  2526  			{From: &sender3, To: &recipient, Value: (*hexutil.Big)(big.NewInt(3000))},
  2527  		}},
  2528  		{Calls: []TransactionArgs{
  2529  			{From: &sender2, To: &recipient, Value: (*hexutil.Big)(big.NewInt(4000))},
  2530  		}},
  2531  	})
  2532  	if err != nil {
  2533  		t.Fatalf("simulation execution failed: %v", err)
  2534  	}
  2535  	require.Len(t, results, 2, "expected 2 simulated blocks")
  2536  	require.Len(t, results[0].Block.Transactions(), 3, "expected 3 transaction in simulated block")
  2537  	require.Len(t, results[1].Block.Transactions(), 1, "expected 1 transaction in 2nd simulated block")
  2538  	enc, err := json.Marshal(results)
  2539  	if err != nil {
  2540  		t.Fatalf("failed to marshal results: %v", err)
  2541  	}
  2542  	type resultType struct {
  2543  		Transactions []struct {
  2544  			From common.Address `json:"from"`
  2545  		}
  2546  	}
  2547  	var summary []resultType
  2548  	if err := json.Unmarshal(enc, &summary); err != nil {
  2549  		t.Fatalf("failed to unmarshal results: %v", err)
  2550  	}
  2551  	require.Len(t, summary, 2, "expected 2 simulated blocks")
  2552  	require.Len(t, summary[0].Transactions, 3, "expected 3 transaction in simulated block")
  2553  	require.Equal(t, sender, summary[0].Transactions[0].From, "sender address mismatch")
  2554  	require.Equal(t, sender2, summary[0].Transactions[1].From, "sender address mismatch")
  2555  	require.Equal(t, sender3, summary[0].Transactions[2].From, "sender address mismatch")
  2556  	require.Len(t, summary[1].Transactions, 1, "expected 1 transaction in simulated block")
  2557  	require.Equal(t, sender2, summary[1].Transactions[0].From, "sender address mismatch")
  2558  }
  2559  
  2560  func TestSignTransaction(t *testing.T) {
  2561  	t.Parallel()
  2562  	// Initialize test accounts
  2563  	var (
  2564  		key, _  = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  2565  		to      = crypto.PubkeyToAddress(key.PublicKey)
  2566  		genesis = &core.Genesis{
  2567  			Config: params.MergedTestChainConfig,
  2568  			Alloc:  types.GenesisAlloc{},
  2569  		}
  2570  	)
  2571  	b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
  2572  		b.SetPoS()
  2573  	})
  2574  	api := NewTransactionAPI(b, nil)
  2575  	res, err := api.FillTransaction(context.Background(), TransactionArgs{
  2576  		From:  &b.acc.Address,
  2577  		To:    &to,
  2578  		Value: (*hexutil.Big)(big.NewInt(1)),
  2579  	})
  2580  	if err != nil {
  2581  		t.Fatalf("failed to fill tx defaults: %v\n", err)
  2582  	}
  2583  
  2584  	res, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
  2585  	if err != nil {
  2586  		t.Fatalf("failed to sign tx: %v\n", err)
  2587  	}
  2588  	tx, err := json.Marshal(res.Tx)
  2589  	if err != nil {
  2590  		t.Fatal(err)
  2591  	}
  2592  	expect := `{"type":"0x2","chainId":"0x1","nonce":"0x0","to":"0x703c4b2bd70c169f5717101caee543299fc946c7","gas":"0x5208","gasPrice":null,"maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x684ee180","value":"0x1","input":"0x","accessList":[],"v":"0x0","r":"0x8fabeb142d585dd9247f459f7e6fe77e2520c88d50ba5d220da1533cea8b34e1","s":"0x582dd68b21aef36ba23f34e49607329c20d981d30404daf749077f5606785ce7","yParity":"0x0","hash":"0x93927839207cfbec395da84b8a2bc38b7b65d2cb2819e9fef1f091f5b1d4cc8f"}`
  2593  	if !bytes.Equal(tx, []byte(expect)) {
  2594  		t.Errorf("result mismatch. Have:\n%s\nWant:\n%s\n", tx, expect)
  2595  	}
  2596  }
  2597  
  2598  func TestSignBlobTransaction(t *testing.T) {
  2599  	t.Parallel()
  2600  	// Initialize test accounts
  2601  	var (
  2602  		key, _  = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  2603  		to      = crypto.PubkeyToAddress(key.PublicKey)
  2604  		genesis = &core.Genesis{
  2605  			Config: params.MergedTestChainConfig,
  2606  			Alloc:  types.GenesisAlloc{},
  2607  		}
  2608  	)
  2609  	b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
  2610  		b.SetPoS()
  2611  	})
  2612  	api := NewTransactionAPI(b, nil)
  2613  	res, err := api.FillTransaction(context.Background(), TransactionArgs{
  2614  		From:       &b.acc.Address,
  2615  		To:         &to,
  2616  		Value:      (*hexutil.Big)(big.NewInt(1)),
  2617  		BlobHashes: []common.Hash{{0x01, 0x22}},
  2618  	})
  2619  	if err != nil {
  2620  		t.Fatalf("failed to fill tx defaults: %v\n", err)
  2621  	}
  2622  
  2623  	_, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
  2624  	if err != nil {
  2625  		t.Fatalf("should not fail on blob transaction")
  2626  	}
  2627  }
  2628  
  2629  func TestSendBlobTransaction(t *testing.T) {
  2630  	t.Parallel()
  2631  	// Initialize test accounts
  2632  	var (
  2633  		key, _  = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  2634  		to      = crypto.PubkeyToAddress(key.PublicKey)
  2635  		genesis = &core.Genesis{
  2636  			Config: params.MergedTestChainConfig,
  2637  			Alloc:  types.GenesisAlloc{},
  2638  		}
  2639  	)
  2640  	b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
  2641  		b.SetPoS()
  2642  	})
  2643  	api := NewTransactionAPI(b, nil)
  2644  	res, err := api.FillTransaction(context.Background(), TransactionArgs{
  2645  		From:       &b.acc.Address,
  2646  		To:         &to,
  2647  		Value:      (*hexutil.Big)(big.NewInt(1)),
  2648  		BlobHashes: []common.Hash{{0x01, 0x22}},
  2649  	})
  2650  	if err != nil {
  2651  		t.Fatalf("failed to fill tx defaults: %v\n", err)
  2652  	}
  2653  
  2654  	_, err = api.SendTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
  2655  	if err == nil {
  2656  		t.Errorf("sending tx should have failed")
  2657  	} else if !errors.Is(err, errBlobTxNotSupported) {
  2658  		t.Errorf("unexpected error. Have %v, want %v\n", err, errBlobTxNotSupported)
  2659  	}
  2660  }
  2661  
  2662  func TestFillBlobTransaction(t *testing.T) {
  2663  	t.Parallel()
  2664  	// Initialize test accounts
  2665  	var (
  2666  		key, _  = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  2667  		to      = crypto.PubkeyToAddress(key.PublicKey)
  2668  		genesis = &core.Genesis{
  2669  			Config: params.MergedTestChainConfig,
  2670  			Alloc:  types.GenesisAlloc{},
  2671  		}
  2672  		emptyBlob                      = new(kzg4844.Blob)
  2673  		emptyBlobs                     = []kzg4844.Blob{*emptyBlob}
  2674  		emptyBlobCommit, _             = kzg4844.BlobToCommitment(emptyBlob)
  2675  		emptyBlobProof, _              = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
  2676  		emptyBlobHash      common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
  2677  	)
  2678  	b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
  2679  		b.SetPoS()
  2680  	})
  2681  	api := NewTransactionAPI(b, nil)
  2682  	type result struct {
  2683  		Hashes  []common.Hash
  2684  		Sidecar *types.BlobTxSidecar
  2685  	}
  2686  	suite := []struct {
  2687  		name string
  2688  		args TransactionArgs
  2689  		err  string
  2690  		want *result
  2691  	}{
  2692  		{
  2693  			name: "TestInvalidParamsCombination1",
  2694  			args: TransactionArgs{
  2695  				From:   &b.acc.Address,
  2696  				To:     &to,
  2697  				Value:  (*hexutil.Big)(big.NewInt(1)),
  2698  				Blobs:  []kzg4844.Blob{{}},
  2699  				Proofs: []kzg4844.Proof{{}},
  2700  			},
  2701  			err: `blob proofs provided while commitments were not`,
  2702  		},
  2703  		{
  2704  			name: "TestInvalidParamsCombination2",
  2705  			args: TransactionArgs{
  2706  				From:        &b.acc.Address,
  2707  				To:          &to,
  2708  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2709  				Blobs:       []kzg4844.Blob{{}},
  2710  				Commitments: []kzg4844.Commitment{{}},
  2711  			},
  2712  			err: `blob commitments provided while proofs were not`,
  2713  		},
  2714  		{
  2715  			name: "TestInvalidParamsCount1",
  2716  			args: TransactionArgs{
  2717  				From:        &b.acc.Address,
  2718  				To:          &to,
  2719  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2720  				Blobs:       []kzg4844.Blob{{}},
  2721  				Commitments: []kzg4844.Commitment{{}, {}},
  2722  				Proofs:      []kzg4844.Proof{{}, {}},
  2723  			},
  2724  			err: `number of blobs and commitments mismatch (have=2, want=1)`,
  2725  		},
  2726  		{
  2727  			name: "TestInvalidParamsCount2",
  2728  			args: TransactionArgs{
  2729  				From:        &b.acc.Address,
  2730  				To:          &to,
  2731  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2732  				Blobs:       []kzg4844.Blob{{}, {}},
  2733  				Commitments: []kzg4844.Commitment{{}, {}},
  2734  				Proofs:      []kzg4844.Proof{{}},
  2735  			},
  2736  			err: `number of blobs and proofs mismatch (have=1, want=2)`,
  2737  		},
  2738  		{
  2739  			name: "TestInvalidProofVerification",
  2740  			args: TransactionArgs{
  2741  				From:        &b.acc.Address,
  2742  				To:          &to,
  2743  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2744  				Blobs:       []kzg4844.Blob{{}, {}},
  2745  				Commitments: []kzg4844.Commitment{{}, {}},
  2746  				Proofs:      []kzg4844.Proof{{}, {}},
  2747  			},
  2748  			err: `failed to verify blob proof: short buffer`,
  2749  		},
  2750  		{
  2751  			name: "TestGenerateBlobHashes",
  2752  			args: TransactionArgs{
  2753  				From:        &b.acc.Address,
  2754  				To:          &to,
  2755  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2756  				Blobs:       emptyBlobs,
  2757  				Commitments: []kzg4844.Commitment{emptyBlobCommit},
  2758  				Proofs:      []kzg4844.Proof{emptyBlobProof},
  2759  			},
  2760  			want: &result{
  2761  				Hashes: []common.Hash{emptyBlobHash},
  2762  				Sidecar: &types.BlobTxSidecar{
  2763  					Blobs:       emptyBlobs,
  2764  					Commitments: []kzg4844.Commitment{emptyBlobCommit},
  2765  					Proofs:      []kzg4844.Proof{emptyBlobProof},
  2766  				},
  2767  			},
  2768  		},
  2769  		{
  2770  			name: "TestValidBlobHashes",
  2771  			args: TransactionArgs{
  2772  				From:        &b.acc.Address,
  2773  				To:          &to,
  2774  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2775  				BlobHashes:  []common.Hash{emptyBlobHash},
  2776  				Blobs:       emptyBlobs,
  2777  				Commitments: []kzg4844.Commitment{emptyBlobCommit},
  2778  				Proofs:      []kzg4844.Proof{emptyBlobProof},
  2779  			},
  2780  			want: &result{
  2781  				Hashes: []common.Hash{emptyBlobHash},
  2782  				Sidecar: &types.BlobTxSidecar{
  2783  					Blobs:       emptyBlobs,
  2784  					Commitments: []kzg4844.Commitment{emptyBlobCommit},
  2785  					Proofs:      []kzg4844.Proof{emptyBlobProof},
  2786  				},
  2787  			},
  2788  		},
  2789  		{
  2790  			name: "TestInvalidBlobHashes",
  2791  			args: TransactionArgs{
  2792  				From:        &b.acc.Address,
  2793  				To:          &to,
  2794  				Value:       (*hexutil.Big)(big.NewInt(1)),
  2795  				BlobHashes:  []common.Hash{{0x01, 0x22}},
  2796  				Blobs:       emptyBlobs,
  2797  				Commitments: []kzg4844.Commitment{emptyBlobCommit},
  2798  				Proofs:      []kzg4844.Proof{emptyBlobProof},
  2799  			},
  2800  			err: fmt.Sprintf("blob hash verification failed (have=%s, want=%s)", common.Hash{0x01, 0x22}, emptyBlobHash),
  2801  		},
  2802  		{
  2803  			name: "TestGenerateBlobProofs",
  2804  			args: TransactionArgs{
  2805  				From:  &b.acc.Address,
  2806  				To:    &to,
  2807  				Value: (*hexutil.Big)(big.NewInt(1)),
  2808  				Blobs: emptyBlobs,
  2809  			},
  2810  			want: &result{
  2811  				Hashes: []common.Hash{emptyBlobHash},
  2812  				Sidecar: &types.BlobTxSidecar{
  2813  					Blobs:       emptyBlobs,
  2814  					Commitments: []kzg4844.Commitment{emptyBlobCommit},
  2815  					Proofs:      []kzg4844.Proof{emptyBlobProof},
  2816  				},
  2817  			},
  2818  		},
  2819  	}
  2820  	for _, tc := range suite {
  2821  		t.Run(tc.name, func(t *testing.T) {
  2822  			t.Parallel()
  2823  
  2824  			res, err := api.FillTransaction(context.Background(), tc.args)
  2825  			if len(tc.err) > 0 {
  2826  				if err == nil {
  2827  					t.Fatalf("missing error. want: %s", tc.err)
  2828  				} else if err.Error() != tc.err {
  2829  					t.Fatalf("error mismatch. want: %s, have: %s", tc.err, err.Error())
  2830  				}
  2831  				return
  2832  			}
  2833  			if err != nil && len(tc.err) == 0 {
  2834  				t.Fatalf("expected no error. have: %s", err)
  2835  			}
  2836  			if res == nil {
  2837  				t.Fatal("result missing")
  2838  			}
  2839  			want, err := json.Marshal(tc.want)
  2840  			if err != nil {
  2841  				t.Fatalf("failed to encode expected: %v", err)
  2842  			}
  2843  			have, err := json.Marshal(result{Hashes: res.Tx.BlobHashes(), Sidecar: res.Tx.BlobTxSidecar()})
  2844  			if err != nil {
  2845  				t.Fatalf("failed to encode computed sidecar: %v", err)
  2846  			}
  2847  			if !bytes.Equal(have, want) {
  2848  				t.Errorf("blob sidecar mismatch. Have: %s, want: %s", have, want)
  2849  			}
  2850  		})
  2851  	}
  2852  }
  2853  
  2854  func argsFromTransaction(tx *types.Transaction, from common.Address) TransactionArgs {
  2855  	var (
  2856  		gas        = tx.Gas()
  2857  		nonce      = tx.Nonce()
  2858  		input      = tx.Data()
  2859  		accessList *types.AccessList
  2860  	)
  2861  	if acl := tx.AccessList(); acl != nil {
  2862  		accessList = &acl
  2863  	}
  2864  	return TransactionArgs{
  2865  		From:                 &from,
  2866  		To:                   tx.To(),
  2867  		Gas:                  (*hexutil.Uint64)(&gas),
  2868  		MaxFeePerGas:         (*hexutil.Big)(tx.GasFeeCap()),
  2869  		MaxPriorityFeePerGas: (*hexutil.Big)(tx.GasTipCap()),
  2870  		Value:                (*hexutil.Big)(tx.Value()),
  2871  		Nonce:                (*hexutil.Uint64)(&nonce),
  2872  		Input:                (*hexutil.Bytes)(&input),
  2873  		ChainID:              (*hexutil.Big)(tx.ChainId()),
  2874  		AccessList:           accessList,
  2875  		BlobFeeCap:           (*hexutil.Big)(tx.BlobGasFeeCap()),
  2876  		BlobHashes:           tx.BlobHashes(),
  2877  	}
  2878  }
  2879  
  2880  type account struct {
  2881  	key  *ecdsa.PrivateKey
  2882  	addr common.Address
  2883  }
  2884  
  2885  func newAccounts(n int) (accounts []account) {
  2886  	for i := 0; i < n; i++ {
  2887  		key, _ := crypto.GenerateKey()
  2888  		addr := crypto.PubkeyToAddress(key.PublicKey)
  2889  		accounts = append(accounts, account{key: key, addr: addr})
  2890  	}
  2891  	slices.SortFunc(accounts, func(a, b account) int { return a.addr.Cmp(b.addr) })
  2892  	return accounts
  2893  }
  2894  
  2895  func newTestAccount() account {
  2896  	// testKey is a private key to use for funding a tester account.
  2897  	key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2898  	// testAddr is the Ethereum address of the tester account.
  2899  	addr := crypto.PubkeyToAddress(key.PublicKey)
  2900  	return account{key: key, addr: addr}
  2901  }
  2902  
  2903  func newRPCBalance(balance *big.Int) *hexutil.Big {
  2904  	rpcBalance := (*hexutil.Big)(balance)
  2905  	return rpcBalance
  2906  }
  2907  
  2908  func hex2Bytes(str string) *hexutil.Bytes {
  2909  	rpcBytes := hexutil.Bytes(common.FromHex(str))
  2910  	return &rpcBytes
  2911  }
  2912  
  2913  func newUint64(v uint64) *hexutil.Uint64 {
  2914  	rpcUint64 := hexutil.Uint64(v)
  2915  	return &rpcUint64
  2916  }
  2917  
  2918  func newBytes(b []byte) *hexutil.Bytes {
  2919  	rpcBytes := hexutil.Bytes(b)
  2920  	return &rpcBytes
  2921  }
  2922  
  2923  func uint256ToBytes(v *uint256.Int) *hexutil.Bytes {
  2924  	b := v.Bytes32()
  2925  	r := hexutil.Bytes(b[:])
  2926  	return &r
  2927  }
  2928  
  2929  func TestRPCMarshalBlock(t *testing.T) {
  2930  	t.Parallel()
  2931  	var (
  2932  		txs []*types.Transaction
  2933  		to  = common.BytesToAddress([]byte{0x11})
  2934  	)
  2935  	for i := uint64(1); i <= 4; i++ {
  2936  		var tx *types.Transaction
  2937  		if i%2 == 0 {
  2938  			tx = types.NewTx(&types.LegacyTx{
  2939  				Nonce:    i,
  2940  				GasPrice: big.NewInt(11111),
  2941  				Gas:      1111,
  2942  				To:       &to,
  2943  				Value:    big.NewInt(111),
  2944  				Data:     []byte{0x11, 0x11, 0x11},
  2945  			})
  2946  		} else {
  2947  			tx = types.NewTx(&types.AccessListTx{
  2948  				ChainID:  big.NewInt(1337),
  2949  				Nonce:    i,
  2950  				GasPrice: big.NewInt(11111),
  2951  				Gas:      1111,
  2952  				To:       &to,
  2953  				Value:    big.NewInt(111),
  2954  				Data:     []byte{0x11, 0x11, 0x11},
  2955  			})
  2956  		}
  2957  		txs = append(txs, tx)
  2958  	}
  2959  	block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, &types.Body{Transactions: txs}, nil, blocktest.NewHasher())
  2960  
  2961  	var testSuite = []struct {
  2962  		inclTx bool
  2963  		fullTx bool
  2964  		want   string
  2965  	}{
  2966  		// without txs
  2967  		{
  2968  			inclTx: false,
  2969  			fullTx: false,
  2970  			want: `{
  2971  				"difficulty": "0x0",
  2972  				"extraData": "0x",
  2973  				"gasLimit": "0x0",
  2974  				"gasUsed": "0x0",
  2975  				"hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  2976  				"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  2977  				"miner": "0x0000000000000000000000000000000000000000",
  2978  				"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  2979  				"nonce": "0x0000000000000000",
  2980  				"number": "0x64",
  2981  				"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  2982  				"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  2983  				"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  2984  				"size": "0x296",
  2985  				"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
  2986  				"timestamp": "0x0",
  2987  				"transactionsRoot": "0x661a9febcfa8f1890af549b874faf9fa274aede26ef489d9db0b25daa569450e",
  2988  				"uncles": []
  2989  			}`,
  2990  		},
  2991  		// only tx hashes
  2992  		{
  2993  			inclTx: true,
  2994  			fullTx: false,
  2995  			want: `{
  2996  				"difficulty": "0x0",
  2997  				"extraData": "0x",
  2998  				"gasLimit": "0x0",
  2999  				"gasUsed": "0x0",
  3000  				"hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  3001  				"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  3002  				"miner": "0x0000000000000000000000000000000000000000",
  3003  				"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  3004  				"nonce": "0x0000000000000000",
  3005  				"number": "0x64",
  3006  				"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  3007  				"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  3008  				"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  3009  				"size": "0x296",
  3010  				"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
  3011  				"timestamp": "0x0",
  3012  				"transactions": [
  3013  					"0x7d39df979e34172322c64983a9ad48302c2b889e55bda35324afecf043a77605",
  3014  					"0x9bba4c34e57c875ff57ac8d172805a26ae912006985395dc1bdf8f44140a7bf4",
  3015  					"0x98909ea1ff040da6be56bc4231d484de1414b3c1dac372d69293a4beb9032cb5",
  3016  					"0x12e1f81207b40c3bdcc13c0ee18f5f86af6d31754d57a0ea1b0d4cfef21abef1"
  3017  				],
  3018  				"transactionsRoot": "0x661a9febcfa8f1890af549b874faf9fa274aede26ef489d9db0b25daa569450e",
  3019  				"uncles": []
  3020  			}`,
  3021  		},
  3022  		// full tx details
  3023  		{
  3024  			inclTx: true,
  3025  			fullTx: true,
  3026  			want: `{
  3027  				"difficulty": "0x0",
  3028  				"extraData": "0x",
  3029  				"gasLimit": "0x0",
  3030  				"gasUsed": "0x0",
  3031  				"hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  3032  				"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  3033  				"miner": "0x0000000000000000000000000000000000000000",
  3034  				"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  3035  				"nonce": "0x0000000000000000",
  3036  				"number": "0x64",
  3037  				"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  3038  				"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  3039  				"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  3040  				"size": "0x296",
  3041  				"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
  3042  				"timestamp": "0x0",
  3043  				"transactions": [
  3044  					{
  3045  						"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  3046  						"blockNumber": "0x64",
  3047  						"from": "0x0000000000000000000000000000000000000000",
  3048  						"gas": "0x457",
  3049  						"gasPrice": "0x2b67",
  3050  						"hash": "0x7d39df979e34172322c64983a9ad48302c2b889e55bda35324afecf043a77605",
  3051  						"input": "0x111111",
  3052  						"nonce": "0x1",
  3053  						"to": "0x0000000000000000000000000000000000000011",
  3054  						"transactionIndex": "0x0",
  3055  						"value": "0x6f",
  3056  						"type": "0x1",
  3057  						"accessList": [],
  3058  						"chainId": "0x539",
  3059  						"v": "0x0",
  3060  						"r": "0x0",
  3061  						"s": "0x0",
  3062  						"yParity": "0x0"
  3063  					},
  3064  					{
  3065  						"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  3066  						"blockNumber": "0x64",
  3067  						"from": "0x0000000000000000000000000000000000000000",
  3068  						"gas": "0x457",
  3069  						"gasPrice": "0x2b67",
  3070  						"hash": "0x9bba4c34e57c875ff57ac8d172805a26ae912006985395dc1bdf8f44140a7bf4",
  3071  						"input": "0x111111",
  3072  						"nonce": "0x2",
  3073  						"to": "0x0000000000000000000000000000000000000011",
  3074  						"transactionIndex": "0x1",
  3075  						"value": "0x6f",
  3076  						"type": "0x0",
  3077  						"chainId": "0x7fffffffffffffee",
  3078  						"v": "0x0",
  3079  						"r": "0x0",
  3080  						"s": "0x0"
  3081  					},
  3082  					{
  3083  						"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  3084  						"blockNumber": "0x64",
  3085  						"from": "0x0000000000000000000000000000000000000000",
  3086  						"gas": "0x457",
  3087  						"gasPrice": "0x2b67",
  3088  						"hash": "0x98909ea1ff040da6be56bc4231d484de1414b3c1dac372d69293a4beb9032cb5",
  3089  						"input": "0x111111",
  3090  						"nonce": "0x3",
  3091  						"to": "0x0000000000000000000000000000000000000011",
  3092  						"transactionIndex": "0x2",
  3093  						"value": "0x6f",
  3094  						"type": "0x1",
  3095  						"accessList": [],
  3096  						"chainId": "0x539",
  3097  						"v": "0x0",
  3098  						"r": "0x0",
  3099  						"s": "0x0",
  3100  						"yParity": "0x0"
  3101  					},
  3102  					{
  3103  						"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
  3104  						"blockNumber": "0x64",
  3105  						"from": "0x0000000000000000000000000000000000000000",
  3106  						"gas": "0x457",
  3107  						"gasPrice": "0x2b67",
  3108  						"hash": "0x12e1f81207b40c3bdcc13c0ee18f5f86af6d31754d57a0ea1b0d4cfef21abef1",
  3109  						"input": "0x111111",
  3110  						"nonce": "0x4",
  3111  						"to": "0x0000000000000000000000000000000000000011",
  3112  						"transactionIndex": "0x3",
  3113  						"value": "0x6f",
  3114  						"type": "0x0",
  3115  						"chainId": "0x7fffffffffffffee",
  3116  						"v": "0x0",
  3117  						"r": "0x0",
  3118  						"s": "0x0"
  3119  					}
  3120  				],
  3121  				"transactionsRoot": "0x661a9febcfa8f1890af549b874faf9fa274aede26ef489d9db0b25daa569450e",
  3122  				"uncles": []
  3123  			}`,
  3124  		},
  3125  	}
  3126  
  3127  	for i, tc := range testSuite {
  3128  		resp := RPCMarshalBlock(block, tc.inclTx, tc.fullTx, params.MainnetChainConfig)
  3129  		out, err := json.Marshal(resp)
  3130  		if err != nil {
  3131  			t.Errorf("test %d: json marshal error: %v", i, err)
  3132  			continue
  3133  		}
  3134  		require.JSONEqf(t, tc.want, string(out), "test %d", i)
  3135  	}
  3136  }
  3137  
  3138  func TestRPCGetBlockOrHeader(t *testing.T) {
  3139  	t.Parallel()
  3140  
  3141  	// Initialize test accounts
  3142  	var (
  3143  		acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  3144  		acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
  3145  		acc1Addr   = crypto.PubkeyToAddress(acc1Key.PublicKey)
  3146  		acc2Addr   = crypto.PubkeyToAddress(acc2Key.PublicKey)
  3147  		genesis    = &core.Genesis{
  3148  			Config: params.TestChainConfig,
  3149  			Alloc: types.GenesisAlloc{
  3150  				acc1Addr: {Balance: big.NewInt(params.Ether)},
  3151  				acc2Addr: {Balance: big.NewInt(params.Ether)},
  3152  			},
  3153  		}
  3154  		genBlocks = 10
  3155  		signer    = types.HomesteadSigner{}
  3156  		tx        = types.NewTx(&types.LegacyTx{
  3157  			Nonce:    11,
  3158  			GasPrice: big.NewInt(11111),
  3159  			Gas:      1111,
  3160  			To:       &acc2Addr,
  3161  			Value:    big.NewInt(111),
  3162  			Data:     []byte{0x11, 0x11, 0x11},
  3163  		})
  3164  		withdrawal = &types.Withdrawal{
  3165  			Index:     0,
  3166  			Validator: 1,
  3167  			Address:   common.Address{0x12, 0x34},
  3168  			Amount:    10,
  3169  		}
  3170  		pending = types.NewBlock(&types.Header{Number: big.NewInt(11), Time: 42}, &types.Body{Transactions: types.Transactions{tx}, Withdrawals: types.Withdrawals{withdrawal}}, nil, blocktest.NewHasher())
  3171  	)
  3172  	backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) {
  3173  		// Transfer from account[0] to account[1]
  3174  		//    value: 1000 wei
  3175  		//    fee:   0 wei
  3176  		tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, acc1Key)
  3177  		b.AddTx(tx)
  3178  	})
  3179  	backend.setPendingBlock(pending)
  3180  	api := NewBlockChainAPI(backend)
  3181  	blockHashes := make([]common.Hash, genBlocks+1)
  3182  	ctx := context.Background()
  3183  	for i := 0; i <= genBlocks; i++ {
  3184  		header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i))
  3185  		if err != nil {
  3186  			t.Errorf("failed to get block: %d err: %v", i, err)
  3187  		}
  3188  		blockHashes[i] = header.Hash()
  3189  	}
  3190  	pendingHash := pending.Hash()
  3191  
  3192  	var testSuite = []struct {
  3193  		blockNumber rpc.BlockNumber
  3194  		blockHash   *common.Hash
  3195  		fullTx      bool
  3196  		reqHeader   bool
  3197  		file        string
  3198  		expectErr   error
  3199  	}{
  3200  		// 0. latest header
  3201  		{
  3202  			blockNumber: rpc.LatestBlockNumber,
  3203  			reqHeader:   true,
  3204  			file:        "tag-latest",
  3205  		},
  3206  		// 1. genesis header
  3207  		{
  3208  			blockNumber: rpc.BlockNumber(0),
  3209  			reqHeader:   true,
  3210  			file:        "number-0",
  3211  		},
  3212  		// 2. #1 header
  3213  		{
  3214  			blockNumber: rpc.BlockNumber(1),
  3215  			reqHeader:   true,
  3216  			file:        "number-1",
  3217  		},
  3218  		// 3. latest-1 header
  3219  		{
  3220  			blockNumber: rpc.BlockNumber(9),
  3221  			reqHeader:   true,
  3222  			file:        "number-latest-1",
  3223  		},
  3224  		// 4. latest+1 header
  3225  		{
  3226  			blockNumber: rpc.BlockNumber(11),
  3227  			reqHeader:   true,
  3228  			file:        "number-latest+1",
  3229  		},
  3230  		// 5. pending header
  3231  		{
  3232  			blockNumber: rpc.PendingBlockNumber,
  3233  			reqHeader:   true,
  3234  			file:        "tag-pending",
  3235  		},
  3236  		// 6. latest block
  3237  		{
  3238  			blockNumber: rpc.LatestBlockNumber,
  3239  			file:        "tag-latest",
  3240  		},
  3241  		// 7. genesis block
  3242  		{
  3243  			blockNumber: rpc.BlockNumber(0),
  3244  			file:        "number-0",
  3245  		},
  3246  		// 8. #1 block
  3247  		{
  3248  			blockNumber: rpc.BlockNumber(1),
  3249  			file:        "number-1",
  3250  		},
  3251  		// 9. latest-1 block
  3252  		{
  3253  			blockNumber: rpc.BlockNumber(9),
  3254  			fullTx:      true,
  3255  			file:        "number-latest-1",
  3256  		},
  3257  		// 10. latest+1 block
  3258  		{
  3259  			blockNumber: rpc.BlockNumber(11),
  3260  			fullTx:      true,
  3261  			file:        "number-latest+1",
  3262  		},
  3263  		// 11. pending block
  3264  		{
  3265  			blockNumber: rpc.PendingBlockNumber,
  3266  			file:        "tag-pending",
  3267  		},
  3268  		// 12. pending block + fullTx
  3269  		{
  3270  			blockNumber: rpc.PendingBlockNumber,
  3271  			fullTx:      true,
  3272  			file:        "tag-pending-fullTx",
  3273  		},
  3274  		// 13. latest header by hash
  3275  		{
  3276  			blockHash: &blockHashes[len(blockHashes)-1],
  3277  			reqHeader: true,
  3278  			file:      "hash-latest",
  3279  		},
  3280  		// 14. genesis header by hash
  3281  		{
  3282  			blockHash: &blockHashes[0],
  3283  			reqHeader: true,
  3284  			file:      "hash-0",
  3285  		},
  3286  		// 15. #1 header
  3287  		{
  3288  			blockHash: &blockHashes[1],
  3289  			reqHeader: true,
  3290  			file:      "hash-1",
  3291  		},
  3292  		// 16. latest-1 header
  3293  		{
  3294  			blockHash: &blockHashes[len(blockHashes)-2],
  3295  			reqHeader: true,
  3296  			file:      "hash-latest-1",
  3297  		},
  3298  		// 17. empty hash
  3299  		{
  3300  			blockHash: &common.Hash{},
  3301  			reqHeader: true,
  3302  			file:      "hash-empty",
  3303  		},
  3304  		// 18. pending hash
  3305  		{
  3306  			blockHash: &pendingHash,
  3307  			reqHeader: true,
  3308  			file:      `hash-pending`,
  3309  		},
  3310  		// 19. latest block
  3311  		{
  3312  			blockHash: &blockHashes[len(blockHashes)-1],
  3313  			file:      "hash-latest",
  3314  		},
  3315  		// 20. genesis block
  3316  		{
  3317  			blockHash: &blockHashes[0],
  3318  			file:      "hash-genesis",
  3319  		},
  3320  		// 21. #1 block
  3321  		{
  3322  			blockHash: &blockHashes[1],
  3323  			file:      "hash-1",
  3324  		},
  3325  		// 22. latest-1 block
  3326  		{
  3327  			blockHash: &blockHashes[len(blockHashes)-2],
  3328  			fullTx:    true,
  3329  			file:      "hash-latest-1-fullTx",
  3330  		},
  3331  		// 23. empty hash + body
  3332  		{
  3333  			blockHash: &common.Hash{},
  3334  			fullTx:    true,
  3335  			file:      "hash-empty-fullTx",
  3336  		},
  3337  		// 24. pending block
  3338  		{
  3339  			blockHash: &pendingHash,
  3340  			file:      `hash-pending`,
  3341  		},
  3342  		// 25. pending block + fullTx
  3343  		{
  3344  			blockHash: &pendingHash,
  3345  			fullTx:    true,
  3346  			file:      "hash-pending-fullTx",
  3347  		},
  3348  	}
  3349  
  3350  	for i, tt := range testSuite {
  3351  		var (
  3352  			result map[string]interface{}
  3353  			err    error
  3354  			rpc    string
  3355  		)
  3356  		if tt.blockHash != nil {
  3357  			if tt.reqHeader {
  3358  				result = api.GetHeaderByHash(context.Background(), *tt.blockHash)
  3359  				rpc = "eth_getHeaderByHash"
  3360  			} else {
  3361  				result, err = api.GetBlockByHash(context.Background(), *tt.blockHash, tt.fullTx)
  3362  				rpc = "eth_getBlockByHash"
  3363  			}
  3364  		} else {
  3365  			if tt.reqHeader {
  3366  				result, err = api.GetHeaderByNumber(context.Background(), tt.blockNumber)
  3367  				rpc = "eth_getHeaderByNumber"
  3368  			} else {
  3369  				result, err = api.GetBlockByNumber(context.Background(), tt.blockNumber, tt.fullTx)
  3370  				rpc = "eth_getBlockByNumber"
  3371  			}
  3372  		}
  3373  		if tt.expectErr != nil {
  3374  			if err == nil {
  3375  				t.Errorf("test %d: want error %v, have nothing", i, tt.expectErr)
  3376  				continue
  3377  			}
  3378  			if !errors.Is(err, tt.expectErr) {
  3379  				t.Errorf("test %d: error mismatch, want %v, have %v", i, tt.expectErr, err)
  3380  			}
  3381  			continue
  3382  		}
  3383  		if err != nil {
  3384  			t.Errorf("test %d: want no error, have %v", i, err)
  3385  			continue
  3386  		}
  3387  
  3388  		testRPCResponseWithFile(t, i, result, rpc, tt.file)
  3389  	}
  3390  }
  3391  
  3392  func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Hash) {
  3393  	config := *params.MergedTestChainConfig
  3394  	var (
  3395  		acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  3396  		acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
  3397  		acc1Addr   = crypto.PubkeyToAddress(acc1Key.PublicKey)
  3398  		acc2Addr   = crypto.PubkeyToAddress(acc2Key.PublicKey)
  3399  		contract   = common.HexToAddress("0000000000000000000000000000000000031ec7")
  3400  		genesis    = &core.Genesis{
  3401  			Config:        &config,
  3402  			ExcessBlobGas: new(uint64),
  3403  			BlobGasUsed:   new(uint64),
  3404  			Alloc: types.GenesisAlloc{
  3405  				acc1Addr: {Balance: big.NewInt(params.Ether)},
  3406  				acc2Addr: {Balance: big.NewInt(params.Ether)},
  3407  				// // SPDX-License-Identifier: GPL-3.0
  3408  				// pragma solidity >=0.7.0 <0.9.0;
  3409  				//
  3410  				// contract Token {
  3411  				//     event Transfer(address indexed from, address indexed to, uint256 value);
  3412  				//     function transfer(address to, uint256 value) public returns (bool) {
  3413  				//         emit Transfer(msg.sender, to, value);
  3414  				//         return true;
  3415  				//     }
  3416  				// }
  3417  				contract: {Balance: big.NewInt(params.Ether), Code: common.FromHex("0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a9059cbb14610030575b600080fd5b61004a6004803603810190610045919061016a565b610060565b60405161005791906101c5565b60405180910390f35b60008273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516100bf91906101ef565b60405180910390a36001905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610101826100d6565b9050919050565b610111816100f6565b811461011c57600080fd5b50565b60008135905061012e81610108565b92915050565b6000819050919050565b61014781610134565b811461015257600080fd5b50565b6000813590506101648161013e565b92915050565b60008060408385031215610181576101806100d1565b5b600061018f8582860161011f565b92505060206101a085828601610155565b9150509250929050565b60008115159050919050565b6101bf816101aa565b82525050565b60006020820190506101da60008301846101b6565b92915050565b6101e981610134565b82525050565b600060208201905061020460008301846101e0565b9291505056fea2646970667358221220b469033f4b77b9565ee84e0a2f04d496b18160d26034d54f9487e57788fd36d564736f6c63430008120033")},
  3418  			},
  3419  		}
  3420  		signer   = types.LatestSignerForChainID(params.TestChainConfig.ChainID)
  3421  		txHashes = make([]common.Hash, genBlocks)
  3422  	)
  3423  
  3424  	backend := newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
  3425  		var (
  3426  			tx  *types.Transaction
  3427  			err error
  3428  		)
  3429  		b.SetPoS()
  3430  		switch i {
  3431  		case 0:
  3432  			// transfer 1000wei
  3433  			tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), types.HomesteadSigner{}, acc1Key)
  3434  		case 1:
  3435  			// create contract
  3436  			tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: nil, Gas: 53100, GasPrice: b.BaseFee(), Data: common.FromHex("0x60806040")}), signer, acc1Key)
  3437  		case 2:
  3438  			// with logs
  3439  			// transfer(address to, uint256 value)
  3440  			data := fmt.Sprintf("0xa9059cbb%s%s", common.HexToHash(common.BigToAddress(big.NewInt(int64(i + 1))).Hex()).String()[2:], common.BytesToHash([]byte{byte(i + 11)}).String()[2:])
  3441  			tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &contract, Gas: 60000, GasPrice: b.BaseFee(), Data: common.FromHex(data)}), signer, acc1Key)
  3442  		case 3:
  3443  			// dynamic fee with logs
  3444  			// transfer(address to, uint256 value)
  3445  			data := fmt.Sprintf("0xa9059cbb%s%s", common.HexToHash(common.BigToAddress(big.NewInt(int64(i + 1))).Hex()).String()[2:], common.BytesToHash([]byte{byte(i + 11)}).String()[2:])
  3446  			fee := big.NewInt(500)
  3447  			fee.Add(fee, b.BaseFee())
  3448  			tx, err = types.SignTx(types.NewTx(&types.DynamicFeeTx{Nonce: uint64(i), To: &contract, Gas: 60000, Value: big.NewInt(1), GasTipCap: big.NewInt(500), GasFeeCap: fee, Data: common.FromHex(data)}), signer, acc1Key)
  3449  		case 4:
  3450  			// access list with contract create
  3451  			accessList := types.AccessList{{
  3452  				Address:     contract,
  3453  				StorageKeys: []common.Hash{{0}},
  3454  			}}
  3455  			tx, err = types.SignTx(types.NewTx(&types.AccessListTx{Nonce: uint64(i), To: nil, Gas: 58100, GasPrice: b.BaseFee(), Data: common.FromHex("0x60806040"), AccessList: accessList}), signer, acc1Key)
  3456  		case 5:
  3457  			// blob tx
  3458  			fee := big.NewInt(500)
  3459  			fee.Add(fee, b.BaseFee())
  3460  			tx, err = types.SignTx(types.NewTx(&types.BlobTx{
  3461  				Nonce:      uint64(i),
  3462  				GasTipCap:  uint256.NewInt(1),
  3463  				GasFeeCap:  uint256.MustFromBig(fee),
  3464  				Gas:        params.TxGas,
  3465  				To:         acc2Addr,
  3466  				BlobFeeCap: uint256.NewInt(1),
  3467  				BlobHashes: []common.Hash{{1}},
  3468  				Value:      new(uint256.Int),
  3469  			}), signer, acc1Key)
  3470  		}
  3471  		if err != nil {
  3472  			t.Errorf("failed to sign tx: %v", err)
  3473  		}
  3474  		if tx != nil {
  3475  			b.AddTx(tx)
  3476  			txHashes[i] = tx.Hash()
  3477  		}
  3478  	})
  3479  	return backend, txHashes
  3480  }
  3481  
  3482  func TestRPCGetTransactionReceipt(t *testing.T) {
  3483  	t.Parallel()
  3484  
  3485  	var (
  3486  		backend, txHashes = setupReceiptBackend(t, 6)
  3487  		api               = NewTransactionAPI(backend, new(AddrLocker))
  3488  	)
  3489  
  3490  	var testSuite = []struct {
  3491  		txHash common.Hash
  3492  		file   string
  3493  	}{
  3494  		// 0. normal success
  3495  		{
  3496  			txHash: txHashes[0],
  3497  			file:   "normal-transfer-tx",
  3498  		},
  3499  		// 1. create contract
  3500  		{
  3501  			txHash: txHashes[1],
  3502  			file:   "create-contract-tx",
  3503  		},
  3504  		// 2. with logs success
  3505  		{
  3506  			txHash: txHashes[2],
  3507  			file:   "with-logs",
  3508  		},
  3509  		// 3. dynamic tx with logs success
  3510  		{
  3511  			txHash: txHashes[3],
  3512  			file:   `dynamic-tx-with-logs`,
  3513  		},
  3514  		// 4. access list tx with create contract
  3515  		{
  3516  			txHash: txHashes[4],
  3517  			file:   "create-contract-with-access-list",
  3518  		},
  3519  		// 5. txhash empty
  3520  		{
  3521  			txHash: common.Hash{},
  3522  			file:   "txhash-empty",
  3523  		},
  3524  		// 6. txhash not found
  3525  		{
  3526  			txHash: common.HexToHash("deadbeef"),
  3527  			file:   "txhash-notfound",
  3528  		},
  3529  		// 7. blob tx
  3530  		{
  3531  			txHash: txHashes[5],
  3532  			file:   "blob-tx",
  3533  		},
  3534  	}
  3535  
  3536  	for i, tt := range testSuite {
  3537  		var (
  3538  			result interface{}
  3539  			err    error
  3540  		)
  3541  		result, err = api.GetTransactionReceipt(context.Background(), tt.txHash)
  3542  		if err != nil {
  3543  			t.Errorf("test %d: want no error, have %v", i, err)
  3544  			continue
  3545  		}
  3546  		testRPCResponseWithFile(t, i, result, "eth_getTransactionReceipt", tt.file)
  3547  	}
  3548  }
  3549  
  3550  func TestRPCGetBlockReceipts(t *testing.T) {
  3551  	t.Parallel()
  3552  
  3553  	var (
  3554  		genBlocks  = 6
  3555  		backend, _ = setupReceiptBackend(t, genBlocks)
  3556  		api        = NewBlockChainAPI(backend)
  3557  	)
  3558  	blockHashes := make([]common.Hash, genBlocks+1)
  3559  	ctx := context.Background()
  3560  	for i := 0; i <= genBlocks; i++ {
  3561  		header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i))
  3562  		if err != nil {
  3563  			t.Errorf("failed to get block: %d err: %v", i, err)
  3564  		}
  3565  		blockHashes[i] = header.Hash()
  3566  	}
  3567  
  3568  	var testSuite = []struct {
  3569  		test rpc.BlockNumberOrHash
  3570  		file string
  3571  	}{
  3572  		// 0. block without any txs(hash)
  3573  		{
  3574  			test: rpc.BlockNumberOrHashWithHash(blockHashes[0], false),
  3575  			file: "number-0",
  3576  		},
  3577  		// 1. block without any txs(number)
  3578  		{
  3579  			test: rpc.BlockNumberOrHashWithNumber(0),
  3580  			file: "number-1",
  3581  		},
  3582  		// 2. earliest tag
  3583  		{
  3584  			test: rpc.BlockNumberOrHashWithNumber(rpc.EarliestBlockNumber),
  3585  			file: "tag-earliest",
  3586  		},
  3587  		// 3. latest tag
  3588  		{
  3589  			test: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber),
  3590  			file: "tag-latest",
  3591  		},
  3592  		// 4. block with legacy transfer tx(hash)
  3593  		{
  3594  			test: rpc.BlockNumberOrHashWithHash(blockHashes[1], false),
  3595  			file: "block-with-legacy-transfer-tx",
  3596  		},
  3597  		// 5. block with contract create tx(number)
  3598  		{
  3599  			test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(2)),
  3600  			file: "block-with-contract-create-tx",
  3601  		},
  3602  		// 6. block with legacy contract call tx(hash)
  3603  		{
  3604  			test: rpc.BlockNumberOrHashWithHash(blockHashes[3], false),
  3605  			file: "block-with-legacy-contract-call-tx",
  3606  		},
  3607  		// 7. block with dynamic fee tx(number)
  3608  		{
  3609  			test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(4)),
  3610  			file: "block-with-dynamic-fee-tx",
  3611  		},
  3612  		// 8. block is empty
  3613  		{
  3614  			test: rpc.BlockNumberOrHashWithHash(common.Hash{}, false),
  3615  			file: "hash-empty",
  3616  		},
  3617  		// 9. block is not found
  3618  		{
  3619  			test: rpc.BlockNumberOrHashWithHash(common.HexToHash("deadbeef"), false),
  3620  			file: "hash-notfound",
  3621  		},
  3622  		// 10. block is not found
  3623  		{
  3624  			test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(genBlocks + 1)),
  3625  			file: "block-notfound",
  3626  		},
  3627  		// 11. block with blob tx
  3628  		{
  3629  			test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(6)),
  3630  			file: "block-with-blob-tx",
  3631  		},
  3632  	}
  3633  
  3634  	for i, tt := range testSuite {
  3635  		var (
  3636  			result interface{}
  3637  			err    error
  3638  		)
  3639  		result, err = api.GetBlockReceipts(context.Background(), tt.test)
  3640  		if err != nil {
  3641  			t.Errorf("test %d: want no error, have %v", i, err)
  3642  			continue
  3643  		}
  3644  		testRPCResponseWithFile(t, i, result, "eth_getBlockReceipts", tt.file)
  3645  	}
  3646  }
  3647  
  3648  func testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc string, file string) {
  3649  	data, err := json.MarshalIndent(result, "", "  ")
  3650  	if err != nil {
  3651  		t.Errorf("test %d: json marshal error", testid)
  3652  		return
  3653  	}
  3654  	outputFile := filepath.Join("testdata", fmt.Sprintf("%s-%s.json", rpc, file))
  3655  	if os.Getenv("WRITE_TEST_FILES") != "" {
  3656  		os.WriteFile(outputFile, data, 0644)
  3657  	}
  3658  	want, err := os.ReadFile(outputFile)
  3659  	if err != nil {
  3660  		t.Fatalf("error reading expected test file: %s output: %v", outputFile, err)
  3661  	}
  3662  	require.JSONEqf(t, string(want), string(data), "test %d: json not match, want: %s, have: %s", testid, string(want), string(data))
  3663  }
  3664  
  3665  func addressToHash(a common.Address) common.Hash {
  3666  	return common.BytesToHash(a.Bytes())
  3667  }
  3668  
  3669  func TestCreateAccessListWithStateOverrides(t *testing.T) {
  3670  	// Initialize test backend
  3671  	genesis := &core.Genesis{
  3672  		Config: params.TestChainConfig,
  3673  		Alloc: types.GenesisAlloc{
  3674  			common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7"): {Balance: big.NewInt(1000000000000000000)},
  3675  		},
  3676  	}
  3677  	backend := newTestBackend(t, 1, genesis, ethash.NewFaker(), nil)
  3678  
  3679  	// Create a new BlockChainAPI instance
  3680  	api := NewBlockChainAPI(backend)
  3681  
  3682  	// Create test contract code - a simple storage contract
  3683  	//
  3684  	// SPDX-License-Identifier: MIT
  3685  	// pragma solidity ^0.8.0;
  3686  	//
  3687  	// contract SimpleStorage {
  3688  	//     uint256 private value;
  3689  	//
  3690  	//     function retrieve() public view returns (uint256) {
  3691  	//         return value;
  3692  	//     }
  3693  	// }
  3694  	var (
  3695  		contractCode = hexutil.Bytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80632e64cec114602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60008054905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056"))
  3696  		// Create state overrides with more complete state
  3697  		contractAddr = common.HexToAddress("0x1234567890123456789012345678901234567890")
  3698  		nonce        = hexutil.Uint64(1)
  3699  		overrides    = &override.StateOverride{
  3700  			contractAddr: override.OverrideAccount{
  3701  				Code:    &contractCode,
  3702  				Balance: (*hexutil.Big)(big.NewInt(1000000000000000000)),
  3703  				Nonce:   &nonce,
  3704  				State: map[common.Hash]common.Hash{
  3705  					common.Hash{}: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000002a"),
  3706  				},
  3707  			},
  3708  		}
  3709  	)
  3710  
  3711  	// Create transaction arguments with gas and value
  3712  	var (
  3713  		from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7")
  3714  		data = hexutil.Bytes(common.Hex2Bytes("2e64cec1")) // retrieve()
  3715  		gas  = hexutil.Uint64(100000)
  3716  		args = TransactionArgs{
  3717  			From:  &from,
  3718  			To:    &contractAddr,
  3719  			Data:  &data,
  3720  			Gas:   &gas,
  3721  			Value: new(hexutil.Big),
  3722  		}
  3723  	)
  3724  	// Call CreateAccessList
  3725  	result, err := api.CreateAccessList(context.Background(), args, nil, overrides)
  3726  	if err != nil {
  3727  		t.Fatalf("Failed to create access list: %v", err)
  3728  	}
  3729  	if err != nil || result == nil {
  3730  		t.Fatalf("Failed to create access list: %v", err)
  3731  	}
  3732  	require.NotNil(t, result.Accesslist)
  3733  
  3734  	// Verify access list contains the contract address and storage slot
  3735  	expected := &types.AccessList{{
  3736  		Address:     contractAddr,
  3737  		StorageKeys: []common.Hash{{}},
  3738  	}}
  3739  	require.Equal(t, expected, result.Accesslist)
  3740  }