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.

110 lines
2.7 KiB

  1. package consensus
  2. import (
  3. "encoding/binary"
  4. // "math/rand"
  5. "testing"
  6. "time"
  7. "github.com/tendermint/tendermint/config/tendermint_test"
  8. "github.com/tendermint/tendermint/types"
  9. tmsp "github.com/tendermint/tmsp/types"
  10. . "github.com/tendermint/go-common"
  11. )
  12. func init() {
  13. config = tendermint_test.ResetConfig("consensus_mempool_test")
  14. }
  15. func TestTxConcurrentWithCommit(t *testing.T) {
  16. state, privVals := randGenesisState(1, false, 10)
  17. cs := newConsensusState(state, privVals[0], NewCounterApplication())
  18. height, round := cs.Height, cs.Round
  19. newBlockCh := subscribeToEvent(cs.evsw, "tester", types.EventStringNewBlock(), 1)
  20. appendTxsRange := func(start, end int) {
  21. // Append some txs.
  22. for i := start; i < end; i++ {
  23. txBytes := make([]byte, 8)
  24. binary.BigEndian.PutUint64(txBytes, uint64(i))
  25. err := cs.mempool.CheckTx(txBytes, nil)
  26. if err != nil {
  27. panic(Fmt("Error after CheckTx: %v", err))
  28. }
  29. // time.Sleep(time.Microsecond * time.Duration(rand.Int63n(3000)))
  30. }
  31. }
  32. NTxs := 10000
  33. go appendTxsRange(0, NTxs)
  34. startTestRound(cs, height, round)
  35. ticker := time.NewTicker(time.Second * 20)
  36. for nTxs := 0; nTxs < NTxs; {
  37. select {
  38. case b := <-newBlockCh:
  39. nTxs += b.(types.EventDataNewBlock).Block.Header.NumTxs
  40. case <-ticker.C:
  41. panic("Timed out waiting to commit blocks with transactions")
  42. }
  43. }
  44. }
  45. // CounterApplication that maintains a mempool state and resets it upon commit
  46. type CounterApplication struct {
  47. txCount int
  48. mempoolTxCount int
  49. }
  50. func NewCounterApplication() *CounterApplication {
  51. return &CounterApplication{}
  52. }
  53. func (app *CounterApplication) Info() string {
  54. return Fmt("txs:%v", app.txCount)
  55. }
  56. func (app *CounterApplication) SetOption(key string, value string) (log string) {
  57. return ""
  58. }
  59. func (app *CounterApplication) AppendTx(tx []byte) tmsp.Result {
  60. return runTx(tx, &app.txCount)
  61. }
  62. func (app *CounterApplication) CheckTx(tx []byte) tmsp.Result {
  63. return runTx(tx, &app.mempoolTxCount)
  64. }
  65. func runTx(tx []byte, countPtr *int) tmsp.Result {
  66. count := *countPtr
  67. tx8 := make([]byte, 8)
  68. copy(tx8[len(tx8)-len(tx):], tx)
  69. txValue := binary.BigEndian.Uint64(tx8)
  70. if txValue != uint64(count) {
  71. return tmsp.Result{
  72. Code: tmsp.CodeType_BadNonce,
  73. Data: nil,
  74. Log: Fmt("Invalid nonce. Expected %v, got %v", count, txValue),
  75. }
  76. }
  77. *countPtr += 1
  78. return tmsp.OK
  79. }
  80. func (app *CounterApplication) Commit() tmsp.Result {
  81. app.mempoolTxCount = app.txCount
  82. if app.txCount == 0 {
  83. return tmsp.OK
  84. } else {
  85. hash := make([]byte, 8)
  86. binary.BigEndian.PutUint64(hash, uint64(app.txCount))
  87. return tmsp.NewResultOK(hash, "")
  88. }
  89. }
  90. func (app *CounterApplication) Query(query []byte) tmsp.Result {
  91. return tmsp.NewResultOK(nil, Fmt("Query is not supported"))
  92. }