github.com/CommerciumBlockchain/go-commercium@v0.0.0-20220709212705-b46438a77516/accounts/abi/bind/backends/simulated_test.go (about)

     1  // Copyright 2022 Commercium
     2  // Copyright 2019 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package backends
    19  
    20  import (
    21  	"bytes"
    22  	"context"
    23  	"errors"
    24  	"math/big"
    25  	"reflect"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/CommerciumBlockchain/go-commercium"
    31  	"github.com/CommerciumBlockchain/go-commercium/accounts/abi"
    32  	"github.com/CommerciumBlockchain/go-commercium/accounts/abi/bind"
    33  	"github.com/CommerciumBlockchain/go-commercium/common"
    34  	"github.com/CommerciumBlockchain/go-commercium/core"
    35  	"github.com/CommerciumBlockchain/go-commercium/core/types"
    36  	"github.com/CommerciumBlockchain/go-commercium/crypto"
    37  	"github.com/CommerciumBlockchain/go-commercium/params"
    38  )
    39  
    40  func TestSimulatedBackend(t *testing.T) {
    41  	key, _ := crypto.GenerateKey() // nolint: gosec
    42  	auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
    43  	genAlloc := make(core.GenesisAlloc)
    44  	genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
    45  
    46  	sim := NewSimulatedBackend(genAlloc)
    47  	defer sim.Close()
    48  
    49  	// should return an error if the tx is not found
    50  	txHash := common.HexToHash("2")
    51  	_, isPending, err := sim.TransactionByHash(context.Background(), txHash)
    52  
    53  	if isPending {
    54  		t.Fatal("transaction should not be pending")
    55  	}
    56  	if err != ethereum.NotFound {
    57  		t.Fatalf("err should be `ethereum.NotFound` but received %v", err)
    58  	}
    59  
    60  	// generate a transaction and confirm you can retrieve it
    61  	code := `6060604052600a8060106000396000f360606040526008565b00`
    62  
    63  	tx := types.NewContractCreation(0, big.NewInt(0), big.NewInt(1), common.FromHex(code))
    64  	tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key)
    65  
    66  	err = sim.SendTransaction(context.Background(), tx)
    67  	if err != nil {
    68  		t.Fatal("error sending transaction")
    69  	}
    70  
    71  	txHash = tx.Hash()
    72  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    73  	if err != nil {
    74  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    75  	}
    76  	if !isPending {
    77  		t.Fatal("transaction should have pending status")
    78  	}
    79  
    80  	sim.Commit()
    81  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    82  	if err != nil {
    83  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    84  	}
    85  	if isPending {
    86  		t.Fatal("transaction should not have pending status")
    87  	}
    88  }
    89  
    90  var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    91  
    92  //  the following is based on this contract:
    93  //  contract T {
    94  //  	event received(address sender, uint amount, bytes memo);
    95  //  	event receivedAddr(address sender);
    96  //
    97  //  	function receive(bytes calldata memo) external payable returns (string memory res) {
    98  //  		emit received(msg.sender, msg.value, memo);
    99  //  		emit receivedAddr(msg.sender);
   100  //		    return "hello world";
   101  //  	}
   102  //  }
   103  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" } ]`
   104  const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   105  const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   106  
   107  // expected return value contains "hello world"
   108  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}
   109  
   110  func simTestBackend(testAddr common.Address) *SimulatedBackend {
   111  	return NewSimulatedBackend(
   112  		core.GenesisAlloc{
   113  			testAddr: {Balance: big.NewInt(10000000000)},
   114  		}, 10000000,
   115  	)
   116  }
   117  
   118  func TestNewSimulatedBackend(t *testing.T) {
   119  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   120  	expectedBal := big.NewInt(10000000000)
   121  	sim := simTestBackend(testAddr)
   122  	defer sim.Close()
   123  
   124  	if sim.config != params.AllEthashProtocolChanges {
   125  		t.Errorf("expected sim config to equal params.AllEthashProtocolChanges, got %v", sim.config)
   126  	}
   127  
   128  	if sim.blockchain.Config() != params.AllEthashProtocolChanges {
   129  		t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config)
   130  	}
   131  
   132  	stateDB, _ := sim.blockchain.State()
   133  	bal := stateDB.GetBalance(testAddr)
   134  	if bal.Cmp(expectedBal) != 0 {
   135  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   136  	}
   137  }
   138  
   139  func TestSimulatedBackend_AdjustTime(t *testing.T) {
   140  	sim := NewSimulatedBackend(
   141  		core.GenesisAlloc{}, 10000000,
   142  	)
   143  	defer sim.Close()
   144  
   145  	prevTime := sim.pendingBlock.Time()
   146  	if err := sim.AdjustTime(time.Second); err != nil {
   147  		t.Error(err)
   148  	}
   149  	newTime := sim.pendingBlock.Time()
   150  
   151  	if newTime-prevTime != uint64(time.Second.Seconds()) {
   152  		t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime)
   153  	}
   154  }
   155  
   156  func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) {
   157  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   158  	sim := simTestBackend(testAddr)
   159  	// Create tx and send
   160  	tx := types.NewTransaction(0, testAddr, big.NewInt(1000), big.NewInt(1), nil)
   161  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   162  	if err != nil {
   163  		t.Errorf("could not sign tx: %v", err)
   164  	}
   165  	sim.SendTransaction(context.Background(), signedTx)
   166  	// AdjustTime should fail on non-empty block
   167  	if err := sim.AdjustTime(time.Second); err == nil {
   168  		t.Error("Expected adjust time to error on non-empty block")
   169  	}
   170  	sim.Commit()
   171  
   172  	prevTime := sim.pendingBlock.Time()
   173  	if err := sim.AdjustTime(time.Minute); err != nil {
   174  		t.Error(err)
   175  	}
   176  	newTime := sim.pendingBlock.Time()
   177  	if newTime-prevTime != uint64(time.Minute.Seconds()) {
   178  		t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime)
   179  	}
   180  	// Put a transaction after adjusting time
   181  	tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), big.NewInt(1), nil)
   182  	signedTx2, err := types.SignTx(tx2, types.HomesteadSigner{}, testKey)
   183  	if err != nil {
   184  		t.Errorf("could not sign tx: %v", err)
   185  	}
   186  	sim.SendTransaction(context.Background(), signedTx2)
   187  	sim.Commit()
   188  	newTime = sim.pendingBlock.Time()
   189  	if newTime-prevTime >= uint64(time.Minute.Seconds()) {
   190  		t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime)
   191  	}
   192  }
   193  
   194  func TestSimulatedBackend_BalanceAt(t *testing.T) {
   195  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   196  	expectedBal := big.NewInt(10000000000)
   197  	sim := simTestBackend(testAddr)
   198  	defer sim.Close()
   199  	bgCtx := context.Background()
   200  
   201  	bal, err := sim.BalanceAt(bgCtx, testAddr, nil)
   202  	if err != nil {
   203  		t.Error(err)
   204  	}
   205  
   206  	if bal.Cmp(expectedBal) != 0 {
   207  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   208  	}
   209  }
   210  
   211  func TestSimulatedBackend_BlockByHash(t *testing.T) {
   212  	sim := NewSimulatedBackend(
   213  		core.GenesisAlloc{}, 10000000,
   214  	)
   215  	defer sim.Close()
   216  	bgCtx := context.Background()
   217  
   218  	block, err := sim.BlockByNumber(bgCtx, nil)
   219  	if err != nil {
   220  		t.Errorf("could not get recent block: %v", err)
   221  	}
   222  	blockByHash, err := sim.BlockByHash(bgCtx, block.Hash())
   223  	if err != nil {
   224  		t.Errorf("could not get recent block: %v", err)
   225  	}
   226  
   227  	if block.Hash() != blockByHash.Hash() {
   228  		t.Errorf("did not get expected block")
   229  	}
   230  }
   231  
   232  func TestSimulatedBackend_BlockByNumber(t *testing.T) {
   233  	sim := NewSimulatedBackend(
   234  		core.GenesisAlloc{}, 10000000,
   235  	)
   236  	defer sim.Close()
   237  	bgCtx := context.Background()
   238  
   239  	block, err := sim.BlockByNumber(bgCtx, nil)
   240  	if err != nil {
   241  		t.Errorf("could not get recent block: %v", err)
   242  	}
   243  	if block.NumberU64() != 0 {
   244  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   245  	}
   246  
   247  	// create one block
   248  	sim.Commit()
   249  
   250  	block, err = sim.BlockByNumber(bgCtx, nil)
   251  	if err != nil {
   252  		t.Errorf("could not get recent block: %v", err)
   253  	}
   254  	if block.NumberU64() != 1 {
   255  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   256  	}
   257  
   258  	blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   259  	if err != nil {
   260  		t.Errorf("could not get block by number: %v", err)
   261  	}
   262  	if blockByNumber.Hash() != block.Hash() {
   263  		t.Errorf("did not get the same block with height of 1 as before")
   264  	}
   265  }
   266  
   267  func TestSimulatedBackend_NonceAt(t *testing.T) {
   268  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   269  
   270  	sim := simTestBackend(testAddr)
   271  	defer sim.Close()
   272  	bgCtx := context.Background()
   273  
   274  	nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0))
   275  	if err != nil {
   276  		t.Errorf("could not get nonce for test addr: %v", err)
   277  	}
   278  
   279  	if nonce != uint64(0) {
   280  		t.Errorf("received incorrect nonce. expected 0, got %v", nonce)
   281  	}
   282  
   283  	// create a signed transaction to send
   284  	tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), 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  	newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   298  	if err != nil {
   299  		t.Errorf("could not get nonce for test addr: %v", err)
   300  	}
   301  
   302  	if newNonce != nonce+uint64(1) {
   303  		t.Errorf("received incorrect nonce. expected 1, got %v", nonce)
   304  	}
   305  	// create some more blocks
   306  	sim.Commit()
   307  	// Check that we can get data for an older block/state
   308  	newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   309  	if err != nil {
   310  		t.Fatalf("could not get nonce for test addr: %v", err)
   311  	}
   312  	if newNonce != nonce+uint64(1) {
   313  		t.Fatalf("received incorrect nonce. expected 1, got %v", nonce)
   314  	}
   315  }
   316  
   317  func TestSimulatedBackend_SendTransaction(t *testing.T) {
   318  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   319  
   320  	sim := simTestBackend(testAddr)
   321  	defer sim.Close()
   322  	bgCtx := context.Background()
   323  
   324  	// create a signed transaction to send
   325  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), big.NewInt(1), nil)
   326  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   327  	if err != nil {
   328  		t.Errorf("could not sign tx: %v", err)
   329  	}
   330  
   331  	// send tx to simulated backend
   332  	err = sim.SendTransaction(bgCtx, signedTx)
   333  	if err != nil {
   334  		t.Errorf("could not add tx to pending block: %v", err)
   335  	}
   336  	sim.Commit()
   337  
   338  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   339  	if err != nil {
   340  		t.Errorf("could not get block at height 1: %v", err)
   341  	}
   342  
   343  	if signedTx.Hash() != block.Transactions()[0].Hash() {
   344  		t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash())
   345  	}
   346  }
   347  
   348  func TestSimulatedBackend_TransactionByHash(t *testing.T) {
   349  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   350  
   351  	sim := NewSimulatedBackend(
   352  		core.GenesisAlloc{
   353  			testAddr: {Balance: big.NewInt(10000000000)},
   354  		}, 10000000,
   355  	)
   356  	defer sim.Close()
   357  	bgCtx := context.Background()
   358  
   359  	// create a signed transaction to send
   360  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), big.NewInt(1), nil)
   361  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   362  	if err != nil {
   363  		t.Errorf("could not sign tx: %v", err)
   364  	}
   365  
   366  	// send tx to simulated backend
   367  	err = sim.SendTransaction(bgCtx, signedTx)
   368  	if err != nil {
   369  		t.Errorf("could not add tx to pending block: %v", err)
   370  	}
   371  
   372  	// ensure tx is committed pending
   373  	receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash())
   374  	if err != nil {
   375  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   376  	}
   377  	if !pending {
   378  		t.Errorf("expected transaction to be in pending state")
   379  	}
   380  	if receivedTx.Hash() != signedTx.Hash() {
   381  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   382  	}
   383  
   384  	sim.Commit()
   385  
   386  	// ensure tx is not and committed pending
   387  	receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash())
   388  	if err != nil {
   389  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   390  	}
   391  	if pending {
   392  		t.Errorf("expected transaction to not be in pending state")
   393  	}
   394  	if receivedTx.Hash() != signedTx.Hash() {
   395  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   396  	}
   397  }
   398  
   399  func TestSimulatedBackend_HeaderByHash(t *testing.T) {
   400  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   401  
   402  	sim := simTestBackend(testAddr)
   403  	defer sim.Close()
   404  	bgCtx := context.Background()
   405  
   406  	header, err := sim.HeaderByNumber(bgCtx, nil)
   407  	if err != nil {
   408  		t.Errorf("could not get recent block: %v", err)
   409  	}
   410  	headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
   411  	if err != nil {
   412  		t.Errorf("could not get recent block: %v", err)
   413  	}
   414  
   415  	if header.Hash() != headerByHash.Hash() {
   416  		t.Errorf("did not get expected block")
   417  	}
   418  }
   419  
   420  func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
   421  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   422  
   423  	sim := simTestBackend(testAddr)
   424  	defer sim.Close()
   425  	bgCtx := context.Background()
   426  
   427  	latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
   428  	if err != nil {
   429  		t.Errorf("could not get header for tip of chain: %v", err)
   430  	}
   431  	if latestBlockHeader == nil {
   432  		t.Errorf("received a nil block header")
   433  	}
   434  	if latestBlockHeader.Number.Uint64() != uint64(0) {
   435  		t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
   436  	}
   437  
   438  	sim.Commit()
   439  
   440  	latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
   441  	if err != nil {
   442  		t.Errorf("could not get header for blockheight of 1: %v", err)
   443  	}
   444  
   445  	blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
   446  	if err != nil {
   447  		t.Errorf("could not get header for blockheight of 1: %v", err)
   448  	}
   449  
   450  	if blockHeader.Hash() != latestBlockHeader.Hash() {
   451  		t.Errorf("block header and latest block header are not the same")
   452  	}
   453  	if blockHeader.Number.Int64() != int64(1) {
   454  		t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
   455  	}
   456  
   457  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   458  	if err != nil {
   459  		t.Errorf("could not get block for blockheight of 1: %v", err)
   460  	}
   461  
   462  	if block.Hash() != blockHeader.Hash() {
   463  		t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
   464  	}
   465  }
   466  
   467  func TestSimulatedBackend_TransactionCount(t *testing.T) {
   468  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   469  
   470  	sim := simTestBackend(testAddr)
   471  	defer sim.Close()
   472  	bgCtx := context.Background()
   473  	currentBlock, err := sim.BlockByNumber(bgCtx, nil)
   474  	if err != nil || currentBlock == nil {
   475  		t.Error("could not get current block")
   476  	}
   477  
   478  	count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
   479  	if err != nil {
   480  		t.Error("could not get current block's transaction count")
   481  	}
   482  
   483  	if count != 0 {
   484  		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
   485  	}
   486  
   487  	// create a signed transaction to send
   488  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), big.NewInt(1), nil)
   489  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   490  	if err != nil {
   491  		t.Errorf("could not sign tx: %v", err)
   492  	}
   493  
   494  	// send tx to simulated backend
   495  	err = sim.SendTransaction(bgCtx, signedTx)
   496  	if err != nil {
   497  		t.Errorf("could not add tx to pending block: %v", err)
   498  	}
   499  
   500  	sim.Commit()
   501  
   502  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   503  	if err != nil {
   504  		t.Errorf("could not get header for tip of chain: %v", err)
   505  	}
   506  
   507  	count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
   508  	if err != nil {
   509  		t.Error("could not get current block's transaction count")
   510  	}
   511  
   512  	if count != 1 {
   513  		t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
   514  	}
   515  }
   516  
   517  func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
   518  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   519  
   520  	sim := simTestBackend(testAddr)
   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), 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 := simTestBackend(testAddr)
   584  	defer sim.Close()
   585  	bgCtx := context.Background()
   586  
   587  	// expect pending nonce to be 0 since account has not been used
   588  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   589  	if err != nil {
   590  		t.Errorf("did not get the pending nonce: %v", err)
   591  	}
   592  
   593  	if pendingNonce != uint64(0) {
   594  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   595  	}
   596  
   597  	// create a signed transaction to send
   598  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), big.NewInt(1), nil)
   599  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   600  	if err != nil {
   601  		t.Errorf("could not sign tx: %v", err)
   602  	}
   603  
   604  	// send tx to simulated backend
   605  	err = sim.SendTransaction(bgCtx, signedTx)
   606  	if err != nil {
   607  		t.Errorf("could not add tx to pending block: %v", err)
   608  	}
   609  
   610  	// expect pending nonce to be 1 since account has submitted one transaction
   611  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   612  	if err != nil {
   613  		t.Errorf("did not get the pending nonce: %v", err)
   614  	}
   615  
   616  	if pendingNonce != uint64(1) {
   617  		t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
   618  	}
   619  
   620  	// make a new transaction with a nonce of 1
   621  	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), big.NewInt(1), nil)
   622  	signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
   623  	if err != nil {
   624  		t.Errorf("could not sign tx: %v", err)
   625  	}
   626  	err = sim.SendTransaction(bgCtx, signedTx)
   627  	if err != nil {
   628  		t.Errorf("could not send tx: %v", err)
   629  	}
   630  
   631  	// expect pending nonce to be 2 since account now has two transactions
   632  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   633  	if err != nil {
   634  		t.Errorf("did not get the pending nonce: %v", err)
   635  	}
   636  
   637  	if pendingNonce != uint64(2) {
   638  		t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
   639  	}
   640  }
   641  
   642  func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
   643  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   644  
   645  	sim := simTestBackend(testAddr)
   646  	defer sim.Close()
   647  	bgCtx := context.Background()
   648  
   649  	// create a signed transaction to send
   650  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), big.NewInt(1), nil)
   651  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   652  	if err != nil {
   653  		t.Errorf("could not sign tx: %v", err)
   654  	}
   655  
   656  	// send tx to simulated backend
   657  	err = sim.SendTransaction(bgCtx, signedTx)
   658  	if err != nil {
   659  		t.Errorf("could not add tx to pending block: %v", err)
   660  	}
   661  	sim.Commit()
   662  
   663  	receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
   664  	if err != nil {
   665  		t.Errorf("could not get transaction receipt: %v", err)
   666  	}
   667  
   668  	if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() {
   669  		t.Errorf("received receipt is not correct: %v", receipt)
   670  	}
   671  }
   672  
   673  func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
   674  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   675  	sim := simTestBackend(testAddr)
   676  	defer sim.Close()
   677  	bgCtx := context.Background()
   678  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   679  	if err != nil {
   680  		t.Errorf("could not get code at test addr: %v", err)
   681  	}
   682  	if len(code) != 0 {
   683  		t.Errorf("got code for account that does not have contract code")
   684  	}
   685  
   686  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   687  	if err != nil {
   688  		t.Errorf("could not get code at test addr: %v", err)
   689  	}
   690  	auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
   691  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   692  	if err != nil {
   693  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   694  	}
   695  
   696  	code, err = sim.PendingCodeAt(bgCtx, contractAddr)
   697  	if err != nil {
   698  		t.Errorf("could not get code at test addr: %v", err)
   699  	}
   700  	if len(code) == 0 {
   701  		t.Errorf("did not get code for account that has contract code")
   702  	}
   703  	// ensure code received equals code deployed
   704  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   705  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   706  	}
   707  }
   708  
   709  func TestSimulatedBackend_CodeAt(t *testing.T) {
   710  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   711  	sim := simTestBackend(testAddr)
   712  	defer sim.Close()
   713  	bgCtx := context.Background()
   714  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   715  	if err != nil {
   716  		t.Errorf("could not get code at test addr: %v", err)
   717  	}
   718  	if len(code) != 0 {
   719  		t.Errorf("got code for account that does not have contract code")
   720  	}
   721  
   722  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   723  	if err != nil {
   724  		t.Errorf("could not get code at test addr: %v", err)
   725  	}
   726  	auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
   727  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   728  	if err != nil {
   729  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   730  	}
   731  
   732  	sim.Commit()
   733  	code, err = sim.CodeAt(bgCtx, contractAddr, nil)
   734  	if err != nil {
   735  		t.Errorf("could not get code at test addr: %v", err)
   736  	}
   737  	if len(code) == 0 {
   738  		t.Errorf("did not get code for account that has contract code")
   739  	}
   740  	// ensure code received equals code deployed
   741  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   742  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   743  	}
   744  }
   745  
   746  // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
   747  //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
   748  func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
   749  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   750  	sim := simTestBackend(testAddr)
   751  	defer sim.Close()
   752  	bgCtx := context.Background()
   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  	contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
   759  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
   760  	if err != nil {
   761  		t.Errorf("could not deploy contract: %v", err)
   762  	}
   763  
   764  	input, err := parsed.Pack("receive", []byte("X"))
   765  	if err != nil {
   766  		t.Errorf("could not pack receive function on contract: %v", err)
   767  	}
   768  
   769  	// make sure you can call the contract in pending state
   770  	res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{
   771  		From: testAddr,
   772  		To:   &addr,
   773  		Data: input,
   774  	})
   775  	if err != nil {
   776  		t.Errorf("could not call receive method on contract: %v", err)
   777  	}
   778  	if len(res) == 0 {
   779  		t.Errorf("result of contract call was empty: %v", res)
   780  	}
   781  
   782  	// while comparing against the byte array is more exact, also compare against the human readable string for readability
   783  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   784  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   785  	}
   786  
   787  	sim.Commit()
   788  
   789  	// make sure you can call the contract
   790  	res, err = sim.CallContract(bgCtx, ethereum.CallMsg{
   791  		From: testAddr,
   792  		To:   &addr,
   793  		Data: input,
   794  	}, nil)
   795  	if err != nil {
   796  		t.Errorf("could not call receive method on contract: %v", err)
   797  	}
   798  	if len(res) == 0 {
   799  		t.Errorf("result of contract call was empty: %v", res)
   800  	}
   801  
   802  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   803  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   804  	}
   805  }
   806  
   807  // This test is based on the following contract:
   808  /*
   809  contract Reverter {
   810      function revertString() public pure{
   811          require(false, "some error");
   812      }
   813      function revertNoString() public pure {
   814          require(false, "");
   815      }
   816      function revertASM() public pure {
   817          assembly {
   818              revert(0x0, 0x0)
   819          }
   820      }
   821      function noRevert() public pure {
   822          assembly {
   823              // Assembles something that looks like require(false, "some error") but is not reverted
   824              mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
   825              mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020)
   826              mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a)
   827              mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000)
   828              return(0x0, 0x64)
   829          }
   830      }
   831  }*/
   832  func TestSimulatedBackend_CallContractRevert(t *testing.T) {
   833  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   834  	sim := simTestBackend(testAddr)
   835  	defer sim.Close()
   836  	bgCtx := context.Background()
   837  
   838  	reverterABI := `[{"inputs": [],"name": "noRevert","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertASM","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertNoString","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertString","outputs": [],"stateMutability": "pure","type": "function"}]`
   839  	reverterBin := "608060405234801561001057600080fd5b506101d3806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634b409e01146100515780639b340e361461005b5780639bd6103714610065578063b7246fc11461006f575b600080fd5b610059610079565b005b6100636100ca565b005b61006d6100cf565b005b610077610145565b005b60006100c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526000815260200160200191505060405180910390fd5b565b600080fd5b6000610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f736f6d65206572726f720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f3fea2646970667358221220cdd8af0609ec4996b7360c7c780bad5c735740c64b1fffc3445aa12d37f07cb164736f6c63430006070033"
   840  
   841  	parsed, err := abi.JSON(strings.NewReader(reverterABI))
   842  	if err != nil {
   843  		t.Errorf("could not get code at test addr: %v", err)
   844  	}
   845  	contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
   846  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim)
   847  	if err != nil {
   848  		t.Errorf("could not deploy contract: %v", err)
   849  	}
   850  
   851  	inputs := make(map[string]interface{}, 3)
   852  	inputs["revertASM"] = nil
   853  	inputs["revertNoString"] = ""
   854  	inputs["revertString"] = "some error"
   855  
   856  	call := make([]func([]byte) ([]byte, error), 2)
   857  	call[0] = func(input []byte) ([]byte, error) {
   858  		return sim.PendingCallContract(bgCtx, ethereum.CallMsg{
   859  			From: testAddr,
   860  			To:   &addr,
   861  			Data: input,
   862  		})
   863  	}
   864  	call[1] = func(input []byte) ([]byte, error) {
   865  		return sim.CallContract(bgCtx, ethereum.CallMsg{
   866  			From: testAddr,
   867  			To:   &addr,
   868  			Data: input,
   869  		}, nil)
   870  	}
   871  
   872  	// Run pending calls then commit
   873  	for _, cl := range call {
   874  		for key, val := range inputs {
   875  			input, err := parsed.Pack(key)
   876  			if err != nil {
   877  				t.Errorf("could not pack %v function on contract: %v", key, err)
   878  			}
   879  
   880  			res, err := cl(input)
   881  			if err == nil {
   882  				t.Errorf("call to %v was not reverted", key)
   883  			}
   884  			if res != nil {
   885  				t.Errorf("result from %v was not nil: %v", key, res)
   886  			}
   887  			if val != nil {
   888  				rerr, ok := err.(*revertError)
   889  				if !ok {
   890  					t.Errorf("expect revert error")
   891  				}
   892  				if rerr.Error() != "execution reverted: "+val.(string) {
   893  					t.Errorf("error was malformed: got %v want %v", rerr.Error(), val)
   894  				}
   895  			} else {
   896  				// revert(0x0,0x0)
   897  				if err.Error() != "execution reverted" {
   898  					t.Errorf("error was malformed: got %v want %v", err, "execution reverted")
   899  				}
   900  			}
   901  		}
   902  		input, err := parsed.Pack("noRevert")
   903  		if err != nil {
   904  			t.Errorf("could not pack noRevert function on contract: %v", err)
   905  		}
   906  		res, err := cl(input)
   907  		if err != nil {
   908  			t.Error("call to noRevert was reverted")
   909  		}
   910  		if res == nil {
   911  			t.Errorf("result from noRevert was nil")
   912  		}
   913  		sim.Commit()
   914  	}
   915  }