// MakeChain creates a chain manager from set command line flags. func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) { datadir := MustMakeDataDir(ctx) cache := ctx.GlobalInt(CacheFlag.Name) var err error if chainDb, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache); err != nil { Fatalf("Could not open database: %v", err) } if ctx.GlobalBool(OlympicFlag.Name) { _, err := core.WriteTestNetGenesisBlock(chainDb) if err != nil { glog.Fatalln(err) } } eventMux := new(event.TypeMux) pow := ethash.New() //genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB) chain, err = core.NewBlockChain(chainDb, pow, eventMux) if err != nil { Fatalf("Could not start chainmanager: %v", err) } return chain, chainDb }
// MakeNodeName creates a node name from a base set and the command line flags. func MakeNodeName(client, version string, ctx *cli.Context) string { name := common.MakeName(client, version) if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 { name += "/" + identity } if ctx.GlobalBool(VMEnableJitFlag.Name) { name += "/JIT" } return name }
// MustMakeDataDir retrieves the currently requested data directory, terminating // if none (or the empty string) is specified. If the node is starting a testnet, // the a subdirectory of the specified datadir will be used. func MustMakeDataDir(ctx *cli.Context) string { if path := ctx.GlobalString(DataDirFlag.Name); path != "" { if ctx.GlobalBool(TestNetFlag.Name) { return filepath.Join(path, "/testnet") } return path } Fatalf("Cannot determine default data directory, please set manually (--datadir)") return "" }
// SetupLogger configures glog from the logging-related command line flags. func SetupLogger(ctx *cli.Context) { glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) glog.CopyStandardLogTo("INFO") glog.SetToStderr(true) if ctx.GlobalIsSet(LogFileFlag.Name) { logger.New("", ctx.GlobalString(LogFileFlag.Name), ctx.GlobalInt(VerbosityFlag.Name)) } if ctx.GlobalIsSet(VMDebugFlag.Name) { vm.Debug = ctx.GlobalBool(VMDebugFlag.Name) } }
// SetupNetwork configures the system for either the main net or some test network. func SetupNetwork(ctx *cli.Context) { switch { case ctx.GlobalBool(OlympicFlag.Name): params.DurationLimit = big.NewInt(8) params.GenesisGasLimit = big.NewInt(3141592) params.MinGasLimit = big.NewInt(125000) params.MaximumExtraDataSize = big.NewInt(1024) NetworkIdFlag.Value = 0 core.BlockReward = big.NewInt(1.5e+18) core.ExpDiffPeriod = big.NewInt(math.MaxInt64) } }
// MakeAccountManager creates an account manager from set command line flags. func MakeAccountManager(ctx *cli.Context) *accounts.Manager { // Create the keystore crypto primitive, light if requested scryptN := crypto.StandardScryptN scryptP := crypto.StandardScryptP if ctx.GlobalBool(LightKDFFlag.Name) { scryptN = crypto.LightScryptN scryptP = crypto.LightScryptP } // Assemble an account manager using the configured datadir var ( datadir = MustMakeDataDir(ctx) keystore = crypto.NewKeyStorePassphrase(filepath.Join(datadir, "keystore"), scryptN, scryptP) ) return accounts.NewManager(keystore) }
// MakeBootstrapNodes creates a list of bootstrap nodes from the command line // flags, reverting to pre-configured ones if none have been specified. func MakeBootstrapNodes(ctx *cli.Context) []*discover.Node { // Return pre-configured nodes if none were manually requested if !ctx.GlobalIsSet(BootnodesFlag.Name) { if ctx.GlobalBool(TestNetFlag.Name) { return TestNetBootNodes } return FrontierBootNodes } // Otherwise parse and use the CLI bootstrap nodes bootnodes := []*discover.Node{} for _, url := range strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",") { node, err := discover.ParseNode(url) if err != nil { glog.V(logger.Error).Infof("Bootstrap URL %s: %v\n", url, err) continue } bootnodes = append(bootnodes, node) } return bootnodes }
// SetupVM configured the VM package's global settings func SetupVM(ctx *cli.Context) { vm.EnableJit = ctx.GlobalBool(VMEnableJitFlag.Name) vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name) vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name)) }
// MakeSystemNode sets up a local node, configures the services to launch and // assembles the P2P protocol stack. func MakeSystemNode(name, version string, extra []byte, ctx *cli.Context) *node.Node { // Avoid conflicting network flags networks, netFlags := 0, []cli.BoolFlag{DevModeFlag, TestNetFlag, OlympicFlag} for _, flag := range netFlags { if ctx.GlobalBool(flag.Name) { networks++ } } if networks > 1 { Fatalf("The %v flags are mutually exclusive", netFlags) } // Configure the node's service container stackConf := &node.Config{ DataDir: MustMakeDataDir(ctx), PrivateKey: MakeNodeKey(ctx), Name: MakeNodeName(name, version, ctx), NoDiscovery: ctx.GlobalBool(NoDiscoverFlag.Name), BootstrapNodes: MakeBootstrapNodes(ctx), ListenAddr: MakeListenAddress(ctx), NAT: MakeNAT(ctx), MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), } // Configure the Ethereum service accman := MakeAccountManager(ctx) ethConf := ð.Config{ Genesis: MakeGenesisBlock(ctx), FastSync: ctx.GlobalBool(FastSyncFlag.Name), BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), DatabaseCache: ctx.GlobalInt(CacheFlag.Name), NetworkId: ctx.GlobalInt(NetworkIdFlag.Name), AccountManager: accman, Etherbase: MakeEtherbase(accman, ctx), MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), ExtraData: MakeMinerExtra(extra, ctx), NatSpec: ctx.GlobalBool(NatspecEnabledFlag.Name), DocRoot: ctx.GlobalString(DocRootFlag.Name), GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)), GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)), GpoMaxGasPrice: common.String2Big(ctx.GlobalString(GpoMaxGasPriceFlag.Name)), GpoFullBlockRatio: ctx.GlobalInt(GpoFullBlockRatioFlag.Name), GpobaseStepDown: ctx.GlobalInt(GpobaseStepDownFlag.Name), GpobaseStepUp: ctx.GlobalInt(GpobaseStepUpFlag.Name), GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name), SolcPath: ctx.GlobalString(SolcPathFlag.Name), AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name), } // Configure the Whisper service shhEnable := ctx.GlobalBool(WhisperEnabledFlag.Name) // Override any default configs in dev mode or the test net switch { case ctx.GlobalBool(OlympicFlag.Name): if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 1 } if !ctx.GlobalIsSet(GenesisFileFlag.Name) { ethConf.Genesis = core.OlympicGenesisBlock() } case ctx.GlobalBool(TestNetFlag.Name): if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 2 } if !ctx.GlobalIsSet(GenesisFileFlag.Name) { ethConf.Genesis = core.TestNetGenesisBlock() } state.StartingNonce = 1048576 // (2**20) case ctx.GlobalBool(DevModeFlag.Name): // Override the base network stack configs if !ctx.GlobalIsSet(DataDirFlag.Name) { stackConf.DataDir = filepath.Join(os.TempDir(), "/ethereum_dev_mode") } if !ctx.GlobalIsSet(MaxPeersFlag.Name) { stackConf.MaxPeers = 0 } if !ctx.GlobalIsSet(ListenPortFlag.Name) { stackConf.ListenAddr = ":0" } // Override the Ethereum protocol configs if !ctx.GlobalIsSet(GenesisFileFlag.Name) { ethConf.Genesis = core.OlympicGenesisBlock() } if !ctx.GlobalIsSet(GasPriceFlag.Name) { ethConf.GasPrice = new(big.Int) } if !ctx.GlobalIsSet(WhisperEnabledFlag.Name) { shhEnable = true } if !ctx.GlobalIsSet(VMDebugFlag.Name) { vm.Debug = true } ethConf.PowTest = true } // Assemble and return the protocol stack stack, err := node.New(stackConf) if err != nil { Fatalf("Failed to create the protocol stack: %v", err) } if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil { Fatalf("Failed to register the Ethereum service: %v", err) } if shhEnable { if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { Fatalf("Failed to register the Whisper service: %v", err) } } return stack }