main.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. // gethrpctest is a command to run the external RPC tests.
  17. package main
  18. import (
  19. "flag"
  20. "log"
  21. "os"
  22. "os/signal"
  23. "github.com/ethereum/go-ethereum/accounts/keystore"
  24. "github.com/ethereum/go-ethereum/crypto"
  25. "github.com/ethereum/go-ethereum/eth"
  26. "github.com/ethereum/go-ethereum/ethdb"
  27. "github.com/ethereum/go-ethereum/logger/glog"
  28. "github.com/ethereum/go-ethereum/node"
  29. "github.com/ethereum/go-ethereum/params"
  30. "github.com/ethereum/go-ethereum/tests"
  31. whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
  32. )
  33. const defaultTestKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
  34. var (
  35. testFile = flag.String("json", "", "Path to the .json test file to load")
  36. testName = flag.String("test", "", "Name of the test from the .json file to run")
  37. testKey = flag.String("key", defaultTestKey, "Private key of a test account to inject")
  38. )
  39. func main() {
  40. flag.Parse()
  41. // Enable logging errors, we really do want to see those
  42. glog.SetV(2)
  43. glog.SetToStderr(true)
  44. // Load the test suite to run the RPC against
  45. tests, err := tests.LoadBlockTests(*testFile)
  46. if err != nil {
  47. log.Fatalf("Failed to load test suite: %v", err)
  48. }
  49. test, found := tests[*testName]
  50. if !found {
  51. log.Fatalf("Requested test (%s) not found within suite", *testName)
  52. }
  53. stack, err := MakeSystemNode(*testKey, test)
  54. if err != nil {
  55. log.Fatalf("Failed to assemble test stack: %v", err)
  56. }
  57. if err := stack.Start(); err != nil {
  58. log.Fatalf("Failed to start test node: %v", err)
  59. }
  60. defer stack.Stop()
  61. log.Println("Test node started...")
  62. // Make sure the tests contained within the suite pass
  63. if err := RunTest(stack, test); err != nil {
  64. log.Fatalf("Failed to run the pre-configured test: %v", err)
  65. }
  66. log.Println("Initial test suite passed...")
  67. quit := make(chan os.Signal, 1)
  68. signal.Notify(quit, os.Interrupt)
  69. <-quit
  70. }
  71. // MakeSystemNode configures a protocol stack for the RPC tests based on a given
  72. // keystore path and initial pre-state.
  73. func MakeSystemNode(privkey string, test *tests.BlockTest) (*node.Node, error) {
  74. // Create a networkless protocol stack
  75. stack, err := node.New(&node.Config{
  76. UseLightweightKDF: true,
  77. IPCPath: node.DefaultIPCEndpoint(""),
  78. HTTPHost: node.DefaultHTTPHost,
  79. HTTPPort: node.DefaultHTTPPort,
  80. HTTPModules: []string{"admin", "db", "eth", "debug", "miner", "net", "shh", "txpool", "personal", "web3"},
  81. WSHost: node.DefaultWSHost,
  82. WSPort: node.DefaultWSPort,
  83. WSModules: []string{"admin", "db", "eth", "debug", "miner", "net", "shh", "txpool", "personal", "web3"},
  84. NoDiscovery: true,
  85. })
  86. if err != nil {
  87. return nil, err
  88. }
  89. // Create the keystore and inject an unlocked account if requested
  90. ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore)
  91. if len(privkey) > 0 {
  92. key, err := crypto.HexToECDSA(privkey)
  93. if err != nil {
  94. return nil, err
  95. }
  96. a, err := ks.ImportECDSA(key, "")
  97. if err != nil {
  98. return nil, err
  99. }
  100. if err := ks.Unlock(a, ""); err != nil {
  101. return nil, err
  102. }
  103. }
  104. // Initialize and register the Ethereum protocol
  105. db, _ := ethdb.NewMemDatabase()
  106. if _, err := test.InsertPreState(db); err != nil {
  107. return nil, err
  108. }
  109. ethConf := &eth.Config{
  110. TestGenesisState: db,
  111. TestGenesisBlock: test.Genesis,
  112. ChainConfig: &params.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock},
  113. }
  114. if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil {
  115. return nil, err
  116. }
  117. // Initialize and register the Whisper protocol
  118. if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil {
  119. return nil, err
  120. }
  121. return stack, nil
  122. }
  123. // RunTest executes the specified test against an already pre-configured protocol
  124. // stack to ensure basic checks pass before running RPC tests.
  125. func RunTest(stack *node.Node, test *tests.BlockTest) error {
  126. var ethereum *eth.Ethereum
  127. stack.Service(&ethereum)
  128. blockchain := ethereum.BlockChain()
  129. // Process the blocks and verify the imported headers
  130. blocks, err := test.TryBlocksInsert(blockchain)
  131. if err != nil {
  132. return err
  133. }
  134. if err := test.ValidateImportedHeaders(blockchain, blocks); err != nil {
  135. return err
  136. }
  137. // Retrieve the assembled state and validate it
  138. stateDb, err := blockchain.State()
  139. if err != nil {
  140. return err
  141. }
  142. if err := test.ValidatePostState(stateDb); err != nil {
  143. return err
  144. }
  145. return nil
  146. }