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