123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package qlight
- import (
- "bytes"
- "fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/private"
- "github.com/ethereum/go-ethereum/private/cache"
- "github.com/ethereum/go-ethereum/private/engine/qlightptm"
- gocache "github.com/patrickmn/go-cache"
- )
- type clientCache struct {
- txCache CacheWithEmpty
- privateBlockCache *gocache.Cache
- db ethdb.Database
- }
- func NewClientCache(db ethdb.Database) (PrivateClientCache, error) {
- cachingTXManager, ok := private.P.(*qlightptm.CachingProxyTxManager)
- if !ok {
- return nil, fmt.Errorf("unable to initialize txCache")
- }
- return NewClientCacheWithEmpty(db, cachingTXManager, gocache.New(cache.DefaultExpiration, cache.CleanupInterval))
- }
- func NewClientCacheWithEmpty(db ethdb.Database, cacheWithEmpty CacheWithEmpty, gocache *gocache.Cache) (PrivateClientCache, error) {
- return &clientCache{
- txCache: cacheWithEmpty,
- privateBlockCache: gocache,
- db: db,
- }, nil
- }
- func (c *clientCache) AddPrivateBlock(blockPrivateData BlockPrivateData) error {
- for _, pvtTx := range blockPrivateData.PrivateTransactions {
- if err := c.txCache.Cache(pvtTx.ToCachable()); err != nil {
- return err
- }
- }
- if !common.EmptyHash(blockPrivateData.PrivateStateRoot) {
- return c.privateBlockCache.Add(blockPrivateData.BlockHash.ToBase64(), blockPrivateData.PrivateStateRoot.ToBase64(), gocache.DefaultExpiration)
- }
- return nil
- }
- func (c *clientCache) CheckAndAddEmptyEntry(hash common.EncryptedPayloadHash) {
- c.txCache.CheckAndAddEmptyToCache(hash)
- }
- func (c *clientCache) ValidatePrivateStateRoot(blockHash common.Hash, publicStateRoot common.Hash) error {
- dbPrivateStateRoot := rawdb.GetPrivateStateRoot(c.db, publicStateRoot)
- cachePrivateStateRootStr, found := c.privateBlockCache.Get(blockHash.ToBase64())
- if !found {
- // this means that we don't have private data for this block or that the server does not have the corresponding
- // private state root (which can happen when caching is enabled on the server side)
- return nil
- }
- cachePrivateStateRootB64, ok := cachePrivateStateRootStr.(string)
- if !ok {
- return fmt.Errorf("Invalid private block cache item")
- }
- cachePrivateStateRoot, err := common.Base64ToHash(cachePrivateStateRootB64)
- if err != nil {
- return fmt.Errorf("Invalid encoding for private state root: %s", cachePrivateStateRootB64)
- }
- if !bytes.Equal(cachePrivateStateRoot.Bytes(), dbPrivateStateRoot.Bytes()) {
- log.Error("QLight - Private state root hash check failure for block", "hash", blockHash)
- return fmt.Errorf("Private root hash missmatch for block %s", blockHash)
- }
- log.Info("QLight - Private state root hash check successful for block", "hash", blockHash)
- return nil
- }
|