gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/cmd/attacher/consolecmd.go (about)

     1  // Copyright 2019 The aquachain Authors
     2  // This file is part of aquachain.
     3  //
     4  // aquachain 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  // aquachain 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 aquachain. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"path/filepath"
    22  	"strings"
    23  
    24  	"github.com/aerth/tgun"
    25  	cli "github.com/urfave/cli"
    26  	"gitlab.com/aquachain/aquachain/cmd/utils"
    27  	"gitlab.com/aquachain/aquachain/node"
    28  	"gitlab.com/aquachain/aquachain/opt/console"
    29  	"gitlab.com/aquachain/aquachain/params"
    30  	rpc "gitlab.com/aquachain/aquachain/rpc/rpcclient"
    31  )
    32  
    33  var (
    34  	socksFlag = &cli.StringFlag{
    35  		Name:  "socks",
    36  		Value: "",
    37  		Usage: "SOCKS Proxy to use for remote RPC calls (attach subcommand)",
    38  	}
    39  
    40  	consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag}
    41  
    42  	attachCommand = cli.Command{
    43  		Action:    utils.MigrateFlags(remoteConsole),
    44  		Name:      "attach",
    45  		Usage:     "Start an interactive JavaScript environment (connect to node)",
    46  		ArgsUsage: "[endpoint]",
    47  		Flags:     append([]cli.Flag{utils.DataDirFlag, socksFlag}, consoleFlags...),
    48  		Category:  "CONSOLE COMMANDS",
    49  		Description: `
    50  The Aquachain console is an interactive shell for the JavaScript runtime environment
    51  which exposes a node admin interface as well as the Ðapp JavaScript API.
    52  See https://gitlab.com/aquachain/aquachain/wiki/JavaScript-Console.
    53  This command allows to open a console on a running aquachain node.`,
    54  	}
    55  )
    56  
    57  // remoteConsole will connect to a remote aquachain instance, attaching a JavaScript
    58  // console to it.
    59  func remoteConsole(ctx *cli.Context) error {
    60  	// Attach to a remotely running aquachain instance and start the JavaScript console
    61  	endpoint := ctx.Args().First()
    62  	datadir := node.DefaultDataDir()
    63  	if endpoint == "" {
    64  		path := datadir
    65  		if ctx.GlobalIsSet(utils.DataDirFlag.Name) {
    66  			path = ctx.GlobalString(utils.DataDirFlag.Name)
    67  		}
    68  		if path != "" {
    69  			if ctx.GlobalBool(utils.TestnetFlag.Name) {
    70  				path = filepath.Join(path, "testnet")
    71  			} else if ctx.GlobalBool(utils.Testnet2Flag.Name) {
    72  				path = filepath.Join(path, "testnet2")
    73  			} else if ctx.GlobalBool(utils.NetworkEthFlag.Name) {
    74  				path = filepath.Join(path, "ethereum")
    75  			} else if ctx.GlobalBool(utils.DeveloperFlag.Name) {
    76  				path = filepath.Join(path, "develop")
    77  			}
    78  		}
    79  		endpoint = fmt.Sprintf("%s/aquachain.ipc", path)
    80  	}
    81  	socks := ctx.GlobalString("socks")
    82  	client, err := dialRPC(endpoint, socks)
    83  	if err != nil {
    84  		utils.Fatalf("Unable to attach to remote aquachain: %v", err)
    85  	}
    86  	config := console.Config{
    87  		DataDir: datadir,
    88  		DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
    89  		Client:  client,
    90  		Preload: utils.MakeConsolePreloads(ctx),
    91  	}
    92  
    93  	console, err := console.New(config)
    94  	if err != nil {
    95  		utils.Fatalf("Failed to start the JavaScript console: %v", err)
    96  	}
    97  	defer console.Stop(false)
    98  
    99  	if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
   100  		console.Evaluate(script)
   101  		return nil
   102  	}
   103  
   104  	// Otherwise print the welcome screen and enter interactive mode
   105  	console.Welcome()
   106  	console.Interactive()
   107  
   108  	return nil
   109  }
   110  
   111  // dialRPC returns a RPC client which connects to the given endpoint.
   112  // The check for empty endpoint implements the defaulting logic
   113  // for "aquachain attach" and "aquachain monitor" with no argument.
   114  func dialRPC(endpoint string, socks string) (*rpc.Client, error) {
   115  	/* log.Info("Dialing RPC server", "endpoint", endpoint)
   116  	if socks != "" {
   117  		log.Info("+SOCKS5")
   118  	} */
   119  	if endpoint == "" {
   120  		endpoint = node.DefaultIPCEndpoint(clientIdentifier)
   121  	}
   122  	if strings.HasPrefix(endpoint, "http") {
   123  		client := &tgun.Client{
   124  			Proxy: socks,
   125  		}
   126  		httpclient, err := client.HTTPClient()
   127  		if err == nil {
   128  			return rpc.DialHTTPCustom(endpoint, httpclient, map[string]string{"User-Agent": "Aquachain/" + params.Version})
   129  		}
   130  	}
   131  	return rpc.Dial(endpoint)
   132  }