github.com/theQRL/go-zond@v0.1.1/cmd/evm/staterunner.go (about) 1 // Copyright 2017 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 package main 18 19 import ( 20 "bufio" 21 "encoding/json" 22 "fmt" 23 "os" 24 25 "github.com/theQRL/go-zond/common" 26 "github.com/theQRL/go-zond/core/rawdb" 27 "github.com/theQRL/go-zond/core/state" 28 "github.com/theQRL/go-zond/core/state/snapshot" 29 "github.com/theQRL/go-zond/core/vm" 30 "github.com/theQRL/go-zond/log" 31 "github.com/theQRL/go-zond/tests" 32 "github.com/theQRL/go-zond/zond/tracers/logger" 33 "github.com/urfave/cli/v2" 34 ) 35 36 var stateTestCommand = &cli.Command{ 37 Action: stateTestCmd, 38 Name: "statetest", 39 Usage: "Executes the given state tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).", 40 ArgsUsage: "<file>", 41 } 42 43 // StatetestResult contains the execution status after running a state test, any 44 // error that might have occurred and a dump of the final state if requested. 45 type StatetestResult struct { 46 Name string `json:"name"` 47 Pass bool `json:"pass"` 48 Root *common.Hash `json:"stateRoot,omitempty"` 49 Fork string `json:"fork"` 50 Error string `json:"error,omitempty"` 51 State *state.Dump `json:"state,omitempty"` 52 } 53 54 func stateTestCmd(ctx *cli.Context) error { 55 // Configure the go-ethereum logger 56 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 57 glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name))) 58 log.Root().SetHandler(glogger) 59 60 // Configure the EVM logger 61 config := &logger.Config{ 62 EnableMemory: !ctx.Bool(DisableMemoryFlag.Name), 63 DisableStack: ctx.Bool(DisableStackFlag.Name), 64 DisableStorage: ctx.Bool(DisableStorageFlag.Name), 65 EnableReturnData: !ctx.Bool(DisableReturnDataFlag.Name), 66 } 67 var cfg vm.Config 68 switch { 69 case ctx.Bool(MachineFlag.Name): 70 cfg.Tracer = logger.NewJSONLogger(config, os.Stderr) 71 72 case ctx.Bool(DebugFlag.Name): 73 cfg.Tracer = logger.NewStructLogger(config) 74 } 75 // Load the test content from the input file 76 if len(ctx.Args().First()) != 0 { 77 return runStateTest(ctx.Args().First(), cfg, ctx.Bool(MachineFlag.Name), ctx.Bool(DumpFlag.Name)) 78 } 79 // Read filenames from stdin and execute back-to-back 80 scanner := bufio.NewScanner(os.Stdin) 81 for scanner.Scan() { 82 fname := scanner.Text() 83 if len(fname) == 0 { 84 return nil 85 } 86 if err := runStateTest(fname, cfg, ctx.Bool(MachineFlag.Name), ctx.Bool(DumpFlag.Name)); err != nil { 87 return err 88 } 89 } 90 return nil 91 } 92 93 // runStateTest loads the state-test given by fname, and executes the test. 94 func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error { 95 src, err := os.ReadFile(fname) 96 if err != nil { 97 return err 98 } 99 var tests map[string]tests.StateTest 100 if err := json.Unmarshal(src, &tests); err != nil { 101 return err 102 } 103 // Iterate over all the tests, run them and aggregate the results 104 results := make([]StatetestResult, 0, len(tests)) 105 for key, test := range tests { 106 for _, st := range test.Subtests() { 107 // Run the test and aggregate the result 108 result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true} 109 test.Run(st, cfg, false, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) { 110 if state != nil { 111 root := state.IntermediateRoot(false) 112 result.Root = &root 113 if jsonOut { 114 fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root) 115 } 116 } 117 if err != nil { 118 // Test failed, mark as so and dump any state to aid debugging 119 result.Pass, result.Error = false, err.Error() 120 if dump { 121 dump := state.RawDump(nil) 122 result.State = &dump 123 } 124 } 125 }) 126 results = append(results, *result) 127 } 128 } 129 out, _ := json.MarshalIndent(results, "", " ") 130 fmt.Println(string(out)) 131 return nil 132 }