github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/cmd/u2u/launcher/consolecmd.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser 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 // The go-ethereum library 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 Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package launcher 18 19 import ( 20 "fmt" 21 "strings" 22 23 "gopkg.in/urfave/cli.v1" 24 25 "github.com/unicornultrafoundation/go-u2u/cmd/utils" 26 "github.com/unicornultrafoundation/go-u2u/console" 27 "github.com/unicornultrafoundation/go-u2u/node" 28 "github.com/unicornultrafoundation/go-u2u/rpc" 29 ) 30 31 var ( 32 consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} 33 34 consoleCommand = cli.Command{ 35 Action: utils.MigrateFlags(localConsole), 36 Name: "console", 37 Usage: "Start an interactive JavaScript environment", 38 Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), testFlags...), 39 Category: "CONSOLE COMMANDS", 40 Description: ` 41 The u2u console is an interactive shell for the JavaScript runtime environment 42 which exposes a node admin interface as well as the Ðapp JavaScript API. 43 See https://github.com/unicornultrafoundation/go-u2u/libs/wiki/JavaScript-Console.`, 44 } 45 46 attachCommand = cli.Command{ 47 Action: utils.MigrateFlags(remoteConsole), 48 Name: "attach", 49 Usage: "Start an interactive JavaScript environment (connect to node)", 50 ArgsUsage: "[endpoint]", 51 Flags: append(consoleFlags, DataDirFlag), 52 Category: "CONSOLE COMMANDS", 53 Description: ` 54 The u2u console is an interactive shell for the JavaScript runtime environment 55 which exposes a node admin interface as well as the Ðapp JavaScript API. 56 See https://github.com/unicornultrafoundation/go-u2u/libs/wiki/JavaScript-Console. 57 This command allows to open a console on a running u2u node.`, 58 } 59 60 javascriptCommand = cli.Command{ 61 Action: utils.MigrateFlags(ephemeralConsole), 62 Name: "js", 63 Usage: "Execute the specified JavaScript files", 64 ArgsUsage: "<jsfile> [jsfile...]", 65 Flags: append(append(nodeFlags, consoleFlags...), testFlags...), 66 Category: "CONSOLE COMMANDS", 67 Description: ` 68 The JavaScript VM exposes a node admin interface as well as the Ðapp 69 JavaScript API. See https://github.com/unicornultrafoundation/go-u2u/libs/wiki/JavaScript-Console`, 70 } 71 ) 72 73 // localConsole starts a new u2u node, attaching a JavaScript console to it at the 74 // same time. 75 func localConsole(ctx *cli.Context) error { 76 // Create and start the node based on the CLI flags 77 cfg := makeAllConfigs(ctx) 78 genesisStore := mayGetGenesisStore(ctx) 79 node, _, nodeClose := makeNode(ctx, cfg, genesisStore) 80 startNode(ctx, node) 81 defer nodeClose() 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 u2u: %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 u2u instance, attaching a JavaScript 114 // console to it. 115 func remoteConsole(ctx *cli.Context) error { 116 // Attach to a remotely running u2u instance and start the JavaScript console 117 endpoint := ctx.Args().First() 118 if endpoint == "" { 119 path := DefaultDataDir() 120 if ctx.GlobalIsSet(DataDirFlag.Name) { 121 path = ctx.GlobalString(DataDirFlag.Name) 122 } 123 endpoint = fmt.Sprintf("%s/u2u.ipc", path) 124 } 125 client, err := dialRPC(endpoint) 126 if err != nil { 127 utils.Fatalf("Unable to attach to remote u2u: %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 "u2u attach" and "u2u 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 rpc which required these prefixes. 162 endpoint = endpoint[4:] 163 } 164 return rpc.Dial(endpoint) 165 } 166 167 // ephemeralConsole starts a new u2u node, attaches an ephemeral JavaScript 168 // console to it, executes each of the files specified as arguments and tears 169 // everything down. 170 func ephemeralConsole(ctx *cli.Context) error { 171 var b strings.Builder 172 for _, file := range ctx.Args() { 173 b.Write([]byte(fmt.Sprintf("loadScript('%s');", file))) 174 } 175 utils.Fatalf(`The "js" command is deprecated. Please use the following instead: 176 u2u --exec "%s" console`, b.String()) 177 return nil 178 }