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