tendermint/mempool/mempool_test.go

203 lines
5.2 KiB
Go
Raw Normal View History

2015-12-01 20:12:01 -08:00
package mempool
import (
2017-07-13 12:03:19 -07:00
"crypto/rand"
2015-12-01 20:12:01 -08:00
"encoding/binary"
"testing"
2017-07-13 12:03:19 -07:00
"time"
2015-12-01 20:12:01 -08:00
2017-05-01 18:25:10 -07:00
"github.com/tendermint/abci/example/counter"
2017-07-13 12:03:19 -07:00
"github.com/tendermint/abci/example/dummy"
"github.com/tendermint/tmlibs/log"
2017-05-01 18:25:10 -07:00
cfg "github.com/tendermint/tendermint/config"
2016-10-10 14:05:50 -07:00
"github.com/tendermint/tendermint/proxy"
2015-12-01 20:12:01 -08:00
"github.com/tendermint/tendermint/types"
)
2017-09-05 13:08:12 -07:00
func newMempoolWithApp(cc proxy.ClientCreator) *Mempool {
2017-05-04 19:33:08 -07:00
config := cfg.ResetTestRoot("mempool_test")
2015-12-01 20:12:01 -08:00
2017-01-12 12:53:32 -08:00
appConnMem, _ := cc.NewABCIClient()
2017-05-16 10:06:35 -07:00
appConnMem.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "mempool"))
2017-09-05 13:08:12 -07:00
appConnMem.Start()
mempool := NewMempool(config.Mempool, appConnMem, 0)
2017-07-13 12:03:19 -07:00
mempool.SetLogger(log.TestingLogger())
return mempool
}
2017-08-09 22:09:04 -07:00
func ensureNoFire(t *testing.T, ch <-chan int, timeoutMS int) {
2017-07-13 12:03:19 -07:00
timer := time.NewTimer(time.Duration(timeoutMS) * time.Millisecond)
select {
case <-ch:
t.Fatal("Expected not to fire")
case <-timer.C:
}
}
2017-08-09 22:09:04 -07:00
func ensureFire(t *testing.T, ch <-chan int, timeoutMS int) {
2017-07-13 12:03:19 -07:00
timer := time.NewTimer(time.Duration(timeoutMS) * time.Millisecond)
select {
case <-ch:
case <-timer.C:
t.Fatal("Expected to fire")
}
}
2017-09-05 13:08:12 -07:00
func checkTxs(t *testing.T, mempool *Mempool, count int) types.Txs {
2017-07-13 12:03:19 -07:00
txs := make(types.Txs, count)
for i := 0; i < count; i++ {
txBytes := make([]byte, 20)
txs[i] = txBytes
rand.Read(txBytes)
err := mempool.CheckTx(txBytes, nil)
if err != nil {
t.Fatal("Error after CheckTx: %v", err)
}
}
return txs
}
func TestTxsAvailable(t *testing.T) {
app := dummy.NewDummyApplication()
cc := proxy.NewLocalClientCreator(app)
2017-09-05 13:08:12 -07:00
mempool := newMempoolWithApp(cc)
mempool.EnableTxsAvailable()
2017-07-13 12:03:19 -07:00
timeoutMS := 500
// with no txs, it shouldnt fire
ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
// send a bunch of txs, it should only fire once
2017-09-05 13:08:12 -07:00
txs := checkTxs(t, mempool, 100)
2017-07-13 12:03:19 -07:00
ensureFire(t, mempool.TxsAvailable(), timeoutMS)
ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
// call update with half the txs.
// it should fire once now for the new height
// since there are still txs left
committedTxs, txs := txs[:50], txs[50:]
mempool.Update(1, committedTxs)
ensureFire(t, mempool.TxsAvailable(), timeoutMS)
ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
// send a bunch more txs. we already fired for this height so it shouldnt fire again
2017-09-05 13:08:12 -07:00
moreTxs := checkTxs(t, mempool, 50)
2017-07-13 12:03:19 -07:00
ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
// now call update with all the txs. it should not fire as there are no txs left
committedTxs = append(txs, moreTxs...)
mempool.Update(2, committedTxs)
ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
// send a bunch more txs, it should only fire once
2017-09-05 13:08:12 -07:00
checkTxs(t, mempool, 100)
2017-07-13 12:03:19 -07:00
ensureFire(t, mempool.TxsAvailable(), timeoutMS)
ensureNoFire(t, mempool.TxsAvailable(), timeoutMS)
}
func TestSerialReap(t *testing.T) {
app := counter.NewCounterApplication(true)
app.SetOption("serial", "on")
cc := proxy.NewLocalClientCreator(app)
2017-09-05 13:08:12 -07:00
mempool := newMempoolWithApp(cc)
2017-01-12 12:53:32 -08:00
appConnCon, _ := cc.NewABCIClient()
2017-05-16 10:06:35 -07:00
appConnCon.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "consensus"))
if _, err := appConnCon.Start(); err != nil {
t.Fatalf("Error starting ABCI client: %v", err.Error())
}
2015-12-01 20:12:01 -08:00
2017-01-12 12:55:03 -08:00
deliverTxsRange := func(start, end int) {
// Deliver some txs.
2015-12-01 20:12:01 -08:00
for i := start; i < end; i++ {
// This will succeed
2016-01-25 14:34:08 -08:00
txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(i))
2016-02-08 00:48:58 -08:00
err := mempool.CheckTx(txBytes, nil)
2015-12-01 20:12:01 -08:00
if err != nil {
t.Fatal("Error after CheckTx: %v", err)
2015-12-01 20:12:01 -08:00
}
// This will fail because not serial (incrementing)
// However, error should still be nil.
// It just won't show up on Reap().
2016-02-08 00:48:58 -08:00
err = mempool.CheckTx(txBytes, nil)
2015-12-01 20:12:01 -08:00
if err != nil {
t.Fatal("Error after CheckTx: %v", err)
2015-12-01 20:12:01 -08:00
}
}
}
reapCheck := func(exp int) {
2016-04-26 19:17:13 -07:00
txs := mempool.Reap(-1)
2015-12-01 20:12:01 -08:00
if len(txs) != exp {
t.Fatalf("Expected to reap %v txs but got %v", exp, len(txs))
}
}
updateRange := func(start, end int) {
txs := make([]types.Tx, 0)
for i := start; i < end; i++ {
2016-01-25 14:34:08 -08:00
txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(i))
2015-12-01 20:12:01 -08:00
txs = append(txs, txBytes)
}
2016-02-14 17:00:33 -08:00
mempool.Update(0, txs)
2015-12-01 20:12:01 -08:00
}
commitRange := func(start, end int) {
2017-01-12 12:55:03 -08:00
// Deliver some txs.
2015-12-01 20:12:01 -08:00
for i := start; i < end; i++ {
2016-01-25 14:34:08 -08:00
txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(i))
2017-01-12 12:55:03 -08:00
res := appConnCon.DeliverTxSync(txBytes)
if !res.IsOK() {
2016-01-25 14:34:08 -08:00
t.Errorf("Error committing tx. Code:%v result:%X log:%v",
res.Code, res.Data, res.Log)
2015-12-01 20:12:01 -08:00
}
}
2016-10-10 14:05:50 -07:00
res := appConnCon.CommitSync()
2016-03-23 02:49:30 -07:00
if len(res.Data) != 8 {
t.Errorf("Error committing. Hash:%X log:%v", res.Data, res.Log)
2015-12-01 20:12:01 -08:00
}
}
//----------------------------------------
2017-01-12 12:55:03 -08:00
// Deliver some txs.
deliverTxsRange(0, 100)
2015-12-01 20:12:01 -08:00
// Reap the txs.
reapCheck(100)
// Reap again. We should get the same amount
reapCheck(100)
2017-01-12 12:55:03 -08:00
// Deliver 0 to 999, we should reap 900 new txs
2015-12-01 20:12:01 -08:00
// because 100 were already counted.
2017-01-12 12:55:03 -08:00
deliverTxsRange(0, 1000)
2015-12-01 20:12:01 -08:00
// Reap the txs.
reapCheck(1000)
// Reap again. We should get the same amount
reapCheck(1000)
// Commit from the conensus AppConn
2015-12-01 20:12:01 -08:00
commitRange(0, 500)
updateRange(0, 500)
// We should have 500 left.
reapCheck(500)
2017-01-12 12:55:03 -08:00
// Deliver 100 invalid txs and 100 valid txs
deliverTxsRange(900, 1100)
// We should have 600 now.
reapCheck(600)
2015-12-01 20:12:01 -08:00
}