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