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.

219 lines
4.8 KiB

  1. package p2p
  2. import (
  3. "fmt"
  4. golog "log"
  5. "net"
  6. "testing"
  7. "time"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. crypto "github.com/tendermint/tendermint/crypto"
  11. "github.com/tendermint/tendermint/crypto/ed25519"
  12. cmn "github.com/tendermint/tendermint/libs/common"
  13. "github.com/tendermint/tendermint/libs/log"
  14. "github.com/tendermint/tendermint/config"
  15. tmconn "github.com/tendermint/tendermint/p2p/conn"
  16. )
  17. const testCh = 0x01
  18. func TestPeerBasic(t *testing.T) {
  19. assert, require := assert.New(t), require.New(t)
  20. // simulate remote peer
  21. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  22. rp.Start()
  23. defer rp.Stop()
  24. p, err := createOutboundPeerAndPerformHandshake(rp.Addr(), cfg, tmconn.DefaultMConnConfig())
  25. require.Nil(err)
  26. err = p.Start()
  27. require.Nil(err)
  28. defer p.Stop()
  29. assert.True(p.IsRunning())
  30. assert.True(p.IsOutbound())
  31. assert.False(p.IsPersistent())
  32. p.persistent = true
  33. assert.True(p.IsPersistent())
  34. assert.Equal(rp.Addr().DialString(), p.Addr().String())
  35. assert.Equal(rp.ID(), p.ID())
  36. }
  37. func TestPeerSend(t *testing.T) {
  38. assert, require := assert.New(t), require.New(t)
  39. config := cfg
  40. // simulate remote peer
  41. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: config}
  42. rp.Start()
  43. defer rp.Stop()
  44. p, err := createOutboundPeerAndPerformHandshake(rp.Addr(), config, tmconn.DefaultMConnConfig())
  45. require.Nil(err)
  46. err = p.Start()
  47. require.Nil(err)
  48. defer p.Stop()
  49. assert.True(p.CanSend(testCh))
  50. assert.True(p.Send(testCh, []byte("Asylum")))
  51. }
  52. func createOutboundPeerAndPerformHandshake(
  53. addr *NetAddress,
  54. config *config.P2PConfig,
  55. mConfig tmconn.MConnConfig,
  56. ) (*peer, error) {
  57. chDescs := []*tmconn.ChannelDescriptor{
  58. {ID: testCh, Priority: 1},
  59. }
  60. reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)}
  61. pk := ed25519.GenPrivKey()
  62. pc, err := testOutboundPeerConn(addr, config, false, pk)
  63. if err != nil {
  64. return nil, err
  65. }
  66. nodeInfo, err := pc.HandshakeTimeout(NodeInfo{
  67. ID: addr.ID,
  68. Moniker: "host_peer",
  69. Network: "testing",
  70. Version: "123.123.123",
  71. Channels: []byte{testCh},
  72. }, 1*time.Second)
  73. if err != nil {
  74. return nil, err
  75. }
  76. p := newPeer(pc, mConfig, nodeInfo, reactorsByCh, chDescs, func(p Peer, r interface{}) {})
  77. p.SetLogger(log.TestingLogger().With("peer", addr))
  78. return p, nil
  79. }
  80. func testDial(addr *NetAddress, cfg *config.P2PConfig) (net.Conn, error) {
  81. if cfg.TestDialFail {
  82. return nil, fmt.Errorf("dial err (peerConfig.DialFail == true)")
  83. }
  84. conn, err := addr.DialTimeout(cfg.DialTimeout)
  85. if err != nil {
  86. return nil, err
  87. }
  88. return conn, nil
  89. }
  90. func testOutboundPeerConn(
  91. addr *NetAddress,
  92. config *config.P2PConfig,
  93. persistent bool,
  94. ourNodePrivKey crypto.PrivKey,
  95. ) (peerConn, error) {
  96. conn, err := testDial(addr, config)
  97. if err != nil {
  98. return peerConn{}, cmn.ErrorWrap(err, "Error creating peer")
  99. }
  100. pc, err := testPeerConn(conn, config, true, persistent, ourNodePrivKey, addr)
  101. if err != nil {
  102. if cerr := conn.Close(); cerr != nil {
  103. return peerConn{}, cmn.ErrorWrap(err, cerr.Error())
  104. }
  105. return peerConn{}, err
  106. }
  107. // ensure dialed ID matches connection ID
  108. if addr.ID != pc.ID() {
  109. if cerr := conn.Close(); cerr != nil {
  110. return peerConn{}, cmn.ErrorWrap(err, cerr.Error())
  111. }
  112. return peerConn{}, ErrSwitchAuthenticationFailure{addr, pc.ID()}
  113. }
  114. return pc, nil
  115. }
  116. type remotePeer struct {
  117. PrivKey crypto.PrivKey
  118. Config *config.P2PConfig
  119. addr *NetAddress
  120. quit chan struct{}
  121. channels cmn.HexBytes
  122. listenAddr string
  123. }
  124. func (rp *remotePeer) Addr() *NetAddress {
  125. return rp.addr
  126. }
  127. func (rp *remotePeer) ID() ID {
  128. return PubKeyToID(rp.PrivKey.PubKey())
  129. }
  130. func (rp *remotePeer) Start() {
  131. if rp.listenAddr == "" {
  132. rp.listenAddr = "127.0.0.1:0"
  133. }
  134. l, e := net.Listen("tcp", rp.listenAddr) // any available address
  135. if e != nil {
  136. golog.Fatalf("net.Listen tcp :0: %+v", e)
  137. }
  138. rp.addr = NewNetAddress(PubKeyToID(rp.PrivKey.PubKey()), l.Addr())
  139. rp.quit = make(chan struct{})
  140. if rp.channels == nil {
  141. rp.channels = []byte{testCh}
  142. }
  143. go rp.accept(l)
  144. }
  145. func (rp *remotePeer) Stop() {
  146. close(rp.quit)
  147. }
  148. func (rp *remotePeer) accept(l net.Listener) {
  149. conns := []net.Conn{}
  150. for {
  151. conn, err := l.Accept()
  152. if err != nil {
  153. golog.Fatalf("Failed to accept conn: %+v", err)
  154. }
  155. pc, err := testInboundPeerConn(conn, rp.Config, rp.PrivKey)
  156. if err != nil {
  157. golog.Fatalf("Failed to create a peer: %+v", err)
  158. }
  159. _, err = handshake(pc.conn, time.Second, NodeInfo{
  160. ID: rp.Addr().ID,
  161. Moniker: "remote_peer",
  162. Network: "testing",
  163. Version: "123.123.123",
  164. ListenAddr: l.Addr().String(),
  165. Channels: rp.channels,
  166. })
  167. if err != nil {
  168. golog.Fatalf("Failed to perform handshake: %+v", err)
  169. }
  170. conns = append(conns, conn)
  171. select {
  172. case <-rp.quit:
  173. for _, conn := range conns {
  174. if err := conn.Close(); err != nil {
  175. golog.Fatal(err)
  176. }
  177. }
  178. return
  179. default:
  180. }
  181. }
  182. }