github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/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  	"errors"
    23  	"math/big"
    24  	"math/rand"
    25  	"reflect"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"go.uber.org/goleak"
    31  
    32  	"github.com/ethereum/go-ethereum"
    33  	"github.com/ethereum/go-ethereum/accounts/abi"
    34  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    35  	"github.com/ethereum/go-ethereum/common"
    36  	"github.com/ethereum/go-ethereum/common/leak"
    37  	"github.com/ethereum/go-ethereum/core"
    38  	"github.com/ethereum/go-ethereum/core/types"
    39  	"github.com/ethereum/go-ethereum/crypto"
    40  	"github.com/ethereum/go-ethereum/params"
    41  )
    42  
    43  func TestSimulatedBackend(t *testing.T) {
    44  	defer goleak.VerifyNone(t, leak.IgnoreList()...)
    45  
    46  	var gasLimit uint64 = 8000029
    47  	key, _ := crypto.GenerateKey() // nolint: gosec
    48  	auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
    49  	genAlloc := make(core.GenesisAlloc)
    50  	genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
    51  
    52  	sim := NewSimulatedBackend(genAlloc, gasLimit)
    53  	defer sim.Close()
    54  
    55  	// should return an error if the tx is not found
    56  	txHash := common.HexToHash("2")
    57  	_, isPending, err := sim.TransactionByHash(context.Background(), txHash)
    58  
    59  	if isPending {
    60  		t.Fatal("transaction should not be pending")
    61  	}
    62  	if err != ethereum.NotFound {
    63  		t.Fatalf("err should be `ethereum.NotFound` but received %v", err)
    64  	}
    65  
    66  	// generate a transaction and confirm you can retrieve it
    67  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
    68  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
    69  
    70  	code := `6060604052600a8060106000396000f360606040526008565b00`
    71  	var gas uint64 = 3000000
    72  	tx := types.NewContractCreation(0, big.NewInt(0), gas, gasPrice, common.FromHex(code))
    73  	tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key)
    74  
    75  	err = sim.SendTransaction(context.Background(), tx)
    76  	if err != nil {
    77  		t.Fatal("error sending transaction")
    78  	}
    79  
    80  	txHash = tx.Hash()
    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 have pending status")
    87  	}
    88  
    89  	sim.Commit()
    90  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    91  	if err != nil {
    92  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    93  	}
    94  	if isPending {
    95  		t.Fatal("transaction should not have pending status")
    96  	}
    97  }
    98  
    99  var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   100  
   101  //  the following is based on this contract:
   102  //  contract T {
   103  //  	event received(address sender, uint amount, bytes memo);
   104  //  	event receivedAddr(address sender);
   105  //
   106  //  	function receive(bytes calldata memo) external payable returns (string memory res) {
   107  //  		emit received(msg.sender, msg.value, memo);
   108  //  		emit receivedAddr(msg.sender);
   109  //		    return "hello world";
   110  //  	}
   111  //  }
   112  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" } ]`
   113  const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   114  const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   115  
   116  // expected return value contains "hello world"
   117  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}
   118  
   119  func simTestBackend(testAddr common.Address) *SimulatedBackend {
   120  	return NewSimulatedBackend(
   121  		core.GenesisAlloc{
   122  			testAddr: {Balance: big.NewInt(10000000000000000)},
   123  		}, 10000000,
   124  	)
   125  }
   126  
   127  func TestNewSimulatedBackend(t *testing.T) {
   128  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   129  	expectedBal := big.NewInt(10000000000000000)
   130  	sim := simTestBackend(testAddr)
   131  	defer sim.Close()
   132  
   133  	if sim.config != params.AllEthashProtocolChanges {
   134  		t.Errorf("expected sim config to equal params.AllEthashProtocolChanges, got %v", sim.config)
   135  	}
   136  
   137  	if sim.blockchain.Config() != params.AllEthashProtocolChanges {
   138  		t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config)
   139  	}
   140  
   141  	stateDB, _ := sim.blockchain.State()
   142  	bal := stateDB.GetBalance(testAddr)
   143  	if bal.Cmp(expectedBal) != 0 {
   144  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   145  	}
   146  }
   147  
   148  func TestAdjustTime(t *testing.T) {
   149  	sim := NewSimulatedBackend(
   150  		core.GenesisAlloc{}, 10000000,
   151  	)
   152  	defer sim.Close()
   153  
   154  	prevTime := sim.pendingBlock.Time()
   155  	if err := sim.AdjustTime(time.Second); err != nil {
   156  		t.Error(err)
   157  	}
   158  	newTime := sim.pendingBlock.Time()
   159  
   160  	if newTime-prevTime != uint64(time.Second.Seconds()) {
   161  		t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime)
   162  	}
   163  }
   164  
   165  func TestNewAdjustTimeFail(t *testing.T) {
   166  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   167  	sim := simTestBackend(testAddr)
   168  
   169  	// Create tx and send
   170  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   171  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   172  
   173  	tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   174  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   175  	if err != nil {
   176  		t.Errorf("could not sign tx: %v", err)
   177  	}
   178  	sim.SendTransaction(context.Background(), signedTx)
   179  	// AdjustTime should fail on non-empty block
   180  	if err := sim.AdjustTime(time.Second); err == nil {
   181  		t.Error("Expected adjust time to error on non-empty block")
   182  	}
   183  	sim.Commit()
   184  
   185  	prevTime := sim.pendingBlock.Time()
   186  	if err := sim.AdjustTime(time.Minute); err != nil {
   187  		t.Error(err)
   188  	}
   189  	newTime := sim.pendingBlock.Time()
   190  	if newTime-prevTime != uint64(time.Minute.Seconds()) {
   191  		t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime)
   192  	}
   193  	// Put a transaction after adjusting time
   194  	tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   195  	signedTx2, err := types.SignTx(tx2, types.HomesteadSigner{}, testKey)
   196  	if err != nil {
   197  		t.Errorf("could not sign tx: %v", err)
   198  	}
   199  	sim.SendTransaction(context.Background(), signedTx2)
   200  	sim.Commit()
   201  	newTime = sim.pendingBlock.Time()
   202  	if newTime-prevTime >= uint64(time.Minute.Seconds()) {
   203  		t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime)
   204  	}
   205  }
   206  
   207  func TestBalanceAt(t *testing.T) {
   208  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   209  	expectedBal := big.NewInt(10000000000000000)
   210  	sim := simTestBackend(testAddr)
   211  	defer sim.Close()
   212  	bgCtx := context.Background()
   213  
   214  	bal, err := sim.BalanceAt(bgCtx, testAddr, nil)
   215  	if err != nil {
   216  		t.Error(err)
   217  	}
   218  
   219  	if bal.Cmp(expectedBal) != 0 {
   220  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   221  	}
   222  }
   223  
   224  func TestBlockByHash(t *testing.T) {
   225  	sim := NewSimulatedBackend(
   226  		core.GenesisAlloc{}, 10000000,
   227  	)
   228  	defer sim.Close()
   229  	bgCtx := context.Background()
   230  
   231  	block, err := sim.BlockByNumber(bgCtx, nil)
   232  	if err != nil {
   233  		t.Errorf("could not get recent block: %v", err)
   234  	}
   235  	blockByHash, err := sim.BlockByHash(bgCtx, block.Hash())
   236  	if err != nil {
   237  		t.Errorf("could not get recent block: %v", err)
   238  	}
   239  
   240  	if block.Hash() != blockByHash.Hash() {
   241  		t.Errorf("did not get expected block")
   242  	}
   243  }
   244  
   245  func TestBlockByNumber(t *testing.T) {
   246  	sim := NewSimulatedBackend(
   247  		core.GenesisAlloc{}, 10000000,
   248  	)
   249  	defer sim.Close()
   250  	bgCtx := context.Background()
   251  
   252  	block, err := sim.BlockByNumber(bgCtx, nil)
   253  	if err != nil {
   254  		t.Errorf("could not get recent block: %v", err)
   255  	}
   256  	if block.NumberU64() != 0 {
   257  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   258  	}
   259  
   260  	// create one block
   261  	sim.Commit()
   262  
   263  	block, err = sim.BlockByNumber(bgCtx, nil)
   264  	if err != nil {
   265  		t.Errorf("could not get recent block: %v", err)
   266  	}
   267  	if block.NumberU64() != 1 {
   268  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   269  	}
   270  
   271  	blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   272  	if err != nil {
   273  		t.Errorf("could not get block by number: %v", err)
   274  	}
   275  	if blockByNumber.Hash() != block.Hash() {
   276  		t.Errorf("did not get the same block with height of 1 as before")
   277  	}
   278  }
   279  
   280  func TestNonceAt(t *testing.T) {
   281  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   282  
   283  	sim := simTestBackend(testAddr)
   284  	defer sim.Close()
   285  	bgCtx := context.Background()
   286  
   287  	nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0))
   288  	if err != nil {
   289  		t.Errorf("could not get nonce for test addr: %v", err)
   290  	}
   291  
   292  	if nonce != uint64(0) {
   293  		t.Errorf("received incorrect nonce. expected 0, got %v", nonce)
   294  	}
   295  
   296  	// create a signed transaction to send
   297  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   298  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   299  
   300  	tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   301  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   302  	if err != nil {
   303  		t.Errorf("could not sign tx: %v", err)
   304  	}
   305  
   306  	// send tx to simulated backend
   307  	err = sim.SendTransaction(bgCtx, signedTx)
   308  	if err != nil {
   309  		t.Errorf("could not add tx to pending block: %v", err)
   310  	}
   311  	sim.Commit()
   312  
   313  	newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   314  	if err != nil {
   315  		t.Errorf("could not get nonce for test addr: %v", err)
   316  	}
   317  
   318  	if newNonce != nonce+uint64(1) {
   319  		t.Errorf("received incorrect nonce. expected 1, got %v", nonce)
   320  	}
   321  	// create some more blocks
   322  	sim.Commit()
   323  	// Check that we can get data for an older block/state
   324  	newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   325  	if err != nil {
   326  		t.Fatalf("could not get nonce for test addr: %v", err)
   327  	}
   328  	if newNonce != nonce+uint64(1) {
   329  		t.Fatalf("received incorrect nonce. expected 1, got %v", nonce)
   330  	}
   331  }
   332  
   333  func TestSendTransaction(t *testing.T) {
   334  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   335  
   336  	sim := simTestBackend(testAddr)
   337  	defer sim.Close()
   338  	bgCtx := context.Background()
   339  
   340  	// create a signed transaction to send
   341  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   342  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   343  
   344  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   345  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   346  	if err != nil {
   347  		t.Errorf("could not sign tx: %v", err)
   348  	}
   349  
   350  	// send tx to simulated backend
   351  	err = sim.SendTransaction(bgCtx, signedTx)
   352  	if err != nil {
   353  		t.Errorf("could not add tx to pending block: %v", err)
   354  	}
   355  	sim.Commit()
   356  
   357  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   358  	if err != nil {
   359  		t.Errorf("could not get block at height 1: %v", err)
   360  	}
   361  
   362  	if signedTx.Hash() != block.Transactions()[0].Hash() {
   363  		t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash())
   364  	}
   365  }
   366  
   367  func TestTransactionByHash(t *testing.T) {
   368  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   369  
   370  	sim := NewSimulatedBackend(
   371  		core.GenesisAlloc{
   372  			testAddr: {Balance: big.NewInt(10000000000000000)},
   373  		}, 10000000,
   374  	)
   375  	defer sim.Close()
   376  	bgCtx := context.Background()
   377  
   378  	// create a signed transaction to send
   379  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   380  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   381  
   382  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   383  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   384  	if err != nil {
   385  		t.Errorf("could not sign tx: %v", err)
   386  	}
   387  
   388  	// send tx to simulated backend
   389  	err = sim.SendTransaction(bgCtx, signedTx)
   390  	if err != nil {
   391  		t.Errorf("could not add tx to pending block: %v", err)
   392  	}
   393  
   394  	// ensure tx is committed pending
   395  	receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash())
   396  	if err != nil {
   397  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   398  	}
   399  	if !pending {
   400  		t.Errorf("expected transaction to be in pending state")
   401  	}
   402  	if receivedTx.Hash() != signedTx.Hash() {
   403  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   404  	}
   405  
   406  	sim.Commit()
   407  
   408  	// ensure tx is not and committed pending
   409  	receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash())
   410  	if err != nil {
   411  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   412  	}
   413  	if pending {
   414  		t.Errorf("expected transaction to not be in pending state")
   415  	}
   416  	if receivedTx.Hash() != signedTx.Hash() {
   417  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   418  	}
   419  }
   420  
   421  func TestEstimateGas(t *testing.T) {
   422  	/*
   423  		pragma solidity ^0.6.4;
   424  		contract GasEstimation {
   425  		    function PureRevert() public { revert(); }
   426  		    function Revert() public { revert("revert reason");}
   427  		    function OOG() public { for (uint i = 0; ; i++) {}}
   428  		    function Assert() public { assert(false);}
   429  		    function Valid() public {}
   430  		}*/
   431  	const contractAbi = "[{\"inputs\":[],\"name\":\"Assert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OOG\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PureRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Revert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Valid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
   432  	const contractBin = "0x60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040523480156100115760006000fd5b506004361061005c5760003560e01c806350f6fe3414610062578063aa8b1d301461006c578063b9b046f914610076578063d8b9839114610080578063e09fface1461008a5761005c565b60006000fd5b61006a610094565b005b6100746100ad565b005b61007e6100b5565b005b6100886100c2565b005b610092610135565b005b6000600090505b5b808060010191505061009b565b505b565b60006000fd5b565b600015156100bf57fe5b5b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f72657665727420726561736f6e0000000000000000000000000000000000000081526020015060200191505060405180910390fd5b565b5b56fea2646970667358221220345bbcbb1a5ecf22b53a78eaebf95f8ee0eceff6d10d4b9643495084d2ec934a64736f6c63430006040033"
   433  
   434  	key, _ := crypto.GenerateKey()
   435  	addr := crypto.PubkeyToAddress(key.PublicKey)
   436  	opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
   437  
   438  	sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000)
   439  	defer sim.Close()
   440  
   441  	parsed, _ := abi.JSON(strings.NewReader(contractAbi))
   442  	contractAddr, _, _, _ := bind.DeployContract(opts, parsed, common.FromHex(contractBin), sim)
   443  	sim.Commit()
   444  
   445  	var cases = []struct {
   446  		name        string
   447  		message     ethereum.CallMsg
   448  		expect      uint64
   449  		expectError error
   450  		expectData  interface{}
   451  	}{
   452  		{"plain transfer(valid)", ethereum.CallMsg{
   453  			From:     addr,
   454  			To:       &addr,
   455  			Gas:      0,
   456  			GasPrice: big.NewInt(0),
   457  			Value:    big.NewInt(1),
   458  			Data:     nil,
   459  		}, params.TxGas, nil, nil},
   460  
   461  		{"plain transfer(invalid)", ethereum.CallMsg{
   462  			From:     addr,
   463  			To:       &contractAddr,
   464  			Gas:      0,
   465  			GasPrice: big.NewInt(0),
   466  			Value:    big.NewInt(1),
   467  			Data:     nil,
   468  		}, 0, errors.New("execution reverted"), nil},
   469  
   470  		{"Revert", ethereum.CallMsg{
   471  			From:     addr,
   472  			To:       &contractAddr,
   473  			Gas:      0,
   474  			GasPrice: big.NewInt(0),
   475  			Value:    nil,
   476  			Data:     common.Hex2Bytes("d8b98391"),
   477  		}, 0, errors.New("execution reverted: revert reason"), "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000"},
   478  
   479  		{"PureRevert", ethereum.CallMsg{
   480  			From:     addr,
   481  			To:       &contractAddr,
   482  			Gas:      0,
   483  			GasPrice: big.NewInt(0),
   484  			Value:    nil,
   485  			Data:     common.Hex2Bytes("aa8b1d30"),
   486  		}, 0, errors.New("execution reverted"), nil},
   487  
   488  		{"OOG", ethereum.CallMsg{
   489  			From:     addr,
   490  			To:       &contractAddr,
   491  			Gas:      100000,
   492  			GasPrice: big.NewInt(0),
   493  			Value:    nil,
   494  			Data:     common.Hex2Bytes("50f6fe34"),
   495  		}, 0, errors.New("gas required exceeds allowance (100000)"), nil},
   496  
   497  		{"Assert", ethereum.CallMsg{
   498  			From:     addr,
   499  			To:       &contractAddr,
   500  			Gas:      100000,
   501  			GasPrice: big.NewInt(0),
   502  			Value:    nil,
   503  			Data:     common.Hex2Bytes("b9b046f9"),
   504  		}, 0, errors.New("invalid opcode: INVALID"), nil},
   505  
   506  		{"Valid", ethereum.CallMsg{
   507  			From:     addr,
   508  			To:       &contractAddr,
   509  			Gas:      100000,
   510  			GasPrice: big.NewInt(0),
   511  			Value:    nil,
   512  			Data:     common.Hex2Bytes("e09fface"),
   513  		}, 21275, nil, nil},
   514  	}
   515  	for _, c := range cases {
   516  		got, err := sim.EstimateGas(context.Background(), c.message)
   517  		if c.expectError != nil {
   518  			if err == nil {
   519  				t.Fatalf("Expect error, got nil")
   520  			}
   521  			if c.expectError.Error() != err.Error() {
   522  				t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
   523  			}
   524  			if c.expectData != nil {
   525  				if err, ok := err.(*revertError); !ok {
   526  					t.Fatalf("Expect revert error, got %T", err)
   527  				} else if !reflect.DeepEqual(err.ErrorData(), c.expectData) {
   528  					t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, err.ErrorData())
   529  				}
   530  			}
   531  			continue
   532  		}
   533  		if got != c.expect {
   534  			t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got)
   535  		}
   536  	}
   537  }
   538  
   539  func TestEstimateGasWithPrice(t *testing.T) {
   540  	key, _ := crypto.GenerateKey()
   541  	addr := crypto.PubkeyToAddress(key.PublicKey)
   542  
   543  	sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000)
   544  	defer sim.Close()
   545  
   546  	recipient := common.HexToAddress("deadbeef")
   547  	var cases = []struct {
   548  		name        string
   549  		message     ethereum.CallMsg
   550  		expect      uint64
   551  		expectError error
   552  	}{
   553  		{"EstimateWithoutPrice", ethereum.CallMsg{
   554  			From:     addr,
   555  			To:       &recipient,
   556  			Gas:      0,
   557  			GasPrice: big.NewInt(0),
   558  			Value:    big.NewInt(100000000000),
   559  			Data:     nil,
   560  		}, 21000, nil},
   561  
   562  		{"EstimateWithPrice", ethereum.CallMsg{
   563  			From:     addr,
   564  			To:       &recipient,
   565  			Gas:      0,
   566  			GasPrice: big.NewInt(100000000000),
   567  			Value:    big.NewInt(100000000000),
   568  			Data:     nil,
   569  		}, 21000, nil},
   570  
   571  		{"EstimateWithVeryHighPrice", ethereum.CallMsg{
   572  			From:     addr,
   573  			To:       &recipient,
   574  			Gas:      0,
   575  			GasPrice: big.NewInt(1e14), // gascost = 2.1ether
   576  			Value:    big.NewInt(1e17), // the remaining balance for fee is 2.1ether
   577  			Data:     nil,
   578  		}, 21000, nil},
   579  
   580  		{"EstimateWithSuperhighPrice", ethereum.CallMsg{
   581  			From:     addr,
   582  			To:       &recipient,
   583  			Gas:      0,
   584  			GasPrice: big.NewInt(2e14), // gascost = 4.2ether
   585  			Value:    big.NewInt(100000000000),
   586  			Data:     nil,
   587  		}, 21000, errors.New("gas required exceeds allowance (10999)")}, // 10999=(2.2ether-1000wei)/(2e14)
   588  
   589  		{"EstimateEIP1559WithHighFees", ethereum.CallMsg{
   590  			From:      addr,
   591  			To:        &addr,
   592  			Gas:       0,
   593  			GasFeeCap: big.NewInt(1e14), // maxgascost = 2.1ether
   594  			GasTipCap: big.NewInt(1),
   595  			Value:     big.NewInt(1e17), // the remaining balance for fee is 2.1ether
   596  			Data:      nil,
   597  		}, params.TxGas, nil},
   598  
   599  		{"EstimateEIP1559WithSuperHighFees", ethereum.CallMsg{
   600  			From:      addr,
   601  			To:        &addr,
   602  			Gas:       0,
   603  			GasFeeCap: big.NewInt(1e14), // maxgascost = 2.1ether
   604  			GasTipCap: big.NewInt(1),
   605  			Value:     big.NewInt(1e17 + 1), // the remaining balance for fee is 2.1ether
   606  			Data:      nil,
   607  		}, params.TxGas, errors.New("gas required exceeds allowance (20999)")}, // 20999=(2.2ether-0.1ether-1wei)/(1e14)
   608  	}
   609  	for i, c := range cases {
   610  		got, err := sim.EstimateGas(context.Background(), c.message)
   611  		if c.expectError != nil {
   612  			if err == nil {
   613  				t.Fatalf("test %d: expect error, got nil", i)
   614  			}
   615  			if c.expectError.Error() != err.Error() {
   616  				t.Fatalf("test %d: expect error, want %v, got %v", i, c.expectError, err)
   617  			}
   618  			continue
   619  		}
   620  		if c.expectError == nil && err != nil {
   621  			t.Fatalf("test %d: didn't expect error, got %v", i, err)
   622  		}
   623  		if got != c.expect {
   624  			t.Fatalf("test %d: gas estimation mismatch, want %d, got %d", i, c.expect, got)
   625  		}
   626  	}
   627  }
   628  
   629  func TestHeaderByHash(t *testing.T) {
   630  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   631  
   632  	sim := simTestBackend(testAddr)
   633  	defer sim.Close()
   634  	bgCtx := context.Background()
   635  
   636  	header, err := sim.HeaderByNumber(bgCtx, nil)
   637  	if err != nil {
   638  		t.Errorf("could not get recent block: %v", err)
   639  	}
   640  	headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
   641  	if err != nil {
   642  		t.Errorf("could not get recent block: %v", err)
   643  	}
   644  
   645  	if header.Hash() != headerByHash.Hash() {
   646  		t.Errorf("did not get expected block")
   647  	}
   648  }
   649  
   650  func TestHeaderByNumber(t *testing.T) {
   651  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   652  
   653  	sim := simTestBackend(testAddr)
   654  	defer sim.Close()
   655  	bgCtx := context.Background()
   656  
   657  	latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
   658  	if err != nil {
   659  		t.Errorf("could not get header for tip of chain: %v", err)
   660  	}
   661  	if latestBlockHeader == nil {
   662  		t.Errorf("received a nil block header")
   663  	}
   664  	if latestBlockHeader.Number.Uint64() != uint64(0) {
   665  		t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
   666  	}
   667  
   668  	sim.Commit()
   669  
   670  	latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
   671  	if err != nil {
   672  		t.Errorf("could not get header for blockheight of 1: %v", err)
   673  	}
   674  
   675  	blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
   676  	if err != nil {
   677  		t.Errorf("could not get header for blockheight of 1: %v", err)
   678  	}
   679  
   680  	if blockHeader.Hash() != latestBlockHeader.Hash() {
   681  		t.Errorf("block header and latest block header are not the same")
   682  	}
   683  	if blockHeader.Number.Int64() != int64(1) {
   684  		t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
   685  	}
   686  
   687  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   688  	if err != nil {
   689  		t.Errorf("could not get block for blockheight of 1: %v", err)
   690  	}
   691  
   692  	if block.Hash() != blockHeader.Hash() {
   693  		t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
   694  	}
   695  }
   696  
   697  func TestTransactionCount(t *testing.T) {
   698  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   699  
   700  	sim := simTestBackend(testAddr)
   701  	defer sim.Close()
   702  	bgCtx := context.Background()
   703  	currentBlock, err := sim.BlockByNumber(bgCtx, nil)
   704  	if err != nil || currentBlock == nil {
   705  		t.Error("could not get current block")
   706  	}
   707  
   708  	count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
   709  	if err != nil {
   710  		t.Error("could not get current block's transaction count")
   711  	}
   712  
   713  	if count != 0 {
   714  		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
   715  	}
   716  	// create a signed transaction to send
   717  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   718  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   719  
   720  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   721  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   722  	if err != nil {
   723  		t.Errorf("could not sign tx: %v", err)
   724  	}
   725  
   726  	// send tx to simulated backend
   727  	err = sim.SendTransaction(bgCtx, signedTx)
   728  	if err != nil {
   729  		t.Errorf("could not add tx to pending block: %v", err)
   730  	}
   731  
   732  	sim.Commit()
   733  
   734  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   735  	if err != nil {
   736  		t.Errorf("could not get header for tip of chain: %v", err)
   737  	}
   738  
   739  	count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
   740  	if err != nil {
   741  		t.Error("could not get current block's transaction count")
   742  	}
   743  
   744  	if count != 1 {
   745  		t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
   746  	}
   747  }
   748  
   749  func TestTransactionInBlock(t *testing.T) {
   750  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   751  
   752  	sim := simTestBackend(testAddr)
   753  	defer sim.Close()
   754  	bgCtx := context.Background()
   755  
   756  	transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0))
   757  	if err == nil && err != errTransactionDoesNotExist {
   758  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   759  	}
   760  	if transaction != nil {
   761  		t.Errorf("expected transaction to be nil but received %v", transaction)
   762  	}
   763  
   764  	// expect pending nonce to be 0 since account has not been used
   765  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   766  	if err != nil {
   767  		t.Errorf("did not get the pending nonce: %v", err)
   768  	}
   769  
   770  	if pendingNonce != uint64(0) {
   771  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   772  	}
   773  	// create a signed transaction to send
   774  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   775  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   776  
   777  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   778  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   779  	if err != nil {
   780  		t.Errorf("could not sign tx: %v", err)
   781  	}
   782  
   783  	// send tx to simulated backend
   784  	err = sim.SendTransaction(bgCtx, signedTx)
   785  	if err != nil {
   786  		t.Errorf("could not add tx to pending block: %v", err)
   787  	}
   788  
   789  	sim.Commit()
   790  
   791  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   792  	if err != nil {
   793  		t.Errorf("could not get header for tip of chain: %v", err)
   794  	}
   795  
   796  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1))
   797  	if err == nil && err != errTransactionDoesNotExist {
   798  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   799  	}
   800  	if transaction != nil {
   801  		t.Errorf("expected transaction to be nil but received %v", transaction)
   802  	}
   803  
   804  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0))
   805  	if err != nil {
   806  		t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err)
   807  	}
   808  
   809  	if signedTx.Hash().String() != transaction.Hash().String() {
   810  		t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String())
   811  	}
   812  }
   813  
   814  func TestPendingNonceAt(t *testing.T) {
   815  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   816  
   817  	sim := simTestBackend(testAddr)
   818  	defer sim.Close()
   819  	bgCtx := context.Background()
   820  
   821  	// expect pending nonce to be 0 since account has not been used
   822  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   823  	if err != nil {
   824  		t.Errorf("did not get the pending nonce: %v", err)
   825  	}
   826  
   827  	if pendingNonce != uint64(0) {
   828  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   829  	}
   830  
   831  	// create a signed transaction to send
   832  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   833  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   834  
   835  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   836  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   837  	if err != nil {
   838  		t.Errorf("could not sign tx: %v", err)
   839  	}
   840  
   841  	// send tx to simulated backend
   842  	err = sim.SendTransaction(bgCtx, signedTx)
   843  	if err != nil {
   844  		t.Errorf("could not add tx to pending block: %v", err)
   845  	}
   846  
   847  	// expect pending nonce to be 1 since account has submitted one transaction
   848  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   849  	if err != nil {
   850  		t.Errorf("did not get the pending nonce: %v", err)
   851  	}
   852  
   853  	if pendingNonce != uint64(1) {
   854  		t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
   855  	}
   856  
   857  	// make a new transaction with a nonce of 1
   858  	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   859  	signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
   860  	if err != nil {
   861  		t.Errorf("could not sign tx: %v", err)
   862  	}
   863  	err = sim.SendTransaction(bgCtx, signedTx)
   864  	if err != nil {
   865  		t.Errorf("could not send tx: %v", err)
   866  	}
   867  
   868  	// expect pending nonce to be 2 since account now has two transactions
   869  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   870  	if err != nil {
   871  		t.Errorf("did not get the pending nonce: %v", err)
   872  	}
   873  
   874  	if pendingNonce != uint64(2) {
   875  		t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
   876  	}
   877  }
   878  
   879  func TestTransactionReceipt(t *testing.T) {
   880  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   881  
   882  	sim := simTestBackend(testAddr)
   883  	defer sim.Close()
   884  	bgCtx := context.Background()
   885  
   886  	// create a signed transaction to send
   887  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
   888  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
   889  
   890  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
   891  	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
   892  	if err != nil {
   893  		t.Errorf("could not sign tx: %v", err)
   894  	}
   895  
   896  	// send tx to simulated backend
   897  	err = sim.SendTransaction(bgCtx, signedTx)
   898  	if err != nil {
   899  		t.Errorf("could not add tx to pending block: %v", err)
   900  	}
   901  	sim.Commit()
   902  
   903  	receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
   904  	if err != nil {
   905  		t.Errorf("could not get transaction receipt: %v", err)
   906  	}
   907  
   908  	if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() {
   909  		t.Errorf("received receipt is not correct: %v", receipt)
   910  	}
   911  }
   912  
   913  func TestSuggestGasPrice(t *testing.T) {
   914  	sim := NewSimulatedBackend(
   915  		core.GenesisAlloc{},
   916  		10000000,
   917  	)
   918  	defer sim.Close()
   919  	bgCtx := context.Background()
   920  	gasPrice, err := sim.SuggestGasPrice(bgCtx)
   921  	if err != nil {
   922  		t.Errorf("could not get gas price: %v", err)
   923  	}
   924  	if gasPrice.Uint64() != sim.pendingBlock.Header().BaseFee.Uint64() {
   925  		t.Errorf("gas price was not expected value of %v. actual: %v", sim.pendingBlock.Header().BaseFee.Uint64(), gasPrice.Uint64())
   926  	}
   927  }
   928  
   929  func TestPendingCodeAt(t *testing.T) {
   930  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   931  	sim := simTestBackend(testAddr)
   932  	defer sim.Close()
   933  	bgCtx := context.Background()
   934  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   935  	if err != nil {
   936  		t.Errorf("could not get code at test addr: %v", err)
   937  	}
   938  	if len(code) != 0 {
   939  		t.Errorf("got code for account that does not have contract code")
   940  	}
   941  
   942  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   943  	if err != nil {
   944  		t.Errorf("could not get code at test addr: %v", err)
   945  	}
   946  	auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
   947  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   948  	if err != nil {
   949  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   950  	}
   951  
   952  	code, err = sim.PendingCodeAt(bgCtx, contractAddr)
   953  	if err != nil {
   954  		t.Errorf("could not get code at test addr: %v", err)
   955  	}
   956  	if len(code) == 0 {
   957  		t.Errorf("did not get code for account that has contract code")
   958  	}
   959  	// ensure code received equals code deployed
   960  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   961  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   962  	}
   963  }
   964  
   965  func TestCodeAt(t *testing.T) {
   966  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   967  	sim := simTestBackend(testAddr)
   968  	defer sim.Close()
   969  	bgCtx := context.Background()
   970  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   971  	if err != nil {
   972  		t.Errorf("could not get code at test addr: %v", err)
   973  	}
   974  	if len(code) != 0 {
   975  		t.Errorf("got code for account that does not have contract code")
   976  	}
   977  
   978  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   979  	if err != nil {
   980  		t.Errorf("could not get code at test addr: %v", err)
   981  	}
   982  	auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
   983  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   984  	if err != nil {
   985  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   986  	}
   987  
   988  	sim.Commit()
   989  	code, err = sim.CodeAt(bgCtx, contractAddr, nil)
   990  	if err != nil {
   991  		t.Errorf("could not get code at test addr: %v", err)
   992  	}
   993  	if len(code) == 0 {
   994  		t.Errorf("did not get code for account that has contract code")
   995  	}
   996  	// ensure code received equals code deployed
   997  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   998  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   999  	}
  1000  }
  1001  
  1002  // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
  1003  //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
  1004  func TestPendingAndCallContract(t *testing.T) {
  1005  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  1006  	sim := simTestBackend(testAddr)
  1007  	defer sim.Close()
  1008  	bgCtx := context.Background()
  1009  
  1010  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
  1011  	if err != nil {
  1012  		t.Errorf("could not get code at test addr: %v", err)
  1013  	}
  1014  	contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
  1015  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
  1016  	if err != nil {
  1017  		t.Errorf("could not deploy contract: %v", err)
  1018  	}
  1019  
  1020  	input, err := parsed.Pack("receive", []byte("X"))
  1021  	if err != nil {
  1022  		t.Errorf("could not pack receive function on contract: %v", err)
  1023  	}
  1024  
  1025  	// make sure you can call the contract in pending state
  1026  	res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{
  1027  		From: testAddr,
  1028  		To:   &addr,
  1029  		Data: input,
  1030  	})
  1031  	if err != nil {
  1032  		t.Errorf("could not call receive method on contract: %v", err)
  1033  	}
  1034  	if len(res) == 0 {
  1035  		t.Errorf("result of contract call was empty: %v", res)
  1036  	}
  1037  
  1038  	// while comparing against the byte array is more exact, also compare against the human readable string for readability
  1039  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
  1040  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
  1041  	}
  1042  
  1043  	sim.Commit()
  1044  
  1045  	// make sure you can call the contract
  1046  	res, err = sim.CallContract(bgCtx, ethereum.CallMsg{
  1047  		From: testAddr,
  1048  		To:   &addr,
  1049  		Data: input,
  1050  	}, nil)
  1051  	if err != nil {
  1052  		t.Errorf("could not call receive method on contract: %v", err)
  1053  	}
  1054  	if len(res) == 0 {
  1055  		t.Errorf("result of contract call was empty: %v", res)
  1056  	}
  1057  
  1058  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
  1059  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
  1060  	}
  1061  }
  1062  
  1063  // This test is based on the following contract:
  1064  /*
  1065  contract Reverter {
  1066      function revertString() public pure{
  1067          require(false, "some error");
  1068      }
  1069      function revertNoString() public pure {
  1070          require(false, "");
  1071      }
  1072      function revertASM() public pure {
  1073          assembly {
  1074              revert(0x0, 0x0)
  1075          }
  1076      }
  1077      function noRevert() public pure {
  1078          assembly {
  1079              // Assembles something that looks like require(false, "some error") but is not reverted
  1080              mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
  1081              mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020)
  1082              mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a)
  1083              mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000)
  1084              return(0x0, 0x64)
  1085          }
  1086      }
  1087  }*/
  1088  func TestCallContractRevert(t *testing.T) {
  1089  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  1090  	sim := simTestBackend(testAddr)
  1091  	defer sim.Close()
  1092  	bgCtx := context.Background()
  1093  
  1094  	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"}]`
  1095  	reverterBin := "608060405234801561001057600080fd5b506101d3806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634b409e01146100515780639b340e361461005b5780639bd6103714610065578063b7246fc11461006f575b600080fd5b610059610079565b005b6100636100ca565b005b61006d6100cf565b005b610077610145565b005b60006100c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526000815260200160200191505060405180910390fd5b565b600080fd5b6000610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f736f6d65206572726f720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f3fea2646970667358221220cdd8af0609ec4996b7360c7c780bad5c735740c64b1fffc3445aa12d37f07cb164736f6c63430006070033"
  1096  
  1097  	parsed, err := abi.JSON(strings.NewReader(reverterABI))
  1098  	if err != nil {
  1099  		t.Errorf("could not get code at test addr: %v", err)
  1100  	}
  1101  	contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
  1102  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim)
  1103  	if err != nil {
  1104  		t.Errorf("could not deploy contract: %v", err)
  1105  	}
  1106  
  1107  	inputs := make(map[string]interface{}, 3)
  1108  	inputs["revertASM"] = nil
  1109  	inputs["revertNoString"] = ""
  1110  	inputs["revertString"] = "some error"
  1111  
  1112  	call := make([]func([]byte) ([]byte, error), 2)
  1113  	call[0] = func(input []byte) ([]byte, error) {
  1114  		return sim.PendingCallContract(bgCtx, ethereum.CallMsg{
  1115  			From: testAddr,
  1116  			To:   &addr,
  1117  			Data: input,
  1118  		})
  1119  	}
  1120  	call[1] = func(input []byte) ([]byte, error) {
  1121  		return sim.CallContract(bgCtx, ethereum.CallMsg{
  1122  			From: testAddr,
  1123  			To:   &addr,
  1124  			Data: input,
  1125  		}, nil)
  1126  	}
  1127  
  1128  	// Run pending calls then commit
  1129  	for _, cl := range call {
  1130  		for key, val := range inputs {
  1131  			input, err := parsed.Pack(key)
  1132  			if err != nil {
  1133  				t.Errorf("could not pack %v function on contract: %v", key, err)
  1134  			}
  1135  
  1136  			res, err := cl(input)
  1137  			if err == nil {
  1138  				t.Errorf("call to %v was not reverted", key)
  1139  			}
  1140  			if res != nil {
  1141  				t.Errorf("result from %v was not nil: %v", key, res)
  1142  			}
  1143  			if val != nil {
  1144  				rerr, ok := err.(*revertError)
  1145  				if !ok {
  1146  					t.Errorf("expect revert error")
  1147  				}
  1148  				if rerr.Error() != "execution reverted: "+val.(string) {
  1149  					t.Errorf("error was malformed: got %v want %v", rerr.Error(), val)
  1150  				}
  1151  			} else {
  1152  				// revert(0x0,0x0)
  1153  				if err.Error() != "execution reverted" {
  1154  					t.Errorf("error was malformed: got %v want %v", err, "execution reverted")
  1155  				}
  1156  			}
  1157  		}
  1158  		input, err := parsed.Pack("noRevert")
  1159  		if err != nil {
  1160  			t.Errorf("could not pack noRevert function on contract: %v", err)
  1161  		}
  1162  		res, err := cl(input)
  1163  		if err != nil {
  1164  			t.Error("call to noRevert was reverted")
  1165  		}
  1166  		if res == nil {
  1167  			t.Errorf("result from noRevert was nil")
  1168  		}
  1169  		sim.Commit()
  1170  	}
  1171  }
  1172  
  1173  // TestFork check that the chain length after a reorg is correct.
  1174  // Steps:
  1175  //  1. Save the current block which will serve as parent for the fork.
  1176  //  2. Mine n blocks with n ∈ [0, 20].
  1177  //  3. Assert that the chain length is n.
  1178  //  4. Fork by using the parent block as ancestor.
  1179  //  5. Mine n+1 blocks which should trigger a reorg.
  1180  //  6. Assert that the chain length is n+1.
  1181  //     Since Commit() was called 2n+1 times in total,
  1182  //     having a chain length of just n+1 means that a reorg occurred.
  1183  func TestFork(t *testing.T) {
  1184  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  1185  	sim := simTestBackend(testAddr)
  1186  	defer sim.Close()
  1187  	// 1.
  1188  	parent := sim.blockchain.CurrentBlock()
  1189  	// 2.
  1190  	n := int(rand.Int31n(21))
  1191  	for i := 0; i < n; i++ {
  1192  		sim.Commit()
  1193  	}
  1194  	// 3.
  1195  	if sim.blockchain.CurrentBlock().NumberU64() != uint64(n) {
  1196  		t.Error("wrong chain length")
  1197  	}
  1198  	// 4.
  1199  	sim.Fork(context.Background(), parent.Hash())
  1200  	// 5.
  1201  	for i := 0; i < n+1; i++ {
  1202  		sim.Commit()
  1203  	}
  1204  	// 6.
  1205  	if sim.blockchain.CurrentBlock().NumberU64() != uint64(n+1) {
  1206  		t.Error("wrong chain length")
  1207  	}
  1208  }
  1209  
  1210  /*
  1211  Example contract to test event emission:
  1212  
  1213  pragma solidity >=0.7.0 <0.9.0;
  1214  contract Callable {
  1215      event Called();
  1216      function Call() public { emit Called(); }
  1217  }
  1218  */
  1219  const callableAbi = "[{\"anonymous\":false,\"inputs\":[],\"name\":\"Called\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
  1220  
  1221  const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806334e2292114602d575b600080fd5b60336035565b005b7f81fab7a4a0aa961db47eefc81f143a5220e8c8495260dd65b1356f1d19d3c7b860405160405180910390a156fea2646970667358221220029436d24f3ac598ceca41d4d712e13ced6d70727f4cdc580667de66d2f51d8b64736f6c63430008010033"
  1222  
  1223  // TestForkLogsReborn check that the simulated reorgs
  1224  // correctly remove and reborn logs.
  1225  // Steps:
  1226  //  1. Deploy the Callable contract.
  1227  //  2. Set up an event subscription.
  1228  //  3. Save the current block which will serve as parent for the fork.
  1229  //  4. Send a transaction.
  1230  //  5. Check that the event was included.
  1231  //  6. Fork by using the parent block as ancestor.
  1232  //  7. Mine two blocks to trigger a reorg.
  1233  //  8. Check that the event was removed.
  1234  //  9. Re-send the transaction and mine a block.
  1235  // 10. Check that the event was reborn.
  1236  func TestForkLogsReborn(t *testing.T) {
  1237  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  1238  	sim := simTestBackend(testAddr)
  1239  	defer sim.Close()
  1240  	// 1.
  1241  	parsed, _ := abi.JSON(strings.NewReader(callableAbi))
  1242  	auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
  1243  	_, _, contract, err := bind.DeployContract(auth, parsed, common.FromHex(callableBin), sim)
  1244  	if err != nil {
  1245  		t.Errorf("deploying contract: %v", err)
  1246  	}
  1247  	sim.Commit()
  1248  	// 2.
  1249  	logs, sub, err := contract.WatchLogs(nil, "Called")
  1250  	if err != nil {
  1251  		t.Errorf("watching logs: %v", err)
  1252  	}
  1253  	defer sub.Unsubscribe()
  1254  	// 3.
  1255  	parent := sim.blockchain.CurrentBlock()
  1256  	// 4.
  1257  	tx, err := contract.Transact(auth, "Call")
  1258  	if err != nil {
  1259  		t.Errorf("transacting: %v", err)
  1260  	}
  1261  	sim.Commit()
  1262  	// 5.
  1263  	log := <-logs
  1264  	if log.TxHash != tx.Hash() {
  1265  		t.Error("wrong event tx hash")
  1266  	}
  1267  	if log.Removed {
  1268  		t.Error("Event should be included")
  1269  	}
  1270  	// 6.
  1271  	if err := sim.Fork(context.Background(), parent.Hash()); err != nil {
  1272  		t.Errorf("forking: %v", err)
  1273  	}
  1274  	// 7.
  1275  	sim.Commit()
  1276  	sim.Commit()
  1277  	// 8.
  1278  	log = <-logs
  1279  	if log.TxHash != tx.Hash() {
  1280  		t.Error("wrong event tx hash")
  1281  	}
  1282  	if !log.Removed {
  1283  		t.Error("Event should be removed")
  1284  	}
  1285  	// 9.
  1286  	if err := sim.SendTransaction(context.Background(), tx); err != nil {
  1287  		t.Errorf("sending transaction: %v", err)
  1288  	}
  1289  	sim.Commit()
  1290  	// 10.
  1291  	log = <-logs
  1292  	if log.TxHash != tx.Hash() {
  1293  		t.Error("wrong event tx hash")
  1294  	}
  1295  	if log.Removed {
  1296  		t.Error("Event should be included")
  1297  	}
  1298  }
  1299  
  1300  // TestForkResendTx checks that re-sending a TX after a fork
  1301  // is possible and does not cause a "nonce mismatch" panic.
  1302  // Steps:
  1303  //  1. Save the current block which will serve as parent for the fork.
  1304  //  2. Send a transaction.
  1305  //  3. Check that the TX is included in block 1.
  1306  //  4. Fork by using the parent block as ancestor.
  1307  //  5. Mine a block, Re-send the transaction and mine another one.
  1308  //  6. Check that the TX is now included in block 2.
  1309  func TestForkResendTx(t *testing.T) {
  1310  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  1311  	sim := simTestBackend(testAddr)
  1312  	defer sim.Close()
  1313  	// 1.
  1314  	parent := sim.blockchain.CurrentBlock()
  1315  	// 2.
  1316  	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
  1317  	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
  1318  
  1319  	_tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
  1320  	tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey)
  1321  	sim.SendTransaction(context.Background(), tx)
  1322  	sim.Commit()
  1323  	// 3.
  1324  	receipt, _ := sim.TransactionReceipt(context.Background(), tx.Hash())
  1325  	if h := receipt.BlockNumber.Uint64(); h != 1 {
  1326  		t.Errorf("TX included in wrong block: %d", h)
  1327  	}
  1328  	// 4.
  1329  	if err := sim.Fork(context.Background(), parent.Hash()); err != nil {
  1330  		t.Errorf("forking: %v", err)
  1331  	}
  1332  	// 5.
  1333  	sim.Commit()
  1334  	if err := sim.SendTransaction(context.Background(), tx); err != nil {
  1335  		t.Errorf("sending transaction: %v", err)
  1336  	}
  1337  	sim.Commit()
  1338  	// 6.
  1339  	receipt, _ = sim.TransactionReceipt(context.Background(), tx.Hash())
  1340  	if h := receipt.BlockNumber.Uint64(); h != 2 {
  1341  		t.Errorf("TX included in wrong block: %d", h)
  1342  	}
  1343  }