github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/neatio/consolecmd.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/signal"
     7  	"path/filepath"
     8  	"strings"
     9  	"syscall"
    10  
    11  	"github.com/neatlab/neatio/network/node"
    12  	"github.com/neatlab/neatio/network/rpc"
    13  	"github.com/neatlab/neatio/utilities/console"
    14  	"github.com/neatlab/neatio/utilities/utils"
    15  	"gopkg.in/urfave/cli.v1"
    16  )
    17  
    18  var (
    19  	consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag}
    20  
    21  	consoleCommand = cli.Command{
    22  		Action:   utils.MigrateFlags(localConsole),
    23  		Name:     "console",
    24  		Usage:    "Start an interactive JavaScript environment",
    25  		Flags:    append(append(nodeFlags, rpcFlags...), consoleFlags...),
    26  		Category: "CONSOLE COMMANDS",
    27  		Description: `
    28  The Geth console is an interactive shell for the JavaScript runtime environment
    29  which exposes a node admin interface as well as the Ðapp JavaScript API.
    30  See https://github.com/neatlab/neatio/wiki/JavaScript-Console.`,
    31  	}
    32  
    33  	attachCommand = cli.Command{
    34  		Action:    utils.MigrateFlags(remoteConsole),
    35  		Name:      "attach",
    36  		Usage:     "Start an interactive JavaScript environment (connect to node)",
    37  		ArgsUsage: "[endpoint]",
    38  		Flags:     append(consoleFlags, utils.DataDirFlag),
    39  		Category:  "CONSOLE COMMANDS",
    40  		Description: `
    41  The Geth 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/neatlab/neatio/wiki/JavaScript-Console.
    44  This command allows to open a console on a running neatio node.`,
    45  	}
    46  
    47  	javascriptCommand = cli.Command{
    48  		Action:    utils.MigrateFlags(ephemeralConsole),
    49  		Name:      "js",
    50  		Usage:     "Execute the specified JavaScript files",
    51  		ArgsUsage: "<jsfile> [jsfile...]",
    52  		Flags:     append(nodeFlags, consoleFlags...),
    53  		Category:  "CONSOLE COMMANDS",
    54  		Description: `
    55  The JavaScript VM exposes a node admin interface as well as the Ðapp
    56  JavaScript API. See https://github.com/neatlab/neatio/wiki/JavaScript-Console`,
    57  	}
    58  )
    59  
    60  func localConsole(ctx *cli.Context) error {
    61  	chainName := ctx.Args().First()
    62  	if chainName == "" {
    63  		utils.Fatalf("This command requires chain name specified.")
    64  	}
    65  
    66  	node := makeFullNode(ctx, GetCMInstance(ctx).cch, chainName)
    67  	utils.StartNode(ctx, node)
    68  	defer node.Close()
    69  
    70  	client, err := node.Attach()
    71  	if err != nil {
    72  		utils.Fatalf("Failed to attach to the inproc neatio: %v", err)
    73  	}
    74  	config := console.Config{
    75  		DataDir: utils.MakeDataDir(ctx),
    76  		DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
    77  		Client:  client,
    78  		Preload: utils.MakeConsolePreloads(ctx),
    79  	}
    80  
    81  	console, err := console.New(config)
    82  	if err != nil {
    83  		utils.Fatalf("Failed to start the JavaScript console: %v", err)
    84  	}
    85  	defer console.Stop(false)
    86  
    87  	if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
    88  		console.Evaluate(script)
    89  		return nil
    90  	}
    91  	console.Welcome()
    92  	console.Interactive()
    93  
    94  	return nil
    95  }
    96  
    97  func remoteConsole(ctx *cli.Context) error {
    98  	endpoint := ctx.Args().First()
    99  	if endpoint == "" {
   100  		path := node.DefaultDataDir()
   101  		if ctx.GlobalIsSet(utils.DataDirFlag.Name) {
   102  			path = ctx.GlobalString(utils.DataDirFlag.Name)
   103  		}
   104  		if path != "" {
   105  			if ctx.GlobalBool(utils.TestnetFlag.Name) {
   106  				path = filepath.Join(path, "testnet")
   107  			}
   108  		}
   109  		endpoint = fmt.Sprintf("%s/neatio.ipc", path)
   110  	}
   111  	client, err := dialRPC(endpoint)
   112  	if err != nil {
   113  		utils.Fatalf("Unable to attach to remote neatio: %v", err)
   114  	}
   115  	config := console.Config{
   116  		DataDir: utils.MakeDataDir(ctx),
   117  		DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
   118  		Client:  client,
   119  		Preload: utils.MakeConsolePreloads(ctx),
   120  	}
   121  
   122  	console, err := console.New(config)
   123  	if err != nil {
   124  		utils.Fatalf("Failed to start the JavaScript console: %v", err)
   125  	}
   126  	defer console.Stop(false)
   127  
   128  	if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
   129  		console.Evaluate(script)
   130  		return nil
   131  	}
   132  
   133  	console.Welcome()
   134  	console.Interactive()
   135  
   136  	return nil
   137  }
   138  
   139  func dialRPC(endpoint string) (*rpc.Client, error) {
   140  	if endpoint == "" {
   141  		endpoint = node.DefaultIPCEndpoint(clientIdentifier)
   142  	} else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
   143  		endpoint = endpoint[4:]
   144  	}
   145  	return rpc.Dial(endpoint)
   146  }
   147  
   148  func ephemeralConsole(ctx *cli.Context) error {
   149  	chainName := ctx.Args().First()
   150  	if chainName == "" {
   151  		utils.Fatalf("This command requires chain name specified.")
   152  	}
   153  
   154  	node := makeFullNode(ctx, GetCMInstance(ctx).cch, chainName)
   155  	utils.StartNode(ctx, node)
   156  	defer node.Close()
   157  
   158  	client, err := node.Attach()
   159  	if err != nil {
   160  		utils.Fatalf("Failed to attach to the inproc neatio: %v", err)
   161  	}
   162  	config := console.Config{
   163  		DataDir: utils.MakeDataDir(ctx),
   164  		DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
   165  		Client:  client,
   166  		Preload: utils.MakeConsolePreloads(ctx),
   167  	}
   168  
   169  	console, err := console.New(config)
   170  	if err != nil {
   171  		utils.Fatalf("Failed to start the JavaScript console: %v", err)
   172  	}
   173  	defer console.Stop(false)
   174  
   175  	for _, file := range ctx.Args() {
   176  		if err = console.Execute(file); err != nil {
   177  			utils.Fatalf("Failed to execute %s: %v", file, err)
   178  		}
   179  	}
   180  	abort := make(chan os.Signal, 1)
   181  	signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM)
   182  
   183  	go func() {
   184  		<-abort
   185  		os.Exit(0)
   186  	}()
   187  	console.Stop(true)
   188  
   189  	return nil
   190  }