|
@ -7,14 +7,13 @@ import ( |
|
|
"sync/atomic" |
|
|
"sync/atomic" |
|
|
"time" |
|
|
"time" |
|
|
|
|
|
|
|
|
"github.com/spf13/viper" |
|
|
|
|
|
|
|
|
|
|
|
abci "github.com/tendermint/abci/types" |
|
|
abci "github.com/tendermint/abci/types" |
|
|
"github.com/tendermint/tendermint/proxy" |
|
|
|
|
|
"github.com/tendermint/tendermint/types" |
|
|
|
|
|
auto "github.com/tendermint/tmlibs/autofile" |
|
|
auto "github.com/tendermint/tmlibs/autofile" |
|
|
"github.com/tendermint/tmlibs/clist" |
|
|
"github.com/tendermint/tmlibs/clist" |
|
|
. "github.com/tendermint/tmlibs/common" |
|
|
|
|
|
|
|
|
cmn "github.com/tendermint/tmlibs/common" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/tendermint/tendermint/proxy" |
|
|
|
|
|
"github.com/tendermint/tendermint/types" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@ -48,7 +47,7 @@ TODO: Better handle abci client errors. (make it automatically handle connection |
|
|
const cacheSize = 100000 |
|
|
const cacheSize = 100000 |
|
|
|
|
|
|
|
|
type Mempool struct { |
|
|
type Mempool struct { |
|
|
config *viper.Viper |
|
|
|
|
|
|
|
|
config Config |
|
|
|
|
|
|
|
|
proxyMtx sync.Mutex |
|
|
proxyMtx sync.Mutex |
|
|
proxyAppConn proxy.AppConnMempool |
|
|
proxyAppConn proxy.AppConnMempool |
|
@ -67,7 +66,7 @@ type Mempool struct { |
|
|
wal *auto.AutoFile |
|
|
wal *auto.AutoFile |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func NewMempool(config *viper.Viper, proxyAppConn proxy.AppConnMempool) *Mempool { |
|
|
|
|
|
|
|
|
func NewMempool(config Config, proxyAppConn proxy.AppConnMempool) *Mempool { |
|
|
mempool := &Mempool{ |
|
|
mempool := &Mempool{ |
|
|
config: config, |
|
|
config: config, |
|
|
proxyAppConn: proxyAppConn, |
|
|
proxyAppConn: proxyAppConn, |
|
@ -86,17 +85,17 @@ func NewMempool(config *viper.Viper, proxyAppConn proxy.AppConnMempool) *Mempool |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (mem *Mempool) initWAL() { |
|
|
func (mem *Mempool) initWAL() { |
|
|
walDir := mem.config.GetString("mempool_wal_dir") |
|
|
|
|
|
|
|
|
walDir := mem.config.WalDir |
|
|
if walDir != "" { |
|
|
if walDir != "" { |
|
|
err := EnsureDir(walDir, 0700) |
|
|
|
|
|
|
|
|
err := cmn.EnsureDir(walDir, 0700) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
log.Error("Error ensuring Mempool wal dir", "error", err) |
|
|
log.Error("Error ensuring Mempool wal dir", "error", err) |
|
|
PanicSanity(err) |
|
|
|
|
|
|
|
|
cmn.PanicSanity(err) |
|
|
} |
|
|
} |
|
|
af, err := auto.OpenAutoFile(walDir + "/wal") |
|
|
af, err := auto.OpenAutoFile(walDir + "/wal") |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
log.Error("Error opening Mempool wal file", "error", err) |
|
|
log.Error("Error opening Mempool wal file", "error", err) |
|
|
PanicSanity(err) |
|
|
|
|
|
|
|
|
cmn.PanicSanity(err) |
|
|
} |
|
|
} |
|
|
mem.wal = af |
|
|
mem.wal = af |
|
|
} |
|
|
} |
|
@ -220,7 +219,7 @@ func (mem *Mempool) resCbRecheck(req *abci.Request, res *abci.Response) { |
|
|
case *abci.Response_CheckTx: |
|
|
case *abci.Response_CheckTx: |
|
|
memTx := mem.recheckCursor.Value.(*mempoolTx) |
|
|
memTx := mem.recheckCursor.Value.(*mempoolTx) |
|
|
if !bytes.Equal(req.GetCheckTx().Tx, memTx.tx) { |
|
|
if !bytes.Equal(req.GetCheckTx().Tx, memTx.tx) { |
|
|
PanicSanity(Fmt("Unexpected tx response from proxy during recheck\n"+ |
|
|
|
|
|
|
|
|
cmn.PanicSanity(cmn.Fmt("Unexpected tx response from proxy during recheck\n"+ |
|
|
"Expected %X, got %X", r.CheckTx.Data, memTx.tx)) |
|
|
"Expected %X, got %X", r.CheckTx.Data, memTx.tx)) |
|
|
} |
|
|
} |
|
|
if r.CheckTx.Code == abci.CodeType_OK { |
|
|
if r.CheckTx.Code == abci.CodeType_OK { |
|
@ -270,7 +269,7 @@ func (mem *Mempool) collectTxs(maxTxs int) types.Txs { |
|
|
} else if maxTxs < 0 { |
|
|
} else if maxTxs < 0 { |
|
|
maxTxs = mem.txs.Len() |
|
|
maxTxs = mem.txs.Len() |
|
|
} |
|
|
} |
|
|
txs := make([]types.Tx, 0, MinInt(mem.txs.Len(), maxTxs)) |
|
|
|
|
|
|
|
|
txs := make([]types.Tx, 0, cmn.MinInt(mem.txs.Len(), maxTxs)) |
|
|
for e := mem.txs.Front(); e != nil && len(txs) < maxTxs; e = e.Next() { |
|
|
for e := mem.txs.Front(); e != nil && len(txs) < maxTxs; e = e.Next() { |
|
|
memTx := e.Value.(*mempoolTx) |
|
|
memTx := e.Value.(*mempoolTx) |
|
|
txs = append(txs, memTx.tx) |
|
|
txs = append(txs, memTx.tx) |
|
@ -299,8 +298,7 @@ func (mem *Mempool) Update(height int, txs types.Txs) { |
|
|
// Recheck mempool txs if any txs were committed in the block
|
|
|
// Recheck mempool txs if any txs were committed in the block
|
|
|
// NOTE/XXX: in some apps a tx could be invalidated due to EndBlock,
|
|
|
// NOTE/XXX: in some apps a tx could be invalidated due to EndBlock,
|
|
|
// so we really still do need to recheck, but this is for debugging
|
|
|
// so we really still do need to recheck, but this is for debugging
|
|
|
if mem.config.GetBool("mempool_recheck") && |
|
|
|
|
|
(mem.config.GetBool("mempool_recheck_empty") || len(txs) > 0) { |
|
|
|
|
|
|
|
|
if mem.config.Recheck && (mem.config.RecheckEmpty || len(txs) > 0) { |
|
|
log.Info("Recheck txs", "numtxs", len(goodTxs)) |
|
|
log.Info("Recheck txs", "numtxs", len(goodTxs)) |
|
|
mem.recheckTxs(goodTxs) |
|
|
mem.recheckTxs(goodTxs) |
|
|
// At this point, mem.txs are being rechecked.
|
|
|
// At this point, mem.txs are being rechecked.
|
|
|