diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 09cc9ee1f..3f44e0f3c 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -35,8 +35,11 @@ import ( "gopkg.in/urfave/cli.v1" ) +var gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) + var ( - app *cli.App + app = utils.NewApp(gitCommit, "the evm command line interface") + DebugFlag = cli.BoolFlag{ Name: "debug", Usage: "output full trace logs", @@ -91,7 +94,6 @@ var ( ) func init() { - app = utils.NewApp("0.2", "the evm command line interface") app.Flags = []cli.Flag{ CreateFlag, DebugFlag, diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 2069df6cd..2d70dcc2c 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -168,7 +168,7 @@ nodes. ) func accountList(ctx *cli.Context) error { - stack := utils.MakeNode(ctx, clientIdentifier, verString) + stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) for i, acct := range stack.AccountManager().Accounts() { fmt.Printf("Account #%d: {%x} %s\n", i, acct.Address, acct.File) } @@ -261,7 +261,7 @@ func ambiguousAddrRecovery(am *accounts.Manager, err *accounts.AmbiguousAddrErro // accountCreate creates a new account into the keystore defined by the CLI flags. func accountCreate(ctx *cli.Context) error { - stack := utils.MakeNode(ctx, clientIdentifier, verString) + stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) account, err := stack.AccountManager().NewAccount(password) @@ -278,7 +278,7 @@ func accountUpdate(ctx *cli.Context) error { if len(ctx.Args()) == 0 { utils.Fatalf("No accounts specified to update") } - stack := utils.MakeNode(ctx, clientIdentifier, verString) + stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) account, oldPassword := unlockAccount(ctx, stack.AccountManager(), ctx.Args().First(), 0, nil) newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) if err := stack.AccountManager().Update(account, oldPassword, newPassword); err != nil { @@ -297,7 +297,7 @@ func importWallet(ctx *cli.Context) error { utils.Fatalf("Could not read wallet file: %v", err) } - stack := utils.MakeNode(ctx, clientIdentifier, verString) + stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx)) acct, err := stack.AccountManager().ImportPreSaleKey(keyJson, passphrase) if err != nil { @@ -316,7 +316,7 @@ func accountImport(ctx *cli.Context) error { if err != nil { utils.Fatalf("Failed to load the private key: %v", err) } - stack := utils.MakeNode(ctx, clientIdentifier, verString) + stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) acct, err := stack.AccountManager().ImportECDSA(key, passphrase) if err != nil { diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index e0e549e12..3f09c0414 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -28,6 +28,7 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/rpc" ) @@ -45,7 +46,7 @@ func TestConsoleWelcome(t *testing.T) { // Gather all the infos the welcome message needs to contain geth.setTemplateFunc("goos", func() string { return runtime.GOOS }) geth.setTemplateFunc("gover", runtime.Version) - geth.setTemplateFunc("gethver", func() string { return verString }) + geth.setTemplateFunc("gethver", func() string { return utils.Version }) geth.setTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) geth.setTemplateFunc("apis", func() []string { apis := append(strings.Split(rpc.DefaultIPCApis, ","), rpc.MetadataApi) @@ -131,7 +132,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint string) { // Gather all the infos the welcome message needs to contain attach.setTemplateFunc("goos", func() string { return runtime.GOOS }) attach.setTemplateFunc("gover", runtime.Version) - attach.setTemplateFunc("gethver", func() string { return verString }) + attach.setTemplateFunc("gethver", func() string { return utils.Version }) attach.setTemplateFunc("etherbase", func() string { return geth.Etherbase }) attach.setTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) attach.setTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go index 4f8b1642e..6c3ca7298 100644 --- a/cmd/geth/genesis_test.go +++ b/cmd/geth/genesis_test.go @@ -100,7 +100,10 @@ func TestCustomGenesis(t *testing.T) { runGeth(t, "--datadir", datadir, "init", json).cmd.Wait() // Query the custom genesis block - geth := runGeth(t, "--datadir", datadir, "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--exec", tt.query, "console") + geth := runGeth(t, + "--datadir", datadir, "--maxpeers", "0", "--port", "0", + "--nodiscover", "--nat", "none", "--ipcdisable", + "--exec", tt.query, "console") geth.expectRegexp(tt.result) geth.expectExit() } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 82eae244d..b5e454d87 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -42,49 +42,24 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" "gopkg.in/urfave/cli.v1" ) const ( - clientIdentifier = "Geth" // Client identifier to advertise over the network - 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 - - versionOracle = "0xfa7b9770ca4cb04296cac84f37736d4041251cdf" // Ethereum address of the Geth release oracle + clientIdentifier = "Geth" // Client identifier to advertise over the network ) var ( - gitCommit string // Git SHA1 commit hash of the release (set via linker flags) - verString string // Combined textual representation of all the version components - relConfig release.Config // Structured version information and release oracle config - app *cli.App + // Git SHA1 commit hash of the release (set via linker flags) + gitCommit = "" + // Ethereum address of the Geth release oracle. + relOracle = common.HexToAddress("0xfa7b9770ca4cb04296cac84f37736d4041251cdf") + // The app that holds all commands and flags. + app = utils.NewApp(gitCommit, "the go-ethereum command line interface") ) func init() { - // Construct the textual version string from the individual components - verString = fmt.Sprintf("%d.%d.%d", versionMajor, versionMinor, versionPatch) - if versionMeta != "" { - verString += "-" + versionMeta - } - if gitCommit != "" { - verString += "-" + gitCommit[:8] - } - // Construct the version release oracle configuration - relConfig.Oracle = common.HexToAddress(versionOracle) - - relConfig.Major = uint32(versionMajor) - relConfig.Minor = uint32(versionMinor) - relConfig.Patch = uint32(versionPatch) - - commit, _ := hex.DecodeString(gitCommit) - copy(relConfig.Commit[:], commit) - // Initialize the CLI app and start Geth - app = utils.NewApp(verString, "the go-ethereum command line interface") app.Action = geth app.HideVersion = true // we have a command to print the version app.Commands = []cli.Command{ @@ -290,35 +265,32 @@ func initGenesis(ctx *cli.Context) error { } func makeFullNode(ctx *cli.Context) *node.Node { - node := utils.MakeNode(ctx, clientIdentifier, verString) - utils.RegisterEthService(ctx, node, relConfig, makeDefaultExtra()) + stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) + utils.RegisterEthService(ctx, stack, utils.MakeDefaultExtraData(clientIdentifier)) + // Whisper must be explicitly enabled, but is auto-enabled in --dev mode. shhEnabled := ctx.GlobalBool(utils.WhisperEnabledFlag.Name) shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DevModeFlag.Name) if shhEnabled || shhAutoEnabled { - utils.RegisterShhService(node) - } - return node -} - -func makeDefaultExtra() []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) + utils.RegisterShhService(stack) } - 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 + // Add the release oracle service so it boots along with node. + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + config := release.Config{ + Oracle: relOracle, + Major: uint32(utils.VersionMajor), + Minor: uint32(utils.VersionMinor), + Patch: uint32(utils.VersionPatch), + } + commit, _ := hex.DecodeString(gitCommit) + copy(config.Commit[:], commit) + return release.NewReleaseService(ctx, config) + }); err != nil { + utils.Fatalf("Failed to register the Geth release oracle service: %v", err) } - return extra + + return stack } // startNode boots up the system node and all registered protocols, after which @@ -326,7 +298,8 @@ func makeDefaultExtra() []byte { // miner. func startNode(ctx *cli.Context, stack *node.Node) { // Report geth version - glog.V(logger.Info).Infof("instance: Geth/%s/%s/%s\n", verString, runtime.Version(), runtime.GOOS) + glog.V(logger.Info).Infof("instance: Geth/%s/%s/%s\n", utils.Version, runtime.Version(), runtime.GOOS) + // Start up the node itself utils.StartNode(stack) @@ -408,7 +381,10 @@ func gpubench(ctx *cli.Context) error { func version(c *cli.Context) error { fmt.Println(clientIdentifier) - fmt.Println("Version:", verString) + fmt.Println("Version:", utils.Version) + if gitCommit != "" { + fmt.Println("Git Commit:", gitCommit) + } fmt.Println("Protocol Versions:", eth.ProtocolVersions) fmt.Println("Network Id:", c.GlobalInt(utils.NetworkIdFlag.Name)) fmt.Println("Go Version:", runtime.Version()) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 488e7fea2..a1f098f29 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -33,7 +33,6 @@ import ( "github.com/ethereum/ethash" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/release" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/crypto" @@ -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 } @@ -608,13 +610,18 @@ func MakePasswordList(ctx *cli.Context) []string { } // MakeNode configures a node with no services from command line flags. -func MakeNode(ctx *cli.Context, name, version string) *node.Node { +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, version, ctx), + Name: MakeNodeName(name, vsn, ctx), NoDiscovery: ctx.GlobalBool(NoDiscoverFlag.Name), BootstrapNodes: MakeBootstrapNodes(ctx), ListenAddr: MakeListenAddress(ctx), @@ -648,7 +655,7 @@ func MakeNode(ctx *cli.Context, name, version string) *node.Node { // RegisterEthService configures eth.Ethereum from command line flags and adds it to the // given node. -func RegisterEthService(ctx *cli.Context, stack *node.Node, relconf release.Config, extra []byte) { +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 { @@ -723,11 +730,6 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, relconf release.Conf }); err != nil { Fatalf("Failed to register the Ethereum 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. 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 . + +// 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 +}