github.com/MetalBlockchain/subnet-evm@v0.4.9/ethclient/ethclient.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 2016 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 ethclient provides a client for the Ethereum RPC API.
    28  package ethclient
    29  
    30  import (
    31  	"context"
    32  	"encoding/json"
    33  	"errors"
    34  	"fmt"
    35  	"math/big"
    36  
    37  	"github.com/MetalBlockchain/metalgo/ids"
    38  	"github.com/MetalBlockchain/subnet-evm/accounts/abi/bind"
    39  	"github.com/MetalBlockchain/subnet-evm/core/types"
    40  	"github.com/MetalBlockchain/subnet-evm/interfaces"
    41  	"github.com/MetalBlockchain/subnet-evm/rpc"
    42  	"github.com/ethereum/go-ethereum/common"
    43  	"github.com/ethereum/go-ethereum/common/hexutil"
    44  )
    45  
    46  // Verify that Client implements required interfaces
    47  var (
    48  	_ bind.AcceptedContractCaller = (*client)(nil)
    49  	_ bind.ContractBackend        = (*client)(nil)
    50  	_ bind.ContractFilterer       = (*client)(nil)
    51  	_ bind.ContractTransactor     = (*client)(nil)
    52  	_ bind.DeployBackend          = (*client)(nil)
    53  
    54  	_ interfaces.ChainReader            = (*client)(nil)
    55  	_ interfaces.ChainStateReader       = (*client)(nil)
    56  	_ interfaces.TransactionReader      = (*client)(nil)
    57  	_ interfaces.TransactionSender      = (*client)(nil)
    58  	_ interfaces.ContractCaller         = (*client)(nil)
    59  	_ interfaces.GasEstimator           = (*client)(nil)
    60  	_ interfaces.GasPricer              = (*client)(nil)
    61  	_ interfaces.LogFilterer            = (*client)(nil)
    62  	_ interfaces.AcceptedStateReader    = (*client)(nil)
    63  	_ interfaces.AcceptedContractCaller = (*client)(nil)
    64  
    65  	_ Client = (*client)(nil)
    66  )
    67  
    68  // Client defines interface for typed wrappers for the Ethereum RPC API.
    69  type Client interface {
    70  	Close()
    71  	ChainID(context.Context) (*big.Int, error)
    72  	BlockByHash(context.Context, common.Hash) (*types.Block, error)
    73  	BlockByNumber(context.Context, *big.Int) (*types.Block, error)
    74  	BlockNumber(context.Context) (uint64, error)
    75  	HeaderByHash(context.Context, common.Hash) (*types.Header, error)
    76  	HeaderByNumber(context.Context, *big.Int) (*types.Header, error)
    77  	TransactionByHash(context.Context, common.Hash) (tx *types.Transaction, isPending bool, err error)
    78  	TransactionSender(context.Context, *types.Transaction, common.Hash, uint) (common.Address, error)
    79  	TransactionCount(context.Context, common.Hash) (uint, error)
    80  	TransactionInBlock(context.Context, common.Hash, uint) (*types.Transaction, error)
    81  	TransactionReceipt(context.Context, common.Hash) (*types.Receipt, error)
    82  	SyncProgress(ctx context.Context) error
    83  	SubscribeNewAcceptedTransactions(context.Context, chan<- *common.Hash) (interfaces.Subscription, error)
    84  	SubscribeNewPendingTransactions(context.Context, chan<- *common.Hash) (interfaces.Subscription, error)
    85  	SubscribeNewHead(context.Context, chan<- *types.Header) (interfaces.Subscription, error)
    86  	NetworkID(context.Context) (*big.Int, error)
    87  	BalanceAt(context.Context, common.Address, *big.Int) (*big.Int, error)
    88  	AssetBalanceAt(context.Context, common.Address, ids.ID, *big.Int) (*big.Int, error)
    89  	StorageAt(context.Context, common.Address, common.Hash, *big.Int) ([]byte, error)
    90  	CodeAt(context.Context, common.Address, *big.Int) ([]byte, error)
    91  	NonceAt(context.Context, common.Address, *big.Int) (uint64, error)
    92  	FilterLogs(context.Context, interfaces.FilterQuery) ([]types.Log, error)
    93  	SubscribeFilterLogs(context.Context, interfaces.FilterQuery, chan<- types.Log) (interfaces.Subscription, error)
    94  	AcceptedCodeAt(context.Context, common.Address) ([]byte, error)
    95  	AcceptedNonceAt(context.Context, common.Address) (uint64, error)
    96  	AcceptedCallContract(context.Context, interfaces.CallMsg) ([]byte, error)
    97  	CallContract(context.Context, interfaces.CallMsg, *big.Int) ([]byte, error)
    98  	CallContractAtHash(ctx context.Context, msg interfaces.CallMsg, blockHash common.Hash) ([]byte, error)
    99  	SuggestGasPrice(context.Context) (*big.Int, error)
   100  	SuggestGasTipCap(context.Context) (*big.Int, error)
   101  	FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*interfaces.FeeHistory, error)
   102  	EstimateGas(context.Context, interfaces.CallMsg) (uint64, error)
   103  	EstimateBaseFee(context.Context) (*big.Int, error)
   104  	SendTransaction(context.Context, *types.Transaction) error
   105  }
   106  
   107  // client defines implementation for typed wrappers for the Ethereum RPC API.
   108  type client struct {
   109  	c *rpc.Client
   110  }
   111  
   112  // Dial connects a client to the given URL.
   113  func Dial(rawurl string) (Client, error) {
   114  	return DialContext(context.Background(), rawurl)
   115  }
   116  
   117  func DialContext(ctx context.Context, rawurl string) (Client, error) {
   118  	c, err := rpc.DialContext(ctx, rawurl)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	return NewClient(c), nil
   123  }
   124  
   125  // NewClient creates a client that uses the given RPC client.
   126  func NewClient(c *rpc.Client) Client {
   127  	return &client{c}
   128  }
   129  
   130  func (ec *client) Close() {
   131  	ec.c.Close()
   132  }
   133  
   134  // Blockchain Access
   135  
   136  // ChainID retrieves the current chain ID for transaction replay protection.
   137  func (ec *client) ChainID(ctx context.Context) (*big.Int, error) {
   138  	var result hexutil.Big
   139  	err := ec.c.CallContext(ctx, &result, "eth_chainId")
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  	return (*big.Int)(&result), err
   144  }
   145  
   146  // BlockByHash returns the given full block.
   147  //
   148  // Note that loading full blocks requires two requests. Use HeaderByHash
   149  // if you don't need all transactions or uncle headers.
   150  func (ec *client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
   151  	return ec.getBlock(ctx, "eth_getBlockByHash", hash, true)
   152  }
   153  
   154  // BlockByNumber returns a block from the current canonical chain. If number is nil, the
   155  // latest known block is returned.
   156  //
   157  // Note that loading full blocks requires two requests. Use HeaderByNumber
   158  // if you don't need all transactions or uncle headers.
   159  func (ec *client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
   160  	return ec.getBlock(ctx, "eth_getBlockByNumber", ToBlockNumArg(number), true)
   161  }
   162  
   163  // BlockNumber returns the most recent block number
   164  func (ec *client) BlockNumber(ctx context.Context) (uint64, error) {
   165  	var result hexutil.Uint64
   166  	err := ec.c.CallContext(ctx, &result, "eth_blockNumber")
   167  	return uint64(result), err
   168  }
   169  
   170  type rpcBlock struct {
   171  	Hash           common.Hash      `json:"hash"`
   172  	Transactions   []rpcTransaction `json:"transactions"`
   173  	UncleHashes    []common.Hash    `json:"uncles"`
   174  	Version        uint32           `json:"version"`
   175  	BlockExtraData *hexutil.Bytes   `json:"blockExtraData"`
   176  }
   177  
   178  func (ec *client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) {
   179  	var raw json.RawMessage
   180  	err := ec.c.CallContext(ctx, &raw, method, args...)
   181  	if err != nil {
   182  		return nil, err
   183  	} else if len(raw) == 0 {
   184  		return nil, interfaces.NotFound
   185  	}
   186  	// Decode header and transactions.
   187  	var head *types.Header
   188  	var body rpcBlock
   189  	if err := json.Unmarshal(raw, &head); err != nil {
   190  		return nil, err
   191  	}
   192  	if err := json.Unmarshal(raw, &body); err != nil {
   193  		return nil, err
   194  	}
   195  	// Quick-verify transaction and uncle lists. This mostly helps with debugging the server.
   196  	if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 {
   197  		return nil, fmt.Errorf("server returned non-empty uncle list but block header indicates no uncles")
   198  	}
   199  	if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
   200  		return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
   201  	}
   202  	if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 {
   203  		return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
   204  	}
   205  	if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 {
   206  		return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
   207  	}
   208  	// Load uncles because they are not included in the block response.
   209  	var uncles []*types.Header
   210  	if len(body.UncleHashes) > 0 {
   211  		uncles = make([]*types.Header, len(body.UncleHashes))
   212  		reqs := make([]rpc.BatchElem, len(body.UncleHashes))
   213  		for i := range reqs {
   214  			reqs[i] = rpc.BatchElem{
   215  				Method: "eth_getUncleByBlockHashAndIndex",
   216  				Args:   []interface{}{body.Hash, hexutil.EncodeUint64(uint64(i))},
   217  				Result: &uncles[i],
   218  			}
   219  		}
   220  		if err := ec.c.BatchCallContext(ctx, reqs); err != nil {
   221  			return nil, err
   222  		}
   223  		for i := range reqs {
   224  			if reqs[i].Error != nil {
   225  				return nil, reqs[i].Error
   226  			}
   227  			if uncles[i] == nil {
   228  				return nil, fmt.Errorf("got null header for uncle %d of block %x", i, body.Hash[:])
   229  			}
   230  		}
   231  	}
   232  	// Fill the sender cache of transactions in the block.
   233  	txs := make([]*types.Transaction, len(body.Transactions))
   234  	for i, tx := range body.Transactions {
   235  		if tx.From != nil {
   236  			setSenderFromServer(tx.tx, *tx.From, body.Hash)
   237  		}
   238  		txs[i] = tx.tx
   239  	}
   240  	return types.NewBlockWithHeader(head).WithBody(txs, uncles), nil
   241  }
   242  
   243  // HeaderByHash returns the block header with the given hash.
   244  func (ec *client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
   245  	var head *types.Header
   246  	err := ec.c.CallContext(ctx, &head, "eth_getBlockByHash", hash, false)
   247  	if err == nil && head == nil {
   248  		err = interfaces.NotFound
   249  	}
   250  	return head, err
   251  }
   252  
   253  // HeaderByNumber returns a block header from the current canonical chain. If number is
   254  // nil, the latest known header is returned.
   255  func (ec *client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
   256  	var head *types.Header
   257  	err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", ToBlockNumArg(number), false)
   258  	if err == nil && head == nil {
   259  		err = interfaces.NotFound
   260  	}
   261  	return head, err
   262  }
   263  
   264  type rpcTransaction struct {
   265  	tx *types.Transaction
   266  	txExtraInfo
   267  }
   268  
   269  type txExtraInfo struct {
   270  	BlockNumber *string         `json:"blockNumber,omitempty"`
   271  	BlockHash   *common.Hash    `json:"blockHash,omitempty"`
   272  	From        *common.Address `json:"from,omitempty"`
   273  }
   274  
   275  func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error {
   276  	if err := json.Unmarshal(msg, &tx.tx); err != nil {
   277  		return err
   278  	}
   279  	return json.Unmarshal(msg, &tx.txExtraInfo)
   280  }
   281  
   282  // TransactionByHash returns the transaction with the given hash.
   283  func (ec *client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) {
   284  	var json *rpcTransaction
   285  	err = ec.c.CallContext(ctx, &json, "eth_getTransactionByHash", hash)
   286  	if err != nil {
   287  		return nil, false, err
   288  	} else if json == nil {
   289  		return nil, false, interfaces.NotFound
   290  	} else if _, r, _ := json.tx.RawSignatureValues(); r == nil {
   291  		return nil, false, fmt.Errorf("server returned transaction without signature")
   292  	}
   293  	if json.From != nil && json.BlockHash != nil {
   294  		setSenderFromServer(json.tx, *json.From, *json.BlockHash)
   295  	}
   296  	return json.tx, json.BlockNumber == nil, nil
   297  }
   298  
   299  // TransactionSender returns the sender address of the given transaction. The transaction
   300  // must be known to the remote node and included in the blockchain at the given block and
   301  // index. The sender is the one derived by the protocol at the time of inclusion.
   302  //
   303  // There is a fast-path for transactions retrieved by TransactionByHash and
   304  // TransactionInBlock. Getting their sender address can be done without an RPC interaction.
   305  func (ec *client) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
   306  	// Try to load the address from the cache.
   307  	sender, err := types.Sender(&senderFromServer{blockhash: block}, tx)
   308  	if err == nil {
   309  		return sender, nil
   310  	}
   311  
   312  	// It was not found in cache, ask the server.
   313  	var meta struct {
   314  		Hash common.Hash
   315  		From common.Address
   316  	}
   317  	if err = ec.c.CallContext(ctx, &meta, "eth_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index)); err != nil {
   318  		return common.Address{}, err
   319  	}
   320  	if meta.Hash == (common.Hash{}) || meta.Hash != tx.Hash() {
   321  		return common.Address{}, errors.New("wrong inclusion block/index")
   322  	}
   323  	return meta.From, nil
   324  }
   325  
   326  // TransactionCount returns the total number of transactions in the given block.
   327  func (ec *client) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) {
   328  	var num hexutil.Uint
   329  	err := ec.c.CallContext(ctx, &num, "eth_getBlockTransactionCountByHash", blockHash)
   330  	return uint(num), err
   331  }
   332  
   333  // TransactionInBlock returns a single transaction at index in the given block.
   334  func (ec *client) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) {
   335  	var json *rpcTransaction
   336  	err := ec.c.CallContext(ctx, &json, "eth_getTransactionByBlockHashAndIndex", blockHash, hexutil.Uint64(index))
   337  	if err != nil {
   338  		return nil, err
   339  	}
   340  	if json == nil {
   341  		return nil, interfaces.NotFound
   342  	} else if _, r, _ := json.tx.RawSignatureValues(); r == nil {
   343  		return nil, fmt.Errorf("server returned transaction without signature")
   344  	}
   345  	if json.From != nil && json.BlockHash != nil {
   346  		setSenderFromServer(json.tx, *json.From, *json.BlockHash)
   347  	}
   348  	return json.tx, err
   349  }
   350  
   351  // TransactionReceipt returns the receipt of a transaction by transaction hash.
   352  // Note that the receipt is not available for pending transactions.
   353  func (ec *client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
   354  	var r *types.Receipt
   355  	err := ec.c.CallContext(ctx, &r, "eth_getTransactionReceipt", txHash)
   356  	if err == nil {
   357  		if r == nil {
   358  			return nil, interfaces.NotFound
   359  		}
   360  	}
   361  	return r, err
   362  }
   363  
   364  // SyncProgress retrieves the current progress of the sync algorithm. If there's
   365  // no sync currently running, it returns nil.
   366  func (ec *client) SyncProgress(ctx context.Context) error {
   367  	var (
   368  		raw     json.RawMessage
   369  		syncing bool
   370  	)
   371  
   372  	if err := ec.c.CallContext(ctx, &raw, "eth_syncing"); err != nil {
   373  		return err
   374  	}
   375  	// If not syncing, the response will be 'false'. To detect this
   376  	// we unmarshal into a boolean and return nil on success.
   377  	// If the chain is syncing, the engine will not forward the
   378  	// request to the chain and a non-nil err will be returned.
   379  	return json.Unmarshal(raw, &syncing)
   380  }
   381  
   382  // SubscribeNewAcceptedTransactions subscribes to notifications about the accepted transaction hashes on the given channel.
   383  func (ec *client) SubscribeNewAcceptedTransactions(ctx context.Context, ch chan<- *common.Hash) (interfaces.Subscription, error) {
   384  	return ec.c.EthSubscribe(ctx, ch, "newAcceptedTransactions")
   385  }
   386  
   387  // SubscribeNewAcceptedTransactions subscribes to notifications about the accepted transaction hashes on the given channel.
   388  func (ec *client) SubscribeNewPendingTransactions(ctx context.Context, ch chan<- *common.Hash) (interfaces.Subscription, error) {
   389  	return ec.c.EthSubscribe(ctx, ch, "newPendingTransactions")
   390  }
   391  
   392  // SubscribeNewHead subscribes to notifications about the current blockchain head
   393  // on the given channel.
   394  func (ec *client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (interfaces.Subscription, error) {
   395  	return ec.c.EthSubscribe(ctx, ch, "newHeads")
   396  }
   397  
   398  // State Access
   399  
   400  // NetworkID returns the network ID (also known as the chain ID) for this chain.
   401  func (ec *client) NetworkID(ctx context.Context) (*big.Int, error) {
   402  	version := new(big.Int)
   403  	var ver string
   404  	if err := ec.c.CallContext(ctx, &ver, "net_version"); err != nil {
   405  		return nil, err
   406  	}
   407  	if _, ok := version.SetString(ver, 10); !ok {
   408  		return nil, fmt.Errorf("invalid net_version result %q", ver)
   409  	}
   410  	return version, nil
   411  }
   412  
   413  // BalanceAt returns the wei balance of the given account.
   414  // The block number can be nil, in which case the balance is taken from the latest known block.
   415  func (ec *client) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) {
   416  	var result hexutil.Big
   417  	err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, ToBlockNumArg(blockNumber))
   418  	return (*big.Int)(&result), err
   419  }
   420  
   421  // AssetBalanceAt returns the [assetID] balance of the given account
   422  // The block number can be nil, in which case the balance is taken from the latest known block.
   423  func (ec *client) AssetBalanceAt(ctx context.Context, account common.Address, assetID ids.ID, blockNumber *big.Int) (*big.Int, error) {
   424  	var result hexutil.Big
   425  	err := ec.c.CallContext(ctx, &result, "eth_getAssetBalance", account, ToBlockNumArg(blockNumber), assetID)
   426  	return (*big.Int)(&result), err
   427  }
   428  
   429  // StorageAt returns the value of key in the contract storage of the given account.
   430  // The block number can be nil, in which case the value is taken from the latest known block.
   431  func (ec *client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) {
   432  	var result hexutil.Bytes
   433  	err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, ToBlockNumArg(blockNumber))
   434  	return result, err
   435  }
   436  
   437  // CodeAt returns the contract code of the given account.
   438  // The block number can be nil, in which case the code is taken from the latest known block.
   439  func (ec *client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) {
   440  	var result hexutil.Bytes
   441  	err := ec.c.CallContext(ctx, &result, "eth_getCode", account, ToBlockNumArg(blockNumber))
   442  	return result, err
   443  }
   444  
   445  // NonceAt returns the account nonce of the given account.
   446  // The block number can be nil, in which case the nonce is taken from the latest known block.
   447  func (ec *client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) {
   448  	var result hexutil.Uint64
   449  	err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, ToBlockNumArg(blockNumber))
   450  	return uint64(result), err
   451  }
   452  
   453  // Filters
   454  
   455  // FilterLogs executes a filter query.
   456  func (ec *client) FilterLogs(ctx context.Context, q interfaces.FilterQuery) ([]types.Log, error) {
   457  	var result []types.Log
   458  	arg, err := toFilterArg(q)
   459  	if err != nil {
   460  		return nil, err
   461  	}
   462  	err = ec.c.CallContext(ctx, &result, "eth_getLogs", arg)
   463  	return result, err
   464  }
   465  
   466  // SubscribeFilterLogs subscribes to the results of a streaming filter query.
   467  func (ec *client) SubscribeFilterLogs(ctx context.Context, q interfaces.FilterQuery, ch chan<- types.Log) (interfaces.Subscription, error) {
   468  	arg, err := toFilterArg(q)
   469  	if err != nil {
   470  		return nil, err
   471  	}
   472  	return ec.c.EthSubscribe(ctx, ch, "logs", arg)
   473  }
   474  
   475  func toFilterArg(q interfaces.FilterQuery) (interface{}, error) {
   476  	arg := map[string]interface{}{
   477  		"address": q.Addresses,
   478  		"topics":  q.Topics,
   479  	}
   480  	if q.BlockHash != nil {
   481  		arg["blockHash"] = *q.BlockHash
   482  		if q.FromBlock != nil || q.ToBlock != nil {
   483  			return nil, fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock")
   484  		}
   485  	} else {
   486  		if q.FromBlock == nil {
   487  			arg["fromBlock"] = "0x0"
   488  		} else {
   489  			arg["fromBlock"] = ToBlockNumArg(q.FromBlock)
   490  		}
   491  		arg["toBlock"] = ToBlockNumArg(q.ToBlock)
   492  	}
   493  	return arg, nil
   494  }
   495  
   496  // AcceptedCodeAt returns the contract code of the given account in the accepted state.
   497  func (ec *client) AcceptedCodeAt(ctx context.Context, account common.Address) ([]byte, error) {
   498  	return ec.CodeAt(ctx, account, nil)
   499  }
   500  
   501  // AcceptedNonceAt returns the account nonce of the given account in the accepted state.
   502  // This is the nonce that should be used for the next transaction.
   503  func (ec *client) AcceptedNonceAt(ctx context.Context, account common.Address) (uint64, error) {
   504  	return ec.NonceAt(ctx, account, nil)
   505  }
   506  
   507  // AcceptedCallContract executes a message call transaction in the accepted
   508  // state.
   509  func (ec *client) AcceptedCallContract(ctx context.Context, msg interfaces.CallMsg) ([]byte, error) {
   510  	return ec.CallContract(ctx, msg, nil)
   511  }
   512  
   513  // Contract Calling
   514  
   515  // CallContract executes a message call transaction, which is directly executed in the VM
   516  // of the node, but never mined into the blockchain.
   517  //
   518  // blockNumber selects the block height at which the call runs. It can be nil, in which
   519  // case the code is taken from the latest known block. Note that state from very old
   520  // blocks might not be available.
   521  func (ec *client) CallContract(ctx context.Context, msg interfaces.CallMsg, blockNumber *big.Int) ([]byte, error) {
   522  	var hex hexutil.Bytes
   523  	err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), ToBlockNumArg(blockNumber))
   524  	if err != nil {
   525  		return nil, err
   526  	}
   527  	return hex, nil
   528  }
   529  
   530  // CallContractAtHash is almost the same as CallContract except that it selects
   531  // the block by block hash instead of block height.
   532  func (ec *client) CallContractAtHash(ctx context.Context, msg interfaces.CallMsg, blockHash common.Hash) ([]byte, error) {
   533  	var hex hexutil.Bytes
   534  	err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), rpc.BlockNumberOrHashWithHash(blockHash, false))
   535  	if err != nil {
   536  		return nil, err
   537  	}
   538  	return hex, nil
   539  }
   540  
   541  // SuggestGasPrice retrieves the currently suggested gas price to allow a timely
   542  // execution of a transaction.
   543  func (ec *client) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
   544  	var hex hexutil.Big
   545  	if err := ec.c.CallContext(ctx, &hex, "eth_gasPrice"); err != nil {
   546  		return nil, err
   547  	}
   548  	return (*big.Int)(&hex), nil
   549  }
   550  
   551  // SuggestGasTipCap retrieves the currently suggested gas tip cap after 1559 to
   552  // allow a timely execution of a transaction.
   553  func (ec *client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
   554  	var hex hexutil.Big
   555  	if err := ec.c.CallContext(ctx, &hex, "eth_maxPriorityFeePerGas"); err != nil {
   556  		return nil, err
   557  	}
   558  	return (*big.Int)(&hex), nil
   559  }
   560  
   561  type feeHistoryResultMarshaling struct {
   562  	OldestBlock  *hexutil.Big     `json:"oldestBlock"`
   563  	Reward       [][]*hexutil.Big `json:"reward,omitempty"`
   564  	BaseFee      []*hexutil.Big   `json:"baseFeePerGas,omitempty"`
   565  	GasUsedRatio []float64        `json:"gasUsedRatio"`
   566  }
   567  
   568  // FeeHistory retrieves the fee market history.
   569  func (ec *client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*interfaces.FeeHistory, error) {
   570  	var res feeHistoryResultMarshaling
   571  	if err := ec.c.CallContext(ctx, &res, "eth_feeHistory", hexutil.Uint(blockCount), ToBlockNumArg(lastBlock), rewardPercentiles); err != nil {
   572  		return nil, err
   573  	}
   574  	reward := make([][]*big.Int, len(res.Reward))
   575  	for i, r := range res.Reward {
   576  		reward[i] = make([]*big.Int, len(r))
   577  		for j, r := range r {
   578  			reward[i][j] = (*big.Int)(r)
   579  		}
   580  	}
   581  	baseFee := make([]*big.Int, len(res.BaseFee))
   582  	for i, b := range res.BaseFee {
   583  		baseFee[i] = (*big.Int)(b)
   584  	}
   585  	return &interfaces.FeeHistory{
   586  		OldestBlock:  (*big.Int)(res.OldestBlock),
   587  		Reward:       reward,
   588  		BaseFee:      baseFee,
   589  		GasUsedRatio: res.GasUsedRatio,
   590  	}, nil
   591  }
   592  
   593  // EstimateGas tries to estimate the gas needed to execute a specific transaction based on
   594  // the current pending state of the backend blockchain. There is no guarantee that this is
   595  // the true gas limit requirement as other transactions may be added or removed by miners,
   596  // but it should provide a basis for setting a reasonable default.
   597  func (ec *client) EstimateGas(ctx context.Context, msg interfaces.CallMsg) (uint64, error) {
   598  	var hex hexutil.Uint64
   599  	err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg))
   600  	if err != nil {
   601  		return 0, err
   602  	}
   603  	return uint64(hex), nil
   604  }
   605  
   606  // EstimateBaseFee tries to estimate the base fee for the next block if it were created
   607  // immediately. There is no guarantee that this will be the base fee used in the next block
   608  // or that the next base fee will be higher or lower than the returned value.
   609  func (ec *client) EstimateBaseFee(ctx context.Context) (*big.Int, error) {
   610  	var hex hexutil.Big
   611  	err := ec.c.CallContext(ctx, &hex, "eth_baseFee")
   612  	if err != nil {
   613  		return nil, err
   614  	}
   615  	return (*big.Int)(&hex), nil
   616  }
   617  
   618  // SendTransaction injects a signed transaction into the pending pool for execution.
   619  //
   620  // If the transaction was a contract creation use the TransactionReceipt method to get the
   621  // contract address after the transaction has been mined.
   622  func (ec *client) SendTransaction(ctx context.Context, tx *types.Transaction) error {
   623  	data, err := tx.MarshalBinary()
   624  	if err != nil {
   625  		return err
   626  	}
   627  	return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
   628  }
   629  
   630  func ToBlockNumArg(number *big.Int) string {
   631  	// The Ethereum implementation uses a different mapping from
   632  	// negative numbers to special strings (latest, pending) then is
   633  	// used on its server side. See rpc/types.go for the comparison.
   634  	// In Subnet EVM, latest, pending, and accepted are all treated the same
   635  	// therefore, if [number] is nil or a negative number in [-3, -1]
   636  	// we want the latest accepted block
   637  	if number == nil {
   638  		return "latest"
   639  	}
   640  	low := big.NewInt(-3)
   641  	high := big.NewInt(-1)
   642  	if number.Cmp(low) >= 0 && number.Cmp(high) <= 0 {
   643  		return "latest"
   644  	}
   645  	return hexutil.EncodeBig(number)
   646  }
   647  
   648  func toCallArg(msg interfaces.CallMsg) interface{} {
   649  	arg := map[string]interface{}{
   650  		"from": msg.From,
   651  		"to":   msg.To,
   652  	}
   653  	if len(msg.Data) > 0 {
   654  		arg["data"] = hexutil.Bytes(msg.Data)
   655  	}
   656  	if msg.Value != nil {
   657  		arg["value"] = (*hexutil.Big)(msg.Value)
   658  	}
   659  	if msg.Gas != 0 {
   660  		arg["gas"] = hexutil.Uint64(msg.Gas)
   661  	}
   662  	if msg.GasPrice != nil {
   663  		arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
   664  	}
   665  	return arg
   666  }