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.

147 lines
3.7 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package p2p
  2. import (
  3. "math/rand"
  4. "net"
  5. crypto "github.com/tendermint/go-crypto"
  6. cmn "github.com/tendermint/tmlibs/common"
  7. "github.com/tendermint/tmlibs/log"
  8. cfg "github.com/tendermint/tendermint/config"
  9. "github.com/tendermint/tendermint/p2p/conn"
  10. )
  11. func AddPeerToSwitch(sw *Switch, peer Peer) {
  12. sw.peers.Add(peer)
  13. }
  14. func CreateRandomPeer(outbound bool) *peer {
  15. addr, netAddr := CreateRoutableAddr()
  16. p := &peer{
  17. nodeInfo: NodeInfo{
  18. ListenAddr: netAddr.DialString(),
  19. PubKey: crypto.GenPrivKeyEd25519().Wrap().PubKey(),
  20. },
  21. outbound: outbound,
  22. mconn: &conn.MConnection{},
  23. }
  24. p.SetLogger(log.TestingLogger().With("peer", addr))
  25. return p
  26. }
  27. func CreateRoutableAddr() (addr string, netAddr *NetAddress) {
  28. for {
  29. var err error
  30. addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256)
  31. netAddr, err = NewNetAddressString(addr)
  32. if err != nil {
  33. panic(err)
  34. }
  35. if netAddr.Routable() {
  36. break
  37. }
  38. }
  39. return
  40. }
  41. //------------------------------------------------------------------
  42. // Connects switches via arbitrary net.Conn. Used for testing.
  43. // MakeConnectedSwitches returns n switches, connected according to the connect func.
  44. // If connect==Connect2Switches, the switches will be fully connected.
  45. // initSwitch defines how the i'th switch should be initialized (ie. with what reactors).
  46. // NOTE: panics if any switch fails to start.
  47. func MakeConnectedSwitches(cfg *cfg.P2PConfig, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
  48. switches := make([]*Switch, n)
  49. for i := 0; i < n; i++ {
  50. switches[i] = MakeSwitch(cfg, i, "testing", "123.123.123", initSwitch)
  51. }
  52. if err := StartSwitches(switches); err != nil {
  53. panic(err)
  54. }
  55. for i := 0; i < n; i++ {
  56. for j := i + 1; j < n; j++ {
  57. connect(switches, i, j)
  58. }
  59. }
  60. return switches
  61. }
  62. // Connect2Switches will connect switches i and j via net.Pipe().
  63. // Blocks until a connection is established.
  64. // NOTE: caller ensures i and j are within bounds.
  65. func Connect2Switches(switches []*Switch, i, j int) {
  66. switchI := switches[i]
  67. switchJ := switches[j]
  68. c1, c2 := conn.NetPipe()
  69. doneCh := make(chan struct{})
  70. go func() {
  71. err := switchI.addPeerWithConnection(c1)
  72. if err != nil {
  73. panic(err)
  74. }
  75. doneCh <- struct{}{}
  76. }()
  77. go func() {
  78. err := switchJ.addPeerWithConnection(c2)
  79. if err != nil {
  80. panic(err)
  81. }
  82. doneCh <- struct{}{}
  83. }()
  84. <-doneCh
  85. <-doneCh
  86. }
  87. func (sw *Switch) addPeerWithConnection(conn net.Conn) error {
  88. peer, err := newInboundPeer(conn, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodeKey.PrivKey, sw.peerConfig)
  89. if err != nil {
  90. if err := conn.Close(); err != nil {
  91. sw.Logger.Error("Error closing connection", "err", err)
  92. }
  93. return err
  94. }
  95. peer.SetLogger(sw.Logger.With("peer", conn.RemoteAddr()))
  96. if err = sw.addPeer(peer); err != nil {
  97. peer.CloseConn()
  98. return err
  99. }
  100. return nil
  101. }
  102. // StartSwitches calls sw.Start() for each given switch.
  103. // It returns the first encountered error.
  104. func StartSwitches(switches []*Switch) error {
  105. for _, s := range switches {
  106. err := s.Start() // start switch and reactors
  107. if err != nil {
  108. return err
  109. }
  110. }
  111. return nil
  112. }
  113. func MakeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
  114. // new switch, add reactors
  115. // TODO: let the config be passed in?
  116. nodeKey := &NodeKey{
  117. PrivKey: crypto.GenPrivKeyEd25519().Wrap(),
  118. }
  119. s := NewSwitch(cfg)
  120. s.SetLogger(log.TestingLogger())
  121. s = initSwitch(i, s)
  122. s.SetNodeInfo(NodeInfo{
  123. PubKey: nodeKey.PubKey(),
  124. Moniker: cmn.Fmt("switch%d", i),
  125. Network: network,
  126. Version: version,
  127. ListenAddr: cmn.Fmt("%v:%v", network, rand.Intn(64512)+1023),
  128. })
  129. s.SetNodeKey(nodeKey)
  130. return s
  131. }