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.

159 lines
3.7 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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package main
  2. import (
  3. "os"
  4. "os/signal"
  5. "github.com/tendermint/tendermint/block"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/config"
  8. "github.com/tendermint/tendermint/consensus"
  9. db_ "github.com/tendermint/tendermint/db"
  10. mempool_ "github.com/tendermint/tendermint/mempool"
  11. "github.com/tendermint/tendermint/p2p"
  12. "github.com/tendermint/tendermint/rpc"
  13. state_ "github.com/tendermint/tendermint/state"
  14. )
  15. type Node struct {
  16. lz []p2p.Listener
  17. sw *p2p.Switch
  18. book *p2p.AddrBook
  19. pexReactor *p2p.PEXReactor
  20. mempoolReactor *mempool_.MempoolReactor
  21. consensusReactor *consensus.ConsensusReactor
  22. privValidator *state_.PrivValidator
  23. }
  24. func NewNode() *Node {
  25. // Get BlockStore
  26. blockStoreDB := db_.GetDB("blockstore")
  27. blockStore := block.NewBlockStore(blockStoreDB)
  28. // Get State
  29. stateDB := db_.GetDB("state")
  30. state := state_.LoadState(stateDB)
  31. if state == nil {
  32. state = state_.MakeGenesisStateFromFile(stateDB, config.GenesisFile())
  33. state.Save()
  34. }
  35. // Get PrivValidator
  36. var privValidator *state_.PrivValidator
  37. if _, err := os.Stat(config.PrivValidatorFile()); err == nil {
  38. privValidator = state_.LoadPrivValidator(config.PrivValidatorFile())
  39. }
  40. // Get PEXReactor
  41. book := p2p.NewAddrBook(config.AddrBookFile())
  42. pexReactor := p2p.NewPEXReactor(book)
  43. // Get MempoolReactor
  44. mempool := mempool_.NewMempool(state)
  45. mempoolReactor := mempool_.NewMempoolReactor(mempool)
  46. // Get ConsensusReactor
  47. consensusReactor := consensus.NewConsensusReactor(blockStore, mempoolReactor, state)
  48. if privValidator != nil {
  49. consensusReactor.SetPrivValidator(privValidator)
  50. }
  51. sw := p2p.NewSwitch([]p2p.Reactor{pexReactor, mempoolReactor, consensusReactor})
  52. return &Node{
  53. sw: sw,
  54. book: book,
  55. pexReactor: pexReactor,
  56. mempoolReactor: mempoolReactor,
  57. consensusReactor: consensusReactor,
  58. privValidator: privValidator,
  59. }
  60. }
  61. func (n *Node) Start() {
  62. log.Info("Starting Node")
  63. for _, l := range n.lz {
  64. go n.inboundConnectionRoutine(l)
  65. }
  66. n.book.Start()
  67. n.sw.Start()
  68. }
  69. func (n *Node) Stop() {
  70. log.Info("Stopping Node")
  71. // TODO: gracefully disconnect from peers.
  72. n.sw.Stop()
  73. n.book.Stop()
  74. }
  75. // Add a Listener to accept inbound peer connections.
  76. func (n *Node) AddListener(l p2p.Listener) {
  77. log.Info(Fmt("Added %v", l))
  78. n.lz = append(n.lz, l)
  79. n.book.AddOurAddress(l.ExternalAddress())
  80. }
  81. func (n *Node) inboundConnectionRoutine(l p2p.Listener) {
  82. for {
  83. inConn, ok := <-l.Connections()
  84. if !ok {
  85. break
  86. }
  87. // New inbound connection!
  88. peer, err := n.sw.AddPeerWithConnection(inConn, false)
  89. if err != nil {
  90. log.Info("Ignoring error from inbound connection: %v\n%v",
  91. peer, err)
  92. continue
  93. }
  94. // NOTE: We don't yet have the external address of the
  95. // remote (if they have a listener at all).
  96. // PEXReactor's pexRoutine will handle that.
  97. }
  98. // cleanup
  99. }
  100. func daemon() {
  101. // Create & start node
  102. n := NewNode()
  103. l := p2p.NewDefaultListener("tcp", config.Config.LAddr, false)
  104. n.AddListener(l)
  105. n.Start()
  106. // If seedNode is provided by config, dial out.
  107. if config.Config.SeedNode != "" {
  108. peer, err := n.sw.DialPeerWithAddress(p2p.NewNetAddressString(config.Config.SeedNode))
  109. if err != nil {
  110. log.Error("Error dialing seed", "error", err)
  111. //n.book.MarkAttempt(addr)
  112. return
  113. } else {
  114. log.Info("Connected to seed", "peer", peer)
  115. }
  116. }
  117. // Run the RPC server.
  118. if config.Config.RPC.HTTPPort != 0 {
  119. rpc.StartHTTPServer()
  120. }
  121. // Sleep forever and then...
  122. trapSignal(func() {
  123. n.Stop()
  124. })
  125. }
  126. func trapSignal(cb func()) {
  127. c := make(chan os.Signal, 1)
  128. signal.Notify(c, os.Interrupt)
  129. go func() {
  130. for sig := range c {
  131. log.Info(Fmt("captured %v, exiting..", sig))
  132. cb()
  133. os.Exit(1)
  134. }
  135. }()
  136. select {}
  137. }