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.

128 lines
2.6 KiB

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