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