func main() { logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel)) // Generate the peer identity key, err := crypto.GenerateKey() if err != nil { fmt.Printf("Failed to generate peer key: %v.\n", err) os.Exit(-1) } name := common.MakeName("whisper-go", "1.0") shh := whisper.New() // Create an Expanse peer to communicate through server := p2p.Server{ PrivateKey: key, MaxPeers: 10, Name: name, Protocols: []p2p.Protocol{shh.Protocol()}, ListenAddr: ":30300", NAT: nat.Any(), } fmt.Println("Starting Expanse peer...") if err := server.Start(); err != nil { fmt.Printf("Failed to start Expanse peer: %v.\n", err) os.Exit(1) } // Send a message to self to check that something works payload := fmt.Sprintf("Hello world, this is %v. In case you're wondering, the time is %v", name, time.Now()) if err := selfSend(shh, []byte(payload)); err != nil { fmt.Printf("Failed to self message: %v.\n", err) os.Exit(-1) } }
// MakeSystemNode configures a protocol stack for the RPC tests based on a given // keystore path and initial pre-state. func MakeSystemNode(keydir string, privkey string, test *tests.BlockTest) (*node.Node, error) { // Create a networkless protocol stack stack, err := node.New(&node.Config{ IPCPath: node.DefaultIPCEndpoint(), HTTPHost: common.DefaultHTTPHost, HTTPPort: common.DefaultHTTPPort, HTTPModules: []string{"admin", "db", "exp", "debug", "miner", "net", "shh", "txpool", "personal", "web3"}, WSHost: common.DefaultWSHost, WSPort: common.DefaultWSPort, WSModules: []string{"admin", "db", "exp", "debug", "miner", "net", "shh", "txpool", "personal", "web3"}, NoDiscovery: true, }) if err != nil { return nil, err } // Create the keystore and inject an unlocked account if requested accman := accounts.NewPlaintextManager(keydir) if len(privkey) > 0 { key, err := crypto.HexToECDSA(privkey) if err != nil { return nil, err } a, err := accman.ImportECDSA(key, "") if err != nil { return nil, err } if err := accman.Unlock(a, ""); err != nil { return nil, err } } // Initialize and register the Expanse protocol db, _ := ethdb.NewMemDatabase() if _, err := test.InsertPreState(db); err != nil { return nil, err } ethConf := &exp.Config{ TestGenesisState: db, TestGenesisBlock: test.Genesis, ChainConfig: &core.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock}, AccountManager: accman, } if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return exp.New(ctx, ethConf) }); err != nil { return nil, err } // Initialize and register the Whisper protocol if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { return nil, err } return stack, nil }
// MakeSystemNode sets up a local node, configures the services to launch and // assembles the P2P protocol stack. func MakeSystemNode(name, version string, relconf release.Config, 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), IPCPath: MakeIPCPath(ctx), HTTPHost: MakeHTTPRpcHost(ctx), HTTPPort: ctx.GlobalInt(RPCPortFlag.Name), HTTPCors: ctx.GlobalString(RPCCORSDomainFlag.Name), HTTPModules: MakeRPCModules(ctx.GlobalString(RPCApiFlag.Name)), WSHost: MakeWSRpcHost(ctx), WSPort: ctx.GlobalInt(WSPortFlag.Name), WSOrigins: ctx.GlobalString(WSAllowedOriginsFlag.Name), WSModules: MakeRPCModules(ctx.GlobalString(WSApiFlag.Name)), } // Configure the Expanse service accman := MakeAccountManager(ctx) jitEnabled := ctx.GlobalBool(VMEnableJitFlag.Name) ethConf := &exp.Config{ ChainConfig: MustMakeChainConfig(ctx), FastSync: ctx.GlobalBool(FastSyncFlag.Name), BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), DatabaseCache: ctx.GlobalInt(CacheFlag.Name), DatabaseHandles: MakeDatabaseHandles(), 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), EnableJit: jitEnabled, ForceJit: ctx.GlobalBool(VMForceJitFlag.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 } ethConf.Genesis = core.OlympicGenesisBlock() case ctx.GlobalBool(TestNetFlag.Name): if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 2 } 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(), "/expanse_dev_mode") } if !ctx.GlobalIsSet(MaxPeersFlag.Name) { stackConf.MaxPeers = 0 } if !ctx.GlobalIsSet(ListenPortFlag.Name) { stackConf.ListenAddr = ":0" } // Override the Ethereum protocol configs ethConf.Genesis = core.OlympicGenesisBlock() if !ctx.GlobalIsSet(GasPriceFlag.Name) { ethConf.GasPrice = new(big.Int) } if !ctx.GlobalIsSet(WhisperEnabledFlag.Name) { shhEnable = 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 exp.New(ctx, ethConf) }); err != nil { Fatalf("Failed to register the Expanse 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) } } if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return release.NewReleaseService(ctx, relconf) }); err != nil { Fatalf("Failed to register the Gexp release oracle service: %v", err) } return stack }
func New(config *Config) (*Expanse, error) { logger.New(config.DataDir, config.LogFile, config.Verbosity) // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 ethdb.OpenFileLimit = 128 / (dbCount + 1) newdb := config.NewDB if newdb == nil { newdb = func(path string) (ethdb.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) } } // Open the chain database and perform any upgrades needed chainDb, err := newdb(filepath.Join(config.DataDir, "chaindata")) if err != nil { if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] { err = fmt.Errorf("%v (check if another instance of geth is already running with the same data directory '%s')", err, config.DataDir) } return nil, fmt.Errorf("blockchain db err: %v", err) } if db, ok := chainDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/chaindata/") } if err := upgradeChainDatabase(chainDb); err != nil { return nil, err } if err := addMipmapBloomBins(chainDb); err != nil { return nil, err } dappDb, err := newdb(filepath.Join(config.DataDir, "dapp")) if err != nil { if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] { err = fmt.Errorf("%v (check if another instance of geth is already running with the same data directory '%s')", err, config.DataDir) } return nil, fmt.Errorf("dapp db err: %v", err) } if db, ok := dappDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/dapp/") } nodeDb := filepath.Join(config.DataDir, "nodes") glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) if len(config.GenesisFile) > 0 { fr, err := os.Open(config.GenesisFile) if err != nil { return nil, err } block, err := core.WriteGenesisBlock(chainDb, fr) if err != nil { return nil, err } glog.V(logger.Info).Infof("Successfully wrote genesis block. New genesis hash = %x\n", block.Hash()) } // different modes switch { case config.Olympic: glog.V(logger.Error).Infoln("Starting Olympic network") fallthrough case config.DevMode: _, err := core.WriteOlympicGenesisBlock(chainDb, 42) if err != nil { return nil, err } case config.TestNet: state.StartingNonce = 1048576 // (2**20) _, err := core.WriteTestNetGenesisBlock(chainDb, 0x6d6f7264656e) if err != nil { return nil, err } } // This is for testing only. if config.GenesisBlock != nil { core.WriteTd(chainDb, config.GenesisBlock.Hash(), config.GenesisBlock.Difficulty()) core.WriteBlock(chainDb, config.GenesisBlock) core.WriteCanonicalHash(chainDb, config.GenesisBlock.Hash(), config.GenesisBlock.NumberU64()) core.WriteHeadBlockHash(chainDb, config.GenesisBlock.Hash()) } if !config.SkipBcVersionCheck { b, _ := chainDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(b).Uint()) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run gexp upgradedb.\n", bcVersion, config.BlockChainVersion) } saveBlockchainVersion(chainDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) exp := &Expanse{ shutdownChan: make(chan bool), chainDb: chainDb, dappDb: dappDb, eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, etherbase: config.Etherbase, clientVersion: config.Name, // TODO should separate from Name netVersionId: config.NetworkId, NatSpec: config.NatSpec, MinerThreads: config.MinerThreads, SolcPath: config.SolcPath, AutoDAG: config.AutoDAG, PowTest: config.PowTest, GpoMinGasPrice: config.GpoMinGasPrice, GpoMaxGasPrice: config.GpoMaxGasPrice, GpoFullBlockRatio: config.GpoFullBlockRatio, GpobaseStepDown: config.GpobaseStepDown, GpobaseStepUp: config.GpobaseStepUp, GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, httpclient: httpclient.New(config.DocRoot), } if config.PowTest { glog.V(logger.Info).Infof("ethash used in test mode") exp.pow, err = ethash.NewForTesting() if err != nil { return nil, err } } else { exp.pow = ethash.New() } //genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) exp.blockchain, err = core.NewBlockChain(chainDb, exp.pow, exp.EventMux()) if err != nil { if err == core.ErrNoGenesis { return nil, fmt.Errorf(`Genesis block not found. Please supply a genesis block with the "--genesis /path/to/file" argument`) } return nil, err } newPool := core.NewTxPool(exp.EventMux(), exp.blockchain.State, exp.blockchain.GasLimit) exp.txPool = newPool if exp.protocolManager, err = NewProtocolManager(config.FastSync, config.NetworkId, exp.eventMux, exp.txPool, exp.pow, exp.blockchain, chainDb); err != nil { return nil, err } exp.miner = miner.New(exp, exp.EventMux(), exp.pow) exp.miner.SetGasPrice(config.GasPrice) exp.miner.SetExtra(config.ExtraData) if config.Shh { exp.whisper = whisper.New() exp.shhVersionId = int(exp.whisper.Version()) } netprv, err := config.nodeKey() if err != nil { return nil, err } protocols := append([]p2p.Protocol{}, exp.protocolManager.SubProtocols...) if config.Shh { protocols = append(protocols, exp.whisper.Protocol()) } exp.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, MaxPeers: config.MaxPeers, MaxPendingPeers: config.MaxPendingPeers, Discovery: config.Discovery, Protocols: protocols, NAT: config.NAT, NoDial: !config.Dial, BootstrapNodes: config.parseBootNodes(), StaticNodes: config.parseNodes(staticNodes), TrustedNodes: config.parseNodes(trustedNodes), NodeDatabase: nodeDb, } if len(config.Port) > 0 { exp.net.ListenAddr = ":" + config.Port } vm.Debug = config.VmDebug return exp, nil }
func New(config *Config) (*Expanse, error) { // Bootstrap database logger.New(config.DataDir, config.LogFile, config.Verbosity) if len(config.LogJSON) > 0 { logger.NewJSONsystem(config.DataDir, config.LogJSON) } // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 ethdb.OpenFileLimit = 128 / (dbCount + 1) newdb := config.NewDB if newdb == nil { newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) } } // attempt to merge database together, upgrading from an old version if err := mergeDatabases(config.DataDir, newdb); err != nil { return nil, err } chainDb, err := newdb(filepath.Join(config.DataDir, "chaindata")) if err != nil { return nil, fmt.Errorf("blockchain db err: %v", err) } if db, ok := chainDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/chaindata/") } dappDb, err := newdb(filepath.Join(config.DataDir, "dapp")) if err != nil { return nil, fmt.Errorf("dapp db err: %v", err) } if db, ok := dappDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/dapp/") } nodeDb := filepath.Join(config.DataDir, "nodes") glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) if len(config.GenesisFile) > 0 { fr, err := os.Open(config.GenesisFile) if err != nil { return nil, err } block, err := core.WriteGenesisBlock(chainDb, fr) if err != nil { return nil, err } glog.V(logger.Info).Infof("Successfully wrote genesis block. New genesis hash = %x\n", block.Hash()) } if config.Olympic { _, err := core.WriteTestNetGenesisBlock(chainDb, 42) if err != nil { return nil, err } glog.V(logger.Error).Infoln("Starting Olympic network") } // This is for testing only. if config.GenesisBlock != nil { core.WriteBlock(chainDb, config.GenesisBlock) core.WriteHead(chainDb, config.GenesisBlock) } if !config.SkipBcVersionCheck { b, _ := chainDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(b).Uint()) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run gexp upgradedb.\n", bcVersion, config.BlockChainVersion) } saveBlockchainVersion(chainDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) exp := &Expanse{ shutdownChan: make(chan bool), databasesClosed: make(chan bool), chainDb: chainDb, dappDb: dappDb, eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, etherbase: config.Etherbase, clientVersion: config.Name, // TODO should separate from Name netVersionId: config.NetworkId, NatSpec: config.NatSpec, MinerThreads: config.MinerThreads, SolcPath: config.SolcPath, AutoDAG: config.AutoDAG, PowTest: config.PowTest, GpoMinGasPrice: config.GpoMinGasPrice, GpoMaxGasPrice: config.GpoMaxGasPrice, GpoFullBlockRatio: config.GpoFullBlockRatio, GpobaseStepDown: config.GpobaseStepDown, GpobaseStepUp: config.GpobaseStepUp, GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, } if config.PowTest { glog.V(logger.Info).Infof("ethash used in test mode") exp.pow, err = ethash.NewForTesting() if err != nil { return nil, err } } else { exp.pow = ethash.New() } //genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) exp.chainManager, err = core.NewChainManager(chainDb, exp.pow, exp.EventMux()) if err != nil { if err == core.ErrNoGenesis { return nil, fmt.Errorf(`Genesis block not found. Please supply a genesis block with the "--genesis /path/to/file" argument`) } return nil, err } exp.txPool = core.NewTxPool(exp.EventMux(), exp.chainManager.State, exp.chainManager.GasLimit) exp.blockProcessor = core.NewBlockProcessor(chainDb, exp.pow, exp.chainManager, exp.EventMux()) exp.chainManager.SetProcessor(exp.blockProcessor) exp.protocolManager = NewProtocolManager(config.NetworkId, exp.eventMux, exp.txPool, exp.pow, exp.chainManager) exp.miner = miner.New(exp, exp.EventMux(), exp.pow) exp.miner.SetGasPrice(config.GasPrice) exp.miner.SetExtra(config.ExtraData) if config.Shh { exp.whisper = whisper.New() exp.shhVersionId = int(exp.whisper.Version()) } netprv, err := config.nodeKey() if err != nil { return nil, err } protocols := append([]p2p.Protocol{}, exp.protocolManager.SubProtocols...) if config.Shh { protocols = append(protocols, exp.whisper.Protocol()) } exp.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, MaxPeers: config.MaxPeers, MaxPendingPeers: config.MaxPendingPeers, Discovery: config.Discovery, Protocols: protocols, NAT: config.NAT, NoDial: !config.Dial, BootstrapNodes: config.parseBootNodes(), StaticNodes: config.parseNodes(staticNodes), TrustedNodes: config.parseNodes(trustedNodes), NodeDatabase: nodeDb, } if len(config.Port) > 0 { exp.net.ListenAddr = ":" + config.Port } vm.Debug = config.VmDebug return exp, nil }