You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package node
  2. import (
  3. "net/http"
  4. "os"
  5. bc "github.com/tendermint/tendermint/blockchain"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/config"
  8. "github.com/tendermint/tendermint/consensus"
  9. dbm "github.com/tendermint/tendermint/db"
  10. "github.com/tendermint/tendermint/events"
  11. mempl "github.com/tendermint/tendermint/mempool"
  12. "github.com/tendermint/tendermint/p2p"
  13. "github.com/tendermint/tendermint/rpc"
  14. "github.com/tendermint/tendermint/rpc/core"
  15. sm "github.com/tendermint/tendermint/state"
  16. )
  17. type Node struct {
  18. sw *p2p.Switch
  19. evsw *events.EventSwitch
  20. book *p2p.AddrBook
  21. blockStore *bc.BlockStore
  22. pexReactor *p2p.PEXReactor
  23. bcReactor *bc.BlockchainReactor
  24. mempoolReactor *mempl.MempoolReactor
  25. consensusState *consensus.ConsensusState
  26. consensusReactor *consensus.ConsensusReactor
  27. privValidator *sm.PrivValidator
  28. }
  29. func NewNode() *Node {
  30. // Get BlockStore
  31. blockStoreDB := dbm.GetDB("blockstore")
  32. blockStore := bc.NewBlockStore(blockStoreDB)
  33. // Get State
  34. stateDB := dbm.GetDB("state")
  35. state := sm.LoadState(stateDB)
  36. if state == nil {
  37. state = sm.MakeGenesisStateFromFile(stateDB, config.App().GetString("GenesisFile"))
  38. state.Save()
  39. }
  40. // Get PrivValidator
  41. var privValidator *sm.PrivValidator
  42. if _, err := os.Stat(config.App().GetString("PrivValidatorFile")); err == nil {
  43. privValidator = sm.LoadPrivValidator(config.App().GetString("PrivValidatorFile"))
  44. log.Info("Loaded PrivValidator", "file", config.App().GetString("PrivValidatorFile"), "privValidator", privValidator)
  45. } else {
  46. log.Info("No PrivValidator found", "file", config.App().GetString("PrivValidatorFile"))
  47. }
  48. eventSwitch := new(events.EventSwitch)
  49. eventSwitch.Start()
  50. // Get PEXReactor
  51. book := p2p.NewAddrBook(config.App().GetString("AddrBookFile"))
  52. pexReactor := p2p.NewPEXReactor(book)
  53. // Get BlockchainReactor
  54. bcReactor := bc.NewBlockchainReactor(state, blockStore, config.App().GetBool("FastSync"))
  55. // Get MempoolReactor
  56. mempool := mempl.NewMempool(state.Copy())
  57. mempoolReactor := mempl.NewMempoolReactor(mempool)
  58. // Get ConsensusReactor
  59. consensusState := consensus.NewConsensusState(state, blockStore, mempoolReactor)
  60. consensusReactor := consensus.NewConsensusReactor(consensusState, blockStore)
  61. if privValidator != nil {
  62. consensusReactor.SetPrivValidator(privValidator)
  63. }
  64. sw := p2p.NewSwitch()
  65. sw.SetNetwork(config.App().GetString("Network"))
  66. sw.AddReactor("PEX", pexReactor)
  67. sw.AddReactor("MEMPOOL", mempoolReactor)
  68. sw.AddReactor("BLOCKCHAIN", bcReactor)
  69. sw.AddReactor("CONSENSUS", consensusReactor)
  70. // add the event switch to all services
  71. // they should all satisfy events.Eventable
  72. SetEventSwitch(eventSwitch, pexReactor, bcReactor, mempoolReactor, consensusReactor)
  73. return &Node{
  74. sw: sw,
  75. evsw: eventSwitch,
  76. book: book,
  77. blockStore: blockStore,
  78. pexReactor: pexReactor,
  79. bcReactor: bcReactor,
  80. mempoolReactor: mempoolReactor,
  81. consensusState: consensusState,
  82. consensusReactor: consensusReactor,
  83. privValidator: privValidator,
  84. }
  85. }
  86. func (n *Node) Start() {
  87. log.Info("Starting Node")
  88. n.book.Start()
  89. n.sw.Start()
  90. if config.App().GetBool("FastSync") {
  91. // TODO: When FastSync is done, start CONSENSUS.
  92. n.sw.Reactor("CONSENSUS").Stop()
  93. }
  94. }
  95. func (n *Node) Stop() {
  96. log.Info("Stopping Node")
  97. // TODO: gracefully disconnect from peers.
  98. n.sw.Stop()
  99. n.book.Stop()
  100. }
  101. // Add the event switch to reactors, mempool, etc.
  102. func SetEventSwitch(evsw *events.EventSwitch, eventables ...events.Eventable) {
  103. for _, e := range eventables {
  104. e.SetEventSwitch(evsw)
  105. }
  106. }
  107. // Add a Listener to accept inbound peer connections.
  108. func (n *Node) AddListener(l p2p.Listener) {
  109. log.Info(Fmt("Added %v", l))
  110. n.sw.AddListener(l)
  111. n.book.AddOurAddress(l.ExternalAddress())
  112. }
  113. func (n *Node) DialSeed() {
  114. addr := p2p.NewNetAddressString(config.App().GetString("SeedNode"))
  115. peer, err := n.sw.DialPeerWithAddress(addr)
  116. if err != nil {
  117. log.Error("Error dialing seed", "error", err)
  118. //n.book.MarkAttempt(addr)
  119. return
  120. } else {
  121. log.Info("Connected to seed", "peer", peer)
  122. n.book.AddAddress(addr, addr)
  123. }
  124. }
  125. func (n *Node) StartRPC() {
  126. core.SetBlockStore(n.blockStore)
  127. core.SetConsensusState(n.consensusState)
  128. core.SetMempoolReactor(n.mempoolReactor)
  129. core.SetSwitch(n.sw)
  130. listenAddr := config.App().GetString("RPC.HTTP.ListenAddr")
  131. mux := http.NewServeMux()
  132. rpc.RegisterEventsHandler(mux, n.evsw)
  133. rpc.RegisterRPCFuncs(mux, core.Routes)
  134. rpc.StartHTTPServer(listenAddr, mux)
  135. }
  136. func (n *Node) Switch() *p2p.Switch {
  137. return n.sw
  138. }
  139. func (n *Node) ConsensusState() *consensus.ConsensusState {
  140. return n.consensusState
  141. }
  142. func (n *Node) MempoolReactor() *mempl.MempoolReactor {
  143. return n.mempoolReactor
  144. }
  145. //------------------------------------------------------------------------------
  146. func RunNode() {
  147. // Create & start node
  148. n := NewNode()
  149. l := p2p.NewDefaultListener("tcp", config.App().GetString("ListenAddr"), false)
  150. n.AddListener(l)
  151. n.Start()
  152. // If seedNode is provided by config, dial out.
  153. if config.App().GetString("SeedNode") != "" {
  154. n.DialSeed()
  155. }
  156. // Run the RPC server.
  157. if config.App().GetString("RPC.HTTP.ListenAddr") != "" {
  158. n.StartRPC()
  159. }
  160. // Sleep forever and then...
  161. TrapSignal(func() {
  162. n.Stop()
  163. })
  164. }