@ -3,6 +3,7 @@ package v0
import (
import (
"bytes"
"bytes"
"context"
"context"
"errors"
"fmt"
"fmt"
"sync"
"sync"
"sync/atomic"
"sync/atomic"
@ -240,7 +241,7 @@ func (mem *CListMempool) CheckTx(
// Note it's possible a tx is still in the cache but no longer in the mempool
// Note it's possible a tx is still in the cache but no longer in the mempool
// (eg. after committing a block, txs are removed from mempool but not cache),
// (eg. after committing a block, txs are removed from mempool but not cache),
// so we only record the sender for txs still in the mempool.
// so we only record the sender for txs still in the mempool.
if e , ok := mem . txsMap . Load ( mempool . TxKey ( tx ) ) ; ok {
if e , ok := mem . txsMap . Load ( tx . Key ( ) ) ; ok {
memTx := e . ( * clist . CElement ) . Value . ( * mempoolTx )
memTx := e . ( * clist . CElement ) . Value . ( * mempoolTx )
_ , loaded := memTx . senders . LoadOrStore ( txInfo . SenderID , true )
_ , loaded := memTx . senders . LoadOrStore ( txInfo . SenderID , true )
// TODO: consider punishing peer for dups,
// TODO: consider punishing peer for dups,
@ -327,7 +328,7 @@ func (mem *CListMempool) reqResCb(
// - resCbFirstTime (lock not held) if tx is valid
// - resCbFirstTime (lock not held) if tx is valid
func ( mem * CListMempool ) addTx ( memTx * mempoolTx ) {
func ( mem * CListMempool ) addTx ( memTx * mempoolTx ) {
e := mem . txs . PushBack ( memTx )
e := mem . txs . PushBack ( memTx )
mem . txsMap . Store ( mempool . TxKey ( memTx . tx ) , e )
mem . txsMap . Store ( memTx . tx . Key ( ) , e )
atomic . AddInt64 ( & mem . txsBytes , int64 ( len ( memTx . tx ) ) )
atomic . AddInt64 ( & mem . txsBytes , int64 ( len ( memTx . tx ) ) )
mem . metrics . TxSizeBytes . Observe ( float64 ( len ( memTx . tx ) ) )
mem . metrics . TxSizeBytes . Observe ( float64 ( len ( memTx . tx ) ) )
}
}
@ -338,7 +339,7 @@ func (mem *CListMempool) addTx(memTx *mempoolTx) {
func ( mem * CListMempool ) removeTx ( tx types . Tx , elem * clist . CElement , removeFromCache bool ) {
func ( mem * CListMempool ) removeTx ( tx types . Tx , elem * clist . CElement , removeFromCache bool ) {
mem . txs . Remove ( elem )
mem . txs . Remove ( elem )
elem . DetachPrev ( )
elem . DetachPrev ( )
mem . txsMap . Delete ( mempool . TxKey ( tx ) )
mem . txsMap . Delete ( tx . Key ( ) )
atomic . AddInt64 ( & mem . txsBytes , int64 ( - len ( tx ) ) )
atomic . AddInt64 ( & mem . txsBytes , int64 ( - len ( tx ) ) )
if removeFromCache {
if removeFromCache {
@ -347,13 +348,16 @@ func (mem *CListMempool) removeTx(tx types.Tx, elem *clist.CElement, removeFromC
}
}
// RemoveTxByKey removes a transaction from the mempool by its TxKey index.
// RemoveTxByKey removes a transaction from the mempool by its TxKey index.
func ( mem * CListMempool ) RemoveTxByKey ( txKey [ mempool . TxKeySize ] byte , removeFromCache bool ) {
func ( mem * CListMempool ) RemoveTxByKey ( txKey types . TxKey ) error {
if e , ok := mem . txsMap . Load ( txKey ) ; ok {
if e , ok := mem . txsMap . Load ( txKey ) ; ok {
memTx := e . ( * clist . CElement ) . Value . ( * mempoolTx )
memTx := e . ( * clist . CElement ) . Value . ( * mempoolTx )
if memTx != nil {
if memTx != nil {
mem . removeTx ( memTx . tx , e . ( * clist . CElement ) , removeFromCache )
mem . removeTx ( memTx . tx , e . ( * clist . CElement ) , false )
return nil
}
}
return errors . New ( "transaction not found" )
}
}
return errors . New ( "invalid transaction found" )
}
}
func ( mem * CListMempool ) isFull ( txSize int ) error {
func ( mem * CListMempool ) isFull ( txSize int ) error {
@ -409,7 +413,7 @@ func (mem *CListMempool) resCbFirstTime(
mem . addTx ( memTx )
mem . addTx ( memTx )
mem . logger . Debug (
mem . logger . Debug (
"added good transaction" ,
"added good transaction" ,
"tx" , mempool . TxHashFromBytes ( tx ) ,
"tx" , types . Tx ( tx ) . Hash ( ) ,
"res" , r ,
"res" , r ,
"height" , memTx . height ,
"height" , memTx . height ,
"total" , mem . Size ( ) ,
"total" , mem . Size ( ) ,
@ -419,7 +423,7 @@ func (mem *CListMempool) resCbFirstTime(
// ignore bad transaction
// ignore bad transaction
mem . logger . Debug (
mem . logger . Debug (
"rejected bad transaction" ,
"rejected bad transaction" ,
"tx" , mempool . TxHashFromBytes ( tx ) ,
"tx" , types . Tx ( tx ) . Hash ( ) ,
"peerID" , peerP2PID ,
"peerID" , peerP2PID ,
"res" , r ,
"res" , r ,
"err" , postCheckErr ,
"err" , postCheckErr ,
@ -460,7 +464,7 @@ func (mem *CListMempool) resCbRecheck(req *abci.Request, res *abci.Response) {
// Good, nothing to do.
// Good, nothing to do.
} else {
} else {
// Tx became invalidated due to newly committed block.
// Tx became invalidated due to newly committed block.
mem . logger . Debug ( "tx is no longer valid" , "tx" , mempool . TxHashFromBytes ( tx ) , "res" , r , "err" , postCheckErr )
mem . logger . Debug ( "tx is no longer valid" , "tx" , types . Tx ( tx ) . Hash ( ) , "res" , r , "err" , postCheckErr )
// NOTE: we remove tx from the cache because it might be good later
// NOTE: we remove tx from the cache because it might be good later
mem . removeTx ( tx , mem . recheckCursor , ! mem . config . KeepInvalidTxsInCache )
mem . removeTx ( tx , mem . recheckCursor , ! mem . config . KeepInvalidTxsInCache )
}
}
@ -598,7 +602,7 @@ func (mem *CListMempool) Update(
// Mempool after:
// Mempool after:
// 100
// 100
// https://github.com/tendermint/tendermint/issues/3322.
// https://github.com/tendermint/tendermint/issues/3322.
if e , ok := mem . txsMap . Load ( mempool . TxKey ( tx ) ) ; ok {
if e , ok := mem . txsMap . Load ( tx . Key ( ) ) ; ok {
mem . removeTx ( tx , e . ( * clist . CElement ) , false )
mem . removeTx ( tx , e . ( * clist . CElement ) , false )
}
}
}
}