retesteth.go 33 KB

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