github.com/ava-labs/subnet-evm@v0.6.4/accounts/abi/bind/backends/simulated.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2015 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package backends
    28  
    29  import (
    30  	"context"
    31  	"errors"
    32  	"fmt"
    33  	"math/big"
    34  	"sync"
    35  	"time"
    36  
    37  	"github.com/ava-labs/subnet-evm/eth"
    38  	"github.com/ava-labs/subnet-evm/vmerrs"
    39  
    40  	"github.com/ava-labs/subnet-evm/accounts/abi"
    41  	"github.com/ava-labs/subnet-evm/accounts/abi/bind"
    42  	"github.com/ava-labs/subnet-evm/consensus/dummy"
    43  	"github.com/ava-labs/subnet-evm/core"
    44  	"github.com/ava-labs/subnet-evm/core/bloombits"
    45  	"github.com/ava-labs/subnet-evm/core/rawdb"
    46  	"github.com/ava-labs/subnet-evm/core/state"
    47  	"github.com/ava-labs/subnet-evm/core/types"
    48  	"github.com/ava-labs/subnet-evm/core/vm"
    49  	"github.com/ava-labs/subnet-evm/eth/filters"
    50  	"github.com/ava-labs/subnet-evm/interfaces"
    51  	"github.com/ava-labs/subnet-evm/params"
    52  	"github.com/ava-labs/subnet-evm/rpc"
    53  	"github.com/ethereum/go-ethereum/common"
    54  	"github.com/ethereum/go-ethereum/common/hexutil"
    55  	"github.com/ethereum/go-ethereum/common/math"
    56  	"github.com/ethereum/go-ethereum/ethdb"
    57  	"github.com/ethereum/go-ethereum/event"
    58  	"github.com/ethereum/go-ethereum/log"
    59  )
    60  
    61  // Verify that SimulatedBackend implements required interfaces
    62  var (
    63  	_ bind.AcceptedContractCaller = (*SimulatedBackend)(nil)
    64  	_ bind.ContractBackend        = (*SimulatedBackend)(nil)
    65  	_ bind.DeployBackend          = (*SimulatedBackend)(nil)
    66  
    67  	_ interfaces.ChainReader            = (*SimulatedBackend)(nil)
    68  	_ interfaces.ChainStateReader       = (*SimulatedBackend)(nil)
    69  	_ interfaces.TransactionReader      = (*SimulatedBackend)(nil)
    70  	_ interfaces.TransactionSender      = (*SimulatedBackend)(nil)
    71  	_ interfaces.ContractCaller         = (*SimulatedBackend)(nil)
    72  	_ interfaces.GasEstimator           = (*SimulatedBackend)(nil)
    73  	_ interfaces.GasPricer              = (*SimulatedBackend)(nil)
    74  	_ interfaces.LogFilterer            = (*SimulatedBackend)(nil)
    75  	_ interfaces.AcceptedStateReader    = (*SimulatedBackend)(nil)
    76  	_ interfaces.AcceptedContractCaller = (*SimulatedBackend)(nil)
    77  )
    78  
    79  var (
    80  	errBlockNumberUnsupported  = errors.New("simulatedBackend cannot access blocks other than the latest block")
    81  	errBlockDoesNotExist       = errors.New("block does not exist in blockchain")
    82  	errTransactionDoesNotExist = errors.New("transaction does not exist")
    83  )
    84  
    85  // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in
    86  // the background. Its main purpose is to allow for easy testing of contract bindings.
    87  // Simulated backend implements the following interfaces:
    88  // ChainReader, ChainStateReader, ContractBackend, ContractCaller, ContractFilterer, ContractTransactor,
    89  // DeployBackend, GasEstimator, GasPricer, LogFilterer, AcceptedContractCaller, TransactionReader, and TransactionSender
    90  type SimulatedBackend struct {
    91  	database   ethdb.Database   // In memory database to store our testing data
    92  	blockchain *core.BlockChain // Ethereum blockchain to handle the consensus
    93  
    94  	mu            sync.Mutex
    95  	acceptedBlock *types.Block   // Currently accepted block that will be imported on request
    96  	acceptedState *state.StateDB // Currently accepted state that will be the active on request
    97  
    98  	events       *filters.EventSystem  // for filtering log events live
    99  	filterSystem *filters.FilterSystem // for filtering database logs
   100  
   101  	config *params.ChainConfig
   102  }
   103  
   104  // NewSimulatedBackendWithDatabase creates a new binding backend based on the given database
   105  // and uses a simulated blockchain for testing purposes.
   106  // A simulated backend always uses chainID 1337.
   107  func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
   108  	copyConfig := *params.TestChainConfig
   109  	copyConfig.ChainID = big.NewInt(1337)
   110  	genesis := core.Genesis{
   111  		Config:   &copyConfig,
   112  		GasLimit: gasLimit,
   113  		Alloc:    alloc,
   114  	}
   115  	cacheConfig := &core.CacheConfig{}
   116  	blockchain, _ := core.NewBlockChain(database, cacheConfig, &genesis, dummy.NewCoinbaseFaker(), vm.Config{}, common.Hash{}, false)
   117  
   118  	backend := &SimulatedBackend{
   119  		database:   database,
   120  		blockchain: blockchain,
   121  		config:     genesis.Config,
   122  	}
   123  
   124  	filterBackend := &filterBackend{database, blockchain, backend}
   125  	backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
   126  	backend.events = filters.NewEventSystem(backend.filterSystem)
   127  
   128  	header := backend.blockchain.CurrentBlock()
   129  	block := backend.blockchain.GetBlock(header.Hash(), header.Number.Uint64())
   130  
   131  	backend.rollback(block)
   132  	return backend
   133  }
   134  
   135  // NewSimulatedBackend creates a new binding backend using a simulated blockchain
   136  // for testing purposes.
   137  // A simulated backend always uses chainID 1337.
   138  func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
   139  	return NewSimulatedBackendWithDatabase(rawdb.NewMemoryDatabase(), alloc, gasLimit)
   140  }
   141  
   142  // Close terminates the underlying blockchain's update loop.
   143  func (b *SimulatedBackend) Close() error {
   144  	b.blockchain.Stop()
   145  	return nil
   146  }
   147  
   148  // Commit imports all the accepted transactions as a single block and starts a
   149  // fresh new state.
   150  func (b *SimulatedBackend) Commit(accept bool) common.Hash {
   151  	b.mu.Lock()
   152  	defer b.mu.Unlock()
   153  
   154  	if _, err := b.blockchain.InsertChain([]*types.Block{b.acceptedBlock}); err != nil {
   155  		panic(err) // This cannot happen unless the simulator is wrong, fail in that case
   156  	}
   157  	if accept {
   158  		if err := b.blockchain.Accept(b.acceptedBlock); err != nil {
   159  			panic(err)
   160  		}
   161  		b.blockchain.DrainAcceptorQueue()
   162  	}
   163  	blockHash := b.acceptedBlock.Hash()
   164  
   165  	// Using the last inserted block here makes it possible to build on a side
   166  	// chain after a fork.
   167  	b.rollback(b.acceptedBlock)
   168  
   169  	return blockHash
   170  }
   171  
   172  // Rollback aborts all accepted transactions, reverting to the last committed state.
   173  func (b *SimulatedBackend) Rollback() {
   174  	b.mu.Lock()
   175  	defer b.mu.Unlock()
   176  
   177  	header := b.blockchain.CurrentBlock()
   178  	block := b.blockchain.GetBlock(header.Hash(), header.Number.Uint64())
   179  
   180  	b.rollback(block)
   181  }
   182  
   183  func (b *SimulatedBackend) rollback(parent *types.Block) {
   184  	blocks, _, _ := core.GenerateChain(b.config, parent, dummy.NewFaker(), b.database, 1, 10, func(int, *core.BlockGen) {})
   185  
   186  	b.acceptedBlock = blocks[0]
   187  	b.acceptedState, _ = state.New(b.acceptedBlock.Root(), b.blockchain.StateCache(), nil)
   188  }
   189  
   190  // Fork creates a side-chain that can be used to simulate reorgs.
   191  //
   192  // This function should be called with the ancestor block where the new side
   193  // chain should be started. Transactions (old and new) can then be applied on
   194  // top and Commit-ed.
   195  //
   196  // Note, the side-chain will only become canonical (and trigger the events) when
   197  // it becomes longer. Until then CallContract will still operate on the current
   198  // canonical chain.
   199  //
   200  // There is a % chance that the side chain becomes canonical at the same length
   201  // to simulate live network behavior.
   202  func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error {
   203  	b.mu.Lock()
   204  	defer b.mu.Unlock()
   205  
   206  	if len(b.acceptedBlock.Transactions()) != 0 {
   207  		return errors.New("accepted block dirty")
   208  	}
   209  	block, err := b.blockByHash(ctx, parent)
   210  	if err != nil {
   211  		return err
   212  	}
   213  	b.rollback(block)
   214  	return nil
   215  }
   216  
   217  // stateByBlockNumber retrieves a state by a given blocknumber.
   218  func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) {
   219  	if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number) == 0 {
   220  		return b.blockchain.State()
   221  	}
   222  	block, err := b.blockByNumber(ctx, blockNumber)
   223  	if err != nil {
   224  		return nil, err
   225  	}
   226  	return b.blockchain.StateAt(block.Root())
   227  }
   228  
   229  // CodeAt returns the code associated with a certain account in the blockchain.
   230  func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
   231  	b.mu.Lock()
   232  	defer b.mu.Unlock()
   233  
   234  	stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
   235  	if err != nil {
   236  		return nil, err
   237  	}
   238  	return stateDB.GetCode(contract), nil
   239  }
   240  
   241  // BalanceAt returns the wei balance of a certain account in the blockchain.
   242  func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) {
   243  	b.mu.Lock()
   244  	defer b.mu.Unlock()
   245  
   246  	stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
   247  	if err != nil {
   248  		return nil, err
   249  	}
   250  	return stateDB.GetBalance(contract), nil
   251  }
   252  
   253  // NonceAt returns the nonce of a certain account in the blockchain.
   254  func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (uint64, error) {
   255  	b.mu.Lock()
   256  	defer b.mu.Unlock()
   257  
   258  	stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
   259  	if err != nil {
   260  		return 0, err
   261  	}
   262  	return stateDB.GetNonce(contract), nil
   263  }
   264  
   265  // StorageAt returns the value of key in the storage of an account in the blockchain.
   266  func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) {
   267  	b.mu.Lock()
   268  	defer b.mu.Unlock()
   269  
   270  	stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
   271  	if err != nil {
   272  		return nil, err
   273  	}
   274  	val := stateDB.GetState(contract, key)
   275  	return val[:], nil
   276  }
   277  
   278  // TransactionReceipt returns the receipt of a transaction.
   279  func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
   280  	b.mu.Lock()
   281  	defer b.mu.Unlock()
   282  
   283  	receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash, b.config)
   284  	if receipt == nil {
   285  		return nil, interfaces.NotFound
   286  	}
   287  	return receipt, nil
   288  }
   289  
   290  // TransactionByHash checks the pool of accepted transactions in addition to the
   291  // blockchain. The isAccepted return value indicates whether the transaction has been
   292  // mined yet. Note that the transaction may not be part of the canonical chain even if
   293  // it's not accepted.
   294  func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) {
   295  	b.mu.Lock()
   296  	defer b.mu.Unlock()
   297  
   298  	tx := b.acceptedBlock.Transaction(txHash)
   299  	if tx != nil {
   300  		return tx, true, nil
   301  	}
   302  	tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash)
   303  	if tx != nil {
   304  		return tx, false, nil
   305  	}
   306  	return nil, false, interfaces.NotFound
   307  }
   308  
   309  // BlockByHash retrieves a block based on the block hash.
   310  func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
   311  	b.mu.Lock()
   312  	defer b.mu.Unlock()
   313  
   314  	return b.blockByHash(ctx, hash)
   315  }
   316  
   317  // blockByHash retrieves a block based on the block hash without Locking.
   318  func (b *SimulatedBackend) blockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
   319  	if hash == b.acceptedBlock.Hash() {
   320  		return b.acceptedBlock, nil
   321  	}
   322  
   323  	block := b.blockchain.GetBlockByHash(hash)
   324  	if block != nil {
   325  		return block, nil
   326  	}
   327  
   328  	return nil, errBlockDoesNotExist
   329  }
   330  
   331  // BlockByNumber retrieves a block from the database by number, caching it
   332  // (associated with its hash) if found.
   333  func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
   334  	b.mu.Lock()
   335  	defer b.mu.Unlock()
   336  
   337  	return b.blockByNumber(ctx, number)
   338  }
   339  
   340  // blockByNumber retrieves a block from the database by number, caching it
   341  // (associated with its hash) if found without Lock.
   342  func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
   343  	if number == nil || number.Cmp(b.acceptedBlock.Number()) == 0 {
   344  		return b.blockByHash(ctx, b.blockchain.CurrentBlock().Hash())
   345  	}
   346  
   347  	block := b.blockchain.GetBlockByNumber(uint64(number.Int64()))
   348  	if block == nil {
   349  		return nil, errBlockDoesNotExist
   350  	}
   351  
   352  	return block, nil
   353  }
   354  
   355  // HeaderByHash returns a block header from the current canonical chain.
   356  func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
   357  	b.mu.Lock()
   358  	defer b.mu.Unlock()
   359  
   360  	if hash == b.acceptedBlock.Hash() {
   361  		return b.acceptedBlock.Header(), nil
   362  	}
   363  
   364  	header := b.blockchain.GetHeaderByHash(hash)
   365  	if header == nil {
   366  		return nil, errBlockDoesNotExist
   367  	}
   368  
   369  	return header, nil
   370  }
   371  
   372  // HeaderByNumber returns a block header from the current canonical chain. If number is
   373  // nil, the latest known header is returned.
   374  func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) {
   375  	b.mu.Lock()
   376  	defer b.mu.Unlock()
   377  
   378  	if block == nil || block.Cmp(b.acceptedBlock.Number()) == 0 {
   379  		return b.blockchain.CurrentHeader(), nil
   380  	}
   381  
   382  	return b.blockchain.GetHeaderByNumber(uint64(block.Int64())), nil
   383  }
   384  
   385  // TransactionCount returns the number of transactions in a given block.
   386  func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) {
   387  	b.mu.Lock()
   388  	defer b.mu.Unlock()
   389  
   390  	if blockHash == b.acceptedBlock.Hash() {
   391  		return uint(b.acceptedBlock.Transactions().Len()), nil
   392  	}
   393  
   394  	block := b.blockchain.GetBlockByHash(blockHash)
   395  	if block == nil {
   396  		return uint(0), errBlockDoesNotExist
   397  	}
   398  
   399  	return uint(block.Transactions().Len()), nil
   400  }
   401  
   402  // TransactionInBlock returns the transaction for a specific block at a specific index.
   403  func (b *SimulatedBackend) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) {
   404  	b.mu.Lock()
   405  	defer b.mu.Unlock()
   406  
   407  	if blockHash == b.acceptedBlock.Hash() {
   408  		transactions := b.acceptedBlock.Transactions()
   409  		if uint(len(transactions)) < index+1 {
   410  			return nil, errTransactionDoesNotExist
   411  		}
   412  
   413  		return transactions[index], nil
   414  	}
   415  
   416  	block := b.blockchain.GetBlockByHash(blockHash)
   417  	if block == nil {
   418  		return nil, errBlockDoesNotExist
   419  	}
   420  
   421  	transactions := block.Transactions()
   422  	if uint(len(transactions)) < index+1 {
   423  		return nil, errTransactionDoesNotExist
   424  	}
   425  
   426  	return transactions[index], nil
   427  }
   428  
   429  // AcceptedCodeAt returns the code associated with an account in the accepted state.
   430  func (b *SimulatedBackend) AcceptedCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
   431  	b.mu.Lock()
   432  	defer b.mu.Unlock()
   433  
   434  	return b.acceptedState.GetCode(contract), nil
   435  }
   436  
   437  func newRevertError(result *core.ExecutionResult) *revertError {
   438  	reason, errUnpack := abi.UnpackRevert(result.Revert())
   439  	err := errors.New("execution reverted")
   440  	if errUnpack == nil {
   441  		err = fmt.Errorf("execution reverted: %v", reason)
   442  	}
   443  	return &revertError{
   444  		error:  err,
   445  		reason: hexutil.Encode(result.Revert()),
   446  	}
   447  }
   448  
   449  // revertError is an API error that encompasses an EVM revert with JSON error
   450  // code and a binary data blob.
   451  type revertError struct {
   452  	error
   453  	reason string // revert reason hex encoded
   454  }
   455  
   456  // ErrorCode returns the JSON error code for a revert.
   457  // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
   458  func (e *revertError) ErrorCode() int {
   459  	return 3
   460  }
   461  
   462  // ErrorData returns the hex encoded revert reason.
   463  func (e *revertError) ErrorData() interface{} {
   464  	return e.reason
   465  }
   466  
   467  // CallContract executes a contract call.
   468  func (b *SimulatedBackend) CallContract(ctx context.Context, call interfaces.CallMsg, blockNumber *big.Int) ([]byte, error) {
   469  	b.mu.Lock()
   470  	defer b.mu.Unlock()
   471  
   472  	if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number) != 0 {
   473  		return nil, errBlockNumberUnsupported
   474  	}
   475  	stateDB, err := b.blockchain.State()
   476  	if err != nil {
   477  		return nil, err
   478  	}
   479  	res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB)
   480  	if err != nil {
   481  		return nil, err
   482  	}
   483  	// If the result contains a revert reason, try to unpack and return it.
   484  	if len(res.Revert()) > 0 {
   485  		return nil, newRevertError(res)
   486  	}
   487  	return res.Return(), res.Err
   488  }
   489  
   490  // AcceptedCallContract executes a contract call on the accepted state.
   491  func (b *SimulatedBackend) AcceptedCallContract(ctx context.Context, call interfaces.CallMsg) ([]byte, error) {
   492  	b.mu.Lock()
   493  	defer b.mu.Unlock()
   494  	defer b.acceptedState.RevertToSnapshot(b.acceptedState.Snapshot())
   495  
   496  	res, err := b.callContract(ctx, call, b.acceptedBlock.Header(), b.acceptedState)
   497  	if err != nil {
   498  		return nil, err
   499  	}
   500  	// If the result contains a revert reason, try to unpack and return it.
   501  	if len(res.Revert()) > 0 {
   502  		return nil, newRevertError(res)
   503  	}
   504  	return res.Return(), res.Err
   505  }
   506  
   507  // AcceptedNonceAt implements AcceptedStateReader.AcceptedNonceAt, retrieving
   508  // the nonce currently accepted for the account.
   509  func (b *SimulatedBackend) AcceptedNonceAt(ctx context.Context, account common.Address) (uint64, error) {
   510  	b.mu.Lock()
   511  	defer b.mu.Unlock()
   512  
   513  	return b.acceptedState.GetOrNewStateObject(account).Nonce(), nil
   514  }
   515  
   516  // SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
   517  // chain doesn't have miners, we just return a gas price of 1 for any call.
   518  func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
   519  	b.mu.Lock()
   520  	defer b.mu.Unlock()
   521  
   522  	if b.acceptedBlock.Header().BaseFee != nil {
   523  		return b.acceptedBlock.Header().BaseFee, nil
   524  	}
   525  	return big.NewInt(1), nil
   526  }
   527  
   528  // SuggestGasTipCap implements ContractTransactor.SuggestGasTipCap. Since the simulated
   529  // chain doesn't have miners, we just return a gas tip of 1 for any call.
   530  func (b *SimulatedBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
   531  	return big.NewInt(1), nil
   532  }
   533  
   534  // EstimateGas executes the requested code against the currently accepted block/state and
   535  // returns the used amount of gas.
   536  func (b *SimulatedBackend) EstimateGas(ctx context.Context, call interfaces.CallMsg) (uint64, error) {
   537  	b.mu.Lock()
   538  	defer b.mu.Unlock()
   539  
   540  	// Determine the lowest and highest possible gas limits to binary search in between
   541  	var (
   542  		lo  uint64 = params.TxGas - 1
   543  		hi  uint64
   544  		cap uint64
   545  	)
   546  	if call.Gas >= params.TxGas {
   547  		hi = call.Gas
   548  	} else {
   549  		hi = b.acceptedBlock.GasLimit()
   550  	}
   551  	// Normalize the max fee per gas the call is willing to spend.
   552  	var feeCap *big.Int
   553  	if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
   554  		return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
   555  	} else if call.GasPrice != nil {
   556  		feeCap = call.GasPrice
   557  	} else if call.GasFeeCap != nil {
   558  		feeCap = call.GasFeeCap
   559  	} else {
   560  		feeCap = common.Big0
   561  	}
   562  	// Recap the highest gas allowance with account's balance.
   563  	if feeCap.BitLen() != 0 {
   564  		balance := b.acceptedState.GetBalance(call.From) // from can't be nil
   565  		available := new(big.Int).Set(balance)
   566  		if call.Value != nil {
   567  			if call.Value.Cmp(available) >= 0 {
   568  				return 0, core.ErrInsufficientFundsForTransfer
   569  			}
   570  			available.Sub(available, call.Value)
   571  		}
   572  		allowance := new(big.Int).Div(available, feeCap)
   573  		if allowance.IsUint64() && hi > allowance.Uint64() {
   574  			transfer := call.Value
   575  			if transfer == nil {
   576  				transfer = new(big.Int)
   577  			}
   578  			log.Info("Gas estimation capped by limited funds", "original", hi, "balance", balance,
   579  				"sent", transfer, "feecap", feeCap, "fundable", allowance)
   580  			hi = allowance.Uint64()
   581  		}
   582  	}
   583  	cap = hi
   584  
   585  	// Create a helper to check if a gas allowance results in an executable transaction
   586  	executable := func(gas uint64) (bool, *core.ExecutionResult, error) {
   587  		call.Gas = gas
   588  
   589  		snapshot := b.acceptedState.Snapshot()
   590  		res, err := b.callContract(ctx, call, b.acceptedBlock.Header(), b.acceptedState)
   591  		b.acceptedState.RevertToSnapshot(snapshot)
   592  
   593  		if err != nil {
   594  			if errors.Is(err, core.ErrIntrinsicGas) {
   595  				return true, nil, nil // Special case, raise gas limit
   596  			}
   597  			return true, nil, err // Bail out
   598  		}
   599  		return res.Failed(), res, nil
   600  	}
   601  	// Execute the binary search and hone in on an executable gas limit
   602  	for lo+1 < hi {
   603  		mid := (hi + lo) / 2
   604  		failed, _, err := executable(mid)
   605  
   606  		// If the error is not nil(consensus error), it means the provided message
   607  		// call or transaction will never be accepted no matter how much gas it is
   608  		// assigned. Return the error directly, don't struggle any more
   609  		if err != nil {
   610  			return 0, err
   611  		}
   612  		if failed {
   613  			lo = mid
   614  		} else {
   615  			hi = mid
   616  		}
   617  	}
   618  	// Reject the transaction as invalid if it still fails at the highest allowance
   619  	if hi == cap {
   620  		failed, result, err := executable(hi)
   621  		if err != nil {
   622  			return 0, err
   623  		}
   624  		if failed {
   625  			if result != nil && result.Err != vmerrs.ErrOutOfGas {
   626  				if len(result.Revert()) > 0 {
   627  					return 0, newRevertError(result)
   628  				}
   629  				return 0, result.Err
   630  			}
   631  			// Otherwise, the specified gas cap is too low
   632  			return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap)
   633  		}
   634  	}
   635  	return hi, nil
   636  }
   637  
   638  // callContract implements common code between normal and accepted contract calls.
   639  // state is modified during execution, make sure to copy it if necessary.
   640  func (b *SimulatedBackend) callContract(ctx context.Context, call interfaces.CallMsg, header *types.Header, stateDB *state.StateDB) (*core.ExecutionResult, error) {
   641  	// Gas prices post 1559 need to be initialized
   642  	if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
   643  		return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
   644  	}
   645  	head := b.blockchain.CurrentHeader()
   646  	if !b.blockchain.Config().IsSubnetEVM(head.Time) {
   647  		// If there's no basefee, then it must be a non-1559 execution
   648  		if call.GasPrice == nil {
   649  			call.GasPrice = new(big.Int)
   650  		}
   651  		call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
   652  	} else {
   653  		// A basefee is provided, necessitating 1559-type execution
   654  		if call.GasPrice != nil {
   655  			// User specified the legacy gas field, convert to 1559 gas typing
   656  			call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
   657  		} else {
   658  			// User specified 1559 gas fields (or none), use those
   659  			if call.GasFeeCap == nil {
   660  				call.GasFeeCap = new(big.Int)
   661  			}
   662  			if call.GasTipCap == nil {
   663  				call.GasTipCap = new(big.Int)
   664  			}
   665  			// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
   666  			call.GasPrice = new(big.Int)
   667  			if call.GasFeeCap.BitLen() > 0 || call.GasTipCap.BitLen() > 0 {
   668  				call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, head.BaseFee), call.GasFeeCap)
   669  			}
   670  		}
   671  	}
   672  	// Ensure message is initialized properly.
   673  	if call.Gas == 0 {
   674  		call.Gas = 50000000
   675  	}
   676  	if call.Value == nil {
   677  		call.Value = new(big.Int)
   678  	}
   679  
   680  	// Set infinite balance to the fake caller account.
   681  	from := stateDB.GetOrNewStateObject(call.From)
   682  	from.SetBalance(math.MaxBig256)
   683  
   684  	// Execute the call.
   685  	msg := &core.Message{
   686  		From:              call.From,
   687  		To:                call.To,
   688  		Value:             call.Value,
   689  		GasLimit:          call.Gas,
   690  		GasPrice:          call.GasPrice,
   691  		GasFeeCap:         call.GasFeeCap,
   692  		GasTipCap:         call.GasTipCap,
   693  		Data:              call.Data,
   694  		AccessList:        call.AccessList,
   695  		SkipAccountChecks: true,
   696  	}
   697  
   698  	// Create a new environment which holds all relevant information
   699  	// about the transaction and calling mechanisms.
   700  	txContext := core.NewEVMTxContext(msg)
   701  	evmContext := core.NewEVMBlockContext(header, b.blockchain, nil)
   702  	vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
   703  	gasPool := new(core.GasPool).AddGas(math.MaxUint64)
   704  
   705  	return core.ApplyMessage(vmEnv, msg, gasPool)
   706  }
   707  
   708  // SendTransaction updates the accepted block to include the given transaction.
   709  func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error {
   710  	b.mu.Lock()
   711  	defer b.mu.Unlock()
   712  
   713  	// Get the last block
   714  	block, err := b.blockByHash(ctx, b.acceptedBlock.ParentHash())
   715  	if err != nil {
   716  		return errors.New("could not fetch parent")
   717  	}
   718  	// Check transaction validity
   719  	signer := types.MakeSigner(b.blockchain.Config(), block.Number(), block.Time())
   720  	sender, err := types.Sender(signer, tx)
   721  	if err != nil {
   722  		return fmt.Errorf("invalid transaction: %v", err)
   723  	}
   724  	nonce := b.acceptedState.GetNonce(sender)
   725  	if tx.Nonce() != nonce {
   726  		return fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce)
   727  	}
   728  	// Include tx in chain
   729  	blocks, _, err := core.GenerateChain(b.config, block, dummy.NewETHFaker(), b.database, 1, 10, func(number int, block *core.BlockGen) {
   730  		for _, tx := range b.acceptedBlock.Transactions() {
   731  			block.AddTxWithChain(b.blockchain, tx)
   732  		}
   733  		block.AddTxWithChain(b.blockchain, tx)
   734  	})
   735  	if err != nil {
   736  		return err
   737  	}
   738  	stateDB, err := b.blockchain.State()
   739  	if err != nil {
   740  		return err
   741  	}
   742  	b.acceptedBlock = blocks[0]
   743  	b.acceptedState, _ = state.New(b.acceptedBlock.Root(), stateDB.Database(), nil)
   744  	return nil
   745  }
   746  
   747  // FilterLogs executes a log filter operation, blocking during execution and
   748  // returning all the results in one batch.
   749  //
   750  // TODO(karalabe): Deprecate when the subscription one can return past data too.
   751  func (b *SimulatedBackend) FilterLogs(ctx context.Context, query interfaces.FilterQuery) ([]types.Log, error) {
   752  	var filter *filters.Filter
   753  	if query.BlockHash != nil {
   754  		// Block filter requested, construct a single-shot filter
   755  		filter = b.filterSystem.NewBlockFilter(*query.BlockHash, query.Addresses, query.Topics)
   756  	} else {
   757  		// Initialize unset filter boundaries to run from genesis to chain head
   758  		from := int64(0)
   759  		if query.FromBlock != nil {
   760  			from = query.FromBlock.Int64()
   761  		}
   762  		to := int64(-1)
   763  		if query.ToBlock != nil {
   764  			to = query.ToBlock.Int64()
   765  		}
   766  		// Construct the range filter
   767  		filter = b.filterSystem.NewRangeFilter(from, to, query.Addresses, query.Topics)
   768  	}
   769  	// Run the filter and return all the logs
   770  	logs, err := filter.Logs(ctx)
   771  	if err != nil {
   772  		return nil, err
   773  	}
   774  	res := make([]types.Log, len(logs))
   775  	for i, nLog := range logs {
   776  		res[i] = *nLog
   777  	}
   778  	return res, nil
   779  }
   780  
   781  // SubscribeFilterLogs creates a background log filtering operation, returning a
   782  // subscription immediately, which can be used to stream the found events.
   783  func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query interfaces.FilterQuery, ch chan<- types.Log) (interfaces.Subscription, error) {
   784  	// Subscribe to contract events
   785  	sink := make(chan []*types.Log)
   786  
   787  	sub, err := b.events.SubscribeLogs(query, sink)
   788  	if err != nil {
   789  		return nil, err
   790  	}
   791  	// Since we're getting logs in batches, we need to flatten them into a plain stream
   792  	return event.NewSubscription(func(quit <-chan struct{}) error {
   793  		defer sub.Unsubscribe()
   794  		for {
   795  			select {
   796  			case logs := <-sink:
   797  				for _, nlog := range logs {
   798  					select {
   799  					case ch <- *nlog:
   800  					case err := <-sub.Err():
   801  						return err
   802  					case <-quit:
   803  						return nil
   804  					}
   805  				}
   806  			case err := <-sub.Err():
   807  				return err
   808  			case <-quit:
   809  				return nil
   810  			}
   811  		}
   812  	}), nil
   813  }
   814  
   815  // SubscribeNewHead returns an event subscription for a new header.
   816  func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (interfaces.Subscription, error) {
   817  	// subscribe to a new head
   818  	sink := make(chan *types.Header)
   819  	sub := b.events.SubscribeNewHeads(sink)
   820  
   821  	return event.NewSubscription(func(quit <-chan struct{}) error {
   822  		defer sub.Unsubscribe()
   823  		for {
   824  			select {
   825  			case head := <-sink:
   826  				select {
   827  				case ch <- head:
   828  				case err := <-sub.Err():
   829  					return err
   830  				case <-quit:
   831  					return nil
   832  				}
   833  			case err := <-sub.Err():
   834  				return err
   835  			case <-quit:
   836  				return nil
   837  			}
   838  		}
   839  	}), nil
   840  }
   841  
   842  // AdjustTime adds a time shift to the simulated clock.
   843  // It can only be called on empty blocks.
   844  func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
   845  	b.mu.Lock()
   846  	defer b.mu.Unlock()
   847  
   848  	if len(b.acceptedBlock.Transactions()) != 0 {
   849  		return errors.New("Could not adjust time on non-empty block")
   850  	}
   851  	block := b.blockchain.GetBlockByHash(b.acceptedBlock.ParentHash())
   852  	if block == nil {
   853  		return errors.New("could not find parent")
   854  	}
   855  
   856  	blocks, _, _ := core.GenerateChain(b.config, block, dummy.NewFaker(), b.database, 1, 10, func(number int, block *core.BlockGen) {
   857  		block.OffsetTime(int64(adjustment.Seconds()))
   858  	})
   859  	stateDB, err := b.blockchain.State()
   860  	if err != nil {
   861  		return err
   862  	}
   863  	b.acceptedBlock = blocks[0]
   864  	b.acceptedState, _ = state.New(b.acceptedBlock.Root(), stateDB.Database(), nil)
   865  	return nil
   866  }
   867  
   868  // Blockchain returns the underlying blockchain.
   869  func (b *SimulatedBackend) Blockchain() *core.BlockChain {
   870  	return b.blockchain
   871  }
   872  
   873  // filterBackend implements filters.Backend to support filtering for logs without
   874  // taking bloom-bits acceleration structures into account.
   875  type filterBackend struct {
   876  	db      ethdb.Database
   877  	bc      *core.BlockChain
   878  	backend *SimulatedBackend
   879  }
   880  
   881  func (fb *filterBackend) SubscribeChainAcceptedEvent(ch chan<- core.ChainEvent) event.Subscription {
   882  	return fb.bc.SubscribeChainAcceptedEvent(ch)
   883  }
   884  
   885  func (fb *filterBackend) SubscribeAcceptedLogsEvent(ch chan<- []*types.Log) event.Subscription {
   886  	return fb.bc.SubscribeAcceptedLogsEvent(ch)
   887  }
   888  
   889  func (fb *filterBackend) SubscribeAcceptedTransactionEvent(ch chan<- core.NewTxsEvent) event.Subscription {
   890  	return fb.bc.SubscribeAcceptedTransactionEvent(ch)
   891  }
   892  
   893  func (fb *filterBackend) IsAllowUnfinalizedQueries() bool {
   894  	return false
   895  }
   896  
   897  func (fb *filterBackend) LastAcceptedBlock() *types.Block {
   898  	return fb.bc.LastAcceptedBlock()
   899  }
   900  
   901  func (fb *filterBackend) GetMaxBlocksPerRequest() int64 {
   902  	return eth.DefaultSettings.MaxBlocksPerRequest
   903  }
   904  
   905  func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db }
   906  
   907  func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") }
   908  
   909  func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
   910  	switch number {
   911  	case rpc.PendingBlockNumber, rpc.FinalizedBlockNumber:
   912  		if block := fb.backend.acceptedBlock; block != nil {
   913  			return block.Header(), nil
   914  		}
   915  		return nil, nil
   916  	case rpc.LatestBlockNumber:
   917  		return fb.bc.CurrentHeader(), nil
   918  	default:
   919  		return fb.bc.GetHeaderByNumber(uint64(number.Int64())), nil
   920  	}
   921  }
   922  
   923  func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
   924  	return fb.bc.GetHeaderByHash(hash), nil
   925  }
   926  
   927  func (fb *filterBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
   928  	if body := fb.bc.GetBody(hash); body != nil {
   929  		return body, nil
   930  	}
   931  	return nil, errors.New("block body not found")
   932  }
   933  
   934  func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
   935  	number := rawdb.ReadHeaderNumber(fb.db, hash)
   936  	if number == nil {
   937  		return nil, nil
   938  	}
   939  	header := rawdb.ReadHeader(fb.db, hash, *number)
   940  	if header == nil {
   941  		return nil, nil
   942  	}
   943  	return rawdb.ReadReceipts(fb.db, hash, *number, header.Time, fb.bc.Config()), nil
   944  }
   945  
   946  func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
   947  	logs := rawdb.ReadLogs(fb.db, hash, number)
   948  	return logs, nil
   949  }
   950  
   951  func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
   952  	return nullSubscription()
   953  }
   954  
   955  func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
   956  	return fb.bc.SubscribeChainEvent(ch)
   957  }
   958  
   959  func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
   960  	return fb.bc.SubscribeRemovedLogsEvent(ch)
   961  }
   962  
   963  func (fb *filterBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
   964  	return fb.bc.SubscribeLogsEvent(ch)
   965  }
   966  
   967  func (fb *filterBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
   968  	return nullSubscription()
   969  }
   970  
   971  func (fb *filterBackend) BloomStatus() (uint64, uint64) { return 4096, 0 }
   972  
   973  func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.MatcherSession) {
   974  	panic("not supported")
   975  }
   976  
   977  func (fb *filterBackend) ChainConfig() *params.ChainConfig {
   978  	panic("not supported")
   979  }
   980  
   981  func (fb *filterBackend) CurrentHeader() *types.Header {
   982  	panic("not supported")
   983  }
   984  
   985  func nullSubscription() event.Subscription {
   986  	return event.NewSubscription(func(quit <-chan struct{}) error {
   987  		<-quit
   988  		return nil
   989  	})
   990  }