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 }