diff --git a/cmd/tendermint/run_node.go b/cmd/tendermint/run_node.go index a66451541..1940a6056 100644 --- a/cmd/tendermint/run_node.go +++ b/cmd/tendermint/run_node.go @@ -13,9 +13,9 @@ import ( // Users wishing to: // * Use an external signer for their validators // * Supply an in-proc abci app -// should import tendermint/tendermint and implement their own RunNode to -// call NewNode with their custom priv validator and/or custom -// proxy.ClientCreator interface +// should import github.com/tendermint/tendermint/node and implement +// their own run_node to call node.NewNode (instead of node.NewNodeDefault) +// with their custom priv validator and/or custom proxy.ClientCreator func run_node(config cfg.Config) { // Wait until the genesis doc becomes available diff --git a/glide.lock b/glide.lock index c024b3913..af5173366 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 41f8fec708e98b7f8c4804be46008493199fa45e89b2d5dc237fd65fe431c62f -updated: 2017-03-04T22:10:20.337283524-05:00 +updated: 2017-03-04T23:34:29.802454496-05:00 imports: - name: github.com/btcsuite/btcd version: d06c0bb181529331be8f8d9350288c420d9e60e4 @@ -101,7 +101,7 @@ imports: - name: github.com/tendermint/go-merkle version: 714d4d04557fd068a7c2a1748241ce8428015a96 - name: github.com/tendermint/go-p2p - version: 17e6ae813fc8399ab96d32dc6b392eb1be8dbe8d + version: 56eebb95eede5f7cf742ecaefa83bed884df99ec subpackages: - upnp - name: github.com/tendermint/go-rpc diff --git a/node/node.go b/node/node.go index f14fc3ec9..2e8177661 100644 --- a/node/node.go +++ b/node/node.go @@ -32,19 +32,25 @@ import ( type Node struct { cmn.BaseService - config cfg.Config - sw *p2p.Switch - evsw types.EventSwitch - blockStore *bc.BlockStore - bcReactor *bc.BlockchainReactor - mempoolReactor *mempl.MempoolReactor - consensusState *consensus.ConsensusState - consensusReactor *consensus.ConsensusReactor - privValidator *types.PrivValidator - genesisDoc *types.GenesisDoc - privKey crypto.PrivKeyEd25519 - proxyApp proxy.AppConns - rpcListeners []net.Listener + // config + config cfg.Config // user config + genesisDoc *types.GenesisDoc // initial validator set + privValidator *types.PrivValidator // local node's validator key + + // network + privKey crypto.PrivKeyEd25519 // local node's p2p key + sw *p2p.Switch // p2p connections + addrBook *p2p.AddrBook // known peers + + // services + evsw types.EventSwitch // pub/sub for services + blockStore *bc.BlockStore // store the blockchain to disk + bcReactor *bc.BlockchainReactor // for fast-syncing + mempoolReactor *mempl.MempoolReactor // for gossipping transactions + consensusState *consensus.ConsensusState // latest consensus state + consensusReactor *consensus.ConsensusReactor // for participating in the consensus + proxyApp proxy.AppConns // connection to the application + rpcListeners []net.Listener // rpc servers } func NewNodeDefault(config cfg.Config) *Node { @@ -119,8 +125,9 @@ func NewNode(config cfg.Config, privValidator *types.PrivValidator, clientCreato sw.AddReactor("CONSENSUS", consensusReactor) // Optionally, start the pex reactor + var addrBook *p2p.AddrBook if config.GetBool("pex_reactor") { - addrBook := p2p.NewAddrBook(config.GetString("addrbook_file"), config.GetBool("addrbook_strict")) + addrBook = p2p.NewAddrBook(config.GetString("addrbook_file"), config.GetBool("addrbook_strict")) pexReactor := p2p.NewPEXReactor(addrBook) sw.AddReactor("PEX", pexReactor) } @@ -166,17 +173,20 @@ func NewNode(config cfg.Config, privValidator *types.PrivValidator, clientCreato } node := &Node{ - config: config, - sw: sw, + config: config, + genesisDoc: state.GenesisDoc, + privValidator: privValidator, + + privKey: privKey, + sw: sw, + addrBook: addrBook, + evsw: eventSwitch, blockStore: blockStore, bcReactor: bcReactor, mempoolReactor: mempoolReactor, consensusState: consensusState, consensusReactor: consensusReactor, - privValidator: privValidator, - genesisDoc: state.GenesisDoc, - privKey: privKey, proxyApp: proxyApp, } node.BaseService = *cmn.NewBaseService(log, "Node", node) @@ -199,10 +209,32 @@ func (n *Node) OnStart() error { return err } - // Dial out of seed nodes exist + // If seeds exist, add them to the address book and dial out if n.config.GetString("seeds") != "" { seeds := strings.Split(n.config.GetString("seeds"), ",") - n.sw.DialSeeds(seeds) + + if n.config.GetBool("pex_reactor") { + // add seeds to `addrBook` to avoid losing + ourAddrS := n.NodeInfo().ListenAddr + ourAddr, _ := p2p.NewNetAddressString(ourAddrS) + for _, s := range seeds { + // do not add ourselves + if s == ourAddrS { + continue + } + + addr, err := p2p.NewNetAddressString(s) + if err != nil { + n.addrBook.AddAddress(addr, ourAddr) + } + } + n.addrBook.Save() + } + + // dial out + if err := n.sw.DialSeeds(seeds); err != nil { + return err + } } // Run the RPC server @@ -374,84 +406,6 @@ func makeNodeInfo(config cfg.Config, sw *p2p.Switch, privKey crypto.PrivKeyEd255 //------------------------------------------------------------------------------ -// Users wishing to: -// * use an external signer for their validators -// * supply an in-proc abci app -// should fork tendermint/tendermint and implement RunNode to -// call NewNode with their custom priv validator and/or custom -// proxy.ClientCreator interface -func RunNode(config cfg.Config) { - // Wait until the genesis doc becomes available - genDocFile := config.GetString("genesis_file") - if !FileExists(genDocFile) { - log.Notice(Fmt("Waiting for genesis file %v...", genDocFile)) - for { - time.Sleep(time.Second) - if !FileExists(genDocFile) { - continue - } - jsonBlob, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc := types.GenesisDocFromJSON(jsonBlob) - if genDoc.ChainID == "" { - PanicSanity(Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) - } - config.Set("chain_id", genDoc.ChainID) - } - } - - // Create & start node - n := NewNodeDefault(config) - - protocol, address := ProtocolAndAddress(config.GetString("node_laddr")) - l := p2p.NewDefaultListener(protocol, address, config.GetBool("skip_upnp")) - n.AddListener(l) - err := n.Start() - if err != nil { - Exit(Fmt("Failed to start node: %v", err)) - } - - log.Notice("Started node", "nodeInfo", n.sw.NodeInfo()) - - if config.GetString("seeds") != "" { - seeds := strings.Split(config.GetString("seeds"), ",") - - if config.GetBool("pex_reactor") { - // add seeds to `addrBook` to avoid losing - r := n.sw.Reactor("PEX").(*p2p.PEXReactor) - ourAddr := n.NodeInfo().ListenAddr - for _, s := range seeds { - // do not add ourselves - if s == ourAddr { - continue - } - - addr := p2p.NewNetAddressString(s) - r.AddPeerAddress(addr, p2p.NewNetAddressString(ourAddr)) - } - r.SaveAddrBook() - } - - // dial out - n.sw.DialSeeds(seeds) - } - - // Run the RPC server. - if config.GetString("rpc_laddr") != "" { - _, err := n.StartRPC() - if err != nil { - PanicCrisis(err) - } - } - - // Sleep forever and then... - TrapSignal(func() { - n.Stop() - }) -} - func (n *Node) NodeInfo() *p2p.NodeInfo { return n.sw.NodeInfo() }