retesteth.go 33 KB

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