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
2.8 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
  1. package main
  2. import (
  3. "os"
  4. "os/signal"
  5. "github.com/tendermint/tendermint/config"
  6. "github.com/tendermint/tendermint/p2p"
  7. )
  8. const (
  9. minNumPeers = 10
  10. maxNumPeers = 20
  11. ensurePeersPeriodSeconds = 30
  12. peerDialTimeoutSeconds = 30
  13. )
  14. type Node struct {
  15. sw *p2p.Switch
  16. book *p2p.AddressBook
  17. quit chan struct{}
  18. }
  19. func NewNode() *Node {
  20. // Define channels for our app
  21. chDescs := []p2p.ChannelDescriptor{
  22. p2p.ChannelDescriptor{
  23. Name: "PEX",
  24. SendBufferSize: 2,
  25. RecvBufferSize: 2,
  26. },
  27. p2p.ChannelDescriptor{
  28. Name: "block",
  29. SendBufferSize: 10,
  30. RecvBufferSize: 10,
  31. },
  32. p2p.ChannelDescriptor{
  33. Name: "mempool",
  34. SendBufferSize: 100,
  35. RecvBufferSize: 100,
  36. },
  37. p2p.ChannelDescriptor{
  38. Name: "consensus",
  39. SendBufferSize: 1000,
  40. RecvBufferSize: 1000,
  41. },
  42. }
  43. sw := p2p.NewSwitch(chDescs)
  44. book := p2p.NewAddrBook(config.AppDir + "/addrbook.json")
  45. return &New{
  46. sw: sw,
  47. book: book,
  48. }
  49. }
  50. func (n *Node) Start() {
  51. n.sw.Start()
  52. n.book.Start()
  53. go p2p.PexHandler(sw, book)
  54. go n.ensurePeersHandler(sw, book)
  55. }
  56. func (n *Node) initPeer(peer *Peer) {
  57. if peer.IsOutgoing() {
  58. // TODO: initiate PEX
  59. }
  60. }
  61. // Add a Listener to accept incoming peer connections.
  62. func (n *Node) AddListener(l Listener) {
  63. go func() {
  64. for {
  65. inConn, ok := <-l.Connections()
  66. if !ok {
  67. break
  68. }
  69. peer, err := n.sw.AddPeerWithConnection(inConn, false)
  70. if err != nil {
  71. log.Infof("Ignoring error from incoming connection: %v\n%v",
  72. peer, err)
  73. continue
  74. }
  75. n.initPeer(peer)
  76. }
  77. }()
  78. }
  79. // Ensures that sufficient peers are connected.
  80. func (n *Node) ensurePeers() {
  81. numPeers := len(n.sw.Peers())
  82. if numPeers < minNumPeers {
  83. // XXX
  84. }
  85. }
  86. func (n *Node) ensurePeersHandler() {
  87. timer := NewRepeatTimer(ensurePeersPeriodSeconds * time.Second)
  88. FOR_LOOP:
  89. for {
  90. select {
  91. case <-timer.Ch:
  92. n.ensurePeers()
  93. case <-n.quit:
  94. break FOR_LOOP
  95. }
  96. }
  97. // cleanup
  98. timer.Stop()
  99. }
  100. func (n *Node) Stop() {
  101. // TODO: gracefully disconnect from peers.
  102. n.sw.Stop()
  103. n.book.Stop()
  104. }
  105. //-----------------------------------------------------------------------------
  106. func main() {
  107. n := NewNode()
  108. l := p2p.NewDefaultListener("tcp", ":8001")
  109. n.AddListener()
  110. if false {
  111. // TODO remove
  112. // let's connect to 66.175.218.199
  113. conn, err := p2p.NewNetAddressString("66.175.218.199:8001").Dial()
  114. if err != nil {
  115. log.Infof("Error connecting to it: %v", err)
  116. return
  117. }
  118. peer, err := sw.AddPeerWithConnection(conn, true)
  119. if err != nil {
  120. log.Infof("Error adding peer with connection: %v", err)
  121. return
  122. }
  123. log.Infof("Connected to peer: %v", peer)
  124. // TODO remove
  125. }
  126. // Sleep forever
  127. trapSignal()
  128. select {}
  129. }
  130. func trapSignal() {
  131. c := make(chan os.Signal, 1)
  132. signal.Notify(c, os.Interrupt)
  133. go func() {
  134. for sig := range c {
  135. log.Infof("captured %v, exiting..", sig)
  136. os.Exit(1)
  137. }
  138. }()
  139. }