main.go 8.0 KB
Newer Older
F
Felix Lange 已提交
1 2 3 4 5 6 7 8 9 10
// 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
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
F
Felix Lange 已提交
12 13 14
// GNU General Public License for more details.
//
// 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/>.
F
Felix Lange 已提交
16

17
// geth is the official command-line client for Ethereum.
18 19 20
package main

import (
21
	"encoding/hex"
O
obscuren 已提交
22 23
	"fmt"
	"os"
O
obscuren 已提交
24
	"runtime"
25
	"strings"
26
	"time"
O
obscuren 已提交
27

28
	"github.com/ethereum/go-ethereum/accounts/keystore"
O
obscuren 已提交
29
	"github.com/ethereum/go-ethereum/cmd/utils"
Z
zelig 已提交
30
	"github.com/ethereum/go-ethereum/common"
31
	"github.com/ethereum/go-ethereum/console"
32
	"github.com/ethereum/go-ethereum/contracts/release"
O
obscuren 已提交
33
	"github.com/ethereum/go-ethereum/eth"
34
	"github.com/ethereum/go-ethereum/internal/debug"
O
obscuren 已提交
35
	"github.com/ethereum/go-ethereum/logger"
36
	"github.com/ethereum/go-ethereum/logger/glog"
37
	"github.com/ethereum/go-ethereum/metrics"
38
	"github.com/ethereum/go-ethereum/node"
39 40
	"github.com/ethereum/go-ethereum/params"
	"github.com/ethereum/go-ethereum/rlp"
41
	"gopkg.in/urfave/cli.v1"
42 43
)

Z
zelig 已提交
44
const (
45
	clientIdentifier = "geth" // Client identifier to advertise over the network
Z
zelig 已提交
46 47
)

48
var (
49 50 51 52 53 54
	// 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")
55
)
56

57
func init() {
58
	// Initialize the CLI app and start Geth
59
	app.Action = geth
60
	app.HideVersion = true // we have a command to print the version
61
	app.Copyright = "Copyright 2013-2016 The go-ethereum Authors"
62
	app.Commands = []cli.Command{
63 64
		// See chaincmd.go:
		initCommand,
65 66 67 68 69
		importCommand,
		exportCommand,
		upgradedbCommand,
		removedbCommand,
		dumpCommand,
70
		// See monitorcmd.go:
71
		monitorCommand,
72
		// See accountcmd.go:
73 74
		accountCommand,
		walletCommand,
75
		// See consolecmd.go:
76 77 78
		consoleCommand,
		attachCommand,
		javascriptCommand,
79 80 81 82
		// See misccmd.go:
		makedagCommand,
		versionCommand,
		licenseCommand,
83
	}
84

85
	app.Flags = []cli.Flag{
86
		utils.IdentityFlag,
87
		utils.UnlockedAccountFlag,
Z
zelig 已提交
88
		utils.PasswordFileFlag,
89 90
		utils.BootnodesFlag,
		utils.DataDirFlag,
K
Kobi Gurkan 已提交
91
		utils.KeyStoreDirFlag,
92
		utils.FastSyncFlag,
93 94 95
		utils.LightModeFlag,
		utils.LightServFlag,
		utils.LightPeersFlag,
96
		utils.LightKDFFlag,
97
		utils.CacheFlag,
98
		utils.TrieCacheGenFlag,
Z
CLI:  
zelig 已提交
99
		utils.JSpathFlag,
100 101
		utils.ListenPortFlag,
		utils.MaxPeersFlag,
102
		utils.MaxPendingPeersFlag,
Z
zelig 已提交
103
		utils.EtherbaseFlag,
104
		utils.GasPriceFlag,
105 106
		utils.MinerThreadsFlag,
		utils.MiningEnabledFlag,
107
		utils.AutoDAGFlag,
108
		utils.TargetGasLimitFlag,
109
		utils.NATFlag,
110
		utils.NoDiscoverFlag,
111
		utils.DiscoveryV5Flag,
112
		utils.NetrestrictFlag,
113 114 115 116 117
		utils.NodeKeyFileFlag,
		utils.NodeKeyHexFlag,
		utils.RPCEnabledFlag,
		utils.RPCListenAddrFlag,
		utils.RPCPortFlag,
118 119 120 121 122
		utils.RPCApiFlag,
		utils.WSEnabledFlag,
		utils.WSListenAddrFlag,
		utils.WSPortFlag,
		utils.WSApiFlag,
B
Bas van Kervel 已提交
123
		utils.WSAllowedOriginsFlag,
B
Bas van Kervel 已提交
124 125 126
		utils.IPCDisabledFlag,
		utils.IPCApiFlag,
		utils.IPCPathFlag,
127
		utils.ExecFlag,
128
		utils.PreloadJSFlag,
129
		utils.WhisperEnabledFlag,
130
		utils.DevModeFlag,
131
		utils.TestNetFlag,
132 133 134
		utils.VMForceJitFlag,
		utils.VMJitCacheFlag,
		utils.VMEnableJitFlag,
135
		utils.VMEnableDebugFlag,
Z
zelig 已提交
136
		utils.NetworkIdFlag,
137
		utils.RPCCORSDomainFlag,
138
		utils.EthStatsURLFlag,
139
		utils.MetricsEnabledFlag,
140
		utils.FakePoWFlag,
141
		utils.SolcPathFlag,
Z
zsfelfoldi 已提交
142 143 144 145 146 147
		utils.GpoMinGasPriceFlag,
		utils.GpoMaxGasPriceFlag,
		utils.GpoFullBlockRatioFlag,
		utils.GpobaseStepDownFlag,
		utils.GpobaseStepUpFlag,
		utils.GpobaseCorrectionFactorFlag,
Z
zelig 已提交
148
		utils.ExtraDataFlag,
149
	}
150 151
	app.Flags = append(app.Flags, debug.Flags...)

152
	app.Before = func(ctx *cli.Context) error {
153
		runtime.GOMAXPROCS(runtime.NumCPU())
154 155 156 157 158
		if err := debug.Setup(ctx); err != nil {
			return err
		}
		// Start system runtime metrics collection
		go metrics.CollectProcessMetrics(3 * time.Second)
159

F
Felix Lange 已提交
160 161 162 163 164 165
		// This should be the only place where reporting is enabled
		// because it is not intended to run while testing.
		// In addition to this check, bad block reports are sent only
		// for chains with the main network genesis block and network id 1.
		eth.EnableBadBlockReporting = true

166
		utils.SetupNetwork(ctx)
167
		return nil
168
	}
169 170 171

	app.After = func(ctx *cli.Context) error {
		debug.Exit()
172
		console.Stdin.Close() // Resets terminal mode.
173 174
		return nil
	}
175
}
O
obscuren 已提交
176

177 178 179 180 181 182
func main() {
	if err := app.Run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
Z
zelig 已提交
183

184 185 186
// geth is the main entry point into the system if no special subcommand is ran.
// It creates a default node based on the command line arguments and runs it in
// blocking mode, waiting for it to be shut down.
187
func geth(ctx *cli.Context) error {
188
	node := makeFullNode(ctx)
189 190
	startNode(ctx, node)
	node.Wait()
191
	return nil
192
}
193

194
func makeFullNode(ctx *cli.Context) *node.Node {
195 196 197 198 199 200 201 202 203 204 205
	// Create the default extradata and construct the base node
	var clientInfo = struct {
		Version   uint
		Name      string
		GoVersion string
		Os        string
	}{uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.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)
	}
206
	if uint64(len(extra)) > params.MaximumExtraDataSize {
207 208 209 210
		glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
		glog.V(logger.Debug).Infof("extra: %x\n", extra)
		extra = nil
	}
211
	stack := utils.MakeNode(ctx, clientIdentifier, gitCommit)
212
	utils.RegisterEthService(ctx, stack, extra)
213

214 215 216 217
	// 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 {
218
		utils.RegisterShhService(stack)
219
	}
220 221 222 223
	// Add the Ethereum Stats daemon if requested
	if url := ctx.GlobalString(utils.EthStatsURLFlag.Name); url != "" {
		utils.RegisterEthStatsService(stack, url)
	}
224 225 226 227
	// 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,
228 229 230
			Major:  uint32(params.VersionMajor),
			Minor:  uint32(params.VersionMinor),
			Patch:  uint32(params.VersionPatch),
231 232 233 234 235 236
		}
		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)
237
	}
238
	return stack
239 240
}

241 242 243 244 245 246
// startNode boots up the system node and all registered protocols, after which
// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
// miner.
func startNode(ctx *cli.Context, stack *node.Node) {
	// Start up the node itself
	utils.StartNode(stack)
247

248
	// Unlock any account specifically requested
249
	ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
250

251 252
	passwords := utils.MakePasswordList(ctx)
	accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
253
	for i, account := range accounts {
254
		if trimmed := strings.TrimSpace(account); trimmed != "" {
255
			unlockAccount(ctx, ks, trimmed, i, passwords)
Z
zelig 已提交
256
		}
Z
zelig 已提交
257
	}
258
	// Start auxiliary services if enabled
259
	if ctx.GlobalBool(utils.MiningEnabledFlag.Name) {
260
		var ethereum *eth.Ethereum
261 262 263
		if err := stack.Service(&ethereum); err != nil {
			utils.Fatalf("ethereum service not running: %v", err)
		}
264
		if err := ethereum.StartMining(ctx.GlobalInt(utils.MinerThreadsFlag.Name)); err != nil {
265
			utils.Fatalf("Failed to start mining: %v", err)
266
		}
267 268
	}
}