mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-19 22:44:24 +00:00
mempool: Filter new txs if they have insufficient gas (#2385)
This also refactors the prior mempool to filter to be known as "precheck filter" and this new filter is called "postcheck filter" This PR also fixes a bug where the precheck filter previously didn't account for the amino overhead, which could a maliciously sized tx to halt blocks from getting any txs in them. * Move maxGas outside of function definition to avoid race condition * Type filter funcs and make public * Use helper method for post check * Remove superfluous Filter suffix * Move default pre/post checks into package * Fix broken references * Fix typos * Expand on examples for checks
This commit is contained in:
committed by
Alexander Simmerl
parent
f99e4010f2
commit
111e627037
+30
-11
@@ -7,6 +7,7 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/mempool"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
@@ -115,11 +116,16 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// Commit locks the mempool, runs the ABCI Commit message, and updates the mempool.
|
||||
// Commit locks the mempool, runs the ABCI Commit message, and updates the
|
||||
// mempool.
|
||||
// It returns the result of calling abci.Commit (the AppHash), and an error.
|
||||
// The Mempool must be locked during commit and update because state is typically reset on Commit and old txs must be replayed
|
||||
// against committed state before new txs are run in the mempool, lest they be invalid.
|
||||
func (blockExec *BlockExecutor) Commit(state State, block *types.Block) ([]byte, error) {
|
||||
// The Mempool must be locked during commit and update because state is
|
||||
// typically reset on Commit and old txs must be replayed against committed
|
||||
// state before new txs are run in the mempool, lest they be invalid.
|
||||
func (blockExec *BlockExecutor) Commit(
|
||||
state State,
|
||||
block *types.Block,
|
||||
) ([]byte, error) {
|
||||
blockExec.mempool.Lock()
|
||||
defer blockExec.mempool.Unlock()
|
||||
|
||||
@@ -134,22 +140,35 @@ func (blockExec *BlockExecutor) Commit(state State, block *types.Block) ([]byte,
|
||||
// Commit block, get hash back
|
||||
res, err := blockExec.proxyApp.CommitSync()
|
||||
if err != nil {
|
||||
blockExec.logger.Error("Client error during proxyAppConn.CommitSync", "err", err)
|
||||
blockExec.logger.Error(
|
||||
"Client error during proxyAppConn.CommitSync",
|
||||
"err", err,
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
// ResponseCommit has no error code - just data
|
||||
|
||||
blockExec.logger.Info("Committed state",
|
||||
blockExec.logger.Info(
|
||||
"Committed state",
|
||||
"height", block.Height,
|
||||
"txs", block.NumTxs,
|
||||
"appHash", fmt.Sprintf("%X", res.Data))
|
||||
"appHash", fmt.Sprintf("%X", res.Data),
|
||||
)
|
||||
|
||||
// Update mempool.
|
||||
if err := blockExec.mempool.Update(block.Height, block.Txs, TxFilter(state)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = blockExec.mempool.Update(
|
||||
block.Height,
|
||||
block.Txs,
|
||||
mempool.PreCheckAminoMaxBytes(
|
||||
types.MaxDataBytesUnknownEvidence(
|
||||
state.ConsensusParams.BlockSize.MaxBytes,
|
||||
state.Validators.Size(),
|
||||
),
|
||||
),
|
||||
mempool.PostCheckMaxGas(state.ConsensusParams.MaxGas),
|
||||
)
|
||||
|
||||
return res.Data, nil
|
||||
return res.Data, err
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
+21
-13
@@ -2,6 +2,7 @@ package state
|
||||
|
||||
import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/mempool"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -23,7 +24,7 @@ type Mempool interface {
|
||||
Size() int
|
||||
CheckTx(types.Tx, func(*abci.Response)) error
|
||||
ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs
|
||||
Update(height int64, txs types.Txs, filter func(types.Tx) bool) error
|
||||
Update(int64, types.Txs, mempool.PreCheckFunc, mempool.PostCheckFunc) error
|
||||
Flush()
|
||||
FlushAppConn() error
|
||||
|
||||
@@ -36,16 +37,23 @@ type MockMempool struct{}
|
||||
|
||||
var _ Mempool = MockMempool{}
|
||||
|
||||
func (MockMempool) Lock() {}
|
||||
func (MockMempool) Unlock() {}
|
||||
func (MockMempool) Size() int { return 0 }
|
||||
func (MockMempool) CheckTx(tx types.Tx, cb func(*abci.Response)) error { return nil }
|
||||
func (MockMempool) ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs { return types.Txs{} }
|
||||
func (MockMempool) Update(height int64, txs types.Txs, filter func(types.Tx) bool) error { return nil }
|
||||
func (MockMempool) Flush() {}
|
||||
func (MockMempool) FlushAppConn() error { return nil }
|
||||
func (MockMempool) TxsAvailable() <-chan struct{} { return make(chan struct{}) }
|
||||
func (MockMempool) EnableTxsAvailable() {}
|
||||
func (MockMempool) Lock() {}
|
||||
func (MockMempool) Unlock() {}
|
||||
func (MockMempool) Size() int { return 0 }
|
||||
func (MockMempool) CheckTx(_ types.Tx, _ func(*abci.Response)) error { return nil }
|
||||
func (MockMempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} }
|
||||
func (MockMempool) Update(
|
||||
_ int64,
|
||||
_ types.Txs,
|
||||
_ mempool.PreCheckFunc,
|
||||
_ mempool.PostCheckFunc,
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
func (MockMempool) Flush() {}
|
||||
func (MockMempool) FlushAppConn() error { return nil }
|
||||
func (MockMempool) TxsAvailable() <-chan struct{} { return make(chan struct{}) }
|
||||
func (MockMempool) EnableTxsAvailable() {}
|
||||
|
||||
//------------------------------------------------------
|
||||
// blockstore
|
||||
@@ -82,5 +90,5 @@ type EvidencePool interface {
|
||||
type MockEvidencePool struct{}
|
||||
|
||||
func (m MockEvidencePool) PendingEvidence(int64) []types.Evidence { return nil }
|
||||
func (m MockEvidencePool) AddEvidence(types.Evidence) error { return nil }
|
||||
func (m MockEvidencePool) Update(*types.Block, State) {}
|
||||
func (m MockEvidencePool) AddEvidence(types.Evidence) error { return nil }
|
||||
func (m MockEvidencePool) Update(*types.Block, State) {}
|
||||
|
||||
Reference in New Issue
Block a user