github.com/klaytn/klaytn@v1.12.1/storage/statedb/cache.go (about)

     1  // Copyright 2020 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package statedb
    18  
    19  import (
    20  	"errors"
    21  	"strings"
    22  	"time"
    23  
    24  	"github.com/go-redis/redis/v7"
    25  )
    26  
    27  type TrieNodeCacheType string
    28  
    29  // TrieNodeCacheConfig contains configuration values of all TrieNodeCache.
    30  type TrieNodeCacheConfig struct {
    31  	CacheType                 TrieNodeCacheType
    32  	NumFetcherPrefetchWorker  int           // Number of workers used to prefetch a block when fetcher works
    33  	UseSnapshotForPrefetch    bool          // Enable snapshot functionality while prefetching
    34  	LocalCacheSizeMiB         int           // Memory allowance (MiB) to use for caching trie nodes in fast cache
    35  	FastCacheFileDir          string        // Directory where the persistent fastcache data is stored
    36  	FastCacheSavePeriod       time.Duration // Period of saving in memory trie cache to file if fastcache is used
    37  	RedisEndpoints            []string      // Endpoints of redis cache
    38  	RedisClusterEnable        bool          // Enable cluster-enabled mode of redis cache
    39  	RedisPublishBlockEnable   bool          // Enable publishing every inserted block to the redis server
    40  	RedisSubscribeBlockEnable bool          // Enable subscribing blocks from the redis server
    41  }
    42  
    43  func (c *TrieNodeCacheConfig) DumpPeriodically() bool {
    44  	if c.CacheType == CacheTypeLocal && c.LocalCacheSizeMiB > 0 && c.FastCacheSavePeriod > 0 {
    45  		return true
    46  	}
    47  	return false
    48  }
    49  
    50  //go:generate mockgen -destination=storage/statedb/mocks/trie_node_cache_mock.go github.com/klaytn/klaytn/storage/statedb TrieNodeCache
    51  // TrieNodeCache interface the cache of stateDB
    52  type TrieNodeCache interface {
    53  	Set(k, v []byte)
    54  	Get(k []byte) []byte
    55  	Has(k []byte) ([]byte, bool)
    56  	UpdateStats() interface{}
    57  	SaveToFile(filePath string, concurrency int) error
    58  	Close() error
    59  }
    60  
    61  type BlockPubSub interface {
    62  	PublishBlock(msg string) error
    63  	SubscribeBlockCh() <-chan *redis.Message
    64  	UnsubscribeBlock() error
    65  }
    66  
    67  const (
    68  	// Available trie node cache types
    69  	CacheTypeLocal  TrieNodeCacheType = "LocalCache"
    70  	CacheTypeRedis                    = "RemoteCache"
    71  	CacheTypeHybrid                   = "HybridCache"
    72  )
    73  
    74  var (
    75  	errNotSupportedCacheType  = errors.New("not supported stateDB TrieNodeCache type")
    76  	errNilTrieNodeCacheConfig = errors.New("TrieNodeCacheConfig is nil")
    77  )
    78  
    79  func (cacheType TrieNodeCacheType) ToValid() TrieNodeCacheType {
    80  	validTrieNodeCacheTypes := []TrieNodeCacheType{CacheTypeLocal, CacheTypeRedis, CacheTypeHybrid}
    81  	for _, validType := range validTrieNodeCacheTypes {
    82  		if strings.ToLower(string(cacheType)) == strings.ToLower(string(validType)) {
    83  			return validType
    84  		}
    85  	}
    86  	logger.Warn("Invalid trie node cache type", "inputType", cacheType, "validTypes", validTrieNodeCacheTypes)
    87  	return ""
    88  }
    89  
    90  // NewTrieNodeCache creates one type of any supported trie node caches.
    91  // NOTE: It returns (nil, nil) when the cache type is CacheTypeLocal and its size is set to zero.
    92  func NewTrieNodeCache(config *TrieNodeCacheConfig) (TrieNodeCache, error) {
    93  	if config == nil {
    94  		return nil, errNilTrieNodeCacheConfig
    95  	}
    96  	switch config.CacheType {
    97  	case CacheTypeLocal:
    98  		return newFastCache(config), nil
    99  	case CacheTypeRedis:
   100  		return newRedisCache(config)
   101  	case CacheTypeHybrid:
   102  		logger.Info("Set hybrid trie node cache using both of localCache (fastCache) and redisCache")
   103  		return newHybridCache(config)
   104  	default:
   105  	}
   106  	logger.Error("Invalid trie node cache type", "cacheType", config.CacheType)
   107  	return nil, errNotSupportedCacheType
   108  }
   109  
   110  func GetEmptyTrieNodeCacheConfig() *TrieNodeCacheConfig {
   111  	return &TrieNodeCacheConfig{
   112  		CacheType:          CacheTypeLocal,
   113  		LocalCacheSizeMiB:  0,
   114  		FastCacheFileDir:   "",
   115  		RedisEndpoints:     nil,
   116  		RedisClusterEnable: false,
   117  	}
   118  }