retesteth.go 31 KB

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