github.com/amazechain/amc@v0.1.3/internal/api/api.go (about)

     1  // Copyright 2022 The AmazeChain Authors
     2  // This file is part of the AmazeChain library.
     3  //
     4  // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package api
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"github.com/amazechain/amc/conf"
    24  	"github.com/amazechain/amc/internal"
    25  	"github.com/amazechain/amc/internal/api/filters"
    26  	vm2 "github.com/amazechain/amc/internal/vm"
    27  	"github.com/amazechain/amc/internal/vm/evmtypes"
    28  	event "github.com/amazechain/amc/modules/event/v2"
    29  	"github.com/amazechain/amc/modules/state"
    30  	"github.com/amazechain/amc/turbo/rpchelper"
    31  	"github.com/holiman/uint256"
    32  
    33  	"math"
    34  	"math/big"
    35  	"time"
    36  
    37  	"github.com/ledgerwatch/erigon-lib/kv"
    38  
    39  	"github.com/amazechain/amc/accounts"
    40  	"github.com/amazechain/amc/common"
    41  	"github.com/amazechain/amc/common/block"
    42  	"github.com/amazechain/amc/common/crypto"
    43  	"github.com/amazechain/amc/common/hexutil"
    44  	"github.com/amazechain/amc/common/transaction"
    45  	"github.com/amazechain/amc/common/types"
    46  	"github.com/amazechain/amc/internal/avm/abi"
    47  	mvm_common "github.com/amazechain/amc/internal/avm/common"
    48  	mvm_types "github.com/amazechain/amc/internal/avm/types"
    49  	"github.com/amazechain/amc/internal/consensus"
    50  	"github.com/amazechain/amc/log"
    51  	"github.com/amazechain/amc/modules/rawdb"
    52  	"github.com/amazechain/amc/modules/rpc/jsonrpc"
    53  	"github.com/amazechain/amc/params"
    54  )
    55  
    56  const (
    57  	// todo
    58  	baseFee       = 5000000
    59  	rpcEVMTimeout = time.Duration(5 * time.Second)
    60  	rpcGasCap     = 50000000
    61  )
    62  
    63  // API compatible EthereumAPI provides an API to access related information.
    64  type API struct {
    65  	db      kv.RwDB
    66  	bc      common.IBlockChain
    67  	engine  consensus.Engine
    68  	txspool common.ITxsPool
    69  
    70  	accountManager *accounts.Manager
    71  	chainConfig    *params.ChainConfig
    72  
    73  	gpo *Oracle
    74  }
    75  
    76  // NewAPI creates a new protocol API.
    77  func NewAPI(bc common.IBlockChain, db kv.RwDB, engine consensus.Engine, txspool common.ITxsPool, accountManager *accounts.Manager, config *params.ChainConfig) *API {
    78  	return &API{
    79  		db:             db,
    80  		bc:             bc,
    81  		engine:         engine,
    82  		txspool:        txspool,
    83  		accountManager: accountManager,
    84  		chainConfig:    config,
    85  	}
    86  }
    87  
    88  func (api *API) SetGpo(gpo *Oracle) {
    89  	api.gpo = gpo
    90  }
    91  
    92  func (api *API) Apis() []jsonrpc.API {
    93  	nonceLock := new(AddrLocker)
    94  	return []jsonrpc.API{
    95  		{
    96  			Namespace: "eth",
    97  			Service:   NewBlockChainAPI(api),
    98  		}, {
    99  			Namespace: "eth",
   100  			Service:   NewAmcAPI(api),
   101  		}, {
   102  			Namespace: "eth",
   103  			Service:   NewTransactionAPI(api, nonceLock),
   104  		}, {
   105  			Namespace: "web3",
   106  			Service:   &Web3API{api},
   107  		}, {
   108  			Namespace: "net",
   109  			Service:   NewNetAPI(api, api.GetChainConfig().ChainID.Uint64()),
   110  		},
   111  		{
   112  			Namespace: "debug",
   113  			Service:   NewDebugAPI(api),
   114  		},
   115  		{
   116  			Namespace: "txpool",
   117  			Service:   NewTxsPoolAPI(api),
   118  		}, {
   119  			Namespace: "eth",
   120  			Service:   filters.NewFilterAPI(api, 5*time.Minute),
   121  		},
   122  	}
   123  }
   124  
   125  func (n *API) TxsPool() common.ITxsPool       { return n.txspool }
   126  func (n *API) Database() kv.RwDB              { return n.db }
   127  func (n *API) Engine() consensus.Engine       { return n.engine }
   128  func (n *API) BlockChain() common.IBlockChain { return n.bc }
   129  func (n *API) GetEvm(ctx context.Context, msg internal.Message, ibs evmtypes.IntraBlockState, header block.IHeader, vmConfig *vm2.Config) (*vm2.EVM, func() error, error) {
   130  	vmError := func() error { return nil }
   131  
   132  	txContext := internal.NewEVMTxContext(msg)
   133  	context := internal.NewEVMBlockContext(header.(*block.Header), internal.GetHashFn(header.(*block.Header), nil), n.engine, nil)
   134  	//tx, err := n.db.BeginRo(ctx)
   135  	//if nil != err {
   136  	//	return nil, nil, err
   137  	//}
   138  	//defer tx.Rollback()
   139  	//
   140  	//stateReader := state.NewPlainStateReader(tx)
   141  
   142  	return vm2.NewEVM(context, txContext, ibs, n.GetChainConfig(), *vmConfig), vmError, nil
   143  }
   144  
   145  func (n *API) State(tx kv.Tx, blockNrOrHash jsonrpc.BlockNumberOrHash) evmtypes.IntraBlockState {
   146  
   147  	_, blockHash, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx)
   148  	if err != nil {
   149  		return nil
   150  	}
   151  
   152  	blockNr := rawdb.ReadHeaderNumber(tx, blockHash)
   153  	if nil == blockNr {
   154  		return nil
   155  	}
   156  
   157  	stateReader := state.NewPlainState(tx, *blockNr+1)
   158  	return state.New(stateReader)
   159  }
   160  
   161  func (n *API) GetChainConfig() *params.ChainConfig {
   162  	return n.chainConfig
   163  }
   164  
   165  func (n *API) RPCGasCap() uint64 {
   166  	return rpcGasCap
   167  }
   168  
   169  // AmcAPI provides an API to access metadata related information.
   170  type AmcAPI struct {
   171  	api *API
   172  }
   173  
   174  // NewAmcAPI creates a new Meta protocol API.
   175  func NewAmcAPI(api *API) *AmcAPI {
   176  	return &AmcAPI{api}
   177  }
   178  
   179  // GasPrice returns a suggestion for a gas price for legacy transactions.
   180  func (s *AmcAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) {
   181  	conf.LightClientGPO.Default = big.NewInt(params.GWei)
   182  	//oracle := NewOracle(s.api.BlockChain(), conf.LightClientGPO)
   183  	tipcap, err := s.api.gpo.SuggestTipCap(ctx, s.api.GetChainConfig())
   184  	if err != nil {
   185  		return nil, err
   186  	}
   187  	if head := s.api.BlockChain().CurrentBlock().Header(); head.BaseFee64() != uint256.NewInt(0) {
   188  		tipcap.Add(tipcap, head.BaseFee64().ToBig())
   189  	}
   190  	return (*hexutil.Big)(tipcap), nil
   191  	//todo hardcode 13Gwei
   192  	//tipcap := 13000000000
   193  	//return (*hexutil.Big)(new(big.Int).SetUint64(uint64(tipcap))), nil
   194  }
   195  
   196  // MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
   197  func (s *AmcAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) {
   198  	tipcap, err := s.api.gpo.SuggestTipCap(ctx, s.api.GetChainConfig())
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  	return (*hexutil.Big)(tipcap), err
   203  }
   204  
   205  type feeHistoryResult struct {
   206  	OldestBlock  *hexutil.Big     `json:"oldestBlock"`
   207  	Reward       [][]*hexutil.Big `json:"reward,omitempty"`
   208  	BaseFee      []*hexutil.Big   `json:"baseFeePerGas,omitempty"`
   209  	GasUsedRatio []float64        `json:"gasUsedRatio"`
   210  }
   211  
   212  // FeeHistory returns the fee market history.
   213  func (s *AmcAPI) FeeHistory(ctx context.Context, blockCount jsonrpc.DecimalOrHex, lastBlock jsonrpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) {
   214  
   215  	var (
   216  		resolvedLastBlock *uint256.Int
   217  		err               error
   218  	)
   219  
   220  	s.api.db.View(ctx, func(tx kv.Tx) error {
   221  		resolvedLastBlock, _, err = rpchelper.GetBlockNumber(jsonrpc.BlockNumberOrHashWithNumber(lastBlock), tx)
   222  		return nil
   223  	})
   224  
   225  	if err != nil {
   226  		return nil, err
   227  	}
   228  
   229  	oldest, reward, baseFee, gasUsed, err := s.api.gpo.FeeHistory(ctx, int(blockCount), lastBlock, resolvedLastBlock, rewardPercentiles)
   230  	if err != nil {
   231  		return nil, err
   232  	}
   233  	results := &feeHistoryResult{
   234  		OldestBlock:  (*hexutil.Big)(oldest),
   235  		GasUsedRatio: gasUsed,
   236  	}
   237  	if reward != nil {
   238  		results.Reward = make([][]*hexutil.Big, len(reward))
   239  		for i, w := range reward {
   240  			results.Reward[i] = make([]*hexutil.Big, len(w))
   241  			for j, v := range w {
   242  				results.Reward[i][j] = (*hexutil.Big)(v)
   243  			}
   244  		}
   245  	}
   246  	if baseFee != nil {
   247  		results.BaseFee = make([]*hexutil.Big, len(baseFee))
   248  		for i, v := range baseFee {
   249  			results.BaseFee[i] = (*hexutil.Big)(v)
   250  		}
   251  	}
   252  	return results, nil
   253  }
   254  
   255  // TxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential.
   256  type TxPoolAPI struct {
   257  	api *API
   258  }
   259  
   260  // NewTxPoolAPI creates a new tx pool service that gives information about the transaction pool.
   261  func NewTxPoolAPI(api *API) *TxPoolAPI {
   262  	return &TxPoolAPI{api}
   263  }
   264  
   265  // Content returns the transactions contained within the transaction pool.
   266  func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction {
   267  	content := map[string]map[string]map[string]*RPCTransaction{
   268  		"pending": make(map[string]map[string]*RPCTransaction),
   269  		"queued":  make(map[string]map[string]*RPCTransaction),
   270  	}
   271  	return content
   272  }
   273  
   274  // ContentFrom returns the transactions contained within the transaction pool.
   275  func (s *TxPoolAPI) ContentFrom(addr types.Address) map[string]map[string]*RPCTransaction {
   276  	content := make(map[string]map[string]*RPCTransaction, 2)
   277  
   278  	return content
   279  }
   280  
   281  // Status returns the number of pending and queued transaction in the pool.
   282  func (s *TxPoolAPI) Status() map[string]hexutil.Uint {
   283  	_, pending, _, queue := s.api.TxsPool().Stats()
   284  	return map[string]hexutil.Uint{
   285  		"pending": hexutil.Uint(pending),
   286  		"queued":  hexutil.Uint(queue),
   287  	}
   288  }
   289  
   290  // Inspect retrieves the content of the transaction pool and flattens it into an
   291  // easily inspectable list.
   292  func (s *TxPoolAPI) Inspect() map[string]map[string]map[string]string {
   293  	content := map[string]map[string]map[string]string{
   294  		"pending": make(map[string]map[string]string),
   295  		"queued":  make(map[string]map[string]string),
   296  	}
   297  
   298  	return content
   299  }
   300  
   301  // AccountAPI provides an API to access accounts managed by this node.
   302  // It offers only methods that can retrieve accounts.
   303  type AccountAPI struct {
   304  }
   305  
   306  // NewAccountAPI creates a new AccountAPI.
   307  func NewAccountAPI() *AccountAPI {
   308  	return &AccountAPI{}
   309  }
   310  
   311  // Accounts returns the collection of accounts this node manages.
   312  func (s *AccountAPI) Accounts() []types.Address {
   313  	//return s.am.Accounts()
   314  	return nil
   315  }
   316  
   317  // BlockChainAPI provides an API to access Ethereum blockchain data.
   318  type BlockChainAPI struct {
   319  	api *API
   320  }
   321  
   322  // NewBlockChainAPI creates a new  blockchain API.
   323  func NewBlockChainAPI(api *API) *BlockChainAPI {
   324  	return &BlockChainAPI{api}
   325  }
   326  
   327  // ChainId get Chain ID
   328  func (api *BlockChainAPI) ChainId() *hexutil.Big {
   329  	return (*hexutil.Big)(api.api.GetChainConfig().ChainID)
   330  }
   331  
   332  // GetBalance get balance
   333  func (s *BlockChainAPI) GetBalance(ctx context.Context, address mvm_common.Address, blockNrOrHash jsonrpc.BlockNumberOrHash) (*hexutil.Big, error) {
   334  	tx, err := s.api.db.BeginRo(ctx)
   335  	if nil != err {
   336  		return nil, err
   337  	}
   338  	defer tx.Rollback()
   339  
   340  	state := s.api.State(tx, blockNrOrHash)
   341  	if state == nil {
   342  		return nil, nil
   343  	}
   344  	balance := state.GetBalance(*mvm_types.ToAmcAddress(&address))
   345  	return (*hexutil.Big)(balance.ToBig()), nil
   346  }
   347  
   348  func (s *BlockChainAPI) BlockNumber() hexutil.Uint64 {
   349  	//jsonrpc.LatestBlockNumber
   350  	header := s.api.BlockChain().CurrentBlock().Header() // latest header should always be available
   351  	return hexutil.Uint64(header.Number64().Uint64())
   352  }
   353  
   354  // GetCode get code
   355  func (s *BlockChainAPI) GetCode(ctx context.Context, address mvm_common.Address, blockNrOrHash jsonrpc.BlockNumberOrHash) (hexutil.Bytes, error) {
   356  	tx, err := s.api.db.BeginRo(ctx)
   357  	if nil != err {
   358  		return nil, err
   359  	}
   360  	defer tx.Rollback()
   361  
   362  	state := s.api.State(tx, blockNrOrHash)
   363  	if state == nil {
   364  		return nil, nil
   365  	}
   366  	code := state.GetCode(*mvm_types.ToAmcAddress(&address))
   367  	return code, nil
   368  }
   369  
   370  // GetStorageAt returns the storage from the state at the given address, key and
   371  // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber metadata block
   372  // numbers are also allowed.
   373  func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address types.Address, key string, blockNrOrHash jsonrpc.BlockNumberOrHash) (hexutil.Bytes, error) {
   374  	tx, err := s.api.db.BeginRo(ctx)
   375  	if nil != err {
   376  		return nil, err
   377  	}
   378  	defer tx.Rollback()
   379  
   380  	state := s.api.State(tx, blockNrOrHash)
   381  	if state == nil {
   382  		return nil, nil
   383  	}
   384  	var va uint256.Int
   385  	k := types.HexToHash(key)
   386  	state.GetState(address, &k, &va)
   387  	return va.Bytes(), nil
   388  }
   389  
   390  // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash
   391  func (s *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash mvm_common.Hash) *hexutil.Uint {
   392  	if block, _ := s.api.BlockChain().GetBlockByHash(mvm_types.ToAmcHash(blockHash)); block != nil {
   393  		//POA donot have Uncles
   394  		n := hexutil.Uint(0)
   395  		return &n
   396  	}
   397  	return nil
   398  }
   399  
   400  // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index.
   401  func (s *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash mvm_common.Hash, index hexutil.Uint) (map[string]interface{}, error) {
   402  	b, err := s.api.BlockChain().GetBlockByHash(mvm_types.ToAmcHash(blockHash))
   403  	if b != nil {
   404  		//POA donot have Uncles
   405  		var uncles []struct{}
   406  		if index >= hexutil.Uint(len(uncles)) {
   407  			return nil, nil
   408  		}
   409  		block := block.NewBlock(&block.Header{}, nil)
   410  		return RPCMarshalBlock(block, s.api.BlockChain(), false, false)
   411  	}
   412  	return nil, err
   413  }
   414  
   415  // Result structs for GetProof
   416  type AccountResult struct {
   417  	Address      types.Address   `json:"address"`
   418  	AccountProof []string        `json:"accountProof"`
   419  	Balance      *hexutil.Big    `json:"balance"`
   420  	CodeHash     types.Hash      `json:"codeHash"`
   421  	Nonce        hexutil.Uint64  `json:"nonce"`
   422  	StorageHash  types.Hash      `json:"storageHash"`
   423  	StorageProof []StorageResult `json:"storageProof"`
   424  }
   425  
   426  type StorageResult struct {
   427  	Key   string       `json:"key"`
   428  	Value *hexutil.Big `json:"value"`
   429  	Proof []string     `json:"proof"`
   430  }
   431  
   432  // // OverrideAccount indicates the overriding fields of account during the execution
   433  // // of a message call.
   434  // // Note, state and stateDiff can't be specified at the same time. If state is
   435  // // set, message execution will only use the data in the given state. Otherwise
   436  // // if statDiff is set, all diff will be applied first and then execute the call
   437  // // message.
   438  type OverrideAccount struct {
   439  	Nonce      *hexutil.Uint64                      `json:"nonce"`
   440  	Code       *hexutil.Bytes                       `json:"code"`
   441  	Balance    **hexutil.Big                        `json:"balance"`
   442  	StatsPrint *map[mvm_common.Hash]mvm_common.Hash `json:"state"`
   443  	StateDiff  *map[mvm_common.Hash]mvm_common.Hash `json:"stateDiff"`
   444  }
   445  
   446  // StateOverride is the collection of overridden accounts.
   447  type StateOverride map[mvm_common.Address]OverrideAccount
   448  
   449  // Apply overrides the fields of specified accounts into the given state.
   450  func (diff *StateOverride) Apply(state *state.IntraBlockState) error {
   451  	if diff == nil {
   452  		return nil
   453  	}
   454  	for addr, account := range *diff {
   455  		// Override account nonce.
   456  		if account.Nonce != nil {
   457  			state.SetNonce(*mvm_types.ToAmcAddress(&addr), uint64(*account.Nonce))
   458  		}
   459  		// Override account(contract) code.
   460  		if account.Code != nil {
   461  			state.SetCode(*mvm_types.ToAmcAddress(&addr), *account.Code)
   462  		}
   463  		// Override account balance.
   464  		if account.Balance != nil {
   465  			balance, _ := uint256.FromBig((*big.Int)(*account.Balance))
   466  			state.SetBalance(*mvm_types.ToAmcAddress(&addr), balance)
   467  		}
   468  		if account.StatsPrint != nil && account.StateDiff != nil {
   469  			return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.String())
   470  		}
   471  		if account.StatsPrint != nil {
   472  			statesPrint := make(map[types.Hash]uint256.Int)
   473  			for k, v := range *account.StatsPrint {
   474  				d, _ := uint256.FromBig(v.Big())
   475  				statesPrint[mvm_types.ToAmcHash(k)] = *d
   476  			}
   477  			state.SetStorage(*mvm_types.ToAmcAddress(&addr), statesPrint)
   478  		}
   479  		// Apply state diff into specified accounts.
   480  		if account.StateDiff != nil {
   481  			for key, value := range *account.StateDiff {
   482  				k := mvm_types.ToAmcHash(key)
   483  				v, _ := uint256.FromBig(value.Big())
   484  				state.SetState(*mvm_types.ToAmcAddress(&addr), &k, *v)
   485  			}
   486  		}
   487  	}
   488  	return nil
   489  }
   490  
   491  // BlockOverrides is a set of header fields to override.
   492  type BlockOverrides struct {
   493  	Number     *hexutil.Big
   494  	Difficulty *hexutil.Big
   495  	Time       *hexutil.Uint64
   496  	GasLimit   *hexutil.Uint64
   497  	Coinbase   *types.Address
   498  	Random     *types.Hash
   499  	BaseFee    *hexutil.Big
   500  }
   501  
   502  // Apply overrides the given header fields into the given block context.
   503  func (diff *BlockOverrides) Apply(blockCtx *evmtypes.BlockContext) {
   504  	if diff == nil {
   505  		return
   506  	}
   507  	if diff.Number != nil {
   508  		blockCtx.BlockNumber = diff.Number.ToInt().Uint64()
   509  	}
   510  	if diff.Difficulty != nil {
   511  		blockCtx.Difficulty = diff.Difficulty.ToInt()
   512  	}
   513  	if diff.Time != nil {
   514  		blockCtx.Time = uint64(*diff.Time)
   515  	}
   516  	if diff.GasLimit != nil {
   517  		blockCtx.GasLimit = uint64(*diff.GasLimit)
   518  	}
   519  	if diff.Coinbase != nil {
   520  		blockCtx.Coinbase = *diff.Coinbase
   521  	}
   522  	if diff.Random != nil {
   523  		blockCtx.PrevRanDao = diff.Random
   524  	}
   525  	if diff.BaseFee != nil {
   526  		blockCtx.BaseFee, _ = uint256.FromBig(diff.BaseFee.ToInt())
   527  	}
   528  }
   529  
   530  func DoCall(ctx context.Context, api *API, args TransactionArgs, blockNrOrHash jsonrpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*internal.ExecutionResult, error) {
   531  	defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
   532  
   533  	// header := api.BlockChain().CurrentBlock().Header()
   534  	//state := api.BlockChain().StateAt(header.Hash()).(*statedb.StateDB)
   535  	var header block.IHeader
   536  	var err error
   537  	if blockNr, ok := blockNrOrHash.Number(); ok {
   538  		if blockNr < jsonrpc.EarliestBlockNumber {
   539  			header = api.BlockChain().CurrentBlock().Header()
   540  		} else {
   541  			header = api.BlockChain().GetHeaderByNumber(uint256.NewInt(uint64(blockNr.Int64())))
   542  		}
   543  	}
   544  	if hash, ok := blockNrOrHash.Hash(); ok {
   545  		header, err = api.BlockChain().GetHeaderByHash(hash)
   546  	}
   547  	if err != nil {
   548  		return nil, err
   549  	}
   550  	//state := api.State(blockNrOrHash).(*statedb.StateDB)
   551  	tx, err := api.db.BeginRo(ctx)
   552  	if nil != err {
   553  		return nil, err
   554  	}
   555  	defer tx.Rollback()
   556  
   557  	//reader := state.NewPlainStateReader(tx)
   558  	//ibs := state.New(reader)
   559  	ibs := api.State(tx, blockNrOrHash)
   560  	if ibs == nil {
   561  		return nil, errors.New("cannot load state")
   562  	}
   563  	if err := overrides.Apply(ibs.(*state.IntraBlockState)); err != nil {
   564  		return nil, err
   565  	}
   566  	// Setup context so it may be cancelled the call has completed
   567  	// or, in case of unmetered gas, setup a context with a timeout.
   568  	var cancel context.CancelFunc
   569  	if timeout > 0 {
   570  		ctx, cancel = context.WithTimeout(ctx, timeout)
   571  	} else {
   572  		ctx, cancel = context.WithCancel(ctx)
   573  	}
   574  	// Make sure the context is cancelled when the call has completed
   575  	// this makes sure resources are cleaned up.
   576  	defer cancel()
   577  
   578  	// Get a new instance of the EVM.
   579  	msg, err := args.ToMessage(globalGasCap, header.BaseFee64().ToBig())
   580  	if err != nil {
   581  		return nil, err
   582  	}
   583  
   584  	//todo debug: , Debug: true, Tracer: vm.NewMarkdownLogger(os.Stdout)
   585  	evm, vmError, err := api.GetEvm(ctx, msg, ibs, header, &vm2.Config{NoBaseFee: true})
   586  	if err != nil {
   587  		return nil, err
   588  	}
   589  	// Wait for the context to be done and cancel the evm. Even if the
   590  	// EVM has finished, cancelling may be done (repeatedly)
   591  	go func() {
   592  		<-ctx.Done()
   593  		evm.Cancel()
   594  	}()
   595  
   596  	// Execute the message.
   597  	gp := new(common.GasPool).AddGas(math.MaxUint64)
   598  	result, err := internal.ApplyMessage(evm, msg, gp, true, false)
   599  	if err := vmError(); err != nil {
   600  		return nil, err
   601  	}
   602  
   603  	if evm.Cancelled() {
   604  		return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout)
   605  	}
   606  	if err != nil {
   607  		return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas())
   608  	}
   609  	return result, nil
   610  }
   611  
   612  func newRevertError(result *internal.ExecutionResult) *revertError {
   613  	reason, errUnpack := abi.UnpackRevert(result.Revert())
   614  	err := fmt.Errorf("execution reverted")
   615  	if errUnpack == nil {
   616  		err = fmt.Errorf("execution reverted: %v", reason)
   617  	}
   618  	return &revertError{
   619  		error:  err,
   620  		reason: hexutil.Encode(result.Revert()),
   621  	}
   622  }
   623  
   624  // revertError is an API error that encompassas an EVM revertal with JSON error
   625  // code and a binary data blob.
   626  type revertError struct {
   627  	error
   628  	reason string // revert reason hex encoded
   629  }
   630  
   631  // ErrorCode returns the JSON error code for a revertal.
   632  // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
   633  func (e *revertError) ErrorCode() int {
   634  	return 3
   635  }
   636  
   637  // ErrorData returns the hex encoded revert reason.
   638  func (e *revertError) ErrorData() interface{} {
   639  	return e.reason
   640  }
   641  
   642  // Call executes the given transaction on the state for the given block number.
   643  //
   644  // Additionally, the caller can specify a batch of contract for fields overriding.
   645  //
   646  // Note, this function doesn't make and changes in the state/blockchain and is
   647  // useful to execute and retrieve values.
   648  func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash jsonrpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) {
   649  
   650  	//b, _ := json.Marshal(args)
   651  	//log.Info("TransactionArgs %s", string(b))
   652  
   653  	result, err := DoCall(ctx, s.api, args, blockNrOrHash, overrides, rpcEVMTimeout, rpcGasCap)
   654  	if err != nil {
   655  		return nil, err
   656  	}
   657  	// If the result contains a revert reason, try to unpack and return it.
   658  	if len(result.Revert()) > 0 {
   659  		return nil, newRevertError(result)
   660  	}
   661  	return result.Return(), result.Err
   662  }
   663  
   664  func BlockByNumber(ctx context.Context, number jsonrpc.BlockNumber, n *API) (block.IBlock, error) {
   665  	// todo
   666  	// Pending block is only known by the miner
   667  	if number == jsonrpc.PendingBlockNumber {
   668  		iblock := n.BlockChain().CurrentBlock()
   669  		return iblock, nil
   670  	}
   671  	// Otherwise resolve and return the block
   672  	if number == jsonrpc.LatestBlockNumber {
   673  		iblock := n.BlockChain().CurrentBlock()
   674  		return iblock, nil
   675  	}
   676  	iblock, err := n.BlockChain().GetBlockByNumber(uint256.NewInt(uint64(number)))
   677  	if err != nil {
   678  		return nil, err
   679  	}
   680  	return iblock, nil
   681  }
   682  
   683  func BlockByNumberOrHash(ctx context.Context, blockNrOrHash jsonrpc.BlockNumberOrHash, api *API) (block.IBlock, error) {
   684  	if blockNr, ok := blockNrOrHash.Number(); ok {
   685  		if blockNr == jsonrpc.PendingBlockNumber {
   686  			return api.BlockChain().CurrentBlock(), nil
   687  		}
   688  		return BlockByNumber(ctx, blockNr, api)
   689  	}
   690  	if hash, ok := blockNrOrHash.Hash(); ok {
   691  		iblock, err := api.BlockChain().GetBlockByHash(types.Hash(hash))
   692  		if err != nil {
   693  			return nil, err
   694  		}
   695  		if iblock == nil {
   696  			return nil, errors.New("header found, but block body is missing")
   697  		}
   698  
   699  		//todo
   700  		//header := iblock.Header()
   701  		//if header == nil {
   702  		//	return nil, errors.New("header for hash not found")
   703  		//}
   704  		//iblock, err = n.BlockChain().GetBlockByNumber(header.Number64())
   705  		//if err != nil {
   706  		//	return nil, err
   707  		//}
   708  		//if blockNrOrHash.RequireCanonical && iblock.Hash() != types.Hash(hash) {
   709  		//	return nil, errors.New("hash is not currently canonical")
   710  		//}
   711  		//iblock, err = n.BlockChain().GetBlockByNumber(n.BlockChain().GetHeader(types.Hash(hash), header.Number64()).Number64())
   712  		//if err != nil {
   713  		//	return nil, err
   714  		//}
   715  		return iblock, nil
   716  	}
   717  	return nil, errors.New("invalid arguments; neither block nor hash specified")
   718  }
   719  
   720  //func StateAndHeaderByNumber(ctx context.Context, n *API, number jsonrpc.BlockNumber) (*common.IStateDB, *block.IHeader, error) {
   721  //	var header block.IHeader
   722  //	var err error
   723  //	if number == jsonrpc.PendingBlockNumber {
   724  //		header = n.BlockChain().CurrentBlock().Header()
   725  //	} else {
   726  //		header, err = n.BlockChain().GetHeaderByNumber(uint256.NewInt(uint64(number)))
   727  //	}
   728  //	if err != nil {
   729  //		return nil, nil, err
   730  //	}
   731  //	if header == nil {
   732  //		return nil, nil, errors.New("header not found")
   733  //	}
   734  //	stateDb := n.BlockChain().StateAt(header.Hash())
   735  //	return &stateDb, &header, nil
   736  //}
   737  
   738  //func StateAndHeaderByNumberOrHash(ctx context.Context, n *API, blockNrOrHash jsonrpc.BlockNumberOrHash) (*common.IStateDB, *block.IHeader, error) {
   739  //	if blockNr, ok := blockNrOrHash.Number(); ok {
   740  //		return StateAndHeaderByNumber(ctx, n, blockNr)
   741  //	}
   742  //	if hash, ok := blockNrOrHash.Hash(); ok {
   743  //		header, err := n.BlockChain().GetHeaderByHash(types.Hash(hash))
   744  //		if err != nil {
   745  //			return nil, nil, err
   746  //		}
   747  //		if header == nil {
   748  //			return nil, nil, errors.New("header for hash not found")
   749  //		}
   750  //		//todo
   751  //		//if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
   752  //		//	return nil, nil, errors.New("hash is not currently canonical")
   753  //		//}
   754  //		stateDb := n.BlockChain().StateAt(header.Hash())
   755  //		return &stateDb, &header, err
   756  //	}
   757  //	return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
   758  //}
   759  
   760  func DoEstimateGas(ctx context.Context, n *API, args TransactionArgs, blockNrOrHash jsonrpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) {
   761  	// Binary search the gas requirement, as it may be higher than the amount used
   762  	var (
   763  		lo  = params.TxGas - 1
   764  		hi  uint64
   765  		cap uint64
   766  	)
   767  	// Use zero address if sender unspecified.
   768  	if args.From == nil {
   769  		args.From = new(mvm_common.Address)
   770  	}
   771  	// Determine the highest gas limit can be used during the estimation.
   772  	if args.Gas != nil && uint64(*args.Gas) >= params.TxGas {
   773  		hi = uint64(*args.Gas)
   774  	} else {
   775  		// Retrieve the block to act as the gas ceiling
   776  		iblock, err := BlockByNumberOrHash(ctx, blockNrOrHash, n)
   777  		if err != nil {
   778  			return 0, err
   779  		}
   780  		if iblock == nil {
   781  			return 0, errors.New("block not found")
   782  		}
   783  		hi = iblock.GasLimit()
   784  	}
   785  
   786  	var feeCap *big.Int
   787  	if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
   788  		return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
   789  	} else if args.GasPrice != nil {
   790  		feeCap = args.GasPrice.ToInt()
   791  	} else if args.MaxFeePerGas != nil {
   792  		feeCap = args.MaxFeePerGas.ToInt()
   793  	} else {
   794  		feeCap = common.Big0
   795  	}
   796  	// Recap the highest gas limit with account's available balance.
   797  	if feeCap.BitLen() != 0 {
   798  		tx, err := n.db.BeginRo(ctx)
   799  		if nil != err {
   800  			return 0, err
   801  		}
   802  		defer tx.Rollback()
   803  		statedb := n.State(tx, blockNrOrHash)
   804  		if statedb == nil {
   805  			return 0, errors.New("cannot load stateDB")
   806  		}
   807  		balance := statedb.GetBalance(*mvm_types.ToAmcAddress(args.From)) // from
   808  
   809  		// can't be nil
   810  		available := new(big.Int).Set(balance.ToBig())
   811  		if args.Value != nil {
   812  			if args.Value.ToInt().Cmp(available) >= 0 {
   813  				return 0, errors.New("insufficient funds for transfer")
   814  			}
   815  			available.Sub(available, args.Value.ToInt())
   816  		}
   817  		allowance := new(big.Int).Div(available, feeCap)
   818  
   819  		// If the allowance is larger than maximum uint64, skip checking
   820  		if allowance.IsUint64() && hi > allowance.Uint64() {
   821  			transfer := args.Value
   822  			if transfer == nil {
   823  				transfer = new(hexutil.Big)
   824  			}
   825  			log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance,
   826  				"sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance)
   827  			hi = allowance.Uint64()
   828  		}
   829  	}
   830  	// Recap the highest gas allowance with specified gascap.
   831  	if gasCap != 0 && hi > gasCap {
   832  		log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
   833  		hi = gasCap
   834  	}
   835  	cap = hi
   836  
   837  	// Create a helper to check if a gas allowance results in an executable transaction
   838  	executable := func(gas uint64) (bool, *internal.ExecutionResult, error) {
   839  		args.Gas = (*hexutil.Uint64)(&gas)
   840  		result, err := DoCall(ctx, n, args, blockNrOrHash, nil, 0, gasCap)
   841  		if err != nil {
   842  			if errors.Is(err, internal.ErrIntrinsicGas) {
   843  				return true, nil, nil // Special case, raise gas limit
   844  			}
   845  			return true, nil, err // Bail out
   846  		}
   847  		return result.Failed(), result, nil
   848  	}
   849  	// Execute the binary search and hone in on an executable gas limit
   850  	for lo+1 < hi {
   851  		mid := (hi + lo) / 2
   852  		failed, _, err := executable(mid)
   853  
   854  		// If the error is not nil(consensus error), it means the provided message
   855  		// call or transaction will never be accepted no matter how much gas it is
   856  		// assigened. Return the error directly, don't struggle any more.
   857  		if err != nil {
   858  			return 0, err
   859  		}
   860  		if failed {
   861  			lo = mid
   862  		} else {
   863  			hi = mid
   864  		}
   865  	}
   866  	// Reject the transaction as invalid if it still fails at the highest allowance
   867  	if hi == cap {
   868  		failed, result, err := executable(hi)
   869  		if err != nil {
   870  			return 0, err
   871  		}
   872  		if failed {
   873  			if result != nil && !errors.Is(result.Err, vm2.ErrOutOfGas) {
   874  				if len(result.Revert()) > 0 {
   875  					return 0, newRevertError(result)
   876  				}
   877  				return 0, result.Err
   878  			}
   879  			// Otherwise, the specified gas cap is too low
   880  			return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap)
   881  		}
   882  	}
   883  	return hexutil.Uint64(hi), nil
   884  	//return hexutil.Uint64(baseFee), nil
   885  }
   886  
   887  // EstimateGas returns an estimate of the amount of gas needed to execute the
   888  // given transaction against the current pending block.
   889  func (s *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *jsonrpc.BlockNumberOrHash) (hexutil.Uint64, error) {
   890  	bNrOrHash := jsonrpc.BlockNumberOrHashWithNumber(jsonrpc.PendingBlockNumber)
   891  	if blockNrOrHash != nil {
   892  		bNrOrHash = *blockNrOrHash
   893  	}
   894  	return DoEstimateGas(ctx, s.api, args, bNrOrHash, rpcGasCap)
   895  }
   896  
   897  // GetBlockByNumber returns the requested canonical block.
   898  //   - When blockNr is -1 the chain head is returned.
   899  //   - When blockNr is -2 the pending chain head is returned.
   900  //   - When fullTx is true all transactions in the block are returned, otherwise
   901  //     only the transaction hash is returned.
   902  func (s *BlockChainAPI) GetBlockByNumber(ctx context.Context, number jsonrpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
   903  
   904  	var (
   905  		block block.IBlock
   906  		err   error
   907  	)
   908  	// header
   909  	if number == jsonrpc.LatestBlockNumber {
   910  		block = s.api.BlockChain().CurrentBlock()
   911  		err = nil
   912  	} else {
   913  		block, err = s.api.BlockChain().GetBlockByNumber(uint256.NewInt(uint64(number.Int64())))
   914  	}
   915  
   916  	if block != nil && err == nil {
   917  		response, err := RPCMarshalBlock(block, s.api.BlockChain(), true, fullTx)
   918  		if err == nil && number == jsonrpc.PendingBlockNumber {
   919  			// Pending blocks need to nil out a few fields
   920  			for _, field := range []string{"hash", "nonce", "miner"} {
   921  				response[field] = nil
   922  			}
   923  		}
   924  		return response, err
   925  	}
   926  
   927  	return nil, err
   928  }
   929  
   930  // GetBlockByHash get block by hash
   931  func (s *BlockChainAPI) GetBlockByHash(ctx context.Context, hash mvm_common.Hash, fullTx bool) (map[string]interface{}, error) {
   932  	block, err := s.api.BlockChain().GetBlockByHash(mvm_types.ToAmcHash(hash))
   933  
   934  	if block != nil {
   935  		return RPCMarshalBlock(block, s.api.BlockChain(), true, fullTx)
   936  	}
   937  	return nil, err
   938  }
   939  
   940  func (s *BlockChainAPI) MinedBlock(ctx context.Context, address types.Address) (*jsonrpc.Subscription, error) {
   941  	notifier, supported := jsonrpc.NotifierFromContext(ctx)
   942  	if !supported {
   943  		return &jsonrpc.Subscription{}, jsonrpc.ErrNotificationsUnsupported
   944  	}
   945  
   946  	if is, err := IsDeposit(s.api.db, address); nil != err || !is {
   947  		if nil != err {
   948  			log.Errorf("IsDeposit(%s) failed, err= %v", address, err)
   949  		}
   950  		return &jsonrpc.Subscription{}, fmt.Errorf("unauthed address: %s", address)
   951  	}
   952  
   953  	rpcSub := notifier.CreateSubscription()
   954  	go func() {
   955  		entire := make(chan common.MinedEntireEvent, 20)
   956  		blocksSub := event.GlobalEvent.Subscribe(entire)
   957  		for {
   958  			select {
   959  			case b := <-entire:
   960  				var pushData state.EntireCode
   961  				pushData.Entire = b.Entire.Entire.Clone()
   962  				pushData.Entire.Header.Root = types.Hash{}
   963  				pushData.Headers = b.Entire.Headers
   964  				pushData.Codes = b.Entire.Codes
   965  				pushData.Rewards = b.Entire.Rewards
   966  				pushData.CoinBase = b.Entire.CoinBase
   967  				log.Trace("send mining block", "addr", address, "blockNr", b.Entire.Entire.Header.Number.Hex(), "blockTime", time.Unix(int64(b.Entire.Entire.Header.Time), 0).Format(time.RFC3339))
   968  				notifier.Notify(rpcSub.ID, pushData)
   969  			case <-rpcSub.Err():
   970  				blocksSub.Unsubscribe()
   971  				return
   972  			case <-notifier.Closed():
   973  				blocksSub.Unsubscribe()
   974  				return
   975  			}
   976  		}
   977  	}()
   978  	return rpcSub, nil
   979  }
   980  
   981  func (s *BlockChainAPI) SubmitSign(sign AggSign) error {
   982  	info := DepositInfo(s.api.db, sign.Address)
   983  	if nil == info {
   984  		return fmt.Errorf("unauthed address: %s", sign.Address)
   985  	}
   986  	sign.PublicKey.SetBytes(info.PublicKey.Bytes())
   987  	go func() {
   988  		sigChannel <- sign
   989  	}()
   990  	return nil
   991  }
   992  
   993  // TransactionAPI exposes methods for reading and creating transaction data.
   994  type TransactionAPI struct {
   995  	api       *API
   996  	nonceLock *AddrLocker
   997  	//signer    types.Signer
   998  }
   999  
  1000  // NewTransactionAPI creates a new RPC service with methods for interacting with transactions.
  1001  func NewTransactionAPI(api *API, nonceLock *AddrLocker) *TransactionAPI {
  1002  	//signer := types.LatestSigner(b.ChainConfig())
  1003  	return &TransactionAPI{api, nonceLock}
  1004  }
  1005  
  1006  // GetTransactionCount returns the number of transactions the given address has sent for the given block number
  1007  func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address mvm_common.Address, blockNrOrHash jsonrpc.BlockNumberOrHash) (*hexutil.Uint64, error) {
  1008  
  1009  	if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == jsonrpc.PendingBlockNumber {
  1010  		nonce := s.api.TxsPool().Nonce(*mvm_types.ToAmcAddress(&address))
  1011  		return (*hexutil.Uint64)(&nonce), nil
  1012  	}
  1013  
  1014  	tx, err := s.api.db.BeginRo(ctx)
  1015  	if nil != err {
  1016  		return nil, err
  1017  	}
  1018  	defer tx.Rollback()
  1019  
  1020  	state := s.api.State(tx, blockNrOrHash)
  1021  	if state == nil {
  1022  		return nil, nil
  1023  	}
  1024  	nonce := state.GetNonce(*mvm_types.ToAmcAddress(&address))
  1025  	return (*hexutil.Uint64)(&nonce), nil
  1026  
  1027  }
  1028  
  1029  func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (mvm_common.Hash, error) {
  1030  
  1031  	//log.Debugf("tx type is : %s", string(input[0]))
  1032  	tx := new(mvm_types.Transaction)
  1033  	err := tx.UnmarshalBinary(input)
  1034  	if err != nil {
  1035  		return mvm_common.Hash{}, err
  1036  	}
  1037  	header := s.api.BlockChain().CurrentBlock().Header() // latest header should always be available
  1038  	metaTx, err := tx.ToAmcTransaction(s.api.GetChainConfig(), header.Number64().ToBig())
  1039  	if err != nil {
  1040  		return mvm_common.Hash{}, err
  1041  	}
  1042  	return SubmitTransaction(context.Background(), s.api, metaTx)
  1043  }
  1044  
  1045  func (s *TransactionAPI) BatchRawTransaction(ctx context.Context, inputs []hexutil.Bytes) ([]mvm_common.Hash, error) {
  1046  
  1047  	//log.Debugf("tx type is : %s", string(input[0]))
  1048  	hs := make([]mvm_common.Hash, len(inputs))
  1049  	for i, t := range inputs {
  1050  		tx := new(mvm_types.Transaction)
  1051  		err := tx.UnmarshalBinary(t)
  1052  		if err != nil {
  1053  			hs[i] = mvm_common.Hash{}
  1054  			return hs, err
  1055  		}
  1056  		header := s.api.BlockChain().CurrentBlock().Header() // latest header should always be available
  1057  		metaTx, err := tx.ToAmcTransaction(s.api.GetChainConfig(), header.Number64().ToBig())
  1058  		if err != nil {
  1059  			hs[i] = mvm_common.Hash{}
  1060  			return hs, err
  1061  		}
  1062  
  1063  		if hs[i], err = SubmitTransaction(context.Background(), s.api, metaTx); nil != err {
  1064  			return hs, err
  1065  		}
  1066  	}
  1067  	return hs, nil
  1068  }
  1069  
  1070  // GetTransactionReceipt returns the transaction receipt for the given transaction hash.
  1071  func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash mvm_common.Hash) (map[string]interface{}, error) {
  1072  	var tx *transaction.Transaction
  1073  	var blockHash types.Hash
  1074  	var index uint64
  1075  	var blockNumber uint64
  1076  	var err error
  1077  	s.api.Database().View(ctx, func(t kv.Tx) error {
  1078  		tx, blockHash, blockNumber, index, err = rawdb.ReadTransactionByHash(t, mvm_types.ToAmcHash(hash))
  1079  		if err != nil || tx == nil {
  1080  			log.Tracef("rawdb.ReadTransactionByHash, err = %v, txhash = %v \n", err, hash)
  1081  			// When the transaction doesn't exist, the RPC method should return JSON null
  1082  			// as per specification.
  1083  		}
  1084  		return nil
  1085  	})
  1086  	if tx == nil {
  1087  		return nil, nil
  1088  	}
  1089  	//tx, blockHash, blockNumber, index, err := rawdb.ReadTransactionByHash(s.api.Database().(kv.Tx), mvm_types.ToAmcHash(hash))
  1090  	//if err != nil || tx == nil {
  1091  	//	// When the transaction doesn't exist, the RPC method should return JSON null
  1092  	//	// as per specification.
  1093  	//	return nil, nil
  1094  	//}
  1095  	//log.Infof("GetTransactionReceipt, hash %+v , %+v, %+v, %+v", tx, blockHash, blockNumber, index)
  1096  	receipts, err := s.api.BlockChain().GetReceipts(blockHash)
  1097  
  1098  	//log.Infof("GetTransactionReceipt, receipts %+v", receipts)
  1099  	if err != nil {
  1100  		return nil, err
  1101  	}
  1102  	if len(receipts) <= int(index) {
  1103  		return nil, nil
  1104  	}
  1105  	receipt := receipts[index]
  1106  
  1107  	from := tx.From()
  1108  	fields := map[string]interface{}{
  1109  		"blockHash":         mvm_types.FromAmcHash(blockHash),
  1110  		"blockNumber":       hexutil.Uint64(blockNumber),
  1111  		"transactionHash":   hash,
  1112  		"transactionIndex":  hexutil.Uint64(index),
  1113  		"from":              mvm_types.FromAmcAddress(from),
  1114  		"to":                mvm_types.FromAmcAddress(tx.To()),
  1115  		"gasUsed":           hexutil.Uint64(receipt.GasUsed),
  1116  		"cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
  1117  		"contractAddress":   nil,
  1118  		"logsBloom":         receipt.Bloom, //receipt.Bloom
  1119  		"type":              hexutil.Uint(tx.Type()),
  1120  	}
  1121  	// Assign the effective gas price paid
  1122  	//todo !IsLondon
  1123  	if false {
  1124  		fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
  1125  	} else {
  1126  		header, err := s.api.BlockChain().GetHeaderByHash(blockHash)
  1127  		if err != nil {
  1128  			return nil, err
  1129  		}
  1130  		gasPrice := new(big.Int).Add(header.BaseFee64().ToBig(), tx.EffectiveGasTipValue(header.BaseFee64()).ToBig())
  1131  		fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64())
  1132  	}
  1133  	// Assign receipt status or post state.
  1134  	if len(receipt.PostState) > 0 {
  1135  		fields["root"] = hexutil.Bytes(receipt.PostState)
  1136  	} else {
  1137  		fields["status"] = hexutil.Uint(receipt.Status)
  1138  	}
  1139  	if receipt.Logs == nil {
  1140  		fields["logs"] = []*mvm_types.Log{}
  1141  	} else {
  1142  		fields["logs"] = mvm_types.FromAmcLogs(receipt.Logs)
  1143  	}
  1144  	// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
  1145  	if !receipt.ContractAddress.IsNull() {
  1146  		fields["contractAddress"] = mvm_types.FromAmcAddress(&receipt.ContractAddress)
  1147  	}
  1148  
  1149  	//json, _ := json.Marshal(fields)
  1150  	//log.Infof("GetTransactionReceipt, result %s", string(json))
  1151  	return fields, nil
  1152  }
  1153  
  1154  // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
  1155  func (s *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash mvm_common.Hash) *hexutil.Uint {
  1156  	if block, _ := s.api.BlockChain().GetBlockByHash(mvm_types.ToAmcHash(blockHash)); block != nil {
  1157  		n := hexutil.Uint(len(block.Transactions()))
  1158  		return &n
  1159  	}
  1160  	return nil
  1161  }
  1162  
  1163  // GetTransactionByHash returns the transaction for the given hash
  1164  func (s *TransactionAPI) GetTransactionByHash(ctx context.Context, hash mvm_common.Hash) (*RPCTransaction, error) {
  1165  	var (
  1166  		tx          *transaction.Transaction
  1167  		blockHash   types.Hash
  1168  		blockNumber uint64
  1169  		index       uint64
  1170  		err         error
  1171  	)
  1172  	if err := s.api.Database().View(ctx, func(t kv.Tx) error {
  1173  		tx, blockHash, blockNumber, index, err = rawdb.ReadTransactionByHash(t, mvm_types.ToAmcHash(hash))
  1174  		if err != nil {
  1175  			// When the transaction doesn't exist, the RPC method should return JSON null
  1176  			// as per specification.
  1177  			return err
  1178  		}
  1179  		return nil
  1180  	}); nil != err {
  1181  		return nil, err
  1182  	}
  1183  	//tx, blockHash, blockNumber, index, err := rawdb.ReadTransactionByHash(s.api.Database().(kv.Tx), mvm_types.ToAmcHash(hash))
  1184  	//if err != nil {
  1185  	//	// When the transaction doesn't exist, the RPC method should return JSON null
  1186  	//	// as per specification.
  1187  	//	return nil, err
  1188  	//}
  1189  
  1190  	if tx != nil {
  1191  		header := s.api.BlockChain().GetHeaderByNumber(uint256.NewInt(blockNumber))
  1192  		if header == nil {
  1193  			return nil, nil
  1194  		}
  1195  		return newRPCTransaction(tx, blockHash, blockNumber, index, header.BaseFee64().ToBig()), nil
  1196  	}
  1197  
  1198  	if tx := s.api.TxsPool().GetTx(mvm_types.ToAmcHash(hash)); tx != nil {
  1199  		return newRPCPendingTransaction(tx, s.api.BlockChain().CurrentBlock().Header()), nil
  1200  	}
  1201  
  1202  	return nil, nil
  1203  }
  1204  
  1205  // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
  1206  func (s *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash mvm_common.Hash, index hexutil.Uint) *RPCTransaction {
  1207  	if block, _ := s.api.BlockChain().GetBlockByHash(mvm_types.ToAmcHash(blockHash)); block != nil {
  1208  		for i, tx := range block.Transactions() {
  1209  			if i == int(index) {
  1210  				return newRPCTransaction(tx, mvm_types.ToAmcHash(blockHash), block.Number64().Uint64(), uint64(index), block.Header().BaseFee64().ToBig())
  1211  			}
  1212  		}
  1213  	}
  1214  	return nil
  1215  }
  1216  
  1217  // SubmitTransaction ?
  1218  func SubmitTransaction(ctx context.Context, api *API, tx *transaction.Transaction) (mvm_common.Hash, error) {
  1219  
  1220  	if err := checkTxFee(*tx.GasPrice(), tx.Gas(), baseFee); err != nil {
  1221  		return mvm_common.Hash{}, err
  1222  	}
  1223  
  1224  	if err := api.TxsPool().AddLocal(tx); err != nil {
  1225  		return mvm_common.Hash{}, err
  1226  	}
  1227  
  1228  	if tx.To() == nil {
  1229  		//log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value())
  1230  	} else {
  1231  		//log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value())
  1232  	}
  1233  	hash := tx.Hash()
  1234  	return mvm_types.FromAmcHash(hash), nil
  1235  }
  1236  
  1237  // SendTransaction Send Transaction
  1238  func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionArgs) (mvm_common.Hash, error) {
  1239  	// Look up the wallet containing the requested signer
  1240  	account := accounts.Account{Address: args.from()}
  1241  
  1242  	//wallet, err := s.b.AccountManager().Find(account)
  1243  	wallet, err := s.api.accountManager.Find(account)
  1244  	if err != nil {
  1245  		return mvm_common.Hash{}, err
  1246  	}
  1247  
  1248  	if args.Nonce == nil {
  1249  		s.nonceLock.LockAddr(args.from())
  1250  		defer s.nonceLock.UnlockAddr(args.from())
  1251  	}
  1252  
  1253  	if err := args.setDefaults(ctx, s.api); err != nil {
  1254  		return mvm_common.Hash{}, err
  1255  	}
  1256  	//header := s.api.BlockChain().CurrentBlock().Header()
  1257  	tx := args.toTransaction()
  1258  
  1259  	signed, err := wallet.SignTx(account, tx, s.api.GetChainConfig().ChainID)
  1260  	if err != nil {
  1261  		return mvm_common.Hash{}, err
  1262  	}
  1263  	// todo sign?
  1264  	//signed := tx
  1265  	return SubmitTransaction(ctx, s.api, signed)
  1266  }
  1267  
  1268  // checkTxFee  todo
  1269  func checkTxFee(gasPrice uint256.Int, gas uint64, cap float64) error {
  1270  	return nil
  1271  }
  1272  
  1273  // toHexSlice creates a slice of hex-strings based on []byte.
  1274  func toHexSlice(b [][]byte) []string {
  1275  	r := make([]string, len(b))
  1276  	for i := range b {
  1277  		r[i] = hexutil.Encode(b[i])
  1278  	}
  1279  	return r
  1280  }
  1281  
  1282  type Web3API struct {
  1283  	stack *API
  1284  }
  1285  
  1286  func (s *Web3API) ClientVersion() string {
  1287  	return "testName"
  1288  }
  1289  
  1290  func (s *Web3API) Sha3(input hexutil.Bytes) hexutil.Bytes {
  1291  	return crypto.Keccak256(input)
  1292  }
  1293  
  1294  type DebugAPI struct {
  1295  	api *API
  1296  }
  1297  
  1298  // NewDebugAPI creates a new instance of DebugAPI.
  1299  func NewDebugAPI(api *API) *DebugAPI {
  1300  	return &DebugAPI{api: api}
  1301  }
  1302  
  1303  // SetHead rewinds the head of the blockchain to a previous block.
  1304  func (api *DebugAPI) SetHead(number hexutil.Uint64) {
  1305  	api.api.BlockChain().SetHead(uint64(number))
  1306  }
  1307  
  1308  func (debug *DebugAPI) GetAccount(ctx context.Context, address types.Address) {
  1309  
  1310  }
  1311  
  1312  // NetAPI offers network related RPC methods
  1313  type NetAPI struct {
  1314  	api            *API
  1315  	networkVersion uint64
  1316  }
  1317  
  1318  // NewNetAPI creates a new net API instance.
  1319  func NewNetAPI(api *API, networkVersion uint64) *NetAPI {
  1320  	return &NetAPI{api, networkVersion}
  1321  }
  1322  
  1323  // Listening returns an indication if the node is listening for network connections.
  1324  func (s *NetAPI) Listening() bool {
  1325  	return true // always listening
  1326  }
  1327  
  1328  // PeerCount returns the number of connected peers
  1329  func (s *NetAPI) PeerCount() hexutil.Uint {
  1330  	//return hexutil.Uint(s.api.P2pServer().PeerCount())
  1331  	return 0
  1332  }
  1333  
  1334  // Version returns the current ethereum protocol version.
  1335  func (s *NetAPI) Version() string {
  1336  	//todo networkID == chainID? s.api.GetChainConfig().ChainID
  1337  	return fmt.Sprintf("%d", s.networkVersion)
  1338  }
  1339  
  1340  // TxsPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential.
  1341  type TxsPoolAPI struct {
  1342  	api *API
  1343  }
  1344  
  1345  // NewTxsPoolAPI creates a new tx pool service that gives information about the transaction pool.
  1346  func NewTxsPoolAPI(api *API) *TxsPoolAPI {
  1347  	return &TxsPoolAPI{api}
  1348  }
  1349  
  1350  // Content returns the transactions contained within the transaction pool.
  1351  func (s *TxsPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction {
  1352  	content := map[string]map[string]map[string]*RPCTransaction{
  1353  		"pending": make(map[string]map[string]*RPCTransaction),
  1354  		"queued":  make(map[string]map[string]*RPCTransaction),
  1355  	}
  1356  	pending, queue := s.api.TxsPool().Content()
  1357  	curHeader := s.api.BlockChain().CurrentBlock().Header()
  1358  	// Flatten the pending transactions
  1359  	for account, txs := range pending {
  1360  		dump := make(map[string]*RPCTransaction)
  1361  		for _, tx := range txs {
  1362  			dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader)
  1363  		}
  1364  		content["pending"][mvm_types.FromAmcAddress(&account).Hex()] = dump
  1365  	}
  1366  	// Flatten the queued transactions
  1367  	for account, txs := range queue {
  1368  		dump := make(map[string]*RPCTransaction)
  1369  		for _, tx := range txs {
  1370  			dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader)
  1371  		}
  1372  		content["queued"][mvm_types.FromAmcAddress(&account).Hex()] = dump
  1373  	}
  1374  	return content
  1375  }
  1376  
  1377  func (api *TransactionAPI) TestBatchTxs(ctx context.Context) {
  1378  	go batchTxs(api.api, 0, 1000000)
  1379  }
  1380  
  1381  func batchTxs(api *API, start, end uint64) error {
  1382  	var (
  1383  		key, _  = crypto.HexToECDSA("d6d8d19bd786d6676819b806694b1100a4414a94e51e9a82a351bd8f7f3f3658")
  1384  		addr    = crypto.PubkeyToAddress(key.PublicKey)
  1385  		signer  = new(transaction.HomesteadSigner)
  1386  		content = context.Background()
  1387  	)
  1388  
  1389  	for i := start; i < end; i++ {
  1390  		tx, _ := transaction.SignTx(transaction.NewTx(
  1391  			&transaction.LegacyTx{
  1392  				Nonce:    uint64(i),
  1393  				Value:    uint256.NewInt(params.Wei),
  1394  				Gas:      params.TxGas,
  1395  				To:       &addr,
  1396  				GasPrice: uint256.NewInt(params.GWei),
  1397  				Data:     nil},
  1398  		), signer, key)
  1399  		tx.SetFrom(addr)
  1400  		_, err := SubmitTransaction(content, api, tx)
  1401  		if nil != err {
  1402  			return err
  1403  		}
  1404  	}
  1405  	return nil
  1406  }