github.com/zhiqiangxu/go-ethereum@v1.9.16-0.20210824055606-be91cfdebc48/cmd/geth/retesteth.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU 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  // go-ethereum 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 General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"fmt"
    23  	"math/big"
    24  	"os"
    25  	"os/signal"
    26  	"strings"
    27  	"time"
    28  
    29  	"github.com/zhiqiangxu/go-ethereum/cmd/utils"
    30  	"github.com/zhiqiangxu/go-ethereum/common"
    31  	"github.com/zhiqiangxu/go-ethereum/common/hexutil"
    32  	"github.com/zhiqiangxu/go-ethereum/common/math"
    33  	"github.com/zhiqiangxu/go-ethereum/consensus"
    34  	"github.com/zhiqiangxu/go-ethereum/consensus/ethash"
    35  	"github.com/zhiqiangxu/go-ethereum/consensus/misc"
    36  	"github.com/zhiqiangxu/go-ethereum/core"
    37  	"github.com/zhiqiangxu/go-ethereum/core/rawdb"
    38  	"github.com/zhiqiangxu/go-ethereum/core/state"
    39  	"github.com/zhiqiangxu/go-ethereum/core/types"
    40  	"github.com/zhiqiangxu/go-ethereum/core/vm"
    41  	"github.com/zhiqiangxu/go-ethereum/crypto"
    42  	"github.com/zhiqiangxu/go-ethereum/ethdb"
    43  	"github.com/zhiqiangxu/go-ethereum/log"
    44  	"github.com/zhiqiangxu/go-ethereum/node"
    45  	"github.com/zhiqiangxu/go-ethereum/params"
    46  	"github.com/zhiqiangxu/go-ethereum/rlp"
    47  	"github.com/zhiqiangxu/go-ethereum/rpc"
    48  	"github.com/zhiqiangxu/go-ethereum/trie"
    49  
    50  	cli "gopkg.in/urfave/cli.v1"
    51  )
    52  
    53  var (
    54  	rpcPortFlag = cli.IntFlag{
    55  		Name:  "rpcport",
    56  		Usage: "HTTP-RPC server listening port",
    57  		Value: node.DefaultHTTPPort,
    58  	}
    59  	retestethCommand = cli.Command{
    60  		Action:      utils.MigrateFlags(retesteth),
    61  		Name:        "retesteth",
    62  		Usage:       "Launches geth in retesteth mode",
    63  		ArgsUsage:   "",
    64  		Flags:       []cli.Flag{rpcPortFlag},
    65  		Category:    "MISCELLANEOUS COMMANDS",
    66  		Description: `Launches geth in retesteth mode (no database, no network, only retesteth RPC interface)`,
    67  	}
    68  )
    69  
    70  type RetestethTestAPI interface {
    71  	SetChainParams(ctx context.Context, chainParams ChainParams) (bool, error)
    72  	MineBlocks(ctx context.Context, number uint64) (bool, error)
    73  	ModifyTimestamp(ctx context.Context, interval uint64) (bool, error)
    74  	ImportRawBlock(ctx context.Context, rawBlock hexutil.Bytes) (common.Hash, error)
    75  	RewindToBlock(ctx context.Context, number uint64) (bool, error)
    76  	GetLogHash(ctx context.Context, txHash common.Hash) (common.Hash, error)
    77  }
    78  
    79  type RetestethEthAPI interface {
    80  	SendRawTransaction(ctx context.Context, rawTx hexutil.Bytes) (common.Hash, error)
    81  	BlockNumber(ctx context.Context) (uint64, error)
    82  	GetBlockByNumber(ctx context.Context, blockNr math.HexOrDecimal64, fullTx bool) (map[string]interface{}, error)
    83  	GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error)
    84  	GetBalance(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (*math.HexOrDecimal256, error)
    85  	GetCode(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (hexutil.Bytes, error)
    86  	GetTransactionCount(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (uint64, error)
    87  }
    88  
    89  type RetestethDebugAPI interface {
    90  	AccountRange(ctx context.Context,
    91  		blockHashOrNumber *math.HexOrDecimal256, txIndex uint64,
    92  		addressHash *math.HexOrDecimal256, maxResults uint64,
    93  	) (AccountRangeResult, error)
    94  	StorageRangeAt(ctx context.Context,
    95  		blockHashOrNumber *math.HexOrDecimal256, txIndex uint64,
    96  		address common.Address,
    97  		begin *math.HexOrDecimal256, maxResults uint64,
    98  	) (StorageRangeResult, error)
    99  }
   100  
   101  type RetestWeb3API interface {
   102  	ClientVersion(ctx context.Context) (string, error)
   103  }
   104  
   105  type RetestethAPI struct {
   106  	ethDb         ethdb.Database
   107  	db            state.Database
   108  	chainConfig   *params.ChainConfig
   109  	author        common.Address
   110  	extraData     []byte
   111  	genesisHash   common.Hash
   112  	engine        *NoRewardEngine
   113  	blockchain    *core.BlockChain
   114  	txMap         map[common.Address]map[uint64]*types.Transaction // Sender -> Nonce -> Transaction
   115  	txSenders     map[common.Address]struct{}                      // Set of transaction senders
   116  	blockInterval uint64
   117  }
   118  
   119  type ChainParams struct {
   120  	SealEngine string                            `json:"sealEngine"`
   121  	Params     CParamsParams                     `json:"params"`
   122  	Genesis    CParamsGenesis                    `json:"genesis"`
   123  	Accounts   map[common.Address]CParamsAccount `json:"accounts"`
   124  }
   125  
   126  type CParamsParams struct {
   127  	AccountStartNonce          math.HexOrDecimal64   `json:"accountStartNonce"`
   128  	HomesteadForkBlock         *math.HexOrDecimal64  `json:"homesteadForkBlock"`
   129  	EIP150ForkBlock            *math.HexOrDecimal64  `json:"EIP150ForkBlock"`
   130  	EIP158ForkBlock            *math.HexOrDecimal64  `json:"EIP158ForkBlock"`
   131  	DaoHardforkBlock           *math.HexOrDecimal64  `json:"daoHardforkBlock"`
   132  	ByzantiumForkBlock         *math.HexOrDecimal64  `json:"byzantiumForkBlock"`
   133  	ConstantinopleForkBlock    *math.HexOrDecimal64  `json:"constantinopleForkBlock"`
   134  	ConstantinopleFixForkBlock *math.HexOrDecimal64  `json:"constantinopleFixForkBlock"`
   135  	IstanbulBlock              *math.HexOrDecimal64  `json:"istanbulForkBlock"`
   136  	ChainID                    *math.HexOrDecimal256 `json:"chainID"`
   137  	MaximumExtraDataSize       math.HexOrDecimal64   `json:"maximumExtraDataSize"`
   138  	TieBreakingGas             bool                  `json:"tieBreakingGas"`
   139  	MinGasLimit                math.HexOrDecimal64   `json:"minGasLimit"`
   140  	MaxGasLimit                math.HexOrDecimal64   `json:"maxGasLimit"`
   141  	GasLimitBoundDivisor       math.HexOrDecimal64   `json:"gasLimitBoundDivisor"`
   142  	MinimumDifficulty          math.HexOrDecimal256  `json:"minimumDifficulty"`
   143  	DifficultyBoundDivisor     math.HexOrDecimal256  `json:"difficultyBoundDivisor"`
   144  	DurationLimit              math.HexOrDecimal256  `json:"durationLimit"`
   145  	BlockReward                math.HexOrDecimal256  `json:"blockReward"`
   146  	NetworkID                  math.HexOrDecimal256  `json:"networkID"`
   147  }
   148  
   149  type CParamsGenesis struct {
   150  	Nonce      math.HexOrDecimal64   `json:"nonce"`
   151  	Difficulty *math.HexOrDecimal256 `json:"difficulty"`
   152  	MixHash    *math.HexOrDecimal256 `json:"mixHash"`
   153  	Author     common.Address        `json:"author"`
   154  	Timestamp  math.HexOrDecimal64   `json:"timestamp"`
   155  	ParentHash common.Hash           `json:"parentHash"`
   156  	ExtraData  hexutil.Bytes         `json:"extraData"`
   157  	GasLimit   math.HexOrDecimal64   `json:"gasLimit"`
   158  }
   159  
   160  type CParamsAccount struct {
   161  	Balance     *math.HexOrDecimal256 `json:"balance"`
   162  	Precompiled *CPAccountPrecompiled `json:"precompiled"`
   163  	Code        hexutil.Bytes         `json:"code"`
   164  	Storage     map[string]string     `json:"storage"`
   165  	Nonce       *math.HexOrDecimal64  `json:"nonce"`
   166  }
   167  
   168  type CPAccountPrecompiled struct {
   169  	Name          string                `json:"name"`
   170  	StartingBlock math.HexOrDecimal64   `json:"startingBlock"`
   171  	Linear        *CPAPrecompiledLinear `json:"linear"`
   172  }
   173  
   174  type CPAPrecompiledLinear struct {
   175  	Base uint64 `json:"base"`
   176  	Word uint64 `json:"word"`
   177  }
   178  
   179  type AccountRangeResult struct {
   180  	AddressMap map[common.Hash]common.Address `json:"addressMap"`
   181  	NextKey    common.Hash                    `json:"nextKey"`
   182  }
   183  
   184  type StorageRangeResult struct {
   185  	Complete bool                   `json:"complete"`
   186  	Storage  map[common.Hash]SRItem `json:"storage"`
   187  }
   188  
   189  type SRItem struct {
   190  	Key   string `json:"key"`
   191  	Value string `json:"value"`
   192  }
   193  
   194  type NoRewardEngine struct {
   195  	inner     consensus.Engine
   196  	rewardsOn bool
   197  }
   198  
   199  func (e *NoRewardEngine) Author(header *types.Header) (common.Address, error) {
   200  	return e.inner.Author(header)
   201  }
   202  
   203  func (e *NoRewardEngine) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   204  	return e.inner.VerifyHeader(chain, header, seal)
   205  }
   206  
   207  func (e *NoRewardEngine) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   208  	return e.inner.VerifyHeaders(chain, headers, seals)
   209  }
   210  
   211  func (e *NoRewardEngine) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   212  	return e.inner.VerifyUncles(chain, block)
   213  }
   214  
   215  func (e *NoRewardEngine) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   216  	return e.inner.VerifySeal(chain, header)
   217  }
   218  
   219  func (e *NoRewardEngine) Prepare(chain consensus.ChainReader, header *types.Header) error {
   220  	return e.inner.Prepare(chain, header)
   221  }
   222  
   223  func (e *NoRewardEngine) accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
   224  	// Simply touch miner and uncle coinbase accounts
   225  	reward := big.NewInt(0)
   226  	for _, uncle := range uncles {
   227  		state.AddBalance(uncle.Coinbase, reward)
   228  	}
   229  	state.AddBalance(header.Coinbase, reward)
   230  }
   231  
   232  func (e *NoRewardEngine) Finalize(chain consensus.ChainReader, header *types.Header, statedb *state.StateDB, txs []*types.Transaction,
   233  	uncles []*types.Header) {
   234  	if e.rewardsOn {
   235  		e.inner.Finalize(chain, header, statedb, txs, uncles)
   236  	} else {
   237  		e.accumulateRewards(chain.Config(), statedb, header, uncles)
   238  		header.Root = statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   239  	}
   240  }
   241  
   242  func (e *NoRewardEngine) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, statedb *state.StateDB, txs []*types.Transaction,
   243  	uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   244  	if e.rewardsOn {
   245  		return e.inner.FinalizeAndAssemble(chain, header, statedb, txs, uncles, receipts)
   246  	} else {
   247  		e.accumulateRewards(chain.Config(), statedb, header, uncles)
   248  		header.Root = statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   249  
   250  		// Header seems complete, assemble into a block and return
   251  		return types.NewBlock(header, txs, uncles, receipts), nil
   252  	}
   253  }
   254  
   255  func (e *NoRewardEngine) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
   256  	return e.inner.Seal(chain, block, results, stop)
   257  }
   258  
   259  func (e *NoRewardEngine) SealHash(header *types.Header) common.Hash {
   260  	return e.inner.SealHash(header)
   261  }
   262  
   263  func (e *NoRewardEngine) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   264  	return e.inner.CalcDifficulty(chain, time, parent)
   265  }
   266  
   267  func (e *NoRewardEngine) APIs(chain consensus.ChainReader) []rpc.API {
   268  	return e.inner.APIs(chain)
   269  }
   270  
   271  func (e *NoRewardEngine) Close() error {
   272  	return e.inner.Close()
   273  }
   274  
   275  func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainParams) (bool, error) {
   276  	// Clean up
   277  	if api.blockchain != nil {
   278  		api.blockchain.Stop()
   279  	}
   280  	if api.engine != nil {
   281  		api.engine.Close()
   282  	}
   283  	if api.ethDb != nil {
   284  		api.ethDb.Close()
   285  	}
   286  	ethDb := rawdb.NewMemoryDatabase()
   287  	accounts := make(core.GenesisAlloc)
   288  	for address, account := range chainParams.Accounts {
   289  		balance := big.NewInt(0)
   290  		if account.Balance != nil {
   291  			balance.Set((*big.Int)(account.Balance))
   292  		}
   293  		var nonce uint64
   294  		if account.Nonce != nil {
   295  			nonce = uint64(*account.Nonce)
   296  		}
   297  		if account.Precompiled == nil || account.Balance != nil {
   298  			storage := make(map[common.Hash]common.Hash)
   299  			for k, v := range account.Storage {
   300  				storage[common.HexToHash(k)] = common.HexToHash(v)
   301  			}
   302  			accounts[address] = core.GenesisAccount{
   303  				Balance: balance,
   304  				Code:    account.Code,
   305  				Nonce:   nonce,
   306  				Storage: storage,
   307  			}
   308  		}
   309  	}
   310  	chainId := big.NewInt(1)
   311  	if chainParams.Params.ChainID != nil {
   312  		chainId.Set((*big.Int)(chainParams.Params.ChainID))
   313  	}
   314  	var (
   315  		homesteadBlock      *big.Int
   316  		daoForkBlock        *big.Int
   317  		eip150Block         *big.Int
   318  		eip155Block         *big.Int
   319  		eip158Block         *big.Int
   320  		byzantiumBlock      *big.Int
   321  		constantinopleBlock *big.Int
   322  		petersburgBlock     *big.Int
   323  		istanbulBlock       *big.Int
   324  	)
   325  	if chainParams.Params.HomesteadForkBlock != nil {
   326  		homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock))
   327  	}
   328  	if chainParams.Params.DaoHardforkBlock != nil {
   329  		daoForkBlock = big.NewInt(int64(*chainParams.Params.DaoHardforkBlock))
   330  	}
   331  	if chainParams.Params.EIP150ForkBlock != nil {
   332  		eip150Block = big.NewInt(int64(*chainParams.Params.EIP150ForkBlock))
   333  	}
   334  	if chainParams.Params.EIP158ForkBlock != nil {
   335  		eip158Block = big.NewInt(int64(*chainParams.Params.EIP158ForkBlock))
   336  		eip155Block = eip158Block
   337  	}
   338  	if chainParams.Params.ByzantiumForkBlock != nil {
   339  		byzantiumBlock = big.NewInt(int64(*chainParams.Params.ByzantiumForkBlock))
   340  	}
   341  	if chainParams.Params.ConstantinopleForkBlock != nil {
   342  		constantinopleBlock = big.NewInt(int64(*chainParams.Params.ConstantinopleForkBlock))
   343  	}
   344  	if chainParams.Params.ConstantinopleFixForkBlock != nil {
   345  		petersburgBlock = big.NewInt(int64(*chainParams.Params.ConstantinopleFixForkBlock))
   346  	}
   347  	if constantinopleBlock != nil && petersburgBlock == nil {
   348  		petersburgBlock = big.NewInt(100000000000)
   349  	}
   350  	if chainParams.Params.IstanbulBlock != nil {
   351  		istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock))
   352  	}
   353  
   354  	genesis := &core.Genesis{
   355  		Config: &params.ChainConfig{
   356  			ChainID:             chainId,
   357  			HomesteadBlock:      homesteadBlock,
   358  			DAOForkBlock:        daoForkBlock,
   359  			DAOForkSupport:      true,
   360  			EIP150Block:         eip150Block,
   361  			EIP155Block:         eip155Block,
   362  			EIP158Block:         eip158Block,
   363  			ByzantiumBlock:      byzantiumBlock,
   364  			ConstantinopleBlock: constantinopleBlock,
   365  			PetersburgBlock:     petersburgBlock,
   366  			IstanbulBlock:       istanbulBlock,
   367  		},
   368  		Nonce:      uint64(chainParams.Genesis.Nonce),
   369  		Timestamp:  uint64(chainParams.Genesis.Timestamp),
   370  		ExtraData:  chainParams.Genesis.ExtraData,
   371  		GasLimit:   uint64(chainParams.Genesis.GasLimit),
   372  		Difficulty: big.NewInt(0).Set((*big.Int)(chainParams.Genesis.Difficulty)),
   373  		Mixhash:    common.BigToHash((*big.Int)(chainParams.Genesis.MixHash)),
   374  		Coinbase:   chainParams.Genesis.Author,
   375  		ParentHash: chainParams.Genesis.ParentHash,
   376  		Alloc:      accounts,
   377  	}
   378  	chainConfig, genesisHash, err := core.SetupGenesisBlock(ethDb, genesis)
   379  	if err != nil {
   380  		return false, err
   381  	}
   382  	fmt.Printf("Chain config: %v\n", chainConfig)
   383  
   384  	var inner consensus.Engine
   385  	switch chainParams.SealEngine {
   386  	case "NoProof", "NoReward":
   387  		inner = ethash.NewFaker()
   388  	case "Ethash":
   389  		inner = ethash.New(ethash.Config{
   390  			CacheDir:         "ethash",
   391  			CachesInMem:      2,
   392  			CachesOnDisk:     3,
   393  			CachesLockMmap:   false,
   394  			DatasetsInMem:    1,
   395  			DatasetsOnDisk:   2,
   396  			DatasetsLockMmap: false,
   397  		}, nil, false)
   398  	default:
   399  		return false, fmt.Errorf("unrecognised seal engine: %s", chainParams.SealEngine)
   400  	}
   401  	engine := &NoRewardEngine{inner: inner, rewardsOn: chainParams.SealEngine != "NoReward"}
   402  
   403  	blockchain, err := core.NewBlockChain(ethDb, nil, chainConfig, engine, vm.Config{}, nil, nil)
   404  	if err != nil {
   405  		return false, err
   406  	}
   407  
   408  	api.chainConfig = chainConfig
   409  	api.genesisHash = genesisHash
   410  	api.author = chainParams.Genesis.Author
   411  	api.extraData = chainParams.Genesis.ExtraData
   412  	api.ethDb = ethDb
   413  	api.engine = engine
   414  	api.blockchain = blockchain
   415  	api.db = state.NewDatabase(api.ethDb)
   416  	api.txMap = make(map[common.Address]map[uint64]*types.Transaction)
   417  	api.txSenders = make(map[common.Address]struct{})
   418  	api.blockInterval = 0
   419  	return true, nil
   420  }
   421  
   422  func (api *RetestethAPI) SendRawTransaction(ctx context.Context, rawTx hexutil.Bytes) (common.Hash, error) {
   423  	tx := new(types.Transaction)
   424  	if err := rlp.DecodeBytes(rawTx, tx); err != nil {
   425  		// Return nil is not by mistake - some tests include sending transaction where gasLimit overflows uint64
   426  		return common.Hash{}, nil
   427  	}
   428  	signer := types.MakeSigner(api.chainConfig, big.NewInt(int64(api.currentNumber())))
   429  	sender, err := types.Sender(signer, tx)
   430  	if err != nil {
   431  		return common.Hash{}, err
   432  	}
   433  	if nonceMap, ok := api.txMap[sender]; ok {
   434  		nonceMap[tx.Nonce()] = tx
   435  	} else {
   436  		nonceMap = make(map[uint64]*types.Transaction)
   437  		nonceMap[tx.Nonce()] = tx
   438  		api.txMap[sender] = nonceMap
   439  	}
   440  	api.txSenders[sender] = struct{}{}
   441  	return tx.Hash(), nil
   442  }
   443  
   444  func (api *RetestethAPI) MineBlocks(ctx context.Context, number uint64) (bool, error) {
   445  	for i := 0; i < int(number); i++ {
   446  		if err := api.mineBlock(); err != nil {
   447  			return false, err
   448  		}
   449  	}
   450  	fmt.Printf("Mined %d blocks\n", number)
   451  	return true, nil
   452  }
   453  
   454  func (api *RetestethAPI) currentNumber() uint64 {
   455  	if current := api.blockchain.CurrentBlock(); current != nil {
   456  		return current.NumberU64()
   457  	}
   458  	return 0
   459  }
   460  
   461  func (api *RetestethAPI) mineBlock() error {
   462  	number := api.currentNumber()
   463  	parentHash := rawdb.ReadCanonicalHash(api.ethDb, number)
   464  	parent := rawdb.ReadBlock(api.ethDb, parentHash, number)
   465  	var timestamp uint64
   466  	if api.blockInterval == 0 {
   467  		timestamp = uint64(time.Now().Unix())
   468  	} else {
   469  		timestamp = parent.Time() + api.blockInterval
   470  	}
   471  	gasLimit := core.CalcGasLimit(parent, 9223372036854775807, 9223372036854775807)
   472  	header := &types.Header{
   473  		ParentHash: parent.Hash(),
   474  		Number:     big.NewInt(int64(number + 1)),
   475  		GasLimit:   gasLimit,
   476  		Extra:      api.extraData,
   477  		Time:       timestamp,
   478  	}
   479  	header.Coinbase = api.author
   480  	if api.engine != nil {
   481  		api.engine.Prepare(api.blockchain, header)
   482  	}
   483  	// If we are care about TheDAO hard-fork check whether to override the extra-data or not
   484  	if daoBlock := api.chainConfig.DAOForkBlock; daoBlock != nil {
   485  		// Check whether the block is among the fork extra-override range
   486  		limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange)
   487  		if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 {
   488  			// Depending whether we support or oppose the fork, override differently
   489  			if api.chainConfig.DAOForkSupport {
   490  				header.Extra = common.CopyBytes(params.DAOForkBlockExtra)
   491  			} else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) {
   492  				header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data
   493  			}
   494  		}
   495  	}
   496  	statedb, err := api.blockchain.StateAt(parent.Root())
   497  	if err != nil {
   498  		return err
   499  	}
   500  	if api.chainConfig.DAOForkSupport && api.chainConfig.DAOForkBlock != nil && api.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
   501  		misc.ApplyDAOHardFork(statedb)
   502  	}
   503  	gasPool := new(core.GasPool).AddGas(header.GasLimit)
   504  	txCount := 0
   505  	var txs []*types.Transaction
   506  	var receipts []*types.Receipt
   507  	var blockFull = gasPool.Gas() < params.TxGas
   508  	for address := range api.txSenders {
   509  		if blockFull {
   510  			break
   511  		}
   512  		m := api.txMap[address]
   513  		for nonce := statedb.GetNonce(address); ; nonce++ {
   514  			if tx, ok := m[nonce]; ok {
   515  				// Try to apply transactions to the state
   516  				statedb.Prepare(tx.Hash(), common.Hash{}, txCount)
   517  				snap := statedb.Snapshot()
   518  
   519  				receipt, err := core.ApplyTransaction(
   520  					api.chainConfig,
   521  					api.blockchain,
   522  					&api.author,
   523  					gasPool,
   524  					statedb,
   525  					header, tx, &header.GasUsed, *api.blockchain.GetVMConfig(),
   526  				)
   527  				if err != nil {
   528  					statedb.RevertToSnapshot(snap)
   529  					break
   530  				}
   531  				txs = append(txs, tx)
   532  				receipts = append(receipts, receipt)
   533  				delete(m, nonce)
   534  				if len(m) == 0 {
   535  					// Last tx for the sender
   536  					delete(api.txMap, address)
   537  					delete(api.txSenders, address)
   538  				}
   539  				txCount++
   540  				if gasPool.Gas() < params.TxGas {
   541  					blockFull = true
   542  					break
   543  				}
   544  			} else {
   545  				break // Gap in the nonces
   546  			}
   547  		}
   548  	}
   549  	block, err := api.engine.FinalizeAndAssemble(api.blockchain, header, statedb, txs, []*types.Header{}, receipts)
   550  	if err != nil {
   551  		return err
   552  	}
   553  	return api.importBlock(block)
   554  }
   555  
   556  func (api *RetestethAPI) importBlock(block *types.Block) error {
   557  	if _, err := api.blockchain.InsertChain([]*types.Block{block}); err != nil {
   558  		return err
   559  	}
   560  	fmt.Printf("Imported block %d,  head is %d\n", block.NumberU64(), api.currentNumber())
   561  	return nil
   562  }
   563  
   564  func (api *RetestethAPI) ModifyTimestamp(ctx context.Context, interval uint64) (bool, error) {
   565  	api.blockInterval = interval
   566  	return true, nil
   567  }
   568  
   569  func (api *RetestethAPI) ImportRawBlock(ctx context.Context, rawBlock hexutil.Bytes) (common.Hash, error) {
   570  	block := new(types.Block)
   571  	if err := rlp.DecodeBytes(rawBlock, block); err != nil {
   572  		return common.Hash{}, err
   573  	}
   574  	fmt.Printf("Importing block %d with parent hash: %x, genesisHash: %x\n", block.NumberU64(), block.ParentHash(), api.genesisHash)
   575  	if err := api.importBlock(block); err != nil {
   576  		return common.Hash{}, err
   577  	}
   578  	return block.Hash(), nil
   579  }
   580  
   581  func (api *RetestethAPI) RewindToBlock(ctx context.Context, newHead uint64) (bool, error) {
   582  	if err := api.blockchain.SetHead(newHead); err != nil {
   583  		return false, err
   584  	}
   585  	// When we rewind, the transaction pool should be cleaned out.
   586  	api.txMap = make(map[common.Address]map[uint64]*types.Transaction)
   587  	api.txSenders = make(map[common.Address]struct{})
   588  	return true, nil
   589  }
   590  
   591  var emptyListHash common.Hash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
   592  
   593  func (api *RetestethAPI) GetLogHash(ctx context.Context, txHash common.Hash) (common.Hash, error) {
   594  	receipt, _, _, _ := rawdb.ReadReceipt(api.ethDb, txHash, api.chainConfig)
   595  	if receipt == nil {
   596  		return emptyListHash, nil
   597  	} else {
   598  		if logListRlp, err := rlp.EncodeToBytes(receipt.Logs); err != nil {
   599  			return common.Hash{}, err
   600  		} else {
   601  			return common.BytesToHash(crypto.Keccak256(logListRlp)), nil
   602  		}
   603  	}
   604  }
   605  
   606  func (api *RetestethAPI) BlockNumber(ctx context.Context) (uint64, error) {
   607  	return api.currentNumber(), nil
   608  }
   609  
   610  func (api *RetestethAPI) GetBlockByNumber(ctx context.Context, blockNr math.HexOrDecimal64, fullTx bool) (map[string]interface{}, error) {
   611  	block := api.blockchain.GetBlockByNumber(uint64(blockNr))
   612  	if block != nil {
   613  		response, err := RPCMarshalBlock(block, true, fullTx)
   614  		if err != nil {
   615  			return nil, err
   616  		}
   617  		response["author"] = response["miner"]
   618  		response["totalDifficulty"] = (*hexutil.Big)(api.blockchain.GetTd(block.Hash(), uint64(blockNr)))
   619  		return response, err
   620  	}
   621  	return nil, fmt.Errorf("block %d not found", blockNr)
   622  }
   623  
   624  func (api *RetestethAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) {
   625  	block := api.blockchain.GetBlockByHash(blockHash)
   626  	if block != nil {
   627  		response, err := RPCMarshalBlock(block, true, fullTx)
   628  		if err != nil {
   629  			return nil, err
   630  		}
   631  		response["author"] = response["miner"]
   632  		response["totalDifficulty"] = (*hexutil.Big)(api.blockchain.GetTd(block.Hash(), block.Number().Uint64()))
   633  		return response, err
   634  	}
   635  	return nil, fmt.Errorf("block 0x%x not found", blockHash)
   636  }
   637  
   638  func (api *RetestethAPI) AccountRange(ctx context.Context,
   639  	blockHashOrNumber *math.HexOrDecimal256, txIndex uint64,
   640  	addressHash *math.HexOrDecimal256, maxResults uint64,
   641  ) (AccountRangeResult, error) {
   642  	var (
   643  		header *types.Header
   644  		block  *types.Block
   645  	)
   646  	if (*big.Int)(blockHashOrNumber).Cmp(big.NewInt(math.MaxInt64)) > 0 {
   647  		blockHash := common.BigToHash((*big.Int)(blockHashOrNumber))
   648  		header = api.blockchain.GetHeaderByHash(blockHash)
   649  		block = api.blockchain.GetBlockByHash(blockHash)
   650  		//fmt.Printf("Account range: %x, txIndex %d, start: %x, maxResults: %d\n", blockHash, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults)
   651  	} else {
   652  		blockNumber := (*big.Int)(blockHashOrNumber).Uint64()
   653  		header = api.blockchain.GetHeaderByNumber(blockNumber)
   654  		block = api.blockchain.GetBlockByNumber(blockNumber)
   655  		//fmt.Printf("Account range: %d, txIndex %d, start: %x, maxResults: %d\n", blockNumber, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults)
   656  	}
   657  	parentHeader := api.blockchain.GetHeaderByHash(header.ParentHash)
   658  	var root common.Hash
   659  	var statedb *state.StateDB
   660  	var err error
   661  	if parentHeader == nil || int(txIndex) >= len(block.Transactions()) {
   662  		root = header.Root
   663  		statedb, err = api.blockchain.StateAt(root)
   664  		if err != nil {
   665  			return AccountRangeResult{}, err
   666  		}
   667  	} else {
   668  		root = parentHeader.Root
   669  		statedb, err = api.blockchain.StateAt(root)
   670  		if err != nil {
   671  			return AccountRangeResult{}, err
   672  		}
   673  		// Recompute transactions up to the target index.
   674  		signer := types.MakeSigner(api.blockchain.Config(), block.Number())
   675  		for idx, tx := range block.Transactions() {
   676  			// Assemble the transaction call message and return if the requested offset
   677  			msg, _ := tx.AsMessage(signer)
   678  			context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil)
   679  			// Not yet the searched for transaction, execute on top of the current state
   680  			vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{})
   681  			if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
   682  				return AccountRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
   683  			}
   684  			// Ensure any modifications are committed to the state
   685  			// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
   686  			root = statedb.IntermediateRoot(vmenv.ChainConfig().IsEIP158(block.Number()))
   687  			if idx == int(txIndex) {
   688  				// This is to make sure root can be opened by OpenTrie
   689  				root, err = statedb.Commit(api.chainConfig.IsEIP158(block.Number()))
   690  				if err != nil {
   691  					return AccountRangeResult{}, err
   692  				}
   693  				break
   694  			}
   695  		}
   696  	}
   697  	accountTrie, err := statedb.Database().OpenTrie(root)
   698  	if err != nil {
   699  		return AccountRangeResult{}, err
   700  	}
   701  	it := trie.NewIterator(accountTrie.NodeIterator(common.BigToHash((*big.Int)(addressHash)).Bytes()))
   702  	result := AccountRangeResult{AddressMap: make(map[common.Hash]common.Address)}
   703  	for i := 0; i < int(maxResults) && it.Next(); i++ {
   704  		if preimage := accountTrie.GetKey(it.Key); preimage != nil {
   705  			result.AddressMap[common.BytesToHash(it.Key)] = common.BytesToAddress(preimage)
   706  		}
   707  	}
   708  	//fmt.Printf("Number of entries returned: %d\n", len(result.AddressMap))
   709  	// Add the 'next key' so clients can continue downloading.
   710  	if it.Next() {
   711  		next := common.BytesToHash(it.Key)
   712  		result.NextKey = next
   713  	}
   714  	return result, nil
   715  }
   716  
   717  func (api *RetestethAPI) GetBalance(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (*math.HexOrDecimal256, error) {
   718  	//fmt.Printf("GetBalance %x, block %d\n", address, blockNr)
   719  	header := api.blockchain.GetHeaderByNumber(uint64(blockNr))
   720  	statedb, err := api.blockchain.StateAt(header.Root)
   721  	if err != nil {
   722  		return nil, err
   723  	}
   724  	return (*math.HexOrDecimal256)(statedb.GetBalance(address)), nil
   725  }
   726  
   727  func (api *RetestethAPI) GetCode(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (hexutil.Bytes, error) {
   728  	header := api.blockchain.GetHeaderByNumber(uint64(blockNr))
   729  	statedb, err := api.blockchain.StateAt(header.Root)
   730  	if err != nil {
   731  		return nil, err
   732  	}
   733  	return statedb.GetCode(address), nil
   734  }
   735  
   736  func (api *RetestethAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (uint64, error) {
   737  	header := api.blockchain.GetHeaderByNumber(uint64(blockNr))
   738  	statedb, err := api.blockchain.StateAt(header.Root)
   739  	if err != nil {
   740  		return 0, err
   741  	}
   742  	return statedb.GetNonce(address), nil
   743  }
   744  
   745  func (api *RetestethAPI) StorageRangeAt(ctx context.Context,
   746  	blockHashOrNumber *math.HexOrDecimal256, txIndex uint64,
   747  	address common.Address,
   748  	begin *math.HexOrDecimal256, maxResults uint64,
   749  ) (StorageRangeResult, error) {
   750  	var (
   751  		header *types.Header
   752  		block  *types.Block
   753  	)
   754  	if (*big.Int)(blockHashOrNumber).Cmp(big.NewInt(math.MaxInt64)) > 0 {
   755  		blockHash := common.BigToHash((*big.Int)(blockHashOrNumber))
   756  		header = api.blockchain.GetHeaderByHash(blockHash)
   757  		block = api.blockchain.GetBlockByHash(blockHash)
   758  		//fmt.Printf("Storage range: %x, txIndex %d, addr: %x, start: %x, maxResults: %d\n",
   759  		//	blockHash, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults)
   760  	} else {
   761  		blockNumber := (*big.Int)(blockHashOrNumber).Uint64()
   762  		header = api.blockchain.GetHeaderByNumber(blockNumber)
   763  		block = api.blockchain.GetBlockByNumber(blockNumber)
   764  		//fmt.Printf("Storage range: %d, txIndex %d, addr: %x, start: %x, maxResults: %d\n",
   765  		//	blockNumber, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults)
   766  	}
   767  	parentHeader := api.blockchain.GetHeaderByHash(header.ParentHash)
   768  	var root common.Hash
   769  	var statedb *state.StateDB
   770  	var err error
   771  	if parentHeader == nil || int(txIndex) >= len(block.Transactions()) {
   772  		root = header.Root
   773  		statedb, err = api.blockchain.StateAt(root)
   774  		if err != nil {
   775  			return StorageRangeResult{}, err
   776  		}
   777  	} else {
   778  		root = parentHeader.Root
   779  		statedb, err = api.blockchain.StateAt(root)
   780  		if err != nil {
   781  			return StorageRangeResult{}, err
   782  		}
   783  		// Recompute transactions up to the target index.
   784  		signer := types.MakeSigner(api.blockchain.Config(), block.Number())
   785  		for idx, tx := range block.Transactions() {
   786  			// Assemble the transaction call message and return if the requested offset
   787  			msg, _ := tx.AsMessage(signer)
   788  			context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil)
   789  			// Not yet the searched for transaction, execute on top of the current state
   790  			vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{})
   791  			if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
   792  				return StorageRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
   793  			}
   794  			// Ensure any modifications are committed to the state
   795  			// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
   796  			_ = statedb.IntermediateRoot(vmenv.ChainConfig().IsEIP158(block.Number()))
   797  			if idx == int(txIndex) {
   798  				// This is to make sure root can be opened by OpenTrie
   799  				_, err = statedb.Commit(vmenv.ChainConfig().IsEIP158(block.Number()))
   800  				if err != nil {
   801  					return StorageRangeResult{}, err
   802  				}
   803  			}
   804  		}
   805  	}
   806  	storageTrie := statedb.StorageTrie(address)
   807  	it := trie.NewIterator(storageTrie.NodeIterator(common.BigToHash((*big.Int)(begin)).Bytes()))
   808  	result := StorageRangeResult{Storage: make(map[common.Hash]SRItem)}
   809  	for i := 0; /*i < int(maxResults) && */ it.Next(); i++ {
   810  		if preimage := storageTrie.GetKey(it.Key); preimage != nil {
   811  			key := (*math.HexOrDecimal256)(big.NewInt(0).SetBytes(preimage))
   812  			v, _, err := rlp.SplitString(it.Value)
   813  			if err != nil {
   814  				return StorageRangeResult{}, err
   815  			}
   816  			value := (*math.HexOrDecimal256)(big.NewInt(0).SetBytes(v))
   817  			ks, _ := key.MarshalText()
   818  			vs, _ := value.MarshalText()
   819  			if len(ks)%2 != 0 {
   820  				ks = append(append(append([]byte{}, ks[:2]...), byte('0')), ks[2:]...)
   821  			}
   822  			if len(vs)%2 != 0 {
   823  				vs = append(append(append([]byte{}, vs[:2]...), byte('0')), vs[2:]...)
   824  			}
   825  			result.Storage[common.BytesToHash(it.Key)] = SRItem{
   826  				Key:   string(ks),
   827  				Value: string(vs),
   828  			}
   829  		}
   830  	}
   831  	if it.Next() {
   832  		result.Complete = false
   833  	} else {
   834  		result.Complete = true
   835  	}
   836  	return result, nil
   837  }
   838  
   839  func (api *RetestethAPI) ClientVersion(ctx context.Context) (string, error) {
   840  	return "Geth-" + params.VersionWithCommit(gitCommit, gitDate), nil
   841  }
   842  
   843  // splitAndTrim splits input separated by a comma
   844  // and trims excessive white space from the substrings.
   845  func splitAndTrim(input string) []string {
   846  	result := strings.Split(input, ",")
   847  	for i, r := range result {
   848  		result[i] = strings.TrimSpace(r)
   849  	}
   850  	return result
   851  }
   852  
   853  func retesteth(ctx *cli.Context) error {
   854  	log.Info("Welcome to retesteth!")
   855  	// register signer API with server
   856  	var (
   857  		extapiURL string
   858  	)
   859  	apiImpl := &RetestethAPI{}
   860  	var testApi RetestethTestAPI = apiImpl
   861  	var ethApi RetestethEthAPI = apiImpl
   862  	var debugApi RetestethDebugAPI = apiImpl
   863  	var web3Api RetestWeb3API = apiImpl
   864  	rpcAPI := []rpc.API{
   865  		{
   866  			Namespace: "test",
   867  			Public:    true,
   868  			Service:   testApi,
   869  			Version:   "1.0",
   870  		},
   871  		{
   872  			Namespace: "eth",
   873  			Public:    true,
   874  			Service:   ethApi,
   875  			Version:   "1.0",
   876  		},
   877  		{
   878  			Namespace: "debug",
   879  			Public:    true,
   880  			Service:   debugApi,
   881  			Version:   "1.0",
   882  		},
   883  		{
   884  			Namespace: "web3",
   885  			Public:    true,
   886  			Service:   web3Api,
   887  			Version:   "1.0",
   888  		},
   889  	}
   890  	vhosts := splitAndTrim(ctx.GlobalString(utils.HTTPVirtualHostsFlag.Name))
   891  	cors := splitAndTrim(ctx.GlobalString(utils.HTTPCORSDomainFlag.Name))
   892  
   893  	// register apis and create handler stack
   894  	srv := rpc.NewServer()
   895  	err := node.RegisterApisFromWhitelist(rpcAPI, []string{"test", "eth", "debug", "web3"}, srv, false)
   896  	if err != nil {
   897  		utils.Fatalf("Could not register RPC apis: %w", err)
   898  	}
   899  	handler := node.NewHTTPHandlerStack(srv, cors, vhosts)
   900  
   901  	// start http server
   902  	var RetestethHTTPTimeouts = rpc.HTTPTimeouts{
   903  		ReadTimeout:  120 * time.Second,
   904  		WriteTimeout: 120 * time.Second,
   905  		IdleTimeout:  120 * time.Second,
   906  	}
   907  	httpEndpoint := fmt.Sprintf("%s:%d", ctx.GlobalString(utils.HTTPListenAddrFlag.Name), ctx.Int(rpcPortFlag.Name))
   908  	httpServer, _, err := node.StartHTTPEndpoint(httpEndpoint, RetestethHTTPTimeouts, handler)
   909  	if err != nil {
   910  		utils.Fatalf("Could not start RPC api: %v", err)
   911  	}
   912  	extapiURL = fmt.Sprintf("http://%s", httpEndpoint)
   913  	log.Info("HTTP endpoint opened", "url", extapiURL)
   914  
   915  	defer func() {
   916  		// Don't bother imposing a timeout here.
   917  		httpServer.Shutdown(context.Background())
   918  		log.Info("HTTP endpoint closed", "url", httpEndpoint)
   919  	}()
   920  
   921  	abortChan := make(chan os.Signal, 11)
   922  	signal.Notify(abortChan, os.Interrupt)
   923  
   924  	sig := <-abortChan
   925  	log.Info("Exiting...", "signal", sig)
   926  	return nil
   927  }