gitlab.com/yannislg/go-pulse@v0.0.0-20210722055913-a3e24e95638d/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  	"github.com/ethereum/go-ethereum"
    28  	"github.com/ethereum/go-ethereum/accounts/abi"
    29  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    30  	"github.com/ethereum/go-ethereum/common"
    31  	"github.com/ethereum/go-ethereum/core"
    32  	"github.com/ethereum/go-ethereum/core/types"
    33  	"github.com/ethereum/go-ethereum/crypto"
    34  	"github.com/ethereum/go-ethereum/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  	sim := NewSimulatedBackend(
   360  		core.GenesisAlloc{}, 10000000,
   361  	)
   362  	defer sim.Close()
   363  	bgCtx := context.Background()
   364  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   365  
   366  	gas, err := sim.EstimateGas(bgCtx, ethereum.CallMsg{
   367  		From:  testAddr,
   368  		To:    &testAddr,
   369  		Value: big.NewInt(1000),
   370  		Data:  []byte{},
   371  	})
   372  	if err != nil {
   373  		t.Errorf("could not estimate gas: %v", err)
   374  	}
   375  
   376  	if gas != params.TxGas {
   377  		t.Errorf("expected 21000 gas cost for a transaction got %v", gas)
   378  	}
   379  }
   380  
   381  func TestSimulatedBackend_HeaderByHash(t *testing.T) {
   382  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   383  
   384  	sim := NewSimulatedBackend(
   385  		core.GenesisAlloc{
   386  			testAddr: {Balance: big.NewInt(10000000000)},
   387  		}, 10000000,
   388  	)
   389  	defer sim.Close()
   390  	bgCtx := context.Background()
   391  
   392  	header, err := sim.HeaderByNumber(bgCtx, nil)
   393  	if err != nil {
   394  		t.Errorf("could not get recent block: %v", err)
   395  	}
   396  	headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
   397  	if err != nil {
   398  		t.Errorf("could not get recent block: %v", err)
   399  	}
   400  
   401  	if header.Hash() != headerByHash.Hash() {
   402  		t.Errorf("did not get expected block")
   403  	}
   404  }
   405  
   406  func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
   407  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   408  
   409  	sim := NewSimulatedBackend(
   410  		core.GenesisAlloc{
   411  			testAddr: {Balance: big.NewInt(10000000000)},
   412  		}, 10000000,
   413  	)
   414  	defer sim.Close()
   415  	bgCtx := context.Background()
   416  
   417  	latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
   418  	if err != nil {
   419  		t.Errorf("could not get header for tip of chain: %v", err)
   420  	}
   421  	if latestBlockHeader == nil {
   422  		t.Errorf("received a nil block header")
   423  	}
   424  	if latestBlockHeader.Number.Uint64() != uint64(0) {
   425  		t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
   426  	}
   427  
   428  	sim.Commit()
   429  
   430  	latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
   431  	if err != nil {
   432  		t.Errorf("could not get header for blockheight of 1: %v", err)
   433  	}
   434  
   435  	blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
   436  	if err != nil {
   437  		t.Errorf("could not get header for blockheight of 1: %v", err)
   438  	}
   439  
   440  	if blockHeader.Hash() != latestBlockHeader.Hash() {
   441  		t.Errorf("block header and latest block header are not the same")
   442  	}
   443  	if blockHeader.Number.Int64() != int64(1) {
   444  		t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
   445  	}
   446  
   447  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   448  	if err != nil {
   449  		t.Errorf("could not get block for blockheight of 1: %v", err)
   450  	}
   451  
   452  	if block.Hash() != blockHeader.Hash() {
   453  		t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
   454  	}
   455  }
   456  
   457  func TestSimulatedBackend_TransactionCount(t *testing.T) {
   458  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   459  
   460  	sim := NewSimulatedBackend(
   461  		core.GenesisAlloc{
   462  			testAddr: {Balance: big.NewInt(10000000000)},
   463  		}, 10000000,
   464  	)
   465  	defer sim.Close()
   466  	bgCtx := context.Background()
   467  	currentBlock, err := sim.BlockByNumber(bgCtx, nil)
   468  	if err != nil || currentBlock == nil {
   469  		t.Error("could not get current block")
   470  	}
   471  
   472  	count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
   473  	if err != nil {
   474  		t.Error("could not get current block's transaction count")
   475  	}
   476  
   477  	if count != 0 {
   478  		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
   479  	}
   480  
   481  	// create a signed transaction to send
   482  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   483  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   484  	if err != nil {
   485  		t.Errorf("could not sign tx: %v", err)
   486  	}
   487  
   488  	// send tx to simulated backend
   489  	err = sim.SendTransaction(bgCtx, signedTx)
   490  	if err != nil {
   491  		t.Errorf("could not add tx to pending block: %v", err)
   492  	}
   493  
   494  	sim.Commit()
   495  
   496  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   497  	if err != nil {
   498  		t.Errorf("could not get header for tip of chain: %v", err)
   499  	}
   500  
   501  	count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
   502  	if err != nil {
   503  		t.Error("could not get current block's transaction count")
   504  	}
   505  
   506  	if count != 1 {
   507  		t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
   508  	}
   509  }
   510  
   511  func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
   512  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   513  
   514  	sim := NewSimulatedBackend(
   515  		core.GenesisAlloc{
   516  			testAddr: {Balance: big.NewInt(10000000000)},
   517  		}, 10000000,
   518  	)
   519  	defer sim.Close()
   520  	bgCtx := context.Background()
   521  
   522  	transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0))
   523  	if err == nil && err != errTransactionDoesNotExist {
   524  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   525  	}
   526  	if transaction != nil {
   527  		t.Errorf("expected transaction to be nil but received %v", transaction)
   528  	}
   529  
   530  	// expect pending nonce to be 0 since account has not been used
   531  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   532  	if err != nil {
   533  		t.Errorf("did not get the pending nonce: %v", err)
   534  	}
   535  
   536  	if pendingNonce != uint64(0) {
   537  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   538  	}
   539  
   540  	// create a signed transaction to send
   541  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   542  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   543  	if err != nil {
   544  		t.Errorf("could not sign tx: %v", err)
   545  	}
   546  
   547  	// send tx to simulated backend
   548  	err = sim.SendTransaction(bgCtx, signedTx)
   549  	if err != nil {
   550  		t.Errorf("could not add tx to pending block: %v", err)
   551  	}
   552  
   553  	sim.Commit()
   554  
   555  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   556  	if err != nil {
   557  		t.Errorf("could not get header for tip of chain: %v", err)
   558  	}
   559  
   560  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1))
   561  	if err == nil && err != errTransactionDoesNotExist {
   562  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   563  	}
   564  	if transaction != nil {
   565  		t.Errorf("expected transaction to be nil but received %v", transaction)
   566  	}
   567  
   568  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0))
   569  	if err != nil {
   570  		t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err)
   571  	}
   572  
   573  	if signedTx.Hash().String() != transaction.Hash().String() {
   574  		t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String())
   575  	}
   576  }
   577  
   578  func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
   579  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   580  
   581  	sim := NewSimulatedBackend(
   582  		core.GenesisAlloc{
   583  			testAddr: {Balance: big.NewInt(10000000000)},
   584  		}, 10000000,
   585  	)
   586  	defer sim.Close()
   587  	bgCtx := context.Background()
   588  
   589  	// expect pending nonce to be 0 since account has not been used
   590  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   591  	if err != nil {
   592  		t.Errorf("did not get the pending nonce: %v", err)
   593  	}
   594  
   595  	if pendingNonce != uint64(0) {
   596  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   597  	}
   598  
   599  	// create a signed transaction to send
   600  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   601  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   602  	if err != nil {
   603  		t.Errorf("could not sign tx: %v", err)
   604  	}
   605  
   606  	// send tx to simulated backend
   607  	err = sim.SendTransaction(bgCtx, signedTx)
   608  	if err != nil {
   609  		t.Errorf("could not add tx to pending block: %v", err)
   610  	}
   611  
   612  	// expect pending nonce to be 1 since account has submitted one transaction
   613  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   614  	if err != nil {
   615  		t.Errorf("did not get the pending nonce: %v", err)
   616  	}
   617  
   618  	if pendingNonce != uint64(1) {
   619  		t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
   620  	}
   621  
   622  	// make a new transaction with a nonce of 1
   623  	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   624  	signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
   625  	if err != nil {
   626  		t.Errorf("could not sign tx: %v", err)
   627  	}
   628  	err = sim.SendTransaction(bgCtx, signedTx)
   629  	if err != nil {
   630  		t.Errorf("could not send tx: %v", err)
   631  	}
   632  
   633  	// expect pending nonce to be 2 since account now has two transactions
   634  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   635  	if err != nil {
   636  		t.Errorf("did not get the pending nonce: %v", err)
   637  	}
   638  
   639  	if pendingNonce != uint64(2) {
   640  		t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
   641  	}
   642  }
   643  
   644  func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
   645  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   646  
   647  	sim := NewSimulatedBackend(
   648  		core.GenesisAlloc{
   649  			testAddr: {Balance: big.NewInt(10000000000)},
   650  		}, 10000000,
   651  	)
   652  	defer sim.Close()
   653  	bgCtx := context.Background()
   654  
   655  	// create a signed transaction to send
   656  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   657  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   658  	if err != nil {
   659  		t.Errorf("could not sign tx: %v", err)
   660  	}
   661  
   662  	// send tx to simulated backend
   663  	err = sim.SendTransaction(bgCtx, signedTx)
   664  	if err != nil {
   665  		t.Errorf("could not add tx to pending block: %v", err)
   666  	}
   667  	sim.Commit()
   668  
   669  	receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
   670  	if err != nil {
   671  		t.Errorf("could not get transaction receipt: %v", err)
   672  	}
   673  
   674  	if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() {
   675  		t.Errorf("received receipt is not correct: %v", receipt)
   676  	}
   677  }
   678  
   679  func TestSimulatedBackend_SuggestGasPrice(t *testing.T) {
   680  	sim := NewSimulatedBackend(
   681  		core.GenesisAlloc{},
   682  		10000000,
   683  	)
   684  	defer sim.Close()
   685  	bgCtx := context.Background()
   686  	gasPrice, err := sim.SuggestGasPrice(bgCtx)
   687  	if err != nil {
   688  		t.Errorf("could not get gas price: %v", err)
   689  	}
   690  	if gasPrice.Uint64() != uint64(1) {
   691  		t.Errorf("gas price was not expected value of 1. actual: %v", gasPrice.Uint64())
   692  	}
   693  }
   694  
   695  func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
   696  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   697  	sim := NewSimulatedBackend(
   698  		core.GenesisAlloc{
   699  			testAddr: {Balance: big.NewInt(10000000000)},
   700  		},
   701  		10000000,
   702  	)
   703  	defer sim.Close()
   704  	bgCtx := context.Background()
   705  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   706  	if err != nil {
   707  		t.Errorf("could not get code at test addr: %v", err)
   708  	}
   709  	if len(code) != 0 {
   710  		t.Errorf("got code for account that does not have contract code")
   711  	}
   712  
   713  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   714  	if err != nil {
   715  		t.Errorf("could not get code at test addr: %v", err)
   716  	}
   717  	auth := bind.NewKeyedTransactor(testKey)
   718  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   719  	if err != nil {
   720  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   721  	}
   722  
   723  	code, err = sim.PendingCodeAt(bgCtx, contractAddr)
   724  	if err != nil {
   725  		t.Errorf("could not get code at test addr: %v", err)
   726  	}
   727  	if len(code) == 0 {
   728  		t.Errorf("did not get code for account that has contract code")
   729  	}
   730  	// ensure code received equals code deployed
   731  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   732  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   733  	}
   734  }
   735  
   736  func TestSimulatedBackend_CodeAt(t *testing.T) {
   737  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   738  	sim := NewSimulatedBackend(
   739  		core.GenesisAlloc{
   740  			testAddr: {Balance: big.NewInt(10000000000)},
   741  		},
   742  		10000000,
   743  	)
   744  	defer sim.Close()
   745  	bgCtx := context.Background()
   746  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   747  	if err != nil {
   748  		t.Errorf("could not get code at test addr: %v", err)
   749  	}
   750  	if len(code) != 0 {
   751  		t.Errorf("got code for account that does not have contract code")
   752  	}
   753  
   754  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   755  	if err != nil {
   756  		t.Errorf("could not get code at test addr: %v", err)
   757  	}
   758  	auth := bind.NewKeyedTransactor(testKey)
   759  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   760  	if err != nil {
   761  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   762  	}
   763  
   764  	sim.Commit()
   765  	code, err = sim.CodeAt(bgCtx, contractAddr, nil)
   766  	if err != nil {
   767  		t.Errorf("could not get code at test addr: %v", err)
   768  	}
   769  	if len(code) == 0 {
   770  		t.Errorf("did not get code for account that has contract code")
   771  	}
   772  	// ensure code received equals code deployed
   773  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   774  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   775  	}
   776  }
   777  
   778  // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
   779  //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
   780  func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
   781  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   782  	sim := NewSimulatedBackend(
   783  		core.GenesisAlloc{
   784  			testAddr: {Balance: big.NewInt(10000000000)},
   785  		},
   786  		10000000,
   787  	)
   788  	defer sim.Close()
   789  	bgCtx := context.Background()
   790  
   791  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   792  	if err != nil {
   793  		t.Errorf("could not get code at test addr: %v", err)
   794  	}
   795  	contractAuth := bind.NewKeyedTransactor(testKey)
   796  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
   797  	if err != nil {
   798  		t.Errorf("could not deploy contract: %v", err)
   799  	}
   800  
   801  	input, err := parsed.Pack("receive", []byte("X"))
   802  	if err != nil {
   803  		t.Errorf("could pack receive function on contract: %v", err)
   804  	}
   805  
   806  	// make sure you can call the contract in pending state
   807  	res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{
   808  		From: testAddr,
   809  		To:   &addr,
   810  		Data: input,
   811  	})
   812  	if err != nil {
   813  		t.Errorf("could not call receive method on contract: %v", err)
   814  	}
   815  	if len(res) == 0 {
   816  		t.Errorf("result of contract call was empty: %v", res)
   817  	}
   818  
   819  	// while comparing against the byte array is more exact, also compare against the human readable string for readability
   820  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   821  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   822  	}
   823  
   824  	sim.Commit()
   825  
   826  	// make sure you can call the contract
   827  	res, err = sim.CallContract(bgCtx, ethereum.CallMsg{
   828  		From: testAddr,
   829  		To:   &addr,
   830  		Data: input,
   831  	}, nil)
   832  	if err != nil {
   833  		t.Errorf("could not call receive method on contract: %v", err)
   834  	}
   835  	if len(res) == 0 {
   836  		t.Errorf("result of contract call was empty: %v", res)
   837  	}
   838  
   839  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   840  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   841  	}
   842  }