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.

213 lines
5.4 KiB

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