main.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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. // geth is the official command-line client for Ethereum.
  17. package main
  18. import (
  19. "encoding/hex"
  20. "fmt"
  21. "io/ioutil"
  22. "os"
  23. "path/filepath"
  24. "runtime"
  25. "strconv"
  26. "strings"
  27. "time"
  28. "github.com/ethereum/ethash"
  29. "github.com/ethereum/go-ethereum/accounts"
  30. "github.com/ethereum/go-ethereum/cmd/utils"
  31. "github.com/ethereum/go-ethereum/common"
  32. "github.com/ethereum/go-ethereum/console"
  33. "github.com/ethereum/go-ethereum/core"
  34. "github.com/ethereum/go-ethereum/eth"
  35. "github.com/ethereum/go-ethereum/ethdb"
  36. "github.com/ethereum/go-ethereum/internal/debug"
  37. "github.com/ethereum/go-ethereum/logger"
  38. "github.com/ethereum/go-ethereum/logger/glog"
  39. "github.com/ethereum/go-ethereum/metrics"
  40. "github.com/ethereum/go-ethereum/node"
  41. "github.com/ethereum/go-ethereum/params"
  42. "github.com/ethereum/go-ethereum/release"
  43. "github.com/ethereum/go-ethereum/rlp"
  44. "gopkg.in/urfave/cli.v1"
  45. )
  46. const (
  47. clientIdentifier = "Geth" // Client identifier to advertise over the network
  48. versionMajor = 1 // Major version component of the current release
  49. versionMinor = 5 // Minor version component of the current release
  50. versionPatch = 0 // Patch version component of the current release
  51. versionMeta = "unstable" // Version metadata to append to the version string
  52. versionOracle = "0xfa7b9770ca4cb04296cac84f37736d4041251cdf" // Ethereum address of the Geth release oracle
  53. )
  54. var (
  55. gitCommit string // Git SHA1 commit hash of the release (set via linker flags)
  56. verString string // Combined textual representation of all the version components
  57. relConfig release.Config // Structured version information and release oracle config
  58. app *cli.App
  59. )
  60. func init() {
  61. // Construct the textual version string from the individual components
  62. verString = fmt.Sprintf("%d.%d.%d", versionMajor, versionMinor, versionPatch)
  63. if versionMeta != "" {
  64. verString += "-" + versionMeta
  65. }
  66. if gitCommit != "" {
  67. verString += "-" + gitCommit[:8]
  68. }
  69. // Construct the version release oracle configuration
  70. relConfig.Oracle = common.HexToAddress(versionOracle)
  71. relConfig.Major = uint32(versionMajor)
  72. relConfig.Minor = uint32(versionMinor)
  73. relConfig.Patch = uint32(versionPatch)
  74. commit, _ := hex.DecodeString(gitCommit)
  75. copy(relConfig.Commit[:], commit)
  76. // Initialize the CLI app and start Geth
  77. app = utils.NewApp(verString, "the go-ethereum command line interface")
  78. app.Action = geth
  79. app.HideVersion = true // we have a command to print the version
  80. app.Commands = []cli.Command{
  81. importCommand,
  82. exportCommand,
  83. upgradedbCommand,
  84. removedbCommand,
  85. dumpCommand,
  86. monitorCommand,
  87. accountCommand,
  88. walletCommand,
  89. consoleCommand,
  90. attachCommand,
  91. javascriptCommand,
  92. {
  93. Action: makedag,
  94. Name: "makedag",
  95. Usage: "generate ethash dag (for testing)",
  96. Description: `
  97. The makedag command generates an ethash DAG in /tmp/dag.
  98. This command exists to support the system testing project.
  99. Regular users do not need to execute it.
  100. `,
  101. },
  102. {
  103. Action: gpuinfo,
  104. Name: "gpuinfo",
  105. Usage: "gpuinfo",
  106. Description: `
  107. Prints OpenCL device info for all found GPUs.
  108. `,
  109. },
  110. {
  111. Action: gpubench,
  112. Name: "gpubench",
  113. Usage: "benchmark GPU",
  114. Description: `
  115. Runs quick benchmark on first GPU found.
  116. `,
  117. },
  118. {
  119. Action: version,
  120. Name: "version",
  121. Usage: "print ethereum version numbers",
  122. Description: `
  123. The output of this command is supposed to be machine-readable.
  124. `,
  125. },
  126. {
  127. Action: initGenesis,
  128. Name: "init",
  129. Usage: "bootstraps and initialises a new genesis block (JSON)",
  130. Description: `
  131. The init command initialises a new genesis block and definition for the network.
  132. This is a destructive action and changes the network in which you will be
  133. participating.
  134. `,
  135. },
  136. }
  137. app.Flags = []cli.Flag{
  138. utils.IdentityFlag,
  139. utils.UnlockedAccountFlag,
  140. utils.PasswordFileFlag,
  141. utils.GenesisFileFlag,
  142. utils.BootnodesFlag,
  143. utils.DataDirFlag,
  144. utils.KeyStoreDirFlag,
  145. utils.BlockchainVersionFlag,
  146. utils.OlympicFlag,
  147. utils.FastSyncFlag,
  148. utils.CacheFlag,
  149. utils.LightKDFFlag,
  150. utils.JSpathFlag,
  151. utils.ListenPortFlag,
  152. utils.MaxPeersFlag,
  153. utils.MaxPendingPeersFlag,
  154. utils.EtherbaseFlag,
  155. utils.GasPriceFlag,
  156. utils.MinerThreadsFlag,
  157. utils.MiningEnabledFlag,
  158. utils.MiningGPUFlag,
  159. utils.AutoDAGFlag,
  160. utils.TargetGasLimitFlag,
  161. utils.NATFlag,
  162. utils.NatspecEnabledFlag,
  163. utils.NoDiscoverFlag,
  164. utils.NodeKeyFileFlag,
  165. utils.NodeKeyHexFlag,
  166. utils.RPCEnabledFlag,
  167. utils.RPCListenAddrFlag,
  168. utils.RPCPortFlag,
  169. utils.RPCApiFlag,
  170. utils.WSEnabledFlag,
  171. utils.WSListenAddrFlag,
  172. utils.WSPortFlag,
  173. utils.WSApiFlag,
  174. utils.WSAllowedOriginsFlag,
  175. utils.IPCDisabledFlag,
  176. utils.IPCApiFlag,
  177. utils.IPCPathFlag,
  178. utils.ExecFlag,
  179. utils.PreloadJSFlag,
  180. utils.WhisperEnabledFlag,
  181. utils.DevModeFlag,
  182. utils.TestNetFlag,
  183. utils.VMForceJitFlag,
  184. utils.VMJitCacheFlag,
  185. utils.VMEnableJitFlag,
  186. utils.NetworkIdFlag,
  187. utils.RPCCORSDomainFlag,
  188. utils.MetricsEnabledFlag,
  189. utils.FakePoWFlag,
  190. utils.SolcPathFlag,
  191. utils.GpoMinGasPriceFlag,
  192. utils.GpoMaxGasPriceFlag,
  193. utils.GpoFullBlockRatioFlag,
  194. utils.GpobaseStepDownFlag,
  195. utils.GpobaseStepUpFlag,
  196. utils.GpobaseCorrectionFactorFlag,
  197. utils.ExtraDataFlag,
  198. }
  199. app.Flags = append(app.Flags, debug.Flags...)
  200. app.Before = func(ctx *cli.Context) error {
  201. runtime.GOMAXPROCS(runtime.NumCPU())
  202. if err := debug.Setup(ctx); err != nil {
  203. return err
  204. }
  205. // Start system runtime metrics collection
  206. go metrics.CollectProcessMetrics(3 * time.Second)
  207. // This should be the only place where reporting is enabled
  208. // because it is not intended to run while testing.
  209. // In addition to this check, bad block reports are sent only
  210. // for chains with the main network genesis block and network id 1.
  211. eth.EnableBadBlockReporting = true
  212. utils.SetupNetwork(ctx)
  213. // Deprecation warning.
  214. if ctx.GlobalIsSet(utils.GenesisFileFlag.Name) {
  215. common.PrintDepricationWarning("--genesis is deprecated. Switch to use 'geth init /path/to/file'")
  216. }
  217. return nil
  218. }
  219. app.After = func(ctx *cli.Context) error {
  220. logger.Flush()
  221. debug.Exit()
  222. console.Stdin.Close() // Resets terminal mode.
  223. return nil
  224. }
  225. }
  226. func main() {
  227. if err := app.Run(os.Args); err != nil {
  228. fmt.Fprintln(os.Stderr, err)
  229. os.Exit(1)
  230. }
  231. }
  232. func makeDefaultExtra() []byte {
  233. var clientInfo = struct {
  234. Version uint
  235. Name string
  236. GoVersion string
  237. Os string
  238. }{uint(versionMajor<<16 | versionMinor<<8 | versionPatch), clientIdentifier, runtime.Version(), runtime.GOOS}
  239. extra, err := rlp.EncodeToBytes(clientInfo)
  240. if err != nil {
  241. glog.V(logger.Warn).Infoln("error setting canonical miner information:", err)
  242. }
  243. if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() {
  244. glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
  245. glog.V(logger.Debug).Infof("extra: %x\n", extra)
  246. return nil
  247. }
  248. return extra
  249. }
  250. // geth is the main entry point into the system if no special subcommand is ran.
  251. // It creates a default node based on the command line arguments and runs it in
  252. // blocking mode, waiting for it to be shut down.
  253. func geth(ctx *cli.Context) error {
  254. node := utils.MakeSystemNode(clientIdentifier, verString, relConfig, makeDefaultExtra(), ctx)
  255. startNode(ctx, node)
  256. node.Wait()
  257. return nil
  258. }
  259. // initGenesis will initialise the given JSON format genesis file and writes it as
  260. // the zero'd block (i.e. genesis) or will fail hard if it can't succeed.
  261. func initGenesis(ctx *cli.Context) error {
  262. genesisPath := ctx.Args().First()
  263. if len(genesisPath) == 0 {
  264. utils.Fatalf("must supply path to genesis JSON file")
  265. }
  266. chainDb, err := ethdb.NewLDBDatabase(filepath.Join(utils.MustMakeDataDir(ctx), "chaindata"), 0, 0)
  267. if err != nil {
  268. utils.Fatalf("could not open database: %v", err)
  269. }
  270. genesisFile, err := os.Open(genesisPath)
  271. if err != nil {
  272. utils.Fatalf("failed to read genesis file: %v", err)
  273. }
  274. block, err := core.WriteGenesisBlock(chainDb, genesisFile)
  275. if err != nil {
  276. utils.Fatalf("failed to write genesis block: %v", err)
  277. }
  278. glog.V(logger.Info).Infof("successfully wrote genesis block and/or chain rule set: %x", block.Hash())
  279. return nil
  280. }
  281. // startNode boots up the system node and all registered protocols, after which
  282. // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
  283. // miner.
  284. func startNode(ctx *cli.Context, stack *node.Node) {
  285. // Start up the node itself
  286. utils.StartNode(stack)
  287. // Unlock any account specifically requested
  288. var accman *accounts.Manager
  289. if err := stack.Service(&accman); err != nil {
  290. utils.Fatalf("ethereum service not running: %v", err)
  291. }
  292. passwords := utils.MakePasswordList(ctx)
  293. accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
  294. for i, account := range accounts {
  295. if trimmed := strings.TrimSpace(account); trimmed != "" {
  296. unlockAccount(ctx, accman, trimmed, i, passwords)
  297. }
  298. }
  299. // Start auxiliary services if enabled
  300. if ctx.GlobalBool(utils.MiningEnabledFlag.Name) {
  301. var ethereum *eth.FullNodeService
  302. if err := stack.Service(&ethereum); err != nil {
  303. utils.Fatalf("ethereum service not running: %v", err)
  304. }
  305. if err := ethereum.StartMining(ctx.GlobalInt(utils.MinerThreadsFlag.Name), ctx.GlobalString(utils.MiningGPUFlag.Name)); err != nil {
  306. utils.Fatalf("Failed to start mining: %v", err)
  307. }
  308. }
  309. }
  310. func makedag(ctx *cli.Context) error {
  311. args := ctx.Args()
  312. wrongArgs := func() {
  313. utils.Fatalf(`Usage: geth makedag <block number> <outputdir>`)
  314. }
  315. switch {
  316. case len(args) == 2:
  317. blockNum, err := strconv.ParseUint(args[0], 0, 64)
  318. dir := args[1]
  319. if err != nil {
  320. wrongArgs()
  321. } else {
  322. dir = filepath.Clean(dir)
  323. // seems to require a trailing slash
  324. if !strings.HasSuffix(dir, "/") {
  325. dir = dir + "/"
  326. }
  327. _, err = ioutil.ReadDir(dir)
  328. if err != nil {
  329. utils.Fatalf("Can't find dir")
  330. }
  331. fmt.Println("making DAG, this could take awhile...")
  332. ethash.MakeDAG(blockNum, dir)
  333. }
  334. default:
  335. wrongArgs()
  336. }
  337. return nil
  338. }
  339. func gpuinfo(ctx *cli.Context) error {
  340. eth.PrintOpenCLDevices()
  341. return nil
  342. }
  343. func gpubench(ctx *cli.Context) error {
  344. args := ctx.Args()
  345. wrongArgs := func() {
  346. utils.Fatalf(`Usage: geth gpubench <gpu number>`)
  347. }
  348. switch {
  349. case len(args) == 1:
  350. n, err := strconv.ParseUint(args[0], 0, 64)
  351. if err != nil {
  352. wrongArgs()
  353. }
  354. eth.GPUBench(n)
  355. case len(args) == 0:
  356. eth.GPUBench(0)
  357. default:
  358. wrongArgs()
  359. }
  360. return nil
  361. }
  362. func version(c *cli.Context) error {
  363. fmt.Println(clientIdentifier)
  364. fmt.Println("Version:", verString)
  365. fmt.Println("Protocol Versions:", eth.ProtocolVersions)
  366. fmt.Println("Network Id:", c.GlobalInt(utils.NetworkIdFlag.Name))
  367. fmt.Println("Go Version:", runtime.Version())
  368. fmt.Println("OS:", runtime.GOOS)
  369. fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
  370. fmt.Printf("GOROOT=%s\n", runtime.GOROOT())
  371. return nil
  372. }