github.com/ConsenSys/Quorum@v20.10.0+incompatible/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/types"
    40  	"github.com/ethereum/go-ethereum/core/vm"
    41  	"github.com/ethereum/go-ethereum/crypto"
    42  	"github.com/ethereum/go-ethereum/ethdb"
    43  	"github.com/ethereum/go-ethereum/log"
    44  	"github.com/ethereum/go-ethereum/node"
    45  	"github.com/ethereum/go-ethereum/params"
    46  	"github.com/ethereum/go-ethereum/plugin/security"
    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  	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  	blockNumber   uint64
   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  	ChainID                    *math.HexOrDecimal256 `json:"chainID"`
   138  	MaximumExtraDataSize       math.HexOrDecimal64   `json:"maximumExtraDataSize"`
   139  	TieBreakingGas             bool                  `json:"tieBreakingGas"`
   140  	MinGasLimit                math.HexOrDecimal64   `json:"minGasLimit"`
   141  	MaxGasLimit                math.HexOrDecimal64   `json:"maxGasLimit"`
   142  	GasLimitBoundDivisor       math.HexOrDecimal64   `json:"gasLimitBoundDivisor"`
   143  	MinimumDifficulty          math.HexOrDecimal256  `json:"minimumDifficulty"`
   144  	DifficultyBoundDivisor     math.HexOrDecimal256  `json:"difficultyBoundDivisor"`
   145  	DurationLimit              math.HexOrDecimal256  `json:"durationLimit"`
   146  	BlockReward                math.HexOrDecimal256  `json:"blockReward"`
   147  	NetworkID                  math.HexOrDecimal256  `json:"networkID"`
   148  }
   149  
   150  type CParamsGenesis struct {
   151  	Nonce      math.HexOrDecimal64   `json:"nonce"`
   152  	Difficulty *math.HexOrDecimal256 `json:"difficulty"`
   153  	MixHash    *math.HexOrDecimal256 `json:"mixHash"`
   154  	Author     common.Address        `json:"author"`
   155  	Timestamp  math.HexOrDecimal64   `json:"timestamp"`
   156  	ParentHash common.Hash           `json:"parentHash"`
   157  	ExtraData  hexutil.Bytes         `json:"extraData"`
   158  	GasLimit   math.HexOrDecimal64   `json:"gasLimit"`
   159  }
   160  
   161  type CParamsAccount struct {
   162  	Balance     *math.HexOrDecimal256 `json:"balance"`
   163  	Precompiled *CPAccountPrecompiled `json:"precompiled"`
   164  	Code        hexutil.Bytes         `json:"code"`
   165  	Storage     map[string]string     `json:"storage"`
   166  	Nonce       *math.HexOrDecimal64  `json:"nonce"`
   167  }
   168  
   169  type CPAccountPrecompiled struct {
   170  	Name          string                `json:"name"`
   171  	StartingBlock math.HexOrDecimal64   `json:"startingBlock"`
   172  	Linear        *CPAPrecompiledLinear `json:"linear"`
   173  }
   174  
   175  type CPAPrecompiledLinear struct {
   176  	Base uint64 `json:"base"`
   177  	Word uint64 `json:"word"`
   178  }
   179  
   180  type AccountRangeResult struct {
   181  	AddressMap map[common.Hash]common.Address `json:"addressMap"`
   182  	NextKey    common.Hash                    `json:"nextKey"`
   183  }
   184  
   185  type StorageRangeResult struct {
   186  	Complete bool                   `json:"complete"`
   187  	Storage  map[common.Hash]SRItem `json:"storage"`
   188  }
   189  
   190  type SRItem struct {
   191  	Key   string `json:"key"`
   192  	Value string `json:"value"`
   193  }
   194  
   195  type NoRewardEngine struct {
   196  	inner     consensus.Engine
   197  	rewardsOn bool
   198  }
   199  
   200  func (sb *NoRewardEngine) Protocol() consensus.Protocol {
   201  	return consensus.NorewardsProtocol
   202  }
   203  
   204  func (e *NoRewardEngine) Author(header *types.Header) (common.Address, error) {
   205  	return e.inner.Author(header)
   206  }
   207  
   208  func (e *NoRewardEngine) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   209  	return e.inner.VerifyHeader(chain, header, seal)
   210  }
   211  
   212  func (e *NoRewardEngine) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   213  	return e.inner.VerifyHeaders(chain, headers, seals)
   214  }
   215  
   216  func (e *NoRewardEngine) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   217  	return e.inner.VerifyUncles(chain, block)
   218  }
   219  
   220  func (e *NoRewardEngine) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   221  	return e.inner.VerifySeal(chain, header)
   222  }
   223  
   224  func (e *NoRewardEngine) Prepare(chain consensus.ChainReader, header *types.Header) error {
   225  	return e.inner.Prepare(chain, header)
   226  }
   227  
   228  func (e *NoRewardEngine) accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
   229  	// Simply touch miner and uncle coinbase accounts
   230  	reward := big.NewInt(0)
   231  	for _, uncle := range uncles {
   232  		state.AddBalance(uncle.Coinbase, reward)
   233  	}
   234  	state.AddBalance(header.Coinbase, reward)
   235  }
   236  
   237  func (e *NoRewardEngine) Finalize(chain consensus.ChainReader, header *types.Header, statedb *state.StateDB, txs []*types.Transaction,
   238  	uncles []*types.Header) {
   239  	if e.rewardsOn {
   240  		e.inner.Finalize(chain, header, statedb, txs, uncles)
   241  	} else {
   242  		e.accumulateRewards(chain.Config(), statedb, header, uncles)
   243  		header.Root = statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   244  	}
   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, 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), 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  	)
   330  	if chainParams.Params.HomesteadForkBlock != nil {
   331  		homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock))
   332  	}
   333  	if chainParams.Params.DaoHardforkBlock != nil {
   334  		daoForkBlock = big.NewInt(int64(*chainParams.Params.DaoHardforkBlock))
   335  	}
   336  	if chainParams.Params.EIP150ForkBlock != nil {
   337  		eip150Block = big.NewInt(int64(*chainParams.Params.EIP150ForkBlock))
   338  	}
   339  	if chainParams.Params.EIP158ForkBlock != nil {
   340  		eip158Block = big.NewInt(int64(*chainParams.Params.EIP158ForkBlock))
   341  		eip155Block = eip158Block
   342  	}
   343  	if chainParams.Params.ByzantiumForkBlock != nil {
   344  		byzantiumBlock = big.NewInt(int64(*chainParams.Params.ByzantiumForkBlock))
   345  	}
   346  	if chainParams.Params.ConstantinopleForkBlock != nil {
   347  		constantinopleBlock = big.NewInt(int64(*chainParams.Params.ConstantinopleForkBlock))
   348  	}
   349  	if chainParams.Params.ConstantinopleFixForkBlock != nil {
   350  		petersburgBlock = big.NewInt(int64(*chainParams.Params.ConstantinopleFixForkBlock))
   351  	}
   352  	if constantinopleBlock != nil && petersburgBlock == nil {
   353  		petersburgBlock = big.NewInt(100000000000)
   354  	}
   355  	if chainParams.Params.IstanbulBlock != nil {
   356  		istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock))
   357  	}
   358  
   359  	genesis := &core.Genesis{
   360  		Config: &params.ChainConfig{
   361  			ChainID:             chainId,
   362  			HomesteadBlock:      homesteadBlock,
   363  			DAOForkBlock:        daoForkBlock,
   364  			DAOForkSupport:      false,
   365  			EIP150Block:         eip150Block,
   366  			EIP155Block:         eip155Block,
   367  			EIP158Block:         eip158Block,
   368  			ByzantiumBlock:      byzantiumBlock,
   369  			ConstantinopleBlock: constantinopleBlock,
   370  			PetersburgBlock:     petersburgBlock,
   371  			IstanbulBlock:       istanbulBlock,
   372  		},
   373  		Nonce:      uint64(chainParams.Genesis.Nonce),
   374  		Timestamp:  uint64(chainParams.Genesis.Timestamp),
   375  		ExtraData:  chainParams.Genesis.ExtraData,
   376  		GasLimit:   uint64(chainParams.Genesis.GasLimit),
   377  		Difficulty: big.NewInt(0).Set((*big.Int)(chainParams.Genesis.Difficulty)),
   378  		Mixhash:    common.BigToHash((*big.Int)(chainParams.Genesis.MixHash)),
   379  		Coinbase:   chainParams.Genesis.Author,
   380  		ParentHash: chainParams.Genesis.ParentHash,
   381  		Alloc:      accounts,
   382  	}
   383  	chainConfig, genesisHash, err := core.SetupGenesisBlock(ethDb, genesis)
   384  	if err != nil {
   385  		return false, err
   386  	}
   387  	fmt.Printf("Chain config: %v\n", chainConfig)
   388  
   389  	var inner consensus.Engine
   390  	switch chainParams.SealEngine {
   391  	case "NoProof", "NoReward":
   392  		inner = ethash.NewFaker()
   393  	case "Ethash":
   394  		inner = ethash.New(ethash.Config{
   395  			CacheDir:       "ethash",
   396  			CachesInMem:    2,
   397  			CachesOnDisk:   3,
   398  			DatasetsInMem:  1,
   399  			DatasetsOnDisk: 2,
   400  		}, nil, false)
   401  	default:
   402  		return false, fmt.Errorf("unrecognised seal engine: %s", chainParams.SealEngine)
   403  	}
   404  	engine := &NoRewardEngine{inner: inner, rewardsOn: chainParams.SealEngine != "NoReward"}
   405  
   406  	blockchain, err := core.NewBlockChain(ethDb, nil, chainConfig, engine, vm.Config{}, nil)
   407  	if err != nil {
   408  		return false, err
   409  	}
   410  
   411  	api.chainConfig = chainConfig
   412  	api.genesisHash = genesisHash
   413  	api.author = chainParams.Genesis.Author
   414  	api.extraData = chainParams.Genesis.ExtraData
   415  	api.ethDb = ethDb
   416  	api.engine = engine
   417  	api.blockchain = blockchain
   418  	api.db = state.NewDatabase(api.ethDb)
   419  	api.blockNumber = 0
   420  	api.txMap = make(map[common.Address]map[uint64]*types.Transaction)
   421  	api.txSenders = make(map[common.Address]struct{})
   422  	api.blockInterval = 0
   423  	return true, nil
   424  }
   425  
   426  func (api *RetestethAPI) SendRawTransaction(ctx context.Context, rawTx hexutil.Bytes) (common.Hash, error) {
   427  	tx := new(types.Transaction)
   428  	if err := rlp.DecodeBytes(rawTx, tx); err != nil {
   429  		// Return nil is not by mistake - some tests include sending transaction where gasLimit overflows uint64
   430  		return common.Hash{}, nil
   431  	}
   432  	signer := types.MakeSigner(api.chainConfig, big.NewInt(int64(api.blockNumber)))
   433  	sender, err := types.Sender(signer, tx)
   434  	if err != nil {
   435  		return common.Hash{}, err
   436  	}
   437  	if nonceMap, ok := api.txMap[sender]; ok {
   438  		nonceMap[tx.Nonce()] = tx
   439  	} else {
   440  		nonceMap = make(map[uint64]*types.Transaction)
   441  		nonceMap[tx.Nonce()] = tx
   442  		api.txMap[sender] = nonceMap
   443  	}
   444  	api.txSenders[sender] = struct{}{}
   445  	return tx.Hash(), nil
   446  }
   447  
   448  func (api *RetestethAPI) MineBlocks(ctx context.Context, number uint64) (bool, error) {
   449  	for i := 0; i < int(number); i++ {
   450  		if err := api.mineBlock(); err != nil {
   451  			return false, err
   452  		}
   453  	}
   454  	fmt.Printf("Mined %d blocks\n", number)
   455  	return true, nil
   456  }
   457  
   458  func (api *RetestethAPI) mineBlock() error {
   459  	parentHash := rawdb.ReadCanonicalHash(api.ethDb, api.blockNumber)
   460  	parent := rawdb.ReadBlock(api.ethDb, parentHash, api.blockNumber)
   461  	var timestamp uint64
   462  	if api.blockInterval == 0 {
   463  		timestamp = uint64(time.Now().Unix())
   464  	} else {
   465  		timestamp = parent.Time() + api.blockInterval
   466  	}
   467  	gasLimit := core.CalcGasLimit(parent, 9223372036854775807, 9223372036854775807)
   468  	header := &types.Header{
   469  		ParentHash: parent.Hash(),
   470  		Number:     big.NewInt(int64(api.blockNumber + 1)),
   471  		GasLimit:   gasLimit,
   472  		Extra:      api.extraData,
   473  		Time:       timestamp,
   474  	}
   475  	header.Coinbase = api.author
   476  	if api.engine != nil {
   477  		api.engine.Prepare(api.blockchain, header)
   478  	}
   479  	// If we are care about TheDAO hard-fork check whether to override the extra-data or not
   480  	if daoBlock := api.chainConfig.DAOForkBlock; daoBlock != nil {
   481  		// Check whether the block is among the fork extra-override range
   482  		limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange)
   483  		if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 {
   484  			// Depending whether we support or oppose the fork, override differently
   485  			if api.chainConfig.DAOForkSupport {
   486  				header.Extra = common.CopyBytes(params.DAOForkBlockExtra)
   487  			} else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) {
   488  				header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data
   489  			}
   490  		}
   491  	}
   492  	statedb, pvtstdb, err := api.blockchain.StateAt(parent.Root())
   493  	if err != nil {
   494  		return err
   495  	}
   496  	if api.chainConfig.DAOForkSupport && api.chainConfig.DAOForkBlock != nil && api.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
   497  		misc.ApplyDAOHardFork(statedb)
   498  	}
   499  	gasPool := new(core.GasPool).AddGas(header.GasLimit)
   500  	txCount := 0
   501  	var txs []*types.Transaction
   502  	var receipts []*types.Receipt
   503  	var coalescedLogs []*types.Log
   504  	var blockFull = gasPool.Gas() < params.TxGas
   505  	for address := range api.txSenders {
   506  		if blockFull {
   507  			break
   508  		}
   509  		m := api.txMap[address]
   510  		for nonce := statedb.GetNonce(address); ; nonce++ {
   511  			if tx, ok := m[nonce]; ok {
   512  				// Try to apply transactions to the state
   513  				statedb.Prepare(tx.Hash(), common.Hash{}, txCount)
   514  				snap := statedb.Snapshot()
   515  
   516  				receipt, _, err := core.ApplyTransaction(
   517  					api.chainConfig,
   518  					api.blockchain,
   519  					&api.author,
   520  					gasPool,
   521  					statedb, pvtstdb,
   522  					header, tx, &header.GasUsed, *api.blockchain.GetVMConfig(),
   523  				)
   524  				if err != nil {
   525  					statedb.RevertToSnapshot(snap)
   526  					break
   527  				}
   528  				txs = append(txs, tx)
   529  				receipts = append(receipts, receipt)
   530  				coalescedLogs = append(coalescedLogs, receipt.Logs...)
   531  				delete(m, nonce)
   532  				if len(m) == 0 {
   533  					// Last tx for the sender
   534  					delete(api.txMap, address)
   535  					delete(api.txSenders, address)
   536  				}
   537  				txCount++
   538  				if gasPool.Gas() < params.TxGas {
   539  					blockFull = true
   540  					break
   541  				}
   542  			} else {
   543  				break // Gap in the nonces
   544  			}
   545  		}
   546  	}
   547  	block, err := api.engine.FinalizeAndAssemble(api.blockchain, header, statedb, txs, []*types.Header{}, receipts)
   548  	if err != nil {
   549  		return err
   550  	}
   551  	return api.importBlock(block)
   552  }
   553  
   554  func (api *RetestethAPI) importBlock(block *types.Block) error {
   555  	if _, err := api.blockchain.InsertChain([]*types.Block{block}); err != nil {
   556  		return err
   557  	}
   558  	api.blockNumber = block.NumberU64()
   559  	fmt.Printf("Imported block %d\n", block.NumberU64())
   560  	return nil
   561  }
   562  
   563  func (api *RetestethAPI) ModifyTimestamp(ctx context.Context, interval uint64) (bool, error) {
   564  	api.blockInterval = interval
   565  	return true, nil
   566  }
   567  
   568  func (api *RetestethAPI) ImportRawBlock(ctx context.Context, rawBlock hexutil.Bytes) (common.Hash, error) {
   569  	block := new(types.Block)
   570  	if err := rlp.DecodeBytes(rawBlock, block); err != nil {
   571  		return common.Hash{}, err
   572  	}
   573  	fmt.Printf("Importing block %d with parent hash: %x, genesisHash: %x\n", block.NumberU64(), block.ParentHash(), api.genesisHash)
   574  	if err := api.importBlock(block); err != nil {
   575  		return common.Hash{}, err
   576  	}
   577  	return block.Hash(), nil
   578  }
   579  
   580  func (api *RetestethAPI) RewindToBlock(ctx context.Context, newHead uint64) (bool, error) {
   581  	if err := api.blockchain.SetHead(newHead); err != nil {
   582  		return false, err
   583  	}
   584  	api.blockNumber = newHead
   585  	return true, nil
   586  }
   587  
   588  var emptyListHash common.Hash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
   589  
   590  func (api *RetestethAPI) GetLogHash(ctx context.Context, txHash common.Hash) (common.Hash, error) {
   591  	receipt, _, _, _ := rawdb.ReadReceipt(api.ethDb, txHash, api.chainConfig)
   592  	if receipt == nil {
   593  		return emptyListHash, nil
   594  	} else {
   595  		if logListRlp, err := rlp.EncodeToBytes(receipt.Logs); err != nil {
   596  			return common.Hash{}, err
   597  		} else {
   598  			return common.BytesToHash(crypto.Keccak256(logListRlp)), nil
   599  		}
   600  	}
   601  }
   602  
   603  func (api *RetestethAPI) BlockNumber(ctx context.Context) (uint64, error) {
   604  	//fmt.Printf("BlockNumber, response: %d\n", api.blockNumber)
   605  	return api.blockNumber, nil
   606  }
   607  
   608  func (api *RetestethAPI) GetBlockByNumber(ctx context.Context, blockNr math.HexOrDecimal64, fullTx bool) (map[string]interface{}, error) {
   609  	block := api.blockchain.GetBlockByNumber(uint64(blockNr))
   610  	if block != nil {
   611  		response, err := RPCMarshalBlock(block, true, fullTx)
   612  		if err != nil {
   613  			return nil, err
   614  		}
   615  		response["author"] = response["miner"]
   616  		response["totalDifficulty"] = (*hexutil.Big)(api.blockchain.GetTd(block.Hash(), uint64(blockNr)))
   617  		return response, err
   618  	}
   619  	return nil, fmt.Errorf("block %d not found", blockNr)
   620  }
   621  
   622  func (api *RetestethAPI) AccountRange(ctx context.Context,
   623  	blockHashOrNumber *math.HexOrDecimal256, txIndex uint64,
   624  	addressHash *math.HexOrDecimal256, maxResults uint64,
   625  ) (AccountRangeResult, error) {
   626  	var (
   627  		header *types.Header
   628  		block  *types.Block
   629  	)
   630  	if (*big.Int)(blockHashOrNumber).Cmp(big.NewInt(math.MaxInt64)) > 0 {
   631  		blockHash := common.BigToHash((*big.Int)(blockHashOrNumber))
   632  		header = api.blockchain.GetHeaderByHash(blockHash)
   633  		block = api.blockchain.GetBlockByHash(blockHash)
   634  		//fmt.Printf("Account range: %x, txIndex %d, start: %x, maxResults: %d\n", blockHash, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults)
   635  	} else {
   636  		blockNumber := (*big.Int)(blockHashOrNumber).Uint64()
   637  		header = api.blockchain.GetHeaderByNumber(blockNumber)
   638  		block = api.blockchain.GetBlockByNumber(blockNumber)
   639  		//fmt.Printf("Account range: %d, txIndex %d, start: %x, maxResults: %d\n", blockNumber, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults)
   640  	}
   641  	parentHeader := api.blockchain.GetHeaderByHash(header.ParentHash)
   642  	var root common.Hash
   643  	var statedb, pvtst *state.StateDB
   644  	var err error
   645  	if parentHeader == nil || int(txIndex) >= len(block.Transactions()) {
   646  		root = header.Root
   647  		statedb, pvtst, err = api.blockchain.StateAt(root)
   648  		if err != nil {
   649  			return AccountRangeResult{}, err
   650  		}
   651  	} else {
   652  		root = parentHeader.Root
   653  		statedb, pvtst, err = api.blockchain.StateAt(root)
   654  		if err != nil {
   655  			return AccountRangeResult{}, err
   656  		}
   657  		// Recompute transactions up to the target index.
   658  		signer := types.MakeSigner(api.blockchain.Config(), block.Number())
   659  		for idx, tx := range block.Transactions() {
   660  			// Assemble the transaction call message and return if the requested offset
   661  			msg, _ := tx.AsMessage(signer)
   662  			context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil)
   663  			// Not yet the searched for transaction, execute on top of the current state
   664  			vmenv := vm.NewEVM(context, statedb, pvtst, api.blockchain.Config(), vm.Config{})
   665  			if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
   666  				return AccountRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
   667  			}
   668  			// Ensure any modifications are committed to the state
   669  			// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
   670  			root = statedb.IntermediateRoot(vmenv.ChainConfig().IsEIP158(block.Number()))
   671  			if idx == int(txIndex) {
   672  				// This is to make sure root can be opened by OpenTrie
   673  				root, err = statedb.Commit(api.chainConfig.IsEIP158(block.Number()))
   674  				if err != nil {
   675  					return AccountRangeResult{}, err
   676  				}
   677  				break
   678  			}
   679  		}
   680  	}
   681  	accountTrie, err := statedb.Database().OpenTrie(root)
   682  	if err != nil {
   683  		return AccountRangeResult{}, err
   684  	}
   685  	it := trie.NewIterator(accountTrie.NodeIterator(common.BigToHash((*big.Int)(addressHash)).Bytes()))
   686  	result := AccountRangeResult{AddressMap: make(map[common.Hash]common.Address)}
   687  	for i := 0; i < int(maxResults) && it.Next(); i++ {
   688  		if preimage := accountTrie.GetKey(it.Key); preimage != nil {
   689  			result.AddressMap[common.BytesToHash(it.Key)] = common.BytesToAddress(preimage)
   690  			//fmt.Printf("%x: %x\n", it.Key, preimage)
   691  		} else {
   692  			//fmt.Printf("could not find preimage for %x\n", it.Key)
   693  		}
   694  	}
   695  	//fmt.Printf("Number of entries returned: %d\n", len(result.AddressMap))
   696  	// Add the 'next key' so clients can continue downloading.
   697  	if it.Next() {
   698  		next := common.BytesToHash(it.Key)
   699  		result.NextKey = next
   700  	}
   701  	return result, nil
   702  }
   703  
   704  func (api *RetestethAPI) GetBalance(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (*math.HexOrDecimal256, error) {
   705  	//fmt.Printf("GetBalance %x, block %d\n", address, blockNr)
   706  	header := api.blockchain.GetHeaderByNumber(uint64(blockNr))
   707  	statedb, _, err := api.blockchain.StateAt(header.Root)
   708  	if err != nil {
   709  		return nil, err
   710  	}
   711  	return (*math.HexOrDecimal256)(statedb.GetBalance(address)), nil
   712  }
   713  
   714  func (api *RetestethAPI) GetCode(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (hexutil.Bytes, error) {
   715  	header := api.blockchain.GetHeaderByNumber(uint64(blockNr))
   716  	statedb, _, err := api.blockchain.StateAt(header.Root)
   717  	if err != nil {
   718  		return nil, err
   719  	}
   720  	return statedb.GetCode(address), nil
   721  }
   722  
   723  func (api *RetestethAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (uint64, error) {
   724  	header := api.blockchain.GetHeaderByNumber(uint64(blockNr))
   725  	statedb, _, err := api.blockchain.StateAt(header.Root)
   726  	if err != nil {
   727  		return 0, err
   728  	}
   729  	return statedb.GetNonce(address), nil
   730  }
   731  
   732  func (api *RetestethAPI) StorageRangeAt(ctx context.Context,
   733  	blockHashOrNumber *math.HexOrDecimal256, txIndex uint64,
   734  	address common.Address,
   735  	begin *math.HexOrDecimal256, maxResults uint64,
   736  ) (StorageRangeResult, error) {
   737  	var (
   738  		header *types.Header
   739  		block  *types.Block
   740  	)
   741  	if (*big.Int)(blockHashOrNumber).Cmp(big.NewInt(math.MaxInt64)) > 0 {
   742  		blockHash := common.BigToHash((*big.Int)(blockHashOrNumber))
   743  		header = api.blockchain.GetHeaderByHash(blockHash)
   744  		block = api.blockchain.GetBlockByHash(blockHash)
   745  		//fmt.Printf("Storage range: %x, txIndex %d, addr: %x, start: %x, maxResults: %d\n",
   746  		//	blockHash, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults)
   747  	} else {
   748  		blockNumber := (*big.Int)(blockHashOrNumber).Uint64()
   749  		header = api.blockchain.GetHeaderByNumber(blockNumber)
   750  		block = api.blockchain.GetBlockByNumber(blockNumber)
   751  		//fmt.Printf("Storage range: %d, txIndex %d, addr: %x, start: %x, maxResults: %d\n",
   752  		//	blockNumber, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults)
   753  	}
   754  	parentHeader := api.blockchain.GetHeaderByHash(header.ParentHash)
   755  	var root common.Hash
   756  	var statedb, pvtstdb *state.StateDB
   757  	var err error
   758  	if parentHeader == nil || int(txIndex) >= len(block.Transactions()) {
   759  		root = header.Root
   760  		statedb, pvtstdb, err = api.blockchain.StateAt(root)
   761  		if err != nil {
   762  			return StorageRangeResult{}, err
   763  		}
   764  	} else {
   765  		root = parentHeader.Root
   766  		statedb, pvtstdb, err = api.blockchain.StateAt(root)
   767  		if err != nil {
   768  			return StorageRangeResult{}, err
   769  		}
   770  		// Recompute transactions up to the target index.
   771  		signer := types.MakeSigner(api.blockchain.Config(), block.Number())
   772  		for idx, tx := range block.Transactions() {
   773  			// Assemble the transaction call message and return if the requested offset
   774  			msg, _ := tx.AsMessage(signer)
   775  			context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil)
   776  			// Not yet the searched for transaction, execute on top of the current state
   777  			vmenv := vm.NewEVM(context, statedb, pvtstdb, api.blockchain.Config(), vm.Config{})
   778  			if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
   779  				return StorageRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
   780  			}
   781  			// Ensure any modifications are committed to the state
   782  			// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
   783  			_ = statedb.IntermediateRoot(vmenv.ChainConfig().IsEIP158(block.Number()))
   784  			if idx == int(txIndex) {
   785  				// This is to make sure root can be opened by OpenTrie
   786  				_, err = statedb.Commit(vmenv.ChainConfig().IsEIP158(block.Number()))
   787  				if err != nil {
   788  					return StorageRangeResult{}, err
   789  				}
   790  			}
   791  		}
   792  	}
   793  	storageTrie := statedb.StorageTrie(address)
   794  	it := trie.NewIterator(storageTrie.NodeIterator(common.BigToHash((*big.Int)(begin)).Bytes()))
   795  	result := StorageRangeResult{Storage: make(map[common.Hash]SRItem)}
   796  	for i := 0; /*i < int(maxResults) && */ it.Next(); i++ {
   797  		if preimage := storageTrie.GetKey(it.Key); preimage != nil {
   798  			key := (*math.HexOrDecimal256)(big.NewInt(0).SetBytes(preimage))
   799  			v, _, err := rlp.SplitString(it.Value)
   800  			if err != nil {
   801  				return StorageRangeResult{}, err
   802  			}
   803  			value := (*math.HexOrDecimal256)(big.NewInt(0).SetBytes(v))
   804  			ks, _ := key.MarshalText()
   805  			vs, _ := value.MarshalText()
   806  			if len(ks)%2 != 0 {
   807  				ks = append(append(append([]byte{}, ks[:2]...), byte('0')), ks[2:]...)
   808  			}
   809  			if len(vs)%2 != 0 {
   810  				vs = append(append(append([]byte{}, vs[:2]...), byte('0')), vs[2:]...)
   811  			}
   812  			result.Storage[common.BytesToHash(it.Key)] = SRItem{
   813  				Key:   string(ks),
   814  				Value: string(vs),
   815  			}
   816  			//fmt.Printf("Key: %s, Value: %s\n", ks, vs)
   817  		} else {
   818  			//fmt.Printf("Did not find preimage for %x\n", it.Key)
   819  		}
   820  	}
   821  	if it.Next() {
   822  		result.Complete = false
   823  	} else {
   824  		result.Complete = true
   825  	}
   826  	return result, nil
   827  }
   828  
   829  func (api *RetestethAPI) ClientVersion(ctx context.Context) (string, error) {
   830  	return "Geth-" + params.VersionWithCommit(gitCommit, gitDate), nil
   831  }
   832  
   833  // splitAndTrim splits input separated by a comma
   834  // and trims excessive white space from the substrings.
   835  func splitAndTrim(input string) []string {
   836  	result := strings.Split(input, ",")
   837  	for i, r := range result {
   838  		result[i] = strings.TrimSpace(r)
   839  	}
   840  	return result
   841  }
   842  
   843  func retesteth(ctx *cli.Context) error {
   844  	log.Info("Welcome to retesteth!")
   845  	// register signer API with server
   846  	var (
   847  		extapiURL string
   848  	)
   849  	apiImpl := &RetestethAPI{}
   850  	var testApi RetestethTestAPI = apiImpl
   851  	var ethApi RetestethEthAPI = apiImpl
   852  	var debugApi RetestethDebugAPI = apiImpl
   853  	var web3Api RetestWeb3API = apiImpl
   854  	rpcAPI := []rpc.API{
   855  		{
   856  			Namespace: "test",
   857  			Public:    true,
   858  			Service:   testApi,
   859  			Version:   "1.0",
   860  		},
   861  		{
   862  			Namespace: "eth",
   863  			Public:    true,
   864  			Service:   ethApi,
   865  			Version:   "1.0",
   866  		},
   867  		{
   868  			Namespace: "debug",
   869  			Public:    true,
   870  			Service:   debugApi,
   871  			Version:   "1.0",
   872  		},
   873  		{
   874  			Namespace: "web3",
   875  			Public:    true,
   876  			Service:   web3Api,
   877  			Version:   "1.0",
   878  		},
   879  	}
   880  	vhosts := splitAndTrim(ctx.GlobalString(utils.RPCVirtualHostsFlag.Name))
   881  	cors := splitAndTrim(ctx.GlobalString(utils.RPCCORSDomainFlag.Name))
   882  
   883  	// start http server
   884  	httpEndpoint := fmt.Sprintf("%s:%d", ctx.GlobalString(utils.RPCListenAddrFlag.Name), ctx.Int(rpcPortFlag.Name))
   885  	listener, _, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, []string{"test", "eth", "debug", "web3"}, cors, vhosts, rpc.DefaultHTTPTimeouts, nil, &security.DisabledAuthenticationManager{})
   886  	if err != nil {
   887  		utils.Fatalf("Could not start RPC api: %v", err)
   888  	}
   889  	extapiURL = fmt.Sprintf("http://%s", httpEndpoint)
   890  	log.Info("HTTP endpoint opened", "url", extapiURL)
   891  
   892  	defer func() {
   893  		listener.Close()
   894  		log.Info("HTTP endpoint closed", "url", httpEndpoint)
   895  	}()
   896  
   897  	abortChan := make(chan os.Signal)
   898  	signal.Notify(abortChan, os.Interrupt)
   899  
   900  	sig := <-abortChan
   901  	log.Info("Exiting...", "signal", sig)
   902  	return nil
   903  }