github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/evm/staterunner.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊的一部分。 11 // 12 //Go以太坊是免费软件:您可以重新发布和/或修改它 13 //根据GNU通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊的分布希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU通用公共许可证了解更多详细信息。 21 // 22 //你应该已经收到一份GNU通用公共许可证的副本 23 //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package main 26 27 import ( 28 "encoding/json" 29 "errors" 30 "fmt" 31 "io/ioutil" 32 "os" 33 34 "github.com/ethereum/go-ethereum/core/state" 35 "github.com/ethereum/go-ethereum/core/vm" 36 "github.com/ethereum/go-ethereum/log" 37 "github.com/ethereum/go-ethereum/tests" 38 39 cli "gopkg.in/urfave/cli.v1" 40 ) 41 42 var stateTestCommand = cli.Command{ 43 Action: stateTestCmd, 44 Name: "statetest", 45 Usage: "executes the given state tests", 46 ArgsUsage: "<file>", 47 } 48 49 //StateTestResult包含运行状态测试后的执行状态,任何 50 //可能发生的错误和最终状态的转储(如果请求)。 51 type StatetestResult struct { 52 Name string `json:"name"` 53 Pass bool `json:"pass"` 54 Fork string `json:"fork"` 55 Error string `json:"error,omitempty"` 56 State *state.Dump `json:"state,omitempty"` 57 } 58 59 func stateTestCmd(ctx *cli.Context) error { 60 if len(ctx.Args().First()) == 0 { 61 return errors.New("path-to-test argument required") 62 } 63 //配置Go以太坊记录器 64 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 65 glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name))) 66 log.Root().SetHandler(glogger) 67 68 //配置EVM记录器 69 config := &vm.LogConfig{ 70 DisableMemory: ctx.GlobalBool(DisableMemoryFlag.Name), 71 DisableStack: ctx.GlobalBool(DisableStackFlag.Name), 72 } 73 var ( 74 tracer vm.Tracer 75 debugger *vm.StructLogger 76 ) 77 switch { 78 case ctx.GlobalBool(MachineFlag.Name): 79 tracer = NewJSONLogger(config, os.Stderr) 80 81 case ctx.GlobalBool(DebugFlag.Name): 82 debugger = vm.NewStructLogger(config) 83 tracer = debugger 84 85 default: 86 debugger = vm.NewStructLogger(config) 87 } 88 //从输入文件加载测试内容 89 src, err := ioutil.ReadFile(ctx.Args().First()) 90 if err != nil { 91 return err 92 } 93 var tests map[string]tests.StateTest 94 if err = json.Unmarshal(src, &tests); err != nil { 95 return err 96 } 97 //迭代所有测试,运行它们并聚合结果 98 cfg := vm.Config{ 99 Tracer: tracer, 100 Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), 101 } 102 results := make([]StatetestResult, 0, len(tests)) 103 for key, test := range tests { 104 for _, st := range test.Subtests() { 105 //运行测试并汇总结果 106 result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true} 107 state, err := test.Run(st, cfg) 108 if err != nil { 109 //测试失败,标记为“是”,并转储任何状态以帮助调试 110 result.Pass, result.Error = false, err.Error() 111 if ctx.GlobalBool(DumpFlag.Name) && state != nil { 112 dump := state.RawDump() 113 result.State = &dump 114 } 115 } 116 //打印evmlab跟踪的状态根(已在上面提交,因此无需再次删除对象 117 if ctx.GlobalBool(MachineFlag.Name) && state != nil { 118 fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", state.IntermediateRoot(false)) 119 } 120 121 results = append(results, *result) 122 123 //打印收集的任何结构化日志 124 if ctx.GlobalBool(DebugFlag.Name) { 125 if debugger != nil { 126 fmt.Fprintln(os.Stderr, "#### TRACE ####") 127 vm.WriteTrace(os.Stderr, debugger.StructLogs()) 128 } 129 } 130 } 131 } 132 out, _ := json.MarshalIndent(results, "", " ") 133 fmt.Println(string(out)) 134 return nil 135 }