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