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.

127 lines
2.6 KiB

11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
  1. package p2p
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "github.com/tendermint/tendermint/binary"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/types"
  9. )
  10. type Peer struct {
  11. BaseService
  12. outbound bool
  13. mconn *MConnection
  14. *types.NodeInfo
  15. Key string
  16. Data *CMap // User data.
  17. }
  18. // NOTE: blocking
  19. // Before creating a peer with newPeer(), perform a handshake on connection.
  20. func peerHandshake(conn net.Conn, ourNodeInfo *types.NodeInfo) (*types.NodeInfo, error) {
  21. var peerNodeInfo = new(types.NodeInfo)
  22. var err1 error
  23. var err2 error
  24. Parallel(
  25. func() {
  26. var n int64
  27. binary.WriteBinary(ourNodeInfo, conn, &n, &err1)
  28. },
  29. func() {
  30. var n int64
  31. binary.ReadBinary(peerNodeInfo, conn, &n, &err2)
  32. log.Notice("Peer handshake", "peerNodeInfo", peerNodeInfo)
  33. })
  34. if err1 != nil {
  35. return nil, err1
  36. }
  37. if err2 != nil {
  38. return nil, err2
  39. }
  40. return peerNodeInfo, nil
  41. }
  42. // NOTE: call peerHandshake on conn before calling newPeer().
  43. func newPeer(conn net.Conn, peerNodeInfo *types.NodeInfo, outbound bool, reactorsByCh map[byte]Reactor, chDescs []*ChannelDescriptor, onPeerError func(*Peer, interface{})) *Peer {
  44. var p *Peer
  45. onReceive := func(chId byte, msgBytes []byte) {
  46. reactor := reactorsByCh[chId]
  47. if reactor == nil {
  48. panic(Fmt("Unknown channel %X", chId))
  49. }
  50. reactor.Receive(chId, p, msgBytes)
  51. }
  52. onError := func(r interface{}) {
  53. p.Stop()
  54. onPeerError(p, r)
  55. }
  56. mconn := NewMConnection(conn, chDescs, onReceive, onError)
  57. p = &Peer{
  58. outbound: outbound,
  59. mconn: mconn,
  60. NodeInfo: peerNodeInfo,
  61. Key: peerNodeInfo.PubKey.KeyString(),
  62. Data: NewCMap(),
  63. }
  64. p.BaseService = *NewBaseService(log, "Peer", p)
  65. return p
  66. }
  67. func (p *Peer) AfterStart() {
  68. p.mconn.Start()
  69. }
  70. func (p *Peer) AfterStop() {
  71. p.mconn.Stop()
  72. }
  73. func (p *Peer) Connection() *MConnection {
  74. return p.mconn
  75. }
  76. func (p *Peer) IsOutbound() bool {
  77. return p.outbound
  78. }
  79. func (p *Peer) Send(chId byte, msg interface{}) bool {
  80. if !p.IsRunning() {
  81. return false
  82. }
  83. return p.mconn.Send(chId, msg)
  84. }
  85. func (p *Peer) TrySend(chId byte, msg interface{}) bool {
  86. if !p.IsRunning() {
  87. return false
  88. }
  89. return p.mconn.TrySend(chId, msg)
  90. }
  91. func (p *Peer) CanSend(chId byte) bool {
  92. if !p.IsRunning() {
  93. return false
  94. }
  95. return p.mconn.CanSend(chId)
  96. }
  97. func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
  98. binary.WriteString(p.Key, w, &n, &err)
  99. return
  100. }
  101. func (p *Peer) String() string {
  102. if p.outbound {
  103. return fmt.Sprintf("Peer{->%v}", p.mconn)
  104. } else {
  105. return fmt.Sprintf("Peer{%v->}", p.mconn)
  106. }
  107. }
  108. func (p *Peer) Equals(other *Peer) bool {
  109. return p.Key == other.Key
  110. }