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.

202 lines
5.2 KiB

7 years ago
  1. package mempool
  2. import (
  3. "crypto/rand"
  4. "encoding/binary"
  5. "testing"
  6. "time"
  7. "github.com/tendermint/abci/example/counter"
  8. "github.com/tendermint/abci/example/dummy"
  9. "github.com/tendermint/tmlibs/log"
  10. cfg "github.com/tendermint/tendermint/config"
  11. "github.com/tendermint/tendermint/proxy"
  12. "github.com/tendermint/tendermint/types"
  13. )
  14. func newMempoolWithApp(cc proxy.ClientCreator) *Mempool {
  15. config := cfg.ResetTestRoot("mempool_test")
  16. appConnMem, _ := cc.NewABCIClient()
  17. appConnMem.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "mempool"))
  18. appConnMem.Start()
  19. mempool := NewMempool(config.Mempool, appConnMem, 0)
  20. mempool.SetLogger(log.TestingLogger())
  21. return mempool
  22. }
  23. func ensureNoFire(t *testing.T, ch <-chan int, timeoutMS int) {
  24. timer := time.NewTimer(time.Duration(timeoutMS) * time.Millisecond)
  25. select {
  26. case <-ch:
  27. t.Fatal("Expected not to fire")
  28. case <-timer.C:
  29. }
  30. }
  31. func ensureFire(t *testing.T, ch <-chan int, timeoutMS int) {
  32. timer := time.NewTimer(time.Duration(timeoutMS) * time.Millisecond)
  33. select {
  34. case <-ch:
  35. case <-timer.C:
  36. t.Fatal("Expected to fire")
  37. }
  38. }
  39. func checkTxs(t *testing.T, mempool *Mempool, count int) types.Txs {
  40. txs := make(types.Txs, count)
  41. for i := 0; i < count; i++ {
  42. txBytes := make([]byte, 20)
  43. txs[i] = txBytes
  44. rand.Read(txBytes)
  45. err := mempool.CheckTx(txBytes, nil)
  46. if err != nil {
  47. t.Fatal("Error after CheckTx: %v", err)
  48. }
  49. }
  50. return txs
  51. }
  52. func TestTxsAvailable(t *testing.T) {
  53. app := dummy.NewDummyApplication()
  54. cc := proxy.NewLocalClientCreator(app)
  55. mempool := newMempoolWithApp(cc)
  56. mempool.EnableTxsAvailable()
  57. timeoutMS := 500
  58. // with no txs, it shouldnt fire
  59. ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
  60. // send a bunch of txs, it should only fire once
  61. txs := checkTxs(t, mempool, 100)
  62. ensureFire(t, mempool.TxsAvailable(), timeoutMS)
  63. ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
  64. // call update with half the txs.
  65. // it should fire once now for the new height
  66. // since there are still txs left
  67. committedTxs, txs := txs[:50], txs[50:]
  68. mempool.Update(1, committedTxs)
  69. ensureFire(t, mempool.TxsAvailable(), timeoutMS)
  70. ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
  71. // send a bunch more txs. we already fired for this height so it shouldnt fire again
  72. moreTxs := checkTxs(t, mempool, 50)
  73. ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
  74. // now call update with all the txs. it should not fire as there are no txs left
  75. committedTxs = append(txs, moreTxs...)
  76. mempool.Update(2, committedTxs)
  77. ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
  78. // send a bunch more txs, it should only fire once
  79. checkTxs(t, mempool, 100)
  80. ensureFire(t, mempool.TxsAvailable(), timeoutMS)
  81. ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
  82. }
  83. func TestSerialReap(t *testing.T) {
  84. app := counter.NewCounterApplication(true)
  85. app.SetOption("serial", "on")
  86. cc := proxy.NewLocalClientCreator(app)
  87. mempool := newMempoolWithApp(cc)
  88. appConnCon, _ := cc.NewABCIClient()
  89. appConnCon.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "consensus"))
  90. if _, err := appConnCon.Start(); err != nil {
  91. t.Fatalf("Error starting ABCI client: %v", err.Error())
  92. }
  93. deliverTxsRange := func(start, end int) {
  94. // Deliver some txs.
  95. for i := start; i < end; i++ {
  96. // This will succeed
  97. txBytes := make([]byte, 8)
  98. binary.BigEndian.PutUint64(txBytes, uint64(i))
  99. err := mempool.CheckTx(txBytes, nil)
  100. if err != nil {
  101. t.Fatal("Error after CheckTx: %v", err)
  102. }
  103. // This will fail because not serial (incrementing)
  104. // However, error should still be nil.
  105. // It just won't show up on Reap().
  106. err = mempool.CheckTx(txBytes, nil)
  107. if err != nil {
  108. t.Fatal("Error after CheckTx: %v", err)
  109. }
  110. }
  111. }
  112. reapCheck := func(exp int) {
  113. txs := mempool.Reap(-1)
  114. if len(txs) != exp {
  115. t.Fatalf("Expected to reap %v txs but got %v", exp, len(txs))
  116. }
  117. }
  118. updateRange := func(start, end int) {
  119. txs := make([]types.Tx, 0)
  120. for i := start; i < end; i++ {
  121. txBytes := make([]byte, 8)
  122. binary.BigEndian.PutUint64(txBytes, uint64(i))
  123. txs = append(txs, txBytes)
  124. }
  125. mempool.Update(0, txs)
  126. }
  127. commitRange := func(start, end int) {
  128. // Deliver some txs.
  129. for i := start; i < end; i++ {
  130. txBytes := make([]byte, 8)
  131. binary.BigEndian.PutUint64(txBytes, uint64(i))
  132. res := appConnCon.DeliverTxSync(txBytes)
  133. if !res.IsOK() {
  134. t.Errorf("Error committing tx. Code:%v result:%X log:%v",
  135. res.Code, res.Data, res.Log)
  136. }
  137. }
  138. res := appConnCon.CommitSync()
  139. if len(res.Data) != 8 {
  140. t.Errorf("Error committing. Hash:%X log:%v", res.Data, res.Log)
  141. }
  142. }
  143. //----------------------------------------
  144. // Deliver some txs.
  145. deliverTxsRange(0, 100)
  146. // Reap the txs.
  147. reapCheck(100)
  148. // Reap again. We should get the same amount
  149. reapCheck(100)
  150. // Deliver 0 to 999, we should reap 900 new txs
  151. // because 100 were already counted.
  152. deliverTxsRange(0, 1000)
  153. // Reap the txs.
  154. reapCheck(1000)
  155. // Reap again. We should get the same amount
  156. reapCheck(1000)
  157. // Commit from the conensus AppConn
  158. commitRange(0, 500)
  159. updateRange(0, 500)
  160. // We should have 500 left.
  161. reapCheck(500)
  162. // Deliver 100 invalid txs and 100 valid txs
  163. deliverTxsRange(900, 1100)
  164. // We should have 600 now.
  165. reapCheck(600)
  166. }