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