diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 9b8fc1cf0..4e83c2dbb 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -19,3 +19,5 @@ ### IMPROVEMENTS: ### BUG FIXES: +- [mempool] \#3699 Revert the change where we only remove valid transactions + from the mempool once a block is committed. diff --git a/mempool/clist_mempool.go b/mempool/clist_mempool.go index c6ff475aa..0d1f3c5b1 100644 --- a/mempool/clist_mempool.go +++ b/mempool/clist_mempool.go @@ -538,24 +538,23 @@ func (mem *CListMempool) Update( if deliverTxResponses[i].Code == abci.CodeTypeOK { // Add valid committed tx to the cache (if missing). _ = mem.cache.Push(tx) - - // Remove valid committed tx from the mempool. - if e, ok := mem.txsMap.Load(txKey(tx)); ok { - mem.removeTx(tx, e.(*clist.CElement), false) - } } else { // Allow invalid transactions to be resubmitted. mem.cache.Remove(tx) + } - // Don't remove invalid tx from the mempool. - // Otherwise evil proposer can drop valid txs. - // Example: - // 100 -> 101 -> 102 - // Block, proposed by evil proposer: - // 101 -> 102 - // Mempool (if you remove txs): - // 100 - // https://github.com/tendermint/tendermint/issues/3322. + // Remove committed tx from the mempool. + // + // Note an evil proposer can drop valid txs! + // Mempool before: + // 100 -> 101 -> 102 + // Block, proposed by an evil proposer: + // 101 -> 102 + // Mempool after: + // 100 + // https://github.com/tendermint/tendermint/issues/3322. + if e, ok := mem.txsMap.Load(txKey(tx)); ok { + mem.removeTx(tx, e.(*clist.CElement), false) } } diff --git a/mempool/clist_mempool_test.go b/mempool/clist_mempool_test.go index 3eb4990b6..bf2c61dd7 100644 --- a/mempool/clist_mempool_test.go +++ b/mempool/clist_mempool_test.go @@ -200,12 +200,15 @@ func TestMempoolUpdate(t *testing.T) { assert.Zero(t, mempool.Size()) } - // 3. Removes invalid transactions from the cache, but leaves them in the mempool (if present) + // 3. Removes invalid transactions from the cache and the mempool (if present) { err := mempool.CheckTx([]byte{0x03}, nil) require.NoError(t, err) mempool.Update(1, []types.Tx{[]byte{0x03}}, abciResponses(1, 1), nil, nil) - assert.Equal(t, 1, mempool.Size()) + assert.Zero(t, mempool.Size()) + + err = mempool.CheckTx([]byte{0x03}, nil) + assert.NoError(t, err) } }