github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/internal/state/tx_filter.go (about)

     1  package state
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	abci "github.com/ari-anchor/sei-tendermint/abci/types"
     8  	"github.com/ari-anchor/sei-tendermint/internal/mempool"
     9  	"github.com/ari-anchor/sei-tendermint/types"
    10  )
    11  
    12  func cachingStateFetcher(store Store) func() (State, error) {
    13  	const ttl = time.Second
    14  
    15  	var (
    16  		last  time.Time
    17  		mutex = &sync.Mutex{}
    18  		cache State
    19  		err   error
    20  	)
    21  
    22  	return func() (State, error) {
    23  		mutex.Lock()
    24  		defer mutex.Unlock()
    25  
    26  		if time.Since(last) < ttl && cache.ChainID != "" {
    27  			return cache, nil
    28  		}
    29  
    30  		cache, err = store.Load()
    31  		if err != nil {
    32  			return State{}, err
    33  		}
    34  		last = time.Now()
    35  
    36  		return cache, nil
    37  	}
    38  
    39  }
    40  
    41  // TxPreCheckFromStore returns a function to filter transactions before processing.
    42  // The function limits the size of a transaction to the block's maximum data size.
    43  func TxPreCheckFromStore(store Store) mempool.PreCheckFunc {
    44  	fetch := cachingStateFetcher(store)
    45  
    46  	return func(tx types.Tx) error {
    47  		state, err := fetch()
    48  		if err != nil {
    49  			return err
    50  		}
    51  
    52  		return TxPreCheckForState(state)(tx)
    53  	}
    54  }
    55  
    56  func TxPreCheckForState(state State) mempool.PreCheckFunc {
    57  	return func(tx types.Tx) error {
    58  		maxDataBytes := types.MaxDataBytesNoEvidence(
    59  			state.ConsensusParams.Block.MaxBytes,
    60  			state.Validators.Size(),
    61  		)
    62  		return mempool.PreCheckMaxBytes(maxDataBytes)(tx)
    63  	}
    64  
    65  }
    66  
    67  // TxPostCheckFromStore returns a function to filter transactions after processing.
    68  // The function limits the gas wanted by a transaction to the block's maximum total gas.
    69  func TxPostCheckFromStore(store Store) mempool.PostCheckFunc {
    70  	fetch := cachingStateFetcher(store)
    71  
    72  	return func(tx types.Tx, resp *abci.ResponseCheckTx) error {
    73  		state, err := fetch()
    74  		if err != nil {
    75  			return err
    76  		}
    77  		return mempool.PostCheckMaxGas(state.ConsensusParams.Block.MaxGas)(tx, resp)
    78  	}
    79  }
    80  
    81  func TxPostCheckForState(state State) mempool.PostCheckFunc {
    82  	return func(tx types.Tx, resp *abci.ResponseCheckTx) error {
    83  		return mempool.PostCheckMaxGas(state.ConsensusParams.Block.MaxGas)(tx, resp)
    84  	}
    85  }