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.

163 lines
3.2 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. package main
  2. // TODO: ensure Mark* gets called.
  3. import (
  4. "os"
  5. "os/signal"
  6. "github.com/tendermint/tendermint/config"
  7. "github.com/tendermint/tendermint/p2p"
  8. )
  9. type Node struct {
  10. lz []p2p.Listener
  11. sw *p2p.Switch
  12. book *p2p.AddrBook
  13. pmgr *p2p.PeerManager
  14. }
  15. func NewNode() *Node {
  16. // Define channels for our app
  17. chDescs := []p2p.ChannelDescriptor{
  18. p2p.ChannelDescriptor{
  19. Name: "PEX",
  20. SendBufferSize: 2,
  21. RecvBufferSize: 2,
  22. },
  23. p2p.ChannelDescriptor{
  24. Name: "block",
  25. SendBufferSize: 10,
  26. RecvBufferSize: 10,
  27. },
  28. p2p.ChannelDescriptor{
  29. Name: "mempool",
  30. SendBufferSize: 100,
  31. RecvBufferSize: 100,
  32. },
  33. p2p.ChannelDescriptor{
  34. Name: "consensus",
  35. SendBufferSize: 1000,
  36. RecvBufferSize: 1000,
  37. },
  38. }
  39. sw := p2p.NewSwitch(chDescs)
  40. book := p2p.NewAddrBook(config.AppDir + "/addrbook.json")
  41. pmgr := p2p.NewPeerManager(sw, book)
  42. return &Node{
  43. sw: sw,
  44. book: book,
  45. pmgr: pmgr,
  46. }
  47. }
  48. func (n *Node) Start() {
  49. log.Info("Starting node")
  50. for _, l := range n.lz {
  51. go n.inboundConnectionHandler(l)
  52. }
  53. n.sw.Start()
  54. n.book.Start()
  55. n.pmgr.Start()
  56. }
  57. // Add a Listener to accept inbound peer connections.
  58. func (n *Node) AddListener(l p2p.Listener) {
  59. log.Info("Added %v", l)
  60. n.lz = append(n.lz, l)
  61. }
  62. func (n *Node) inboundConnectionHandler(l p2p.Listener) {
  63. for {
  64. inConn, ok := <-l.Connections()
  65. if !ok {
  66. break
  67. }
  68. // New inbound connection!
  69. peer, err := n.sw.AddPeerWithConnection(inConn, false)
  70. if err != nil {
  71. log.Info("Ignoring error from inbound connection: %v\n%v",
  72. peer, err)
  73. continue
  74. }
  75. // NOTE: We don't yet have the external address of the
  76. // remote (if they have a listener at all).
  77. // PeerManager's pexHandler will handle that.
  78. }
  79. // cleanup
  80. }
  81. func (n *Node) SendOurExternalAddrs(peer *p2p.Peer) {
  82. // Send listener our external address(es)
  83. addrs := []*p2p.NetAddress{}
  84. for _, l := range n.lz {
  85. addrs = append(addrs, l.ExternalAddress())
  86. }
  87. msg := &p2p.PexAddrsMessage{Addrs: addrs}
  88. peer.Send(p2p.NewPacket(p2p.PexCh, msg))
  89. // On the remote end, the pexHandler may choose
  90. // to add these to its book.
  91. }
  92. func (n *Node) newPeersHandler() {
  93. for {
  94. peer, ok := <-n.pmgr.NewPeers()
  95. if !ok {
  96. break
  97. }
  98. // New outbound peer!
  99. n.SendOurExternalAddrs(peer)
  100. }
  101. }
  102. func (n *Node) Stop() {
  103. log.Info("Stopping node")
  104. // TODO: gracefully disconnect from peers.
  105. n.sw.Stop()
  106. n.book.Stop()
  107. n.pmgr.Stop()
  108. }
  109. //-----------------------------------------------------------------------------
  110. func main() {
  111. // Create & start node
  112. n := NewNode()
  113. l := p2p.NewDefaultListener("tcp", config.Config.LAddr)
  114. n.AddListener(l)
  115. n.Start()
  116. // Seed?
  117. if config.Config.Seed != "" {
  118. peer, err := n.sw.DialPeerWithAddress(p2p.NewNetAddressString(config.Config.Seed))
  119. if err != nil {
  120. log.Error("Error dialing seed: %v", err)
  121. //n.book.MarkAttempt(addr)
  122. return
  123. } else {
  124. log.Info("Connected to seed: %v", peer)
  125. n.SendOurExternalAddrs(peer)
  126. }
  127. }
  128. // Sleep forever and then...
  129. trapSignal(func() {
  130. n.Stop()
  131. })
  132. }
  133. func trapSignal(cb func()) {
  134. c := make(chan os.Signal, 1)
  135. signal.Notify(c, os.Interrupt)
  136. go func() {
  137. for sig := range c {
  138. log.Info("captured %v, exiting..", sig)
  139. cb()
  140. os.Exit(1)
  141. }
  142. }()
  143. select {}
  144. }