main.go 11 KB

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