github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/cmd/utils/flags.go (about)

     1  // Copyright 2015 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 utils
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"fmt"
    22  	"log"
    23  	"math/big"
    24  	"net"
    25  	"net/http"
    26  	"os"
    27  	"path/filepath"
    28  	"runtime"
    29  	"strconv"
    30  
    31  	"github.com/codegangsta/cli"
    32  	"github.com/ethereum/ethash"
    33  	"github.com/ethereum/go-ethereum/accounts"
    34  	"github.com/ethereum/go-ethereum/common"
    35  	"github.com/ethereum/go-ethereum/core"
    36  	"github.com/ethereum/go-ethereum/core/vm"
    37  	"github.com/ethereum/go-ethereum/crypto"
    38  	"github.com/ethereum/go-ethereum/eth"
    39  	"github.com/ethereum/go-ethereum/ethdb"
    40  	"github.com/ethereum/go-ethereum/event"
    41  	"github.com/ethereum/go-ethereum/logger"
    42  	"github.com/ethereum/go-ethereum/logger/glog"
    43  	"github.com/ethereum/go-ethereum/metrics"
    44  	"github.com/ethereum/go-ethereum/p2p/nat"
    45  	"github.com/ethereum/go-ethereum/rpc/api"
    46  	"github.com/ethereum/go-ethereum/rpc/codec"
    47  	"github.com/ethereum/go-ethereum/rpc/comms"
    48  	"github.com/ethereum/go-ethereum/rpc/shared"
    49  	"github.com/ethereum/go-ethereum/rpc/useragent"
    50  	"github.com/ethereum/go-ethereum/xeth"
    51  )
    52  
    53  func init() {
    54  	cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...]
    55  
    56  VERSION:
    57     {{.Version}}
    58  
    59  COMMANDS:
    60     {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
    61     {{end}}{{if .Flags}}
    62  GLOBAL OPTIONS:
    63     {{range .Flags}}{{.}}
    64     {{end}}{{end}}
    65  `
    66  
    67  	cli.CommandHelpTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...]
    68  {{if .Description}}{{.Description}}
    69  {{end}}{{if .Subcommands}}
    70  SUBCOMMANDS:
    71  	{{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
    72  	{{end}}{{end}}{{if .Flags}}
    73  OPTIONS:
    74  	{{range .Flags}}{{.}}
    75  	{{end}}{{end}}
    76  `
    77  }
    78  
    79  // NewApp creates an app with sane defaults.
    80  func NewApp(version, usage string) *cli.App {
    81  	app := cli.NewApp()
    82  	app.Name = filepath.Base(os.Args[0])
    83  	app.Author = ""
    84  	//app.Authors = nil
    85  	app.Email = ""
    86  	app.Version = version
    87  	app.Usage = usage
    88  	return app
    89  }
    90  
    91  // These are all the command line flags we support.
    92  // If you add to this list, please remember to include the
    93  // flag in the appropriate command definition.
    94  //
    95  // The flags are defined here so their names and help texts
    96  // are the same for all commands.
    97  
    98  var (
    99  	// General settings
   100  	DataDirFlag = DirectoryFlag{
   101  		Name:  "datadir",
   102  		Usage: "Data directory to be used",
   103  		Value: DirectoryString{common.DefaultDataDir()},
   104  	}
   105  	NetworkIdFlag = cli.IntFlag{
   106  		Name:  "networkid",
   107  		Usage: "Network Id (integer)",
   108  		Value: eth.NetworkId,
   109  	}
   110  	BlockchainVersionFlag = cli.IntFlag{
   111  		Name:  "blockchainversion",
   112  		Usage: "Blockchain version (integer)",
   113  		Value: core.BlockChainVersion,
   114  	}
   115  	GenesisNonceFlag = cli.IntFlag{
   116  		Name:  "genesisnonce",
   117  		Usage: "Sets the genesis nonce",
   118  		Value: 42,
   119  	}
   120  	GenesisFileFlag = cli.StringFlag{
   121  		Name:  "genesis",
   122  		Usage: "Inserts/Overwrites the genesis block (json format)",
   123  	}
   124  	IdentityFlag = cli.StringFlag{
   125  		Name:  "identity",
   126  		Usage: "Custom node name",
   127  	}
   128  	NatspecEnabledFlag = cli.BoolFlag{
   129  		Name:  "natspec",
   130  		Usage: "Enable NatSpec confirmation notice",
   131  	}
   132  	CacheFlag = cli.IntFlag{
   133  		Name:  "cache",
   134  		Usage: "Megabytes of memory allocated to internal caching",
   135  		Value: 0,
   136  	}
   137  	OlympicFlag = cli.BoolFlag{
   138  		Name:  "olympic",
   139  		Usage: "Use olympic style protocol",
   140  	}
   141  
   142  	// miner settings
   143  	MinerThreadsFlag = cli.IntFlag{
   144  		Name:  "minerthreads",
   145  		Usage: "Number of miner threads",
   146  		Value: runtime.NumCPU(),
   147  	}
   148  	MiningEnabledFlag = cli.BoolFlag{
   149  		Name:  "mine",
   150  		Usage: "Enable mining",
   151  	}
   152  	AutoDAGFlag = cli.BoolFlag{
   153  		Name:  "autodag",
   154  		Usage: "Enable automatic DAG pregeneration",
   155  	}
   156  	EtherbaseFlag = cli.StringFlag{
   157  		Name:  "etherbase",
   158  		Usage: "Public address for block mining rewards. By default the address first created is used",
   159  		Value: "0",
   160  	}
   161  	GasPriceFlag = cli.StringFlag{
   162  		Name:  "gasprice",
   163  		Usage: "Sets the minimal gasprice when mining transactions",
   164  		Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
   165  	}
   166  
   167  	UnlockedAccountFlag = cli.StringFlag{
   168  		Name:  "unlock",
   169  		Usage: "Unlock the account given until this program exits (prompts for password). '--unlock n' unlocks the n-th account in order or creation.",
   170  		Value: "",
   171  	}
   172  	PasswordFileFlag = cli.StringFlag{
   173  		Name:  "password",
   174  		Usage: "Path to password file to use with options and subcommands needing a password",
   175  		Value: "",
   176  	}
   177  
   178  	// vm flags
   179  	VMDebugFlag = cli.BoolFlag{
   180  		Name:  "vmdebug",
   181  		Usage: "Virtual Machine debug output",
   182  	}
   183  	VMForceJitFlag = cli.BoolFlag{
   184  		Name:  "forcejit",
   185  		Usage: "Force the JIT VM to take precedence",
   186  	}
   187  	VMJitCacheFlag = cli.IntFlag{
   188  		Name:  "jitcache",
   189  		Usage: "Amount of cached JIT VM programs",
   190  		Value: 64,
   191  	}
   192  	VMEnableJitFlag = cli.BoolFlag{
   193  		Name:  "jitvm",
   194  		Usage: "Enable the JIT VM",
   195  	}
   196  
   197  	// logging and debug settings
   198  	LogFileFlag = cli.StringFlag{
   199  		Name:  "logfile",
   200  		Usage: "Send log output to a file",
   201  	}
   202  	VerbosityFlag = cli.IntFlag{
   203  		Name:  "verbosity",
   204  		Usage: "Logging verbosity: 0-6 (0=silent, 1=error, 2=warn, 3=info, 4=core, 5=debug, 6=debug detail)",
   205  		Value: int(logger.InfoLevel),
   206  	}
   207  	LogJSONFlag = cli.StringFlag{
   208  		Name:  "logjson",
   209  		Usage: "Send json structured log output to a file or '-' for standard output (default: no json output)",
   210  		Value: "",
   211  	}
   212  	LogToStdErrFlag = cli.BoolFlag{
   213  		Name:  "logtostderr",
   214  		Usage: "Logs are written to standard error instead of to files.",
   215  	}
   216  	LogVModuleFlag = cli.GenericFlag{
   217  		Name:  "vmodule",
   218  		Usage: "The syntax of the argument is a comma-separated list of pattern=N, where pattern is a literal file name (minus the \".go\" suffix) or \"glob\" pattern and N is a log verbosity level.",
   219  		Value: glog.GetVModule(),
   220  	}
   221  	BacktraceAtFlag = cli.GenericFlag{
   222  		Name:  "backtrace_at",
   223  		Usage: "If set to a file and line number (e.g., \"block.go:271\") holding a logging statement, a stack trace will be logged",
   224  		Value: glog.GetTraceLocation(),
   225  	}
   226  	PProfEanbledFlag = cli.BoolFlag{
   227  		Name:  "pprof",
   228  		Usage: "Enable the profiling server on localhost",
   229  	}
   230  	PProfPortFlag = cli.IntFlag{
   231  		Name:  "pprofport",
   232  		Usage: "Port on which the profiler should listen",
   233  		Value: 6060,
   234  	}
   235  	MetricsEnabledFlag = cli.BoolFlag{
   236  		Name:  metrics.MetricsEnabledFlag,
   237  		Usage: "Enables metrics collection and reporting",
   238  	}
   239  
   240  	// RPC settings
   241  	RPCEnabledFlag = cli.BoolFlag{
   242  		Name:  "rpc",
   243  		Usage: "Enable the JSON-RPC server",
   244  	}
   245  	RPCListenAddrFlag = cli.StringFlag{
   246  		Name:  "rpcaddr",
   247  		Usage: "Listening address for the JSON-RPC server",
   248  		Value: "127.0.0.1",
   249  	}
   250  	RPCPortFlag = cli.IntFlag{
   251  		Name:  "rpcport",
   252  		Usage: "Port on which the JSON-RPC server should listen",
   253  		Value: 8545,
   254  	}
   255  	RPCCORSDomainFlag = cli.StringFlag{
   256  		Name:  "rpccorsdomain",
   257  		Usage: "Domain on which to send Access-Control-Allow-Origin header",
   258  		Value: "",
   259  	}
   260  	RpcApiFlag = cli.StringFlag{
   261  		Name:  "rpcapi",
   262  		Usage: "Specify the API's which are offered over the HTTP RPC interface",
   263  		Value: comms.DefaultHttpRpcApis,
   264  	}
   265  	IPCDisabledFlag = cli.BoolFlag{
   266  		Name:  "ipcdisable",
   267  		Usage: "Disable the IPC-RPC server",
   268  	}
   269  	IPCApiFlag = cli.StringFlag{
   270  		Name:  "ipcapi",
   271  		Usage: "Specify the API's which are offered over the IPC interface",
   272  		Value: comms.DefaultIpcApis,
   273  	}
   274  	IPCPathFlag = DirectoryFlag{
   275  		Name:  "ipcpath",
   276  		Usage: "Filename for IPC socket/pipe",
   277  		Value: DirectoryString{common.DefaultIpcPath()},
   278  	}
   279  	ExecFlag = cli.StringFlag{
   280  		Name:  "exec",
   281  		Usage: "Execute javascript statement (only in combination with console/attach)",
   282  	}
   283  	// Network Settings
   284  	MaxPeersFlag = cli.IntFlag{
   285  		Name:  "maxpeers",
   286  		Usage: "Maximum number of network peers (network disabled if set to 0)",
   287  		Value: 25,
   288  	}
   289  	MaxPendingPeersFlag = cli.IntFlag{
   290  		Name:  "maxpendpeers",
   291  		Usage: "Maximum number of pending connection attempts (defaults used if set to 0)",
   292  		Value: 0,
   293  	}
   294  	ListenPortFlag = cli.IntFlag{
   295  		Name:  "port",
   296  		Usage: "Network listening port",
   297  		Value: 30303,
   298  	}
   299  	BootnodesFlag = cli.StringFlag{
   300  		Name:  "bootnodes",
   301  		Usage: "Space-separated enode URLs for p2p discovery bootstrap",
   302  		Value: "",
   303  	}
   304  	NodeKeyFileFlag = cli.StringFlag{
   305  		Name:  "nodekey",
   306  		Usage: "P2P node key file",
   307  	}
   308  	NodeKeyHexFlag = cli.StringFlag{
   309  		Name:  "nodekeyhex",
   310  		Usage: "P2P node key as hex (for testing)",
   311  	}
   312  	NATFlag = cli.StringFlag{
   313  		Name:  "nat",
   314  		Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
   315  		Value: "any",
   316  	}
   317  	NoDiscoverFlag = cli.BoolFlag{
   318  		Name:  "nodiscover",
   319  		Usage: "Disables the peer discovery mechanism (manual peer addition)",
   320  	}
   321  	WhisperEnabledFlag = cli.BoolFlag{
   322  		Name:  "shh",
   323  		Usage: "Enable whisper",
   324  	}
   325  	// ATM the url is left to the user and deployment to
   326  	JSpathFlag = cli.StringFlag{
   327  		Name:  "jspath",
   328  		Usage: "JS library path to be used with console and js subcommands",
   329  		Value: ".",
   330  	}
   331  	SolcPathFlag = cli.StringFlag{
   332  		Name:  "solc",
   333  		Usage: "solidity compiler to be used",
   334  		Value: "solc",
   335  	}
   336  	GpoMinGasPriceFlag = cli.StringFlag{
   337  		Name:  "gpomin",
   338  		Usage: "Minimum suggested gas price",
   339  		Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
   340  	}
   341  	GpoMaxGasPriceFlag = cli.StringFlag{
   342  		Name:  "gpomax",
   343  		Usage: "Maximum suggested gas price",
   344  		Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(),
   345  	}
   346  	GpoFullBlockRatioFlag = cli.IntFlag{
   347  		Name:  "gpofull",
   348  		Usage: "Full block threshold for gas price calculation (%)",
   349  		Value: 80,
   350  	}
   351  	GpobaseStepDownFlag = cli.IntFlag{
   352  		Name:  "gpobasedown",
   353  		Usage: "Suggested gas price base step down ratio (1/1000)",
   354  		Value: 10,
   355  	}
   356  	GpobaseStepUpFlag = cli.IntFlag{
   357  		Name:  "gpobaseup",
   358  		Usage: "Suggested gas price base step up ratio (1/1000)",
   359  		Value: 100,
   360  	}
   361  	GpobaseCorrectionFactorFlag = cli.IntFlag{
   362  		Name:  "gpobasecf",
   363  		Usage: "Suggested gas price base correction factor (%)",
   364  		Value: 110,
   365  	}
   366  )
   367  
   368  // MakeNAT creates a port mapper from set command line flags.
   369  func MakeNAT(ctx *cli.Context) nat.Interface {
   370  	natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name))
   371  	if err != nil {
   372  		Fatalf("Option %s: %v", NATFlag.Name, err)
   373  	}
   374  	return natif
   375  }
   376  
   377  // MakeNodeKey creates a node key from set command line flags.
   378  func MakeNodeKey(ctx *cli.Context) (key *ecdsa.PrivateKey) {
   379  	hex, file := ctx.GlobalString(NodeKeyHexFlag.Name), ctx.GlobalString(NodeKeyFileFlag.Name)
   380  	var err error
   381  	switch {
   382  	case file != "" && hex != "":
   383  		Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
   384  	case file != "":
   385  		if key, err = crypto.LoadECDSA(file); err != nil {
   386  			Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)
   387  		}
   388  	case hex != "":
   389  		if key, err = crypto.HexToECDSA(hex); err != nil {
   390  			Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
   391  		}
   392  	}
   393  	return key
   394  }
   395  
   396  // MakeEthConfig creates ethereum options from set command line flags.
   397  func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
   398  	customName := ctx.GlobalString(IdentityFlag.Name)
   399  	if len(customName) > 0 {
   400  		clientID += "/" + customName
   401  	}
   402  	am := MakeAccountManager(ctx)
   403  	etherbase, err := ParamToAddress(ctx.GlobalString(EtherbaseFlag.Name), am)
   404  	if err != nil {
   405  		glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default")
   406  	}
   407  
   408  	return &eth.Config{
   409  		Name:                    common.MakeName(clientID, version),
   410  		DataDir:                 ctx.GlobalString(DataDirFlag.Name),
   411  		GenesisNonce:            ctx.GlobalInt(GenesisNonceFlag.Name),
   412  		GenesisFile:             ctx.GlobalString(GenesisFileFlag.Name),
   413  		BlockChainVersion:       ctx.GlobalInt(BlockchainVersionFlag.Name),
   414  		DatabaseCache:           ctx.GlobalInt(CacheFlag.Name),
   415  		SkipBcVersionCheck:      false,
   416  		NetworkId:               ctx.GlobalInt(NetworkIdFlag.Name),
   417  		LogFile:                 ctx.GlobalString(LogFileFlag.Name),
   418  		Verbosity:               ctx.GlobalInt(VerbosityFlag.Name),
   419  		LogJSON:                 ctx.GlobalString(LogJSONFlag.Name),
   420  		Etherbase:               common.HexToAddress(etherbase),
   421  		MinerThreads:            ctx.GlobalInt(MinerThreadsFlag.Name),
   422  		AccountManager:          am,
   423  		VmDebug:                 ctx.GlobalBool(VMDebugFlag.Name),
   424  		MaxPeers:                ctx.GlobalInt(MaxPeersFlag.Name),
   425  		MaxPendingPeers:         ctx.GlobalInt(MaxPendingPeersFlag.Name),
   426  		Port:                    ctx.GlobalString(ListenPortFlag.Name),
   427  		Olympic:                 ctx.GlobalBool(OlympicFlag.Name),
   428  		NAT:                     MakeNAT(ctx),
   429  		NatSpec:                 ctx.GlobalBool(NatspecEnabledFlag.Name),
   430  		Discovery:               !ctx.GlobalBool(NoDiscoverFlag.Name),
   431  		NodeKey:                 MakeNodeKey(ctx),
   432  		Shh:                     ctx.GlobalBool(WhisperEnabledFlag.Name),
   433  		Dial:                    true,
   434  		BootNodes:               ctx.GlobalString(BootnodesFlag.Name),
   435  		GasPrice:                common.String2Big(ctx.GlobalString(GasPriceFlag.Name)),
   436  		GpoMinGasPrice:          common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)),
   437  		GpoMaxGasPrice:          common.String2Big(ctx.GlobalString(GpoMaxGasPriceFlag.Name)),
   438  		GpoFullBlockRatio:       ctx.GlobalInt(GpoFullBlockRatioFlag.Name),
   439  		GpobaseStepDown:         ctx.GlobalInt(GpobaseStepDownFlag.Name),
   440  		GpobaseStepUp:           ctx.GlobalInt(GpobaseStepUpFlag.Name),
   441  		GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name),
   442  		SolcPath:                ctx.GlobalString(SolcPathFlag.Name),
   443  		AutoDAG:                 ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name),
   444  	}
   445  }
   446  
   447  // SetupLogger configures glog from the logging-related command line flags.
   448  func SetupLogger(ctx *cli.Context) {
   449  	glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
   450  	glog.CopyStandardLogTo("INFO")
   451  	glog.SetToStderr(true)
   452  	glog.SetLogDir(ctx.GlobalString(LogFileFlag.Name))
   453  }
   454  
   455  // SetupVM configured the VM package's global settings
   456  func SetupVM(ctx *cli.Context) {
   457  	vm.EnableJit = ctx.GlobalBool(VMEnableJitFlag.Name)
   458  	vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name)
   459  	vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
   460  }
   461  
   462  // MakeChain creates a chain manager from set command line flags.
   463  func MakeChain(ctx *cli.Context) (chain *core.ChainManager, chainDb common.Database) {
   464  	datadir := ctx.GlobalString(DataDirFlag.Name)
   465  	cache := ctx.GlobalInt(CacheFlag.Name)
   466  
   467  	var err error
   468  	if chainDb, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache); err != nil {
   469  		Fatalf("Could not open database: %v", err)
   470  	}
   471  	if ctx.GlobalBool(OlympicFlag.Name) {
   472  		InitOlympic()
   473  		_, err := core.WriteTestNetGenesisBlock(chainDb, 42)
   474  		if err != nil {
   475  			glog.Fatalln(err)
   476  		}
   477  	}
   478  
   479  	eventMux := new(event.TypeMux)
   480  	pow := ethash.New()
   481  	//genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
   482  	chain, err = core.NewChainManager(chainDb, pow, eventMux)
   483  	if err != nil {
   484  		Fatalf("Could not start chainmanager: %v", err)
   485  	}
   486  
   487  	proc := core.NewBlockProcessor(chainDb, pow, chain, eventMux)
   488  	chain.SetProcessor(proc)
   489  	return chain, chainDb
   490  }
   491  
   492  // MakeChain creates an account manager from set command line flags.
   493  func MakeAccountManager(ctx *cli.Context) *accounts.Manager {
   494  	dataDir := ctx.GlobalString(DataDirFlag.Name)
   495  	ks := crypto.NewKeyStorePassphrase(filepath.Join(dataDir, "keystore"))
   496  	return accounts.NewManager(ks)
   497  }
   498  
   499  func IpcSocketPath(ctx *cli.Context) (ipcpath string) {
   500  	if runtime.GOOS == "windows" {
   501  		ipcpath = common.DefaultIpcPath()
   502  		if ctx.GlobalIsSet(IPCPathFlag.Name) {
   503  			ipcpath = ctx.GlobalString(IPCPathFlag.Name)
   504  		}
   505  	} else {
   506  		ipcpath = common.DefaultIpcPath()
   507  		if ctx.GlobalIsSet(DataDirFlag.Name) {
   508  			ipcpath = filepath.Join(ctx.GlobalString(DataDirFlag.Name), "geth.ipc")
   509  		}
   510  		if ctx.GlobalIsSet(IPCPathFlag.Name) {
   511  			ipcpath = ctx.GlobalString(IPCPathFlag.Name)
   512  		}
   513  	}
   514  
   515  	return
   516  }
   517  
   518  func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
   519  	config := comms.IpcConfig{
   520  		Endpoint: IpcSocketPath(ctx),
   521  	}
   522  
   523  	initializer := func(conn net.Conn) (shared.EthereumApi, error) {
   524  		fe := useragent.NewRemoteFrontend(conn, eth.AccountManager())
   525  		xeth := xeth.New(eth, fe)
   526  		codec := codec.JSON
   527  
   528  		apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
   529  		if err != nil {
   530  			return nil, err
   531  		}
   532  
   533  		return api.Merge(apis...), nil
   534  	}
   535  
   536  	return comms.StartIpc(config, codec.JSON, initializer)
   537  }
   538  
   539  func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
   540  	config := comms.HttpConfig{
   541  		ListenAddress: ctx.GlobalString(RPCListenAddrFlag.Name),
   542  		ListenPort:    uint(ctx.GlobalInt(RPCPortFlag.Name)),
   543  		CorsDomain:    ctx.GlobalString(RPCCORSDomainFlag.Name),
   544  	}
   545  
   546  	xeth := xeth.New(eth, nil)
   547  	codec := codec.JSON
   548  
   549  	apis, err := api.ParseApiString(ctx.GlobalString(RpcApiFlag.Name), codec, xeth, eth)
   550  	if err != nil {
   551  		return err
   552  	}
   553  
   554  	return comms.StartHttp(config, codec, api.Merge(apis...))
   555  }
   556  
   557  func StartPProf(ctx *cli.Context) {
   558  	address := fmt.Sprintf("localhost:%d", ctx.GlobalInt(PProfPortFlag.Name))
   559  	go func() {
   560  		log.Println(http.ListenAndServe(address, nil))
   561  	}()
   562  }
   563  
   564  func ParamToAddress(addr string, am *accounts.Manager) (addrHex string, err error) {
   565  	if !((len(addr) == 40) || (len(addr) == 42)) { // with or without 0x
   566  		index, err := strconv.Atoi(addr)
   567  		if err != nil {
   568  			Fatalf("Invalid account address '%s'", addr)
   569  		}
   570  
   571  		addrHex, err = am.AddressByIndex(index)
   572  		if err != nil {
   573  			return "", err
   574  		}
   575  	} else {
   576  		addrHex = addr
   577  	}
   578  	return
   579  }