github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/accounts/abi/bind/backends/simulated_test.go (about)

     1  // Copyright 2019 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 backends
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"math/big"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	ethereum "github.com/ethereum-optimism/optimism/l2geth"
    28  	"github.com/ethereum-optimism/optimism/l2geth/accounts/abi"
    29  	"github.com/ethereum-optimism/optimism/l2geth/accounts/abi/bind"
    30  	"github.com/ethereum-optimism/optimism/l2geth/common"
    31  	"github.com/ethereum-optimism/optimism/l2geth/core"
    32  	"github.com/ethereum-optimism/optimism/l2geth/core/types"
    33  	"github.com/ethereum-optimism/optimism/l2geth/crypto"
    34  	"github.com/ethereum-optimism/optimism/l2geth/params"
    35  )
    36  
    37  func TestSimulatedBackend(t *testing.T) {
    38  	var gasLimit uint64 = 8000029
    39  	key, _ := crypto.GenerateKey() // nolint: gosec
    40  	auth := bind.NewKeyedTransactor(key)
    41  	genAlloc := make(core.GenesisAlloc)
    42  	genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
    43  
    44  	sim := NewSimulatedBackend(genAlloc, gasLimit)
    45  	defer sim.Close()
    46  
    47  	// should return an error if the tx is not found
    48  	txHash := common.HexToHash("2")
    49  	_, isPending, err := sim.TransactionByHash(context.Background(), txHash)
    50  
    51  	if isPending {
    52  		t.Fatal("transaction should not be pending")
    53  	}
    54  	if err != ethereum.NotFound {
    55  		t.Fatalf("err should be `ethereum.NotFound` but received %v", err)
    56  	}
    57  
    58  	// generate a transaction and confirm you can retrieve it
    59  	code := `6060604052600a8060106000396000f360606040526008565b00`
    60  	var gas uint64 = 3000000
    61  	tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code))
    62  	tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key)
    63  
    64  	err = sim.SendTransaction(context.Background(), tx)
    65  	if err != nil {
    66  		t.Fatal("error sending transaction")
    67  	}
    68  
    69  	txHash = tx.Hash()
    70  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    71  	if err != nil {
    72  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    73  	}
    74  	if !isPending {
    75  		t.Fatal("transaction should have pending status")
    76  	}
    77  
    78  	sim.Commit()
    79  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    80  	if err != nil {
    81  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    82  	}
    83  	if isPending {
    84  		t.Fatal("transaction should not have pending status")
    85  	}
    86  }
    87  
    88  var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    89  
    90  //  the following is based on this contract:
    91  //  contract T {
    92  //  	event received(address sender, uint amount, bytes memo);
    93  //  	event receivedAddr(address sender);
    94  //
    95  //  	function receive(bytes calldata memo) external payable returns (string memory res) {
    96  //  		emit received(msg.sender, msg.value, memo);
    97  //  		emit receivedAddr(msg.sender);
    98  //		    return "hello world";
    99  //  	}
   100  //  }
   101  const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]`
   102  const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   103  const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   104  
   105  // expected return value contains "hello world"
   106  var expectedReturn = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   107  
   108  func TestNewSimulatedBackend(t *testing.T) {
   109  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   110  	expectedBal := big.NewInt(10000000000)
   111  	sim := NewSimulatedBackend(
   112  		core.GenesisAlloc{
   113  			testAddr: {Balance: expectedBal},
   114  		}, 10000000,
   115  	)
   116  	defer sim.Close()
   117  
   118  	if sim.config != params.AllEthashProtocolChanges {
   119  		t.Errorf("expected sim config to equal params.AllEthashProtocolChanges, got %v", sim.config)
   120  	}
   121  
   122  	if sim.blockchain.Config() != params.AllEthashProtocolChanges {
   123  		t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config)
   124  	}
   125  
   126  	statedb, _ := sim.blockchain.State()
   127  	bal := statedb.GetBalance(testAddr)
   128  	if bal.Cmp(expectedBal) != 0 {
   129  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   130  	}
   131  }
   132  
   133  func TestSimulatedBackend_AdjustTime(t *testing.T) {
   134  	sim := NewSimulatedBackend(
   135  		core.GenesisAlloc{}, 10000000,
   136  	)
   137  	defer sim.Close()
   138  
   139  	prevTime := sim.pendingBlock.Time()
   140  	err := sim.AdjustTime(time.Second)
   141  	if err != nil {
   142  		t.Error(err)
   143  	}
   144  	newTime := sim.pendingBlock.Time()
   145  
   146  	if newTime-prevTime != uint64(time.Second.Seconds()) {
   147  		t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime)
   148  	}
   149  }
   150  
   151  func TestSimulatedBackend_BalanceAt(t *testing.T) {
   152  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   153  	expectedBal := big.NewInt(10000000000)
   154  	sim := NewSimulatedBackend(
   155  		core.GenesisAlloc{
   156  			testAddr: {Balance: expectedBal},
   157  		}, 10000000,
   158  	)
   159  	defer sim.Close()
   160  	bgCtx := context.Background()
   161  
   162  	bal, err := sim.BalanceAt(bgCtx, testAddr, nil)
   163  	if err != nil {
   164  		t.Error(err)
   165  	}
   166  
   167  	if bal.Cmp(expectedBal) != 0 {
   168  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   169  	}
   170  }
   171  
   172  func TestSimulatedBackend_BlockByHash(t *testing.T) {
   173  	sim := NewSimulatedBackend(
   174  		core.GenesisAlloc{}, 10000000,
   175  	)
   176  	defer sim.Close()
   177  	bgCtx := context.Background()
   178  
   179  	block, err := sim.BlockByNumber(bgCtx, nil)
   180  	if err != nil {
   181  		t.Errorf("could not get recent block: %v", err)
   182  	}
   183  	blockByHash, err := sim.BlockByHash(bgCtx, block.Hash())
   184  	if err != nil {
   185  		t.Errorf("could not get recent block: %v", err)
   186  	}
   187  
   188  	if block.Hash() != blockByHash.Hash() {
   189  		t.Errorf("did not get expected block")
   190  	}
   191  }
   192  
   193  func TestSimulatedBackend_BlockByNumber(t *testing.T) {
   194  	sim := NewSimulatedBackend(
   195  		core.GenesisAlloc{}, 10000000,
   196  	)
   197  	defer sim.Close()
   198  	bgCtx := context.Background()
   199  
   200  	block, err := sim.BlockByNumber(bgCtx, nil)
   201  	if err != nil {
   202  		t.Errorf("could not get recent block: %v", err)
   203  	}
   204  	if block.NumberU64() != 0 {
   205  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   206  	}
   207  
   208  	// create one block
   209  	sim.Commit()
   210  
   211  	block, err = sim.BlockByNumber(bgCtx, nil)
   212  	if err != nil {
   213  		t.Errorf("could not get recent block: %v", err)
   214  	}
   215  	if block.NumberU64() != 1 {
   216  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   217  	}
   218  
   219  	blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   220  	if err != nil {
   221  		t.Errorf("could not get block by number: %v", err)
   222  	}
   223  	if blockByNumber.Hash() != block.Hash() {
   224  		t.Errorf("did not get the same block with height of 1 as before")
   225  	}
   226  }
   227  
   228  func TestSimulatedBackend_NonceAt(t *testing.T) {
   229  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   230  
   231  	sim := NewSimulatedBackend(
   232  		core.GenesisAlloc{
   233  			testAddr: {Balance: big.NewInt(10000000000)},
   234  		}, 10000000,
   235  	)
   236  	defer sim.Close()
   237  	bgCtx := context.Background()
   238  
   239  	nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0))
   240  	if err != nil {
   241  		t.Errorf("could not get nonce for test addr: %v", err)
   242  	}
   243  
   244  	if nonce != uint64(0) {
   245  		t.Errorf("received incorrect nonce. expected 0, got %v", nonce)
   246  	}
   247  
   248  	// create a signed transaction to send
   249  	tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   250  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   251  	if err != nil {
   252  		t.Errorf("could not sign tx: %v", err)
   253  	}
   254  
   255  	// send tx to simulated backend
   256  	err = sim.SendTransaction(bgCtx, signedTx)
   257  	if err != nil {
   258  		t.Errorf("could not add tx to pending block: %v", err)
   259  	}
   260  	sim.Commit()
   261  
   262  	newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   263  	if err != nil {
   264  		t.Errorf("could not get nonce for test addr: %v", err)
   265  	}
   266  
   267  	if newNonce != nonce+uint64(1) {
   268  		t.Errorf("received incorrect nonce. expected 1, got %v", nonce)
   269  	}
   270  }
   271  
   272  func TestSimulatedBackend_SendTransaction(t *testing.T) {
   273  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   274  
   275  	sim := NewSimulatedBackend(
   276  		core.GenesisAlloc{
   277  			testAddr: {Balance: big.NewInt(10000000000)},
   278  		}, 10000000,
   279  	)
   280  	defer sim.Close()
   281  	bgCtx := context.Background()
   282  
   283  	// create a signed transaction to send
   284  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   285  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   286  	if err != nil {
   287  		t.Errorf("could not sign tx: %v", err)
   288  	}
   289  
   290  	// send tx to simulated backend
   291  	err = sim.SendTransaction(bgCtx, signedTx)
   292  	if err != nil {
   293  		t.Errorf("could not add tx to pending block: %v", err)
   294  	}
   295  	sim.Commit()
   296  
   297  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   298  	if err != nil {
   299  		t.Errorf("could not get block at height 1: %v", err)
   300  	}
   301  
   302  	if signedTx.Hash() != block.Transactions()[0].Hash() {
   303  		t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash())
   304  	}
   305  }
   306  
   307  func TestSimulatedBackend_TransactionByHash(t *testing.T) {
   308  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   309  
   310  	sim := NewSimulatedBackend(
   311  		core.GenesisAlloc{
   312  			testAddr: {Balance: big.NewInt(10000000000)},
   313  		}, 10000000,
   314  	)
   315  	defer sim.Close()
   316  	bgCtx := context.Background()
   317  
   318  	// create a signed transaction to send
   319  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   320  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   321  	if err != nil {
   322  		t.Errorf("could not sign tx: %v", err)
   323  	}
   324  
   325  	// send tx to simulated backend
   326  	err = sim.SendTransaction(bgCtx, signedTx)
   327  	if err != nil {
   328  		t.Errorf("could not add tx to pending block: %v", err)
   329  	}
   330  
   331  	// ensure tx is committed pending
   332  	receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash())
   333  	if err != nil {
   334  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   335  	}
   336  	if !pending {
   337  		t.Errorf("expected transaction to be in pending state")
   338  	}
   339  	if receivedTx.Hash() != signedTx.Hash() {
   340  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   341  	}
   342  
   343  	sim.Commit()
   344  
   345  	// ensure tx is not and committed pending
   346  	receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash())
   347  	if err != nil {
   348  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   349  	}
   350  	if pending {
   351  		t.Errorf("expected transaction to not be in pending state")
   352  	}
   353  	if receivedTx.Hash() != signedTx.Hash() {
   354  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   355  	}
   356  }
   357  
   358  func TestSimulatedBackend_EstimateGas(t *testing.T) {
   359  	t.Skip("OVM breaks this because gas consumption is not yet standardized")
   360  
   361  	sim := NewSimulatedBackend(
   362  		core.GenesisAlloc{}, 10000000,
   363  	)
   364  	defer sim.Close()
   365  	bgCtx := context.Background()
   366  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   367  
   368  	gas, err := sim.EstimateGas(bgCtx, ethereum.CallMsg{
   369  		From:  testAddr,
   370  		To:    &testAddr,
   371  		Value: big.NewInt(1000),
   372  		Data:  []byte{},
   373  	})
   374  	if err != nil {
   375  		t.Errorf("could not estimate gas: %v", err)
   376  	}
   377  
   378  	if gas != params.TxGas {
   379  		t.Errorf("expected 21000 gas cost for a transaction got %v", gas)
   380  	}
   381  }
   382  
   383  func TestSimulatedBackend_HeaderByHash(t *testing.T) {
   384  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   385  
   386  	sim := NewSimulatedBackend(
   387  		core.GenesisAlloc{
   388  			testAddr: {Balance: big.NewInt(10000000000)},
   389  		}, 10000000,
   390  	)
   391  	defer sim.Close()
   392  	bgCtx := context.Background()
   393  
   394  	header, err := sim.HeaderByNumber(bgCtx, nil)
   395  	if err != nil {
   396  		t.Errorf("could not get recent block: %v", err)
   397  	}
   398  	headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
   399  	if err != nil {
   400  		t.Errorf("could not get recent block: %v", err)
   401  	}
   402  
   403  	if header.Hash() != headerByHash.Hash() {
   404  		t.Errorf("did not get expected block")
   405  	}
   406  }
   407  
   408  func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
   409  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   410  
   411  	sim := NewSimulatedBackend(
   412  		core.GenesisAlloc{
   413  			testAddr: {Balance: big.NewInt(10000000000)},
   414  		}, 10000000,
   415  	)
   416  	defer sim.Close()
   417  	bgCtx := context.Background()
   418  
   419  	latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
   420  	if err != nil {
   421  		t.Errorf("could not get header for tip of chain: %v", err)
   422  	}
   423  	if latestBlockHeader == nil {
   424  		t.Errorf("received a nil block header")
   425  	}
   426  	if latestBlockHeader.Number.Uint64() != uint64(0) {
   427  		t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
   428  	}
   429  
   430  	sim.Commit()
   431  
   432  	latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
   433  	if err != nil {
   434  		t.Errorf("could not get header for blockheight of 1: %v", err)
   435  	}
   436  
   437  	blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
   438  	if err != nil {
   439  		t.Errorf("could not get header for blockheight of 1: %v", err)
   440  	}
   441  
   442  	if blockHeader.Hash() != latestBlockHeader.Hash() {
   443  		t.Errorf("block header and latest block header are not the same")
   444  	}
   445  	if blockHeader.Number.Int64() != int64(1) {
   446  		t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
   447  	}
   448  
   449  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   450  	if err != nil {
   451  		t.Errorf("could not get block for blockheight of 1: %v", err)
   452  	}
   453  
   454  	if block.Hash() != blockHeader.Hash() {
   455  		t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
   456  	}
   457  }
   458  
   459  func TestSimulatedBackend_TransactionCount(t *testing.T) {
   460  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   461  
   462  	sim := NewSimulatedBackend(
   463  		core.GenesisAlloc{
   464  			testAddr: {Balance: big.NewInt(10000000000)},
   465  		}, 10000000,
   466  	)
   467  	defer sim.Close()
   468  	bgCtx := context.Background()
   469  	currentBlock, err := sim.BlockByNumber(bgCtx, nil)
   470  	if err != nil || currentBlock == nil {
   471  		t.Error("could not get current block")
   472  	}
   473  
   474  	count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
   475  	if err != nil {
   476  		t.Error("could not get current block's transaction count")
   477  	}
   478  
   479  	if count != 0 {
   480  		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
   481  	}
   482  
   483  	// create a signed transaction to send
   484  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   485  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   486  	if err != nil {
   487  		t.Errorf("could not sign tx: %v", err)
   488  	}
   489  
   490  	// send tx to simulated backend
   491  	err = sim.SendTransaction(bgCtx, signedTx)
   492  	if err != nil {
   493  		t.Errorf("could not add tx to pending block: %v", err)
   494  	}
   495  
   496  	sim.Commit()
   497  
   498  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   499  	if err != nil {
   500  		t.Errorf("could not get header for tip of chain: %v", err)
   501  	}
   502  
   503  	count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
   504  	if err != nil {
   505  		t.Error("could not get current block's transaction count")
   506  	}
   507  
   508  	if count != 1 {
   509  		t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
   510  	}
   511  }
   512  
   513  func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
   514  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   515  
   516  	sim := NewSimulatedBackend(
   517  		core.GenesisAlloc{
   518  			testAddr: {Balance: big.NewInt(10000000000)},
   519  		}, 10000000,
   520  	)
   521  	defer sim.Close()
   522  	bgCtx := context.Background()
   523  
   524  	transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0))
   525  	if err == nil && err != errTransactionDoesNotExist {
   526  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   527  	}
   528  	if transaction != nil {
   529  		t.Errorf("expected transaction to be nil but received %v", transaction)
   530  	}
   531  
   532  	// expect pending nonce to be 0 since account has not been used
   533  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   534  	if err != nil {
   535  		t.Errorf("did not get the pending nonce: %v", err)
   536  	}
   537  
   538  	if pendingNonce != uint64(0) {
   539  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   540  	}
   541  
   542  	// create a signed transaction to send
   543  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   544  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   545  	if err != nil {
   546  		t.Errorf("could not sign tx: %v", err)
   547  	}
   548  
   549  	// send tx to simulated backend
   550  	err = sim.SendTransaction(bgCtx, signedTx)
   551  	if err != nil {
   552  		t.Errorf("could not add tx to pending block: %v", err)
   553  	}
   554  
   555  	sim.Commit()
   556  
   557  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   558  	if err != nil {
   559  		t.Errorf("could not get header for tip of chain: %v", err)
   560  	}
   561  
   562  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1))
   563  	if err == nil && err != errTransactionDoesNotExist {
   564  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   565  	}
   566  	if transaction != nil {
   567  		t.Errorf("expected transaction to be nil but received %v", transaction)
   568  	}
   569  
   570  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0))
   571  	if err != nil {
   572  		t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err)
   573  	}
   574  
   575  	if signedTx.Hash().String() != transaction.Hash().String() {
   576  		t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String())
   577  	}
   578  }
   579  
   580  func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
   581  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   582  
   583  	sim := NewSimulatedBackend(
   584  		core.GenesisAlloc{
   585  			testAddr: {Balance: big.NewInt(10000000000)},
   586  		}, 10000000,
   587  	)
   588  	defer sim.Close()
   589  	bgCtx := context.Background()
   590  
   591  	// expect pending nonce to be 0 since account has not been used
   592  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   593  	if err != nil {
   594  		t.Errorf("did not get the pending nonce: %v", err)
   595  	}
   596  
   597  	if pendingNonce != uint64(0) {
   598  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   599  	}
   600  
   601  	// create a signed transaction to send
   602  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   603  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   604  	if err != nil {
   605  		t.Errorf("could not sign tx: %v", err)
   606  	}
   607  
   608  	// send tx to simulated backend
   609  	err = sim.SendTransaction(bgCtx, signedTx)
   610  	if err != nil {
   611  		t.Errorf("could not add tx to pending block: %v", err)
   612  	}
   613  
   614  	// expect pending nonce to be 1 since account has submitted one transaction
   615  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   616  	if err != nil {
   617  		t.Errorf("did not get the pending nonce: %v", err)
   618  	}
   619  
   620  	if pendingNonce != uint64(1) {
   621  		t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
   622  	}
   623  
   624  	// make a new transaction with a nonce of 1
   625  	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   626  	signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
   627  	if err != nil {
   628  		t.Errorf("could not sign tx: %v", err)
   629  	}
   630  	err = sim.SendTransaction(bgCtx, signedTx)
   631  	if err != nil {
   632  		t.Errorf("could not send tx: %v", err)
   633  	}
   634  
   635  	// expect pending nonce to be 2 since account now has two transactions
   636  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   637  	if err != nil {
   638  		t.Errorf("did not get the pending nonce: %v", err)
   639  	}
   640  
   641  	if pendingNonce != uint64(2) {
   642  		t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
   643  	}
   644  }
   645  
   646  func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
   647  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   648  
   649  	sim := NewSimulatedBackend(
   650  		core.GenesisAlloc{
   651  			testAddr: {Balance: big.NewInt(10000000000)},
   652  		}, 10000000,
   653  	)
   654  	defer sim.Close()
   655  	bgCtx := context.Background()
   656  
   657  	// create a signed transaction to send
   658  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   659  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   660  	if err != nil {
   661  		t.Errorf("could not sign tx: %v", err)
   662  	}
   663  
   664  	// send tx to simulated backend
   665  	err = sim.SendTransaction(bgCtx, signedTx)
   666  	if err != nil {
   667  		t.Errorf("could not add tx to pending block: %v", err)
   668  	}
   669  	sim.Commit()
   670  
   671  	receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
   672  	if err != nil {
   673  		t.Errorf("could not get transaction receipt: %v", err)
   674  	}
   675  
   676  	if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() {
   677  		t.Errorf("received receipt is not correct: %v", receipt)
   678  	}
   679  }
   680  
   681  func TestSimulatedBackend_SuggestGasPrice(t *testing.T) {
   682  	sim := NewSimulatedBackend(
   683  		core.GenesisAlloc{},
   684  		10000000,
   685  	)
   686  	defer sim.Close()
   687  	bgCtx := context.Background()
   688  	gasPrice, err := sim.SuggestGasPrice(bgCtx)
   689  	if err != nil {
   690  		t.Errorf("could not get gas price: %v", err)
   691  	}
   692  	if gasPrice.Uint64() != uint64(1) {
   693  		t.Errorf("gas price was not expected value of 1. actual: %v", gasPrice.Uint64())
   694  	}
   695  }
   696  
   697  func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
   698  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   699  	sim := NewSimulatedBackend(
   700  		core.GenesisAlloc{
   701  			testAddr: {Balance: big.NewInt(10000000000)},
   702  		},
   703  		10000000,
   704  	)
   705  	defer sim.Close()
   706  	bgCtx := context.Background()
   707  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   708  	if err != nil {
   709  		t.Errorf("could not get code at test addr: %v", err)
   710  	}
   711  	if len(code) != 0 {
   712  		t.Errorf("got code for account that does not have contract code")
   713  	}
   714  
   715  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   716  	if err != nil {
   717  		t.Errorf("could not get code at test addr: %v", err)
   718  	}
   719  	auth := bind.NewKeyedTransactor(testKey)
   720  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   721  	if err != nil {
   722  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   723  	}
   724  
   725  	code, err = sim.PendingCodeAt(bgCtx, contractAddr)
   726  	if err != nil {
   727  		t.Errorf("could not get code at test addr: %v", err)
   728  	}
   729  	if len(code) == 0 {
   730  		t.Errorf("did not get code for account that has contract code")
   731  	}
   732  	// ensure code received equals code deployed
   733  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   734  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   735  	}
   736  }
   737  
   738  func TestSimulatedBackend_CodeAt(t *testing.T) {
   739  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   740  	sim := NewSimulatedBackend(
   741  		core.GenesisAlloc{
   742  			testAddr: {Balance: big.NewInt(10000000000)},
   743  		},
   744  		10000000,
   745  	)
   746  	defer sim.Close()
   747  	bgCtx := context.Background()
   748  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   749  	if err != nil {
   750  		t.Errorf("could not get code at test addr: %v", err)
   751  	}
   752  	if len(code) != 0 {
   753  		t.Errorf("got code for account that does not have contract code")
   754  	}
   755  
   756  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   757  	if err != nil {
   758  		t.Errorf("could not get code at test addr: %v", err)
   759  	}
   760  	auth := bind.NewKeyedTransactor(testKey)
   761  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   762  	if err != nil {
   763  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   764  	}
   765  
   766  	sim.Commit()
   767  	code, err = sim.CodeAt(bgCtx, contractAddr, nil)
   768  	if err != nil {
   769  		t.Errorf("could not get code at test addr: %v", err)
   770  	}
   771  	if len(code) == 0 {
   772  		t.Errorf("did not get code for account that has contract code")
   773  	}
   774  	// ensure code received equals code deployed
   775  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   776  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   777  	}
   778  }
   779  
   780  // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
   781  //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
   782  func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
   783  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   784  	sim := NewSimulatedBackend(
   785  		core.GenesisAlloc{
   786  			testAddr: {Balance: big.NewInt(10000000000)},
   787  		},
   788  		10000000,
   789  	)
   790  	defer sim.Close()
   791  	bgCtx := context.Background()
   792  
   793  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   794  	if err != nil {
   795  		t.Errorf("could not get code at test addr: %v", err)
   796  	}
   797  	contractAuth := bind.NewKeyedTransactor(testKey)
   798  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
   799  	if err != nil {
   800  		t.Errorf("could not deploy contract: %v", err)
   801  	}
   802  
   803  	input, err := parsed.Pack("receive", []byte("X"))
   804  	if err != nil {
   805  		t.Errorf("could pack receive function on contract: %v", err)
   806  	}
   807  
   808  	// make sure you can call the contract in pending state
   809  	res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{
   810  		From: testAddr,
   811  		To:   &addr,
   812  		Data: input,
   813  	})
   814  	if err != nil {
   815  		t.Errorf("could not call receive method on contract: %v", err)
   816  	}
   817  	if len(res) == 0 {
   818  		t.Errorf("result of contract call was empty: %v", res)
   819  	}
   820  
   821  	// while comparing against the byte array is more exact, also compare against the human readable string for readability
   822  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   823  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   824  	}
   825  
   826  	sim.Commit()
   827  
   828  	// make sure you can call the contract
   829  	res, err = sim.CallContract(bgCtx, ethereum.CallMsg{
   830  		From: testAddr,
   831  		To:   &addr,
   832  		Data: input,
   833  	}, nil)
   834  	if err != nil {
   835  		t.Errorf("could not call receive method on contract: %v", err)
   836  	}
   837  	if len(res) == 0 {
   838  		t.Errorf("result of contract call was empty: %v", res)
   839  	}
   840  
   841  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   842  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   843  	}
   844  }