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