github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/rpc/backend/cache_lru.go (about)

     1  package backend
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/ethereum/go-ethereum/common"
     7  	"github.com/fibonacci-chain/fbc/x/evm/watcher"
     8  	lru "github.com/hashicorp/golang-lru"
     9  	"github.com/spf13/viper"
    10  )
    11  
    12  var ErrLruNotInitialized = errors.New("lru has not been Initialized")
    13  var ErrLruDataNotFound = errors.New("lru : not found")
    14  var ErrLruDataWrongType = errors.New("lru : wrong type")
    15  
    16  const (
    17  	FlagApiBackendBlockLruCache = "rpc-block-cache"
    18  	FlagApiBackendTxLruCache    = "rpc-tx-cache"
    19  )
    20  
    21  type LruCache struct {
    22  	lruTx              *lru.Cache
    23  	lruBlock           *lru.Cache
    24  	lruBlockInfo       *lru.Cache
    25  	lruBlockWithFullTx *lru.Cache
    26  }
    27  
    28  func NewLruCache() *LruCache {
    29  	blockLruSize := viper.GetInt(FlagApiBackendBlockLruCache)
    30  	txLruSize := viper.GetInt(FlagApiBackendTxLruCache)
    31  	//init lru cache for tx
    32  	lruTx, err := lru.New(txLruSize)
    33  	if err != nil {
    34  		panic(errors.New("Failed to init LRU for Tx, err :" + err.Error()))
    35  	}
    36  	//init lru cache for block
    37  	lruBlock, err := lru.New(blockLruSize)
    38  	if err != nil {
    39  		panic(errors.New("Failed to init LRU for Block, err :" + err.Error()))
    40  	}
    41  	//init lru cache for blockinfo
    42  	lruBlockInfo, err := lru.New(blockLruSize)
    43  	if err != nil {
    44  		panic(errors.New("Failed to init LRU for Block, err :" + err.Error()))
    45  	}
    46  	//init lru cache for blockWithFullTx
    47  	lruBlockWithFullTx, err := lru.New(blockLruSize)
    48  	if err != nil {
    49  		panic(errors.New("Failed to init LRU for Block, err :" + err.Error()))
    50  	}
    51  	return &LruCache{
    52  		lruTx:              lruTx,
    53  		lruBlock:           lruBlock,
    54  		lruBlockInfo:       lruBlockInfo,
    55  		lruBlockWithFullTx: lruBlockWithFullTx,
    56  	}
    57  }
    58  
    59  func (lc *LruCache) GetBlockByNumber(number uint64, fullTx bool) (*watcher.Block, error) {
    60  	hash, err := lc.GetBlockHash(number)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	return lc.GetBlockByHash(hash, fullTx)
    65  }
    66  func (lc *LruCache) GetBlockByHash(hash common.Hash, fullTx bool) (*watcher.Block, error) {
    67  	var data interface{}
    68  	var ok bool
    69  	if fullTx {
    70  		data, ok = lc.lruBlockWithFullTx.Get(hash)
    71  	} else {
    72  		data, ok = lc.lruBlock.Get(hash)
    73  	}
    74  	if !ok {
    75  		return nil, ErrLruDataNotFound
    76  	}
    77  	res, ok := data.(*watcher.Block)
    78  	if !ok {
    79  		return nil, ErrLruDataWrongType
    80  	}
    81  	return res, nil
    82  }
    83  func (lc *LruCache) AddOrUpdateBlock(hash common.Hash, block *watcher.Block, fullTx bool) {
    84  	if fullTx {
    85  		lc.lruBlockWithFullTx.PeekOrAdd(hash, block)
    86  	} else {
    87  		lc.lruBlock.PeekOrAdd(hash, block)
    88  	}
    89  	lc.AddOrUpdateBlockHash(uint64(block.Number), hash)
    90  	if block.Transactions != nil && fullTx {
    91  		txs, ok := block.Transactions.([]*watcher.Transaction)
    92  		if ok {
    93  			for _, tx := range txs {
    94  				lc.AddOrUpdateTransaction(tx.Hash, tx)
    95  			}
    96  		}
    97  	}
    98  }
    99  func (lc *LruCache) GetTransaction(hash common.Hash) (*watcher.Transaction, error) {
   100  	data, ok := lc.lruTx.Get(hash)
   101  	if !ok {
   102  		return nil, ErrLruDataNotFound
   103  	}
   104  	tx, ok := data.(*watcher.Transaction)
   105  	if !ok {
   106  		return nil, ErrLruDataWrongType
   107  	}
   108  	return tx, nil
   109  }
   110  func (lc *LruCache) AddOrUpdateTransaction(hash common.Hash, tx *watcher.Transaction) {
   111  	lc.lruTx.PeekOrAdd(hash, tx)
   112  }
   113  func (lc *LruCache) GetBlockHash(number uint64) (common.Hash, error) {
   114  	data, ok := lc.lruBlockInfo.Get(number)
   115  	if !ok {
   116  		return common.Hash{}, ErrLruDataNotFound
   117  	}
   118  	dataHash, ok := data.(common.Hash)
   119  	if !ok {
   120  		return common.Hash{}, ErrLruDataWrongType
   121  	}
   122  	return dataHash, nil
   123  }
   124  func (lc *LruCache) AddOrUpdateBlockHash(number uint64, hash common.Hash) {
   125  	lc.lruBlockInfo.PeekOrAdd(number, hash)
   126  }