github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/cmd/gvnt/consolecmd.go (about) 1 // Copyright 2016 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 "fmt" 21 "os" 22 "os/signal" 23 "strings" 24 "syscall" 25 26 "github.com/vntchain/go-vnt/cmd/utils" 27 "github.com/vntchain/go-vnt/console" 28 "github.com/vntchain/go-vnt/node" 29 "github.com/vntchain/go-vnt/rpc" 30 cli "gopkg.in/urfave/cli.v1" 31 ) 32 33 var ( 34 consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} 35 36 consoleCommand = cli.Command{ 37 Action: utils.MigrateFlags(localConsole), 38 Name: "console", 39 Usage: "Start an interactive JavaScript environment", 40 Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), whisperFlags...), 41 Category: "CONSOLE COMMANDS", 42 Description: ` 43 The Gvnt console is an interactive shell for the JavaScript runtime environment 44 which exposes a node admin interface as well as the Ðapp JavaScript API. 45 See https://github.com/vntchain/go-vnt/wiki/JavaScript-Console.`, 46 } 47 48 attachCommand = cli.Command{ 49 Action: utils.MigrateFlags(remoteConsole), 50 Name: "attach", 51 Usage: "Start an interactive JavaScript environment (connect to node)", 52 ArgsUsage: "[endpoint]", 53 Flags: append(consoleFlags, utils.DataDirFlag), 54 Category: "CONSOLE COMMANDS", 55 Description: ` 56 The Gvnt console is an interactive shell for the JavaScript runtime environment 57 which exposes a node admin interface as well as the Ðapp JavaScript API. 58 See https://github.com/vntchain/go-vnt/wiki/JavaScript-Console. 59 This command allows to open a console on a running gvnt node.`, 60 } 61 62 javascriptCommand = cli.Command{ 63 Action: utils.MigrateFlags(ephemeralConsole), 64 Name: "js", 65 Usage: "Execute the specified JavaScript files", 66 ArgsUsage: "<jsfile> [jsfile...]", 67 Flags: append(nodeFlags, consoleFlags...), 68 Category: "CONSOLE COMMANDS", 69 Description: ` 70 The JavaScript VM exposes a node admin interface as well as the Ðapp 71 JavaScript API. See https://github.com/vntchain/go-vnt/wiki/JavaScript-Console`, 72 } 73 ) 74 75 // localConsole starts a new gvnt node, attaching a JavaScript console to it at the 76 // same time. 77 func localConsole(ctx *cli.Context) error { 78 // Create and start the node based on the CLI flags 79 node := makeFullNode(ctx) 80 startNode(ctx, node) 81 defer node.Stop() 82 83 // Attach to the newly started node and start the JavaScript console 84 client, err := node.Attach() 85 if err != nil { 86 utils.Fatalf("Failed to attach to the inproc gvnt: %v", err) 87 } 88 config := console.Config{ 89 DataDir: utils.MakeDataDir(ctx), 90 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 91 Client: client, 92 Preload: utils.MakeConsolePreloads(ctx), 93 } 94 95 console, err := console.New(config) 96 if err != nil { 97 utils.Fatalf("Failed to start the JavaScript console: %v", err) 98 } 99 defer console.Stop(false) 100 101 // If only a short execution was requested, evaluate and return 102 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 103 console.Evaluate(script) 104 return nil 105 } 106 // Otherwise print the welcome screen and enter interactive mode 107 console.Welcome() 108 console.Interactive() 109 110 return nil 111 } 112 113 // remoteConsole will connect to a remote gvnt instance, attaching a JavaScript 114 // console to it. 115 func remoteConsole(ctx *cli.Context) error { 116 // Attach to a remotely running gvnt instance and start the JavaScript console 117 endpoint := ctx.Args().First() 118 if endpoint == "" { 119 path := node.DefaultDataDir() 120 if ctx.GlobalIsSet(utils.DataDirFlag.Name) { 121 path = ctx.GlobalString(utils.DataDirFlag.Name) 122 } 123 endpoint = fmt.Sprintf("%s/gvnt.ipc", path) 124 } 125 client, err := dialRPC(endpoint) 126 if err != nil { 127 utils.Fatalf("Unable to attach to remote gvnt: %v", err) 128 } 129 config := console.Config{ 130 DataDir: utils.MakeDataDir(ctx), 131 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 132 Client: client, 133 Preload: utils.MakeConsolePreloads(ctx), 134 } 135 136 console, err := console.New(config) 137 if err != nil { 138 utils.Fatalf("Failed to start the JavaScript console: %v", err) 139 } 140 defer console.Stop(false) 141 142 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 143 console.Evaluate(script) 144 return nil 145 } 146 147 // Otherwise print the welcome screen and enter interactive mode 148 console.Welcome() 149 console.Interactive() 150 151 return nil 152 } 153 154 // dialRPC returns a RPC client which connects to the given endpoint. 155 // The check for empty endpoint implements the defaulting logic 156 // for "gvnt attach" and "gvnt monitor" with no argument. 157 func dialRPC(endpoint string) (*rpc.Client, error) { 158 if endpoint == "" { 159 endpoint = node.DefaultIPCEndpoint(clientIdentifier) 160 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 161 // Backwards compatibility with gvnt < 1.5 which required 162 // these prefixes. 163 endpoint = endpoint[4:] 164 } 165 return rpc.Dial(endpoint) 166 } 167 168 // ephemeralConsole starts a new gvnt node, attaches an ephemeral JavaScript 169 // console to it, executes each of the files specified as arguments and tears 170 // everything down. 171 func ephemeralConsole(ctx *cli.Context) error { 172 // Create and start the node based on the CLI flags 173 node := makeFullNode(ctx) 174 startNode(ctx, node) 175 defer node.Stop() 176 177 // Attach to the newly started node and start the JavaScript console 178 client, err := node.Attach() 179 if err != nil { 180 utils.Fatalf("Failed to attach to the inproc gvnt: %v", err) 181 } 182 config := console.Config{ 183 DataDir: utils.MakeDataDir(ctx), 184 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 185 Client: client, 186 Preload: utils.MakeConsolePreloads(ctx), 187 } 188 189 console, err := console.New(config) 190 if err != nil { 191 utils.Fatalf("Failed to start the JavaScript console: %v", err) 192 } 193 defer console.Stop(false) 194 195 // Evaluate each of the specified JavaScript files 196 for _, file := range ctx.Args() { 197 if err = console.Execute(file); err != nil { 198 utils.Fatalf("Failed to execute %s: %v", file, err) 199 } 200 } 201 // Wait for pending callbacks, but stop for Ctrl-C. 202 abort := make(chan os.Signal, 1) 203 signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM) 204 205 go func() { 206 <-abort 207 os.Exit(0) 208 }() 209 console.Stop(true) 210 211 return nil 212 }