github.com/Unheilbar/quorum@v1.0.0/qlight/client_cache.go (about) 1 package qlight 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/ethereum/go-ethereum/common" 8 "github.com/ethereum/go-ethereum/core/rawdb" 9 "github.com/ethereum/go-ethereum/ethdb" 10 "github.com/ethereum/go-ethereum/log" 11 "github.com/ethereum/go-ethereum/private" 12 "github.com/ethereum/go-ethereum/private/cache" 13 "github.com/ethereum/go-ethereum/private/engine/qlightptm" 14 gocache "github.com/patrickmn/go-cache" 15 ) 16 17 type clientCache struct { 18 txCache CacheWithEmpty 19 privateBlockCache *gocache.Cache 20 db ethdb.Database 21 } 22 23 func NewClientCache(db ethdb.Database) (PrivateClientCache, error) { 24 cachingTXManager, ok := private.P.(*qlightptm.CachingProxyTxManager) 25 if !ok { 26 return nil, fmt.Errorf("unable to initialize txCache") 27 } 28 return NewClientCacheWithEmpty(db, cachingTXManager, gocache.New(cache.DefaultExpiration, cache.CleanupInterval)) 29 } 30 31 func NewClientCacheWithEmpty(db ethdb.Database, cacheWithEmpty CacheWithEmpty, gocache *gocache.Cache) (PrivateClientCache, error) { 32 return &clientCache{ 33 txCache: cacheWithEmpty, 34 privateBlockCache: gocache, 35 db: db, 36 }, nil 37 } 38 39 func (c *clientCache) AddPrivateBlock(blockPrivateData BlockPrivateData) error { 40 for _, pvtTx := range blockPrivateData.PrivateTransactions { 41 if err := c.txCache.Cache(pvtTx.ToCachable()); err != nil { 42 return err 43 } 44 } 45 if !common.EmptyHash(blockPrivateData.PrivateStateRoot) { 46 return c.privateBlockCache.Add(blockPrivateData.BlockHash.ToBase64(), blockPrivateData.PrivateStateRoot.ToBase64(), gocache.DefaultExpiration) 47 } 48 return nil 49 } 50 51 func (c *clientCache) CheckAndAddEmptyEntry(hash common.EncryptedPayloadHash) { 52 c.txCache.CheckAndAddEmptyToCache(hash) 53 } 54 55 func (c *clientCache) ValidatePrivateStateRoot(blockHash common.Hash, publicStateRoot common.Hash) error { 56 dbPrivateStateRoot := rawdb.GetPrivateStateRoot(c.db, publicStateRoot) 57 58 cachePrivateStateRootStr, found := c.privateBlockCache.Get(blockHash.ToBase64()) 59 if !found { 60 // this means that we don't have private data for this block or that the server does not have the corresponding 61 // private state root (which can happen when caching is enabled on the server side) 62 return nil 63 } 64 cachePrivateStateRootB64, ok := cachePrivateStateRootStr.(string) 65 if !ok { 66 return fmt.Errorf("Invalid private block cache item") 67 } 68 cachePrivateStateRoot, err := common.Base64ToHash(cachePrivateStateRootB64) 69 if err != nil { 70 return fmt.Errorf("Invalid encoding for private state root: %s", cachePrivateStateRootB64) 71 } 72 if !bytes.Equal(cachePrivateStateRoot.Bytes(), dbPrivateStateRoot.Bytes()) { 73 log.Error("QLight - Private state root hash check failure for block", "hash", blockHash) 74 return fmt.Errorf("Private root hash missmatch for block %s", blockHash) 75 } 76 log.Info("QLight - Private state root hash check successful for block", "hash", blockHash) 77 return nil 78 }