diff options
Diffstat (limited to 'cmd/utils')
-rw-r--r-- | cmd/utils/client.go | 55 | ||||
-rw-r--r-- | cmd/utils/flags.go | 240 | ||||
-rw-r--r-- | cmd/utils/version.go | 64 |
3 files changed, 167 insertions, 192 deletions
diff --git a/cmd/utils/client.go b/cmd/utils/client.go deleted file mode 100644 index cc9647580..000000000 --- a/cmd/utils/client.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. - -package utils - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/rpc" - "gopkg.in/urfave/cli.v1" -) - -// NewRemoteRPCClient returns a RPC client which connects to a running geth instance. -// Depending on the given context this can either be a IPC or a HTTP client. -func NewRemoteRPCClient(ctx *cli.Context) (rpc.Client, error) { - if ctx.Args().Present() { - endpoint := ctx.Args().First() - return NewRemoteRPCClientFromString(endpoint) - } - // use IPC by default - return rpc.NewIPCClient(node.DefaultIPCEndpoint()) -} - -// NewRemoteRPCClientFromString returns a RPC client which connects to the given -// endpoint. It must start with either `ipc:` or `rpc:` (HTTP). -func NewRemoteRPCClientFromString(endpoint string) (rpc.Client, error) { - if strings.HasPrefix(endpoint, "ipc:") { - return rpc.NewIPCClient(endpoint[4:]) - } - if strings.HasPrefix(endpoint, "rpc:") { - return rpc.NewHTTPClient(endpoint[4:]) - } - if strings.HasPrefix(endpoint, "http://") { - return rpc.NewHTTPClient(endpoint) - } - if strings.HasPrefix(endpoint, "ws:") { - return rpc.NewWSClient(endpoint) - } - return nil, fmt.Errorf("invalid endpoint") -} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 38ba3a9ba..3ab556a8f 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -47,7 +47,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" - "github.com/ethereum/go-ethereum/release" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/whisper" "gopkg.in/urfave/cli.v1" @@ -80,13 +79,16 @@ OPTIONS: } // NewApp creates an app with sane defaults. -func NewApp(version, usage string) *cli.App { +func NewApp(gitCommit, usage string) *cli.App { app := cli.NewApp() app.Name = filepath.Base(os.Args[0]) app.Author = "" //app.Authors = nil app.Email = "" - app.Version = version + app.Version = Version + if gitCommit != "" { + app.Version += "-" + gitCommit[:8] + } app.Usage = usage return app } @@ -126,10 +128,6 @@ var ( Name: "dev", Usage: "Developer mode: pre-configured private network with several debugging flags", } - GenesisFileFlag = cli.StringFlag{ - Name: "genesis", - Usage: "Insert/overwrite the genesis block (JSON format)", - } IdentityFlag = cli.StringFlag{ Name: "identity", Usage: "Custom node name", @@ -148,11 +146,6 @@ var ( Usage: "Megabytes of memory allocated to internal caching (min 16MB / database forced)", Value: 128, } - BlockchainVersionFlag = cli.IntFlag{ - Name: "blockchainversion", - Usage: "Blockchain version (integer)", - Value: core.BlockChainVersion, - } FastSyncFlag = cli.BoolFlag{ Name: "fast", Usage: "Enable fast syncing through state downloads", @@ -161,6 +154,15 @@ var ( Name: "lightkdf", Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", } + // Fork settings + SupportDAOFork = cli.BoolFlag{ + Name: "support-dao-fork", + Usage: "Updates the chain rules to support the DAO hard-fork", + } + OpposeDAOFork = cli.BoolFlag{ + Name: "oppose-dao-fork", + Usage: "Updates the chain rules to oppose the DAO hard-fork", + } // Miner settings // TODO: refactor CPU vs GPU mining flags MiningEnabledFlag = cli.BoolFlag{ @@ -408,16 +410,6 @@ func MustMakeDataDir(ctx *cli.Context) string { return "" } -// MakeKeyStoreDir resolves the folder to use for storing the account keys from the -// set command line flags, returning the explicitly requested path, or one inside -// the data directory otherwise. -func MakeKeyStoreDir(datadir string, ctx *cli.Context) string { - if path := ctx.GlobalString(KeyStoreDirFlag.Name); path != "" { - return path - } - return filepath.Join(datadir, "keystore") -} - // MakeIPCPath creates an IPC path configuration from the set command line flags, // returning an empty string if IPC was explicitly disabled, or the set path. func MakeIPCPath(ctx *cli.Context) string { @@ -534,20 +526,6 @@ func MakeWSRpcHost(ctx *cli.Context) string { return ctx.GlobalString(WSListenAddrFlag.Name) } -// MakeGenesisBlock loads up a genesis block from an input file specified in the -// command line, or returns the empty string if none set. -func MakeGenesisBlock(ctx *cli.Context) string { - genesis := ctx.GlobalString(GenesisFileFlag.Name) - if genesis == "" { - return "" - } - data, err := ioutil.ReadFile(genesis) - if err != nil { - Fatalf("Failed to load custom genesis file: %v", err) - } - return string(data) -} - // MakeDatabaseHandles raises out the number of allowed file handles per process // for Geth and returns half of the allowance to assign to the database. func MakeDatabaseHandles() int { @@ -564,20 +542,6 @@ func MakeDatabaseHandles() int { return limit / 2 // Leave half for networking and other stuff } -// MakeAccountManager creates an account manager from set command line flags. -func MakeAccountManager(ctx *cli.Context) *accounts.Manager { - // Create the keystore crypto primitive, light if requested - scryptN := accounts.StandardScryptN - scryptP := accounts.StandardScryptP - if ctx.GlobalBool(LightKDFFlag.Name) { - scryptN = accounts.LightScryptN - scryptP = accounts.LightScryptP - } - datadir := MustMakeDataDir(ctx) - keydir := MakeKeyStoreDir(datadir, ctx) - return accounts.NewManager(keydir, scryptN, scryptP) -} - // MakeAddress converts an account specified directly as a hex encoded string or // a key index in the key store to an internal account representation. func MakeAddress(accman *accounts.Manager, account string) (accounts.Account, error) { @@ -640,9 +604,53 @@ func MakePasswordList(ctx *cli.Context) []string { return lines } -// MakeSystemNode sets up a local node, configures the services to launch and -// assembles the P2P protocol stack. -func MakeSystemNode(name, version string, relconf release.Config, extra []byte, ctx *cli.Context) *node.Node { +// MakeNode configures a node with no services from command line flags. +func MakeNode(ctx *cli.Context, name, gitCommit string) *node.Node { + vsn := Version + if gitCommit != "" { + vsn += "-" + gitCommit[:8] + } + + config := &node.Config{ + DataDir: MustMakeDataDir(ctx), + KeyStoreDir: ctx.GlobalString(KeyStoreDirFlag.Name), + UseLightweightKDF: ctx.GlobalBool(LightKDFFlag.Name), + PrivateKey: MakeNodeKey(ctx), + Name: MakeNodeName(name, vsn, ctx), + NoDiscovery: ctx.GlobalBool(NoDiscoverFlag.Name), + BootstrapNodes: MakeBootstrapNodes(ctx), + ListenAddr: MakeListenAddress(ctx), + NAT: MakeNAT(ctx), + MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), + MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), + IPCPath: MakeIPCPath(ctx), + HTTPHost: MakeHTTPRpcHost(ctx), + HTTPPort: ctx.GlobalInt(RPCPortFlag.Name), + HTTPCors: ctx.GlobalString(RPCCORSDomainFlag.Name), + HTTPModules: MakeRPCModules(ctx.GlobalString(RPCApiFlag.Name)), + WSHost: MakeWSRpcHost(ctx), + WSPort: ctx.GlobalInt(WSPortFlag.Name), + WSOrigins: ctx.GlobalString(WSAllowedOriginsFlag.Name), + WSModules: MakeRPCModules(ctx.GlobalString(WSApiFlag.Name)), + } + if ctx.GlobalBool(DevModeFlag.Name) { + if !ctx.GlobalIsSet(DataDirFlag.Name) { + config.DataDir = filepath.Join(os.TempDir(), "/ethereum_dev_mode") + } + // --dev mode does not need p2p networking. + config.MaxPeers = 0 + config.ListenAddr = ":0" + } + stack, err := node.New(config) + if err != nil { + Fatalf("Failed to create the protocol stack: %v", err) + } + return stack +} + +// RegisterEthService configures eth.Ethereum from command line flags and adds it to the +// given node. +func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) { // Avoid conflicting network flags networks, netFlags := 0, []cli.BoolFlag{DevModeFlag, TestNetFlag, OlympicFlag} for _, flag := range netFlags { @@ -653,29 +661,6 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, if networks > 1 { Fatalf("The %v flags are mutually exclusive", netFlags) } - // Configure the node's service container - stackConf := &node.Config{ - DataDir: MustMakeDataDir(ctx), - PrivateKey: MakeNodeKey(ctx), - Name: MakeNodeName(name, version, ctx), - NoDiscovery: ctx.GlobalBool(NoDiscoverFlag.Name), - BootstrapNodes: MakeBootstrapNodes(ctx), - ListenAddr: MakeListenAddress(ctx), - NAT: MakeNAT(ctx), - MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), - MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), - IPCPath: MakeIPCPath(ctx), - HTTPHost: MakeHTTPRpcHost(ctx), - HTTPPort: ctx.GlobalInt(RPCPortFlag.Name), - HTTPCors: ctx.GlobalString(RPCCORSDomainFlag.Name), - HTTPModules: MakeRPCModules(ctx.GlobalString(RPCApiFlag.Name)), - WSHost: MakeWSRpcHost(ctx), - WSPort: ctx.GlobalInt(WSPortFlag.Name), - WSOrigins: ctx.GlobalString(WSAllowedOriginsFlag.Name), - WSModules: MakeRPCModules(ctx.GlobalString(WSApiFlag.Name)), - } - // Configure the Ethereum service - accman := MakeAccountManager(ctx) // initialise new random number generator rand := rand.New(rand.NewSource(time.Now().UnixNano())) @@ -688,15 +673,12 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, } ethConf := ð.Config{ + Etherbase: MakeEtherbase(stack.AccountManager(), ctx), ChainConfig: MustMakeChainConfig(ctx), - Genesis: MakeGenesisBlock(ctx), FastSync: ctx.GlobalBool(FastSyncFlag.Name), - BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), DatabaseCache: ctx.GlobalInt(CacheFlag.Name), DatabaseHandles: MakeDatabaseHandles(), NetworkId: ctx.GlobalInt(NetworkIdFlag.Name), - AccountManager: accman, - Etherbase: MakeEtherbase(accman, ctx), MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), ExtraData: MakeMinerExtra(extra, ctx), NatSpec: ctx.GlobalBool(NatspecEnabledFlag.Name), @@ -713,8 +695,6 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, SolcPath: ctx.GlobalString(SolcPathFlag.Name), AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name), } - // Configure the Whisper service - shhEnable := ctx.GlobalBool(WhisperEnabledFlag.Name) // Override any default configs in dev mode or the test net switch { @@ -722,70 +702,35 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 1 } - if !ctx.GlobalIsSet(GenesisFileFlag.Name) { - ethConf.Genesis = core.OlympicGenesisBlock() - } + ethConf.Genesis = core.OlympicGenesisBlock() case ctx.GlobalBool(TestNetFlag.Name): if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 2 } - if !ctx.GlobalIsSet(GenesisFileFlag.Name) { - ethConf.Genesis = core.TestNetGenesisBlock() - } + ethConf.Genesis = core.TestNetGenesisBlock() state.StartingNonce = 1048576 // (2**20) case ctx.GlobalBool(DevModeFlag.Name): - // Override the base network stack configs - if !ctx.GlobalIsSet(DataDirFlag.Name) { - stackConf.DataDir = filepath.Join(os.TempDir(), "/ethereum_dev_mode") - } - if !ctx.GlobalIsSet(MaxPeersFlag.Name) { - stackConf.MaxPeers = 0 - } - if !ctx.GlobalIsSet(ListenPortFlag.Name) { - stackConf.ListenAddr = ":0" - } - // Override the Ethereum protocol configs - if !ctx.GlobalIsSet(GenesisFileFlag.Name) { - ethConf.Genesis = core.OlympicGenesisBlock() - } + ethConf.Genesis = core.OlympicGenesisBlock() if !ctx.GlobalIsSet(GasPriceFlag.Name) { ethConf.GasPrice = new(big.Int) } - if !ctx.GlobalIsSet(WhisperEnabledFlag.Name) { - shhEnable = true - } ethConf.PowTest = true } - // Assemble and return the protocol stack - stack, err := node.New(stackConf) - if err != nil { - Fatalf("Failed to create the protocol stack: %v", err) - } - - if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { - return accman, nil - }); err != nil { - Fatalf("Failed to register the account manager service: %v", err) - } if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil { Fatalf("Failed to register the Ethereum service: %v", err) } - if shhEnable { - if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { - Fatalf("Failed to register the Whisper service: %v", err) - } - } - if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { - return release.NewReleaseService(ctx, relconf) - }); err != nil { - Fatalf("Failed to register the Geth release oracle service: %v", err) +} + +// RegisterShhService configures whisper and adds it to the given node. +func RegisterShhService(stack *node.Node) { + if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { + Fatalf("Failed to register the Whisper service: %v", err) } - return stack } // SetupNetwork configures the system for either the main net or some test network. @@ -813,24 +758,45 @@ func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig { // MustMakeChainConfigFromDb reads the chain configuration from the given database. func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig { - genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0) + // If the chain is already initialized, use any existing chain configs + config := new(core.ChainConfig) + genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0) if genesis != nil { - // Existing genesis block, use stored config if available. storedConfig, err := core.GetChainConfig(db, genesis.Hash()) - if err == nil { - return storedConfig - } else if err != core.ChainConfigNotFoundErr { + switch err { + case nil: + config = storedConfig + case core.ChainConfigNotFoundErr: + // No configs found, use empty, will populate below + default: Fatalf("Could not make chain configuration: %v", err) } } - var homesteadBlockNo *big.Int - if ctx.GlobalBool(TestNetFlag.Name) { - homesteadBlockNo = params.TestNetHomesteadBlock - } else { - homesteadBlockNo = params.MainNetHomesteadBlock + // Set any missing fields due to them being unset or system upgrade + if config.HomesteadBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.HomesteadBlock = params.TestNetHomesteadBlock + } else { + config.HomesteadBlock = params.MainNetHomesteadBlock + } + } + if config.DAOForkBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.DAOForkBlock = params.TestNetDAOForkBlock + } else { + config.DAOForkBlock = params.MainNetDAOForkBlock + } + config.DAOForkSupport = true + } + // Force override any existing configs if explicitly requested + switch { + case ctx.GlobalBool(SupportDAOFork.Name): + config.DAOForkSupport = true + case ctx.GlobalBool(OpposeDAOFork.Name): + config.DAOForkSupport = false } - return &core.ChainConfig{HomesteadBlock: homesteadBlockNo} + return config } // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. diff --git a/cmd/utils/version.go b/cmd/utils/version.go new file mode 100644 index 000000000..03633d694 --- /dev/null +++ b/cmd/utils/version.go @@ -0,0 +1,64 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. + +// Package utils contains internal helper functions for go-ethereum commands. +package utils + +import ( + "fmt" + "runtime" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + VersionMajor = 1 // Major version component of the current release + VersionMinor = 5 // Minor version component of the current release + VersionPatch = 0 // Patch version component of the current release + VersionMeta = "unstable" // Version metadata to append to the version string +) + +// Version holds the textual version string. +var Version = func() string { + v := fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch) + if VersionMeta != "" { + v += "-" + VersionMeta + } + return v +}() + +// MakeDefaultExtraData returns the default Ethereum block extra data blob. +func MakeDefaultExtraData(clientIdentifier string) []byte { + var clientInfo = struct { + Version uint + Name string + GoVersion string + Os string + }{uint(VersionMajor<<16 | VersionMinor<<8 | VersionPatch), clientIdentifier, runtime.Version(), runtime.GOOS} + extra, err := rlp.EncodeToBytes(clientInfo) + if err != nil { + glog.V(logger.Warn).Infoln("error setting canonical miner information:", err) + } + if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() { + glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize) + glog.V(logger.Debug).Infof("extra: %x\n", extra) + return nil + } + return extra +} |