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.

153 lines
3.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package mempool
  2. import (
  3. "bytes"
  4. "fmt"
  5. "sync/atomic"
  6. "github.com/tendermint/tendermint/binary"
  7. "github.com/tendermint/tendermint/events"
  8. "github.com/tendermint/tendermint/p2p"
  9. "github.com/tendermint/tendermint/types"
  10. )
  11. var (
  12. MempoolChannel = byte(0x30)
  13. )
  14. // MempoolReactor handles mempool tx broadcasting amongst peers.
  15. type MempoolReactor struct {
  16. sw *p2p.Switch
  17. quit chan struct{}
  18. started uint32
  19. stopped uint32
  20. Mempool *Mempool
  21. evsw *events.EventSwitch
  22. }
  23. func NewMempoolReactor(mempool *Mempool) *MempoolReactor {
  24. memR := &MempoolReactor{
  25. quit: make(chan struct{}),
  26. Mempool: mempool,
  27. }
  28. return memR
  29. }
  30. // Implements Reactor
  31. func (memR *MempoolReactor) Start(sw *p2p.Switch) {
  32. if atomic.CompareAndSwapUint32(&memR.started, 0, 1) {
  33. memR.sw = sw
  34. log.Info("Starting MempoolReactor")
  35. }
  36. }
  37. // Implements Reactor
  38. func (memR *MempoolReactor) Stop() {
  39. if atomic.CompareAndSwapUint32(&memR.stopped, 0, 1) {
  40. log.Info("Stopping MempoolReactor")
  41. close(memR.quit)
  42. }
  43. }
  44. // Implements Reactor
  45. func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor {
  46. return []*p2p.ChannelDescriptor{
  47. &p2p.ChannelDescriptor{
  48. Id: MempoolChannel,
  49. Priority: 5,
  50. },
  51. }
  52. }
  53. // Implements Reactor
  54. func (pexR *MempoolReactor) AddPeer(peer *p2p.Peer) {
  55. }
  56. // Implements Reactor
  57. func (pexR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) {
  58. }
  59. // Implements Reactor
  60. func (memR *MempoolReactor) Receive(chId byte, src *p2p.Peer, msgBytes []byte) {
  61. _, msg_, err := DecodeMessage(msgBytes)
  62. if err != nil {
  63. log.Warn("Error decoding message", "error", err)
  64. return
  65. }
  66. log.Info("MempoolReactor received message", "msg", msg_)
  67. switch msg := msg_.(type) {
  68. case *TxMessage:
  69. err := memR.Mempool.AddTx(msg.Tx)
  70. if err != nil {
  71. // Bad, seen, or conflicting tx.
  72. log.Debug("Could not add tx", "tx", msg.Tx)
  73. return
  74. } else {
  75. log.Debug("Added valid tx", "tx", msg.Tx)
  76. }
  77. // Share tx.
  78. // We use a simple shotgun approach for now.
  79. // TODO: improve efficiency
  80. for _, peer := range memR.sw.Peers().List() {
  81. if peer.Key == src.Key {
  82. continue
  83. }
  84. peer.TrySend(MempoolChannel, msg)
  85. }
  86. default:
  87. // Ignore unknown message
  88. }
  89. }
  90. func (memR *MempoolReactor) BroadcastTx(tx types.Tx) error {
  91. err := memR.Mempool.AddTx(tx)
  92. if err != nil {
  93. return err
  94. }
  95. msg := &TxMessage{Tx: tx}
  96. memR.sw.Broadcast(MempoolChannel, msg)
  97. return nil
  98. }
  99. // implements events.Eventable
  100. func (memR *MempoolReactor) SetEventSwitch(evsw *events.EventSwitch) {
  101. memR.evsw = evsw
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Messages
  105. const (
  106. msgTypeUnknown = byte(0x00)
  107. msgTypeTx = byte(0x10)
  108. )
  109. // TODO: check for unnecessary extra bytes at the end.
  110. func DecodeMessage(bz []byte) (msgType byte, msg interface{}, err error) {
  111. n := new(int64)
  112. msgType = bz[0]
  113. r := bytes.NewReader(bz)
  114. switch msgType {
  115. case msgTypeTx:
  116. msg = binary.ReadBinary(&TxMessage{}, r, n, &err)
  117. default:
  118. msg = nil
  119. }
  120. return
  121. }
  122. //-------------------------------------
  123. type TxMessage struct {
  124. Tx types.Tx
  125. }
  126. func (m *TxMessage) TypeByte() byte { return msgTypeTx }
  127. func (m *TxMessage) String() string {
  128. return fmt.Sprintf("[TxMessage %v]", m.Tx)
  129. }