github.com/hyperion-hyn/go-ethereum@v2.4.0+incompatible/cmd/geth/main.go (about) 1 // Copyright 2014 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 // geth is the official command-line client for Ethereum. 18 package main 19 20 import ( 21 "errors" 22 "fmt" 23 "math" 24 "os" 25 godebug "runtime/debug" 26 "sort" 27 "strconv" 28 "strings" 29 "time" 30 31 "github.com/elastic/gosigar" 32 "github.com/ethereum/go-ethereum/accounts" 33 "github.com/ethereum/go-ethereum/accounts/keystore" 34 "github.com/ethereum/go-ethereum/cmd/utils" 35 "github.com/ethereum/go-ethereum/console" 36 "github.com/ethereum/go-ethereum/eth" 37 "github.com/ethereum/go-ethereum/ethclient" 38 "github.com/ethereum/go-ethereum/internal/debug" 39 "github.com/ethereum/go-ethereum/log" 40 "github.com/ethereum/go-ethereum/metrics" 41 "github.com/ethereum/go-ethereum/node" 42 "github.com/ethereum/go-ethereum/permission" 43 "gopkg.in/urfave/cli.v1" 44 ) 45 46 const ( 47 clientIdentifier = "geth" // Client identifier to advertise over the network 48 ) 49 50 var ( 51 // Git SHA1 commit hash of the release (set via linker flags) 52 gitCommit = "" 53 // The app that holds all commands and flags. 54 app = utils.NewApp(gitCommit, "the go-ethereum command line interface") 55 // flags that configure the node 56 nodeFlags = []cli.Flag{ 57 utils.IdentityFlag, 58 utils.UnlockedAccountFlag, 59 utils.PasswordFileFlag, 60 utils.BootnodesFlag, 61 utils.BootnodesV4Flag, 62 utils.BootnodesV5Flag, 63 utils.DataDirFlag, 64 utils.KeyStoreDirFlag, 65 utils.NoUSBFlag, 66 utils.DashboardEnabledFlag, 67 utils.DashboardAddrFlag, 68 utils.DashboardPortFlag, 69 utils.DashboardRefreshFlag, 70 utils.EthashCacheDirFlag, 71 utils.EthashCachesInMemoryFlag, 72 utils.EthashCachesOnDiskFlag, 73 utils.EthashDatasetDirFlag, 74 utils.EthashDatasetsInMemoryFlag, 75 utils.EthashDatasetsOnDiskFlag, 76 utils.TxPoolLocalsFlag, 77 utils.TxPoolNoLocalsFlag, 78 utils.TxPoolJournalFlag, 79 utils.TxPoolRejournalFlag, 80 utils.TxPoolPriceLimitFlag, 81 utils.TxPoolPriceBumpFlag, 82 utils.TxPoolAccountSlotsFlag, 83 utils.TxPoolGlobalSlotsFlag, 84 utils.TxPoolAccountQueueFlag, 85 utils.TxPoolGlobalQueueFlag, 86 utils.TxPoolLifetimeFlag, 87 utils.SyncModeFlag, 88 utils.GCModeFlag, 89 utils.LightServFlag, 90 utils.LightPeersFlag, 91 utils.LightKDFFlag, 92 utils.CacheFlag, 93 utils.CacheDatabaseFlag, 94 utils.CacheGCFlag, 95 utils.TrieCacheGenFlag, 96 utils.ListenPortFlag, 97 utils.MaxPeersFlag, 98 utils.MaxPendingPeersFlag, 99 utils.MiningEnabledFlag, 100 utils.MinerThreadsFlag, 101 utils.MinerLegacyThreadsFlag, 102 utils.MinerNotifyFlag, 103 utils.MinerGasTargetFlag, 104 utils.MinerLegacyGasTargetFlag, 105 utils.MinerGasLimitFlag, 106 utils.MinerGasPriceFlag, 107 utils.MinerLegacyGasPriceFlag, 108 utils.MinerEtherbaseFlag, 109 utils.MinerLegacyEtherbaseFlag, 110 utils.MinerExtraDataFlag, 111 utils.MinerLegacyExtraDataFlag, 112 utils.MinerRecommitIntervalFlag, 113 utils.MinerNoVerfiyFlag, 114 utils.NATFlag, 115 utils.NoDiscoverFlag, 116 utils.DiscoveryV5Flag, 117 utils.NetrestrictFlag, 118 utils.NodeKeyFileFlag, 119 utils.NodeKeyHexFlag, 120 utils.DeveloperFlag, 121 utils.DeveloperPeriodFlag, 122 utils.TestnetFlag, 123 utils.RinkebyFlag, 124 utils.OttomanFlag, 125 utils.VMEnableDebugFlag, 126 utils.NetworkIdFlag, 127 utils.RPCCORSDomainFlag, 128 utils.RPCVirtualHostsFlag, 129 utils.EthStatsURLFlag, 130 utils.MetricsEnabledFlag, 131 utils.FakePoWFlag, 132 utils.NoCompactionFlag, 133 utils.GpoBlocksFlag, 134 utils.GpoPercentileFlag, 135 utils.EWASMInterpreterFlag, 136 utils.EVMInterpreterFlag, 137 configFileFlag, 138 // Quorum 139 utils.EnableNodePermissionFlag, 140 utils.RaftModeFlag, 141 utils.RaftBlockTimeFlag, 142 utils.RaftJoinExistingFlag, 143 utils.RaftPortFlag, 144 utils.RaftDNSEnabledFlag, 145 utils.EmitCheckpointsFlag, 146 utils.IstanbulRequestTimeoutFlag, 147 utils.IstanbulBlockPeriodFlag, 148 // End-Quorum 149 } 150 151 rpcFlags = []cli.Flag{ 152 utils.RPCEnabledFlag, 153 utils.RPCListenAddrFlag, 154 utils.RPCPortFlag, 155 utils.RPCApiFlag, 156 utils.WSEnabledFlag, 157 utils.WSListenAddrFlag, 158 utils.WSPortFlag, 159 utils.WSApiFlag, 160 utils.WSAllowedOriginsFlag, 161 utils.IPCDisabledFlag, 162 utils.IPCPathFlag, 163 } 164 165 whisperFlags = []cli.Flag{ 166 utils.WhisperEnabledFlag, 167 utils.WhisperMaxMessageSizeFlag, 168 utils.WhisperMinPOWFlag, 169 utils.WhisperRestrictConnectionBetweenLightClientsFlag, 170 } 171 172 metricsFlags = []cli.Flag{ 173 utils.MetricsEnableInfluxDBFlag, 174 utils.MetricsInfluxDBEndpointFlag, 175 utils.MetricsInfluxDBDatabaseFlag, 176 utils.MetricsInfluxDBUsernameFlag, 177 utils.MetricsInfluxDBPasswordFlag, 178 utils.MetricsInfluxDBHostTagFlag, 179 } 180 ) 181 182 func init() { 183 // Initialize the CLI app and start Geth 184 app.Action = geth 185 app.HideVersion = true // we have a command to print the version 186 app.Copyright = "Copyright 2013-2018 The go-ethereum Authors" 187 app.Commands = []cli.Command{ 188 // See chaincmd.go: 189 initCommand, 190 importCommand, 191 exportCommand, 192 importPreimagesCommand, 193 exportPreimagesCommand, 194 copydbCommand, 195 removedbCommand, 196 dumpCommand, 197 // See monitorcmd.go: 198 monitorCommand, 199 // See accountcmd.go: 200 accountCommand, 201 walletCommand, 202 // See consolecmd.go: 203 consoleCommand, 204 attachCommand, 205 javascriptCommand, 206 // See misccmd.go: 207 makecacheCommand, 208 makedagCommand, 209 versionCommand, 210 bugCommand, 211 licenseCommand, 212 // See config.go 213 dumpConfigCommand, 214 } 215 sort.Sort(cli.CommandsByName(app.Commands)) 216 217 app.Flags = append(app.Flags, nodeFlags...) 218 app.Flags = append(app.Flags, rpcFlags...) 219 app.Flags = append(app.Flags, consoleFlags...) 220 app.Flags = append(app.Flags, debug.Flags...) 221 app.Flags = append(app.Flags, whisperFlags...) 222 app.Flags = append(app.Flags, metricsFlags...) 223 224 app.Before = func(ctx *cli.Context) error { 225 logdir := "" 226 if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { 227 logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs") 228 } 229 if err := debug.Setup(ctx, logdir); err != nil { 230 return err 231 } 232 // Cap the cache allowance and tune the garbage collector 233 var mem gosigar.Mem 234 if err := mem.Get(); err == nil { 235 allowance := int(mem.Total / 1024 / 1024 / 3) 236 if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance { 237 log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) 238 ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance)) 239 } 240 } 241 // Ensure Go's GC ignores the database cache for trigger percentage 242 cache := ctx.GlobalInt(utils.CacheFlag.Name) 243 gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) 244 245 log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) 246 godebug.SetGCPercent(int(gogc)) 247 248 // Start metrics export if enabled 249 utils.SetupMetrics(ctx) 250 251 // Start system runtime metrics collection 252 go metrics.CollectProcessMetrics(3 * time.Second) 253 254 return nil 255 } 256 257 app.After = func(ctx *cli.Context) error { 258 debug.Exit() 259 console.Stdin.Close() // Resets terminal mode. 260 return nil 261 } 262 } 263 264 func main() { 265 if err := app.Run(os.Args); err != nil { 266 fmt.Fprintln(os.Stderr, err) 267 os.Exit(1) 268 } 269 } 270 271 // geth is the main entry point into the system if no special subcommand is ran. 272 // It creates a default node based on the command line arguments and runs it in 273 // blocking mode, waiting for it to be shut down. 274 func geth(ctx *cli.Context) error { 275 if args := ctx.Args(); len(args) > 0 { 276 return fmt.Errorf("invalid command: %q", args[0]) 277 } 278 279 if !quorumValidatePrivateTransactionManager() { 280 return errors.New("the PRIVATE_CONFIG environment variable must be specified for Quorum") 281 } 282 283 node := makeFullNode(ctx) 284 startNode(ctx, node) 285 286 // Check if a valid consensus is used 287 quorumValidateConsensus(node, ctx.GlobalBool(utils.RaftModeFlag.Name)) 288 289 node.Wait() 290 return nil 291 } 292 293 // startNode boots up the system node and all registered protocols, after which 294 // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the 295 // miner. 296 func startNode(ctx *cli.Context, stack *node.Node) { 297 log.DoEmitCheckpoints = ctx.GlobalBool(utils.EmitCheckpointsFlag.Name) 298 debug.Memsize.Add("node", stack) 299 300 // Start up the node itself 301 utils.StartNode(stack) 302 303 // Unlock any account specifically requested 304 ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) 305 306 passwords := utils.MakePasswordList(ctx) 307 unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") 308 for i, account := range unlocks { 309 if trimmed := strings.TrimSpace(account); trimmed != "" { 310 unlockAccount(ctx, ks, trimmed, i, passwords) 311 } 312 } 313 // Register wallet event handlers to open and auto-derive wallets 314 events := make(chan accounts.WalletEvent, 16) 315 stack.AccountManager().Subscribe(events) 316 317 go func() { 318 // Create a chain state reader for self-derivation 319 rpcClient, err := stack.Attach() 320 if err != nil { 321 utils.Fatalf("Failed to attach to self: %v", err) 322 } 323 stateReader := ethclient.NewClient(rpcClient) 324 325 // Open any wallets already attached 326 for _, wallet := range stack.AccountManager().Wallets() { 327 if err := wallet.Open(""); err != nil { 328 log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) 329 } 330 } 331 // Listen for wallet event till termination 332 for event := range events { 333 switch event.Kind { 334 case accounts.WalletArrived: 335 if err := event.Wallet.Open(""); err != nil { 336 log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) 337 } 338 case accounts.WalletOpened: 339 status, _ := event.Wallet.Status() 340 log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) 341 342 derivationPath := accounts.DefaultBaseDerivationPath 343 if event.Wallet.URL().Scheme == "ledger" { 344 derivationPath = accounts.DefaultLedgerBaseDerivationPath 345 } 346 event.Wallet.SelfDerive(derivationPath, stateReader) 347 348 case accounts.WalletDropped: 349 log.Info("Old wallet dropped", "url", event.Wallet.URL()) 350 event.Wallet.Close() 351 } 352 } 353 }() 354 355 // Quorum 356 // 357 // checking if permissions is enabled and staring the permissions service 358 if stack.IsPermissionEnabled() { 359 var permissionService *permission.PermissionCtrl 360 if err := stack.Service(&permissionService); err != nil { 361 utils.Fatalf("Permission service not runnning: %v", err) 362 } 363 if err := permissionService.AfterStart(); err != nil { 364 utils.Fatalf("Permission service post construct failure: %v", err) 365 } 366 } 367 368 // Start auxiliary services if enabled 369 if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { 370 // Mining only makes sense if a full Ethereum node is running 371 if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { 372 utils.Fatalf("Light clients do not support mining") 373 } 374 var ethereum *eth.Ethereum 375 if err := stack.Service(ðereum); err != nil { 376 utils.Fatalf("Ethereum service not running: %v", err) 377 } 378 // Set the gas price to the limits from the CLI and start mining 379 gasprice := utils.GlobalBig(ctx, utils.MinerLegacyGasPriceFlag.Name) 380 if ctx.IsSet(utils.MinerGasPriceFlag.Name) { 381 gasprice = utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name) 382 } 383 ethereum.TxPool().SetGasPrice(gasprice) 384 385 threads := ctx.GlobalInt(utils.MinerLegacyThreadsFlag.Name) 386 if ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) { 387 threads = ctx.GlobalInt(utils.MinerThreadsFlag.Name) 388 } 389 if err := ethereum.StartMining(threads); err != nil { 390 utils.Fatalf("Failed to start mining: %v", err) 391 } 392 } 393 394 }