blocktestcmd.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2015 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. "fmt"
  19. "os"
  20. "github.com/codegangsta/cli"
  21. "github.com/ethereum/go-ethereum/cmd/utils"
  22. "github.com/ethereum/go-ethereum/common"
  23. "github.com/ethereum/go-ethereum/eth"
  24. "github.com/ethereum/go-ethereum/ethdb"
  25. "github.com/ethereum/go-ethereum/tests"
  26. )
  27. var blocktestCommand = cli.Command{
  28. Action: runBlockTest,
  29. Name: "blocktest",
  30. Usage: `loads a block test file`,
  31. Description: `
  32. The first argument should be a block test file.
  33. The second argument is the name of a block test from the file.
  34. The block test will be loaded into an in-memory database.
  35. If loading succeeds, the RPC server is started. Clients will
  36. be able to interact with the chain defined by the test.
  37. `,
  38. }
  39. func runBlockTest(ctx *cli.Context) {
  40. var (
  41. file, testname string
  42. rpc bool
  43. )
  44. args := ctx.Args()
  45. switch {
  46. case len(args) == 1:
  47. file = args[0]
  48. case len(args) == 2:
  49. file, testname = args[0], args[1]
  50. case len(args) == 3:
  51. file, testname = args[0], args[1]
  52. rpc = true
  53. default:
  54. utils.Fatalf(`Usage: ethereum blocktest <path-to-test-file> [ <test-name> [ "rpc" ] ]`)
  55. }
  56. bt, err := tests.LoadBlockTests(file)
  57. if err != nil {
  58. utils.Fatalf("%v", err)
  59. }
  60. // run all tests if no test name is specified
  61. if testname == "" {
  62. ecode := 0
  63. for name, test := range bt {
  64. fmt.Printf("----------------- Running Block Test %q\n", name)
  65. ethereum, err := runOneBlockTest(ctx, test)
  66. if err != nil {
  67. fmt.Println(err)
  68. fmt.Println("FAIL")
  69. ecode = 1
  70. }
  71. if ethereum != nil {
  72. ethereum.Stop()
  73. ethereum.WaitForShutdown()
  74. }
  75. }
  76. os.Exit(ecode)
  77. return
  78. }
  79. // otherwise, run the given test
  80. test, ok := bt[testname]
  81. if !ok {
  82. utils.Fatalf("Test file does not contain test named %q", testname)
  83. }
  84. ethereum, err := runOneBlockTest(ctx, test)
  85. if err != nil {
  86. utils.Fatalf("%v", err)
  87. }
  88. defer ethereum.Stop()
  89. if rpc {
  90. fmt.Println("Block Test post state validated, starting RPC interface.")
  91. startEth(ctx, ethereum)
  92. utils.StartRPC(ethereum, ctx)
  93. ethereum.WaitForShutdown()
  94. }
  95. }
  96. func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
  97. cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
  98. cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }
  99. cfg.MaxPeers = 0 // disable network
  100. cfg.Shh = false // disable whisper
  101. cfg.NAT = nil // disable port mapping
  102. ethereum, err := eth.New(cfg)
  103. if err != nil {
  104. return nil, err
  105. }
  106. // if err := ethereum.Start(); err != nil {
  107. // return nil, err
  108. // }
  109. // import the genesis block
  110. ethereum.ResetWithGenesisBlock(test.Genesis)
  111. // import pre accounts
  112. statedb, err := test.InsertPreState(ethereum)
  113. if err != nil {
  114. return ethereum, fmt.Errorf("InsertPreState: %v", err)
  115. }
  116. if err := test.TryBlocksInsert(ethereum.ChainManager()); err != nil {
  117. return ethereum, fmt.Errorf("Block Test load error: %v", err)
  118. }
  119. if err := test.ValidatePostState(statedb); err != nil {
  120. return ethereum, fmt.Errorf("post state validation failed: %v", err)
  121. }
  122. return ethereum, nil
  123. }