github.com/theQRL/go-zond@v0.1.1/accounts/abi/bind/backends/simulated.go (about)

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