diff --git a/go.mod b/go.mod index 9987c10d67..a82266e6a3 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,13 @@ replace github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220224 require ( github.com/allegro/bigcache/v3 v3.1.0 github.com/andybalholm/brotli v1.0.5 + github.com/dgraph-io/ristretto v0.1.1 github.com/docker/docker v1.6.2 github.com/docker/go-connections v0.4.0 github.com/edgelesssys/ego v1.1.0 - github.com/eko/gocache/lib/v4 v4.1.2 - github.com/eko/gocache/store/bigcache/v4 v4.1.2 + github.com/eko/gocache/lib/v4 v4.1.5 + github.com/eko/gocache/store/bigcache/v4 v4.2.1 + github.com/eko/gocache/store/ristretto/v4 v4.2.1 github.com/ethereum/go-ethereum v1.12.2 github.com/gin-contrib/cors v1.4.0 github.com/gin-gonic/gin v1.9.1 @@ -65,6 +67,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.3.1 // indirect github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -82,6 +85,7 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.3.0 // indirect + github.com/golang/glog v1.0.0 // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect diff --git a/go.sum b/go.sum index a867591d1b..1930bf71df 100644 --- a/go.sum +++ b/go.sum @@ -129,7 +129,10 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etly github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -140,6 +143,7 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= @@ -148,10 +152,12 @@ github.com/edgelesssys/ego v1.1.0 h1:UcDiGGJ8PF8YStlticxi2hMgPqRTtP42FzaGaAxm9Ys github.com/edgelesssys/ego v1.1.0/go.mod h1:ex4cDvgi0l6wxDm5xBaQzJqi547FMPDsxv+3ERLJfLI= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/eko/gocache/lib/v4 v4.1.2 h1:cX54GhJJsfc5jvCEaPW8595h9Pq6bbNfkv0o/669Tw4= -github.com/eko/gocache/lib/v4 v4.1.2/go.mod h1:FqyrANKct257VFHVVs11m6V2syGobOmHycQCyRSMwu0= -github.com/eko/gocache/store/bigcache/v4 v4.1.2 h1:8uMDpgxTG7BvyLHBFqL3Ao809bVrXfrWqo7v6ALiwTw= -github.com/eko/gocache/store/bigcache/v4 v4.1.2/go.mod h1:Lut5Sk/yI835w02tmwx4ecezYQo445L5sdICsk1zgho= +github.com/eko/gocache/lib/v4 v4.1.5 h1:CeMQmdIzwBKKLRjk3FCDXzNFsQTyqJ01JLI7Ib0C9r8= +github.com/eko/gocache/lib/v4 v4.1.5/go.mod h1:XaNfCwW8KYW1bRZ/KoHA1TugnnkMz0/gT51NDIu7LSY= +github.com/eko/gocache/store/bigcache/v4 v4.2.1 h1:xf9R5HZqmrfT4+NzlJPQJQUWftfWW06FHbjz4IEjE08= +github.com/eko/gocache/store/bigcache/v4 v4.2.1/go.mod h1:Q9+hxUE+XUVGSRGP1tqW8sPHcZ50PfyBVh9VKh0OjrA= +github.com/eko/gocache/store/ristretto/v4 v4.2.1 h1:xB5E1LP1gh8yUV1G3KVRSL4T0OTnxp4OixuTljn2848= +github.com/eko/gocache/store/ristretto/v4 v4.2.1/go.mod h1:KyshDyWQqfSVrg2rH06fFQZTj6vG2fxlY7oAW9oxNHY= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -245,6 +251,8 @@ github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzq github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -799,6 +807,7 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/go/common/cache_util.go b/go/common/cache_util.go new file mode 100644 index 0000000000..6a502c4d2d --- /dev/null +++ b/go/common/cache_util.go @@ -0,0 +1,31 @@ +package common + +import ( + "context" + + "github.com/eko/gocache/lib/v4/cache" + gethlog "github.com/ethereum/go-ethereum/log" + "github.com/ten-protocol/go-ten/go/common/log" +) + +func GetCachedValue[V any](cache *cache.Cache[V], logger gethlog.Logger, key any, onFailed func(any) (V, error)) (V, error) { + value, err := cache.Get(context.Background(), key) + if err != nil { + // todo metrics for cache misses + b, err := onFailed(key) + if err != nil { + return b, err + } + CacheValue(cache, logger, key, b) + return b, err + } + + return value, err +} + +func CacheValue[V any](cache *cache.Cache[V], logger gethlog.Logger, key any, v V) { + err := cache.Set(context.Background(), key, v) + if err != nil { + logger.Error("Could not store value in cache", log.ErrKey, err) + } +} diff --git a/go/common/gethencoding/geth_encoding.go b/go/common/gethencoding/geth_encoding.go index 3577ea6c70..51e132d3aa 100644 --- a/go/common/gethencoding/geth_encoding.go +++ b/go/common/gethencoding/geth_encoding.go @@ -1,7 +1,6 @@ package gethencoding import ( - "context" "encoding/json" "fmt" "math/big" @@ -10,11 +9,10 @@ import ( "time" "unsafe" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/allegro/bigcache/v3" + "github.com/dgraph-io/ristretto" "github.com/eko/gocache/lib/v4/cache" - bigcache_store "github.com/eko/gocache/store/bigcache/v4" + ristretto_store "github.com/eko/gocache/store/ristretto/v4" + gethlog "github.com/ethereum/go-ethereum/log" "github.com/ten-protocol/go-ten/go/common/log" "github.com/ten-protocol/go-ten/go/enclave/storage" @@ -52,7 +50,7 @@ type EncodingService interface { } type gethEncodingServiceImpl struct { - convertedCache *cache.Cache[[]byte] + convertedCache *cache.Cache[*types.Header] // small converted cache storage storage.Storage @@ -61,19 +59,18 @@ type gethEncodingServiceImpl struct { func NewGethEncodingService(storage storage.Storage, logger gethlog.Logger) EncodingService { // todo (tudor) figure out the context and the config - cfg := bigcache.DefaultConfig(2 * time.Minute) - cfg.Shards = 512 - // 1GB cache. Max value in a shard is 2MB. No batch or block should be larger than that - cfg.HardMaxCacheSize = cfg.Shards * 4 - bigcacheClient, err := bigcache.New(context.Background(), cfg) + ristrettoCache, err := ristretto.NewCache(&ristretto.Config{ + NumCounters: 1000, // number of keys to track frequency of 100. + MaxCost: 1 << 28, // maximum cost of cache (256MB). + BufferItems: 64, // number of keys per Get buffer. + }) if err != nil { - logger.Crit("Could not initialise bigcache", log.ErrKey, err) + panic(err) } - - bigcacheStore := bigcache_store.NewBigcache(bigcacheClient) + ristrettoStore := ristretto_store.NewRistretto(ristrettoCache) return &gethEncodingServiceImpl{ - convertedCache: cache.New[[]byte](bigcacheStore), + convertedCache: cache.New[*types.Header](ristrettoStore), storage: storage, logger: logger, } @@ -275,75 +272,54 @@ func ExtractEthCall(param interface{}) (*gethapi.TransactionArgs, error) { // CreateEthHeaderForBatch - the EVM requires an Ethereum "block" header. // In this function we are creating one from the Batch Header func (enc *gethEncodingServiceImpl) CreateEthHeaderForBatch(h *common.BatchHeader) (*types.Header, error) { - // todo - cache only when there is some "final" arg - value, err := enc.convertedCache.Get(context.Background(), h.Hash()) - if err == nil { - v := new(types.Header) - err = rlp.DecodeBytes(value, v) + return common.GetCachedValue(enc.convertedCache, enc.logger, h.Hash(), func(a any) (*types.Header, error) { + // deterministically calculate the private randomness that will be exposed to the evm + secret, err := enc.storage.FetchSecret() if err != nil { - enc.logger.Error("Failed reading from the cache", log.ErrKey, err) + enc.logger.Crit("Could not fetch shared secret. Exiting.", log.ErrKey, err) } - return v, err - } + randomness := crypto.CalculateRootBatchEntropy(secret[:], h.Number) - // deterministically calculate the private randomness that will be exposed to the evm - secret, err := enc.storage.FetchSecret() - if err != nil { - enc.logger.Crit("Could not fetch shared secret. Exiting.", log.ErrKey, err) - } - randomness := crypto.CalculateRootBatchEntropy(secret[:], h.Number) + // calculate the converted hash of the parent, for a correct converted chain + convertedParentHash := gethcommon.Hash{} - // calculate the converted hash of the parent, for a correct converted chain - convertedParentHash := gethcommon.Hash{} - - // handle genesis - if h.SequencerOrderNo.Uint64() > common.L2GenesisSeqNo { - convertedParentHash, err = enc.storage.FetchConvertedHash(h.ParentHash) - if err != nil { - enc.logger.Error("Cannot find the converted value for the parent of", log.BatchSeqNoKey, h.SequencerOrderNo) - return nil, err + // handle genesis + if h.SequencerOrderNo.Uint64() > common.L2GenesisSeqNo { + convertedParentHash, err = enc.storage.FetchConvertedHash(h.ParentHash) + if err != nil { + enc.logger.Error("Cannot find the converted value for the parent of", log.BatchSeqNoKey, h.SequencerOrderNo) + return nil, err + } } - } - baseFee := uint64(0) - if h.BaseFee != nil { - baseFee = h.BaseFee.Uint64() - } - - gethHeader := types.Header{ - ParentHash: convertedParentHash, - UncleHash: gethcommon.Hash{}, - Root: h.Root, - TxHash: h.TxHash, - ReceiptHash: h.ReceiptHash, - Difficulty: big.NewInt(0), - Number: h.Number, - GasLimit: h.GasLimit, - GasUsed: h.GasUsed, - BaseFee: big.NewInt(0).SetUint64(baseFee), - Coinbase: h.Coinbase, - Time: h.Time, - MixDigest: randomness, - Nonce: types.BlockNonce{}, - Extra: h.SequencerOrderNo.Bytes(), - WithdrawalsHash: nil, - BlobGasUsed: nil, - ExcessBlobGas: nil, - Bloom: types.Bloom{}, - } - - // cache value - encoded, err := rlp.EncodeToBytes(&gethHeader) - if err != nil { - enc.logger.Error("Could not encode value to store in cache", log.ErrKey, err) - return nil, err - } - err = enc.convertedCache.Set(context.Background(), h.Hash(), encoded) - if err != nil { - enc.logger.Error("Could not store value in cache", log.ErrKey, err) - } + baseFee := uint64(0) + if h.BaseFee != nil { + baseFee = h.BaseFee.Uint64() + } - return &gethHeader, nil + gethHeader := types.Header{ + ParentHash: convertedParentHash, + UncleHash: gethcommon.Hash{}, + Root: h.Root, + TxHash: h.TxHash, + ReceiptHash: h.ReceiptHash, + Difficulty: big.NewInt(0), + Number: h.Number, + GasLimit: h.GasLimit, + GasUsed: h.GasUsed, + BaseFee: big.NewInt(0).SetUint64(baseFee), + Coinbase: h.Coinbase, + Time: h.Time, + MixDigest: randomness, + Nonce: types.BlockNonce{}, + Extra: h.SequencerOrderNo.Bytes(), + WithdrawalsHash: nil, + BlobGasUsed: nil, + ExcessBlobGas: nil, + Bloom: types.Bloom{}, + } + return &gethHeader, nil + }) } // this type is needed for accessing the internals diff --git a/go/enclave/crosschain/block_message_extractor.go b/go/enclave/crosschain/block_message_extractor.go index 8742c894c6..ed9fa1afa3 100644 --- a/go/enclave/crosschain/block_message_extractor.go +++ b/go/enclave/crosschain/block_message_extractor.go @@ -61,7 +61,7 @@ func (m *blockMessageExtractor) StoreCrossChainValueTransfers(block *common.L1Bl return nil } - m.logger.Trace(fmt.Sprintf("Storing %d value transfers for block", len(transfers)), log.BlockHashKey, block.Hash()) + m.logger.Trace("Storing value transfers for block", "nr", len(transfers), log.BlockHashKey, block.Hash()) err = m.storage.StoreValueTransfers(block.Hash(), transfers) if err != nil { m.logger.Crit("Unable to store the transfers", log.ErrKey, err) @@ -82,7 +82,7 @@ func (m *blockMessageExtractor) StoreCrossChainMessages(block *common.L1Block, r return nil } - lazilyLogReceiptChecksum(fmt.Sprintf("Processing block: %s receipts: %d", block.Hash(), len(receipts)), receipts, m.logger) + lazilyLogReceiptChecksum(block, receipts, m.logger) messages, err := m.getCrossChainMessages(block, receipts) if err != nil { m.logger.Error("Converting receipts to messages failed.", log.ErrKey, err) diff --git a/go/enclave/crosschain/common.go b/go/enclave/crosschain/common.go index f9a91782e8..c18bec19e5 100644 --- a/go/enclave/crosschain/common.go +++ b/go/enclave/crosschain/common.go @@ -5,6 +5,8 @@ import ( "errors" "strings" + "github.com/ten-protocol/go-ten/go/common/log" + "github.com/ethereum/go-ethereum/accounts/abi" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -23,8 +25,8 @@ var ( ValueTransferEventID = MessageBusABI.Events["ValueTransfer"].ID ) -func lazilyLogReceiptChecksum(msg string, receipts types.Receipts, logger gethlog.Logger) { - logger.Trace(msg, "Hash", +func lazilyLogReceiptChecksum(block *common.L1Block, receipts types.Receipts, logger gethlog.Logger) { + logger.Trace("Processing block", log.BlockHashKey, block.Hash(), "nr_rec", len(receipts), "Hash", gethlog.Lazy{Fn: func() string { hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) hasher.Reset() diff --git a/go/enclave/events/subscription_manager.go b/go/enclave/events/subscription_manager.go index 170f4f980d..91e675bf17 100644 --- a/go/enclave/events/subscription_manager.go +++ b/go/enclave/events/subscription_manager.go @@ -6,6 +6,8 @@ import ( "math/big" "sync" + "github.com/ten-protocol/go-ten/go/common/log" + "github.com/ten-protocol/go-ten/go/enclave/core" "github.com/ten-protocol/go-ten/go/enclave/storage" @@ -153,7 +155,7 @@ func (s *SubscriptionManager) GetSubscribedLogsForBatch(batch *core.Batch, recei if relevant { relevantLogsForSub = append(relevantLogsForSub, logItem) } - s.logger.Debug(fmt.Sprintf("Subscription %s. Account %s. Log %v. Extracted addresses: %v. Relevant: %t", id, sub.Account, logItem, userAddrs, relevant)) + s.logger.Debug("Subscription", log.SubIDKey, id, "acc", sub.Account, "log", logItem, "extr_addr", userAddrs, "relev", relevant) } if len(relevantLogsForSub) > 0 { relevantLogsPerSubscription[id] = relevantLogsForSub @@ -239,21 +241,21 @@ func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []geth Logs: for _, logItem := range logs { if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > logItem.BlockNumber { - logger.Debug(fmt.Sprintf("Skipping log = %v", logItem), "reason", "In the past. The starting block num for filter is bigger than log") + logger.Debug("Skipping log ", "log", logItem, "reason", "In the past. The starting block num for filter is bigger than log") continue } if toBlock != nil && toBlock.Int64() > 0 && toBlock.Uint64() < logItem.BlockNumber { - logger.Debug(fmt.Sprintf("Skipping log = %v", logItem), "reason", "In the future. The ending block num for filter is smaller than log") + logger.Debug("Skipping log ", "log", logItem, "reason", "In the future. The ending block num for filter is smaller than log") continue } if len(addresses) > 0 && !includes(addresses, logItem.Address) { - logger.Debug(fmt.Sprintf("Skipping log = %v", logItem), "reason", "The contract address of the log is not an address of interest") + logger.Debug("Skipping log ", "log", logItem, "reason", "The contract address of the log is not an address of interest") continue } // If the to filtered topics is greater than the amount of topics in logs, skip. if len(topics) > len(logItem.Topics) { - logger.Debug(fmt.Sprintf("Skipping log = %v", logItem), "reason", "Insufficient topics. The log has less topics than the required one to satisfy the query") + logger.Debug("Skipping log ", "log", logItem, "reason", "Insufficient topics. The log has less topics than the required one to satisfy the query") continue } for i, sub := range topics { @@ -265,7 +267,7 @@ Logs: } } if !match { - logger.Debug(fmt.Sprintf("Skipping log = %v", logItem), "reason", "Topics do not match.") + logger.Debug("Skipping log ", "log", logItem, "reason", "Topics do not match.") continue Logs } } diff --git a/go/enclave/storage/db_cache.go b/go/enclave/storage/db_cache.go deleted file mode 100644 index 555e2b060e..0000000000 --- a/go/enclave/storage/db_cache.go +++ /dev/null @@ -1,39 +0,0 @@ -package storage - -import ( - "context" - - "github.com/eko/gocache/lib/v4/cache" - gethlog "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ten-protocol/go-ten/go/common/log" -) - -func getCachedValue[V any](cache *cache.Cache[[]byte], logger gethlog.Logger, key any, onFailed func(any) (V, error)) (V, error) { - value, err := cache.Get(context.Background(), key) - if err != nil { - // todo metrics for cache misses - b, err := onFailed(key) - if err != nil { - return b, err - } - cacheValue(cache, logger, key, b) - return b, err - } - - v := new(V) - err = rlp.DecodeBytes(value, v) - return *v, err -} - -func cacheValue(cache *cache.Cache[[]byte], logger gethlog.Logger, key any, v any) { - encoded, err := rlp.EncodeToBytes(v) - if err != nil { - logger.Error("Could not encode value to store in cache", log.ErrKey, err) - return - } - err = cache.Set(context.Background(), key, encoded) - if err != nil { - logger.Error("Could not store value in cache", log.ErrKey, err) - } -} diff --git a/go/enclave/storage/storage.go b/go/enclave/storage/storage.go index 8ac4fb7eab..d587a19dda 100644 --- a/go/enclave/storage/storage.go +++ b/go/enclave/storage/storage.go @@ -2,18 +2,17 @@ package storage import ( "bytes" - "context" "crypto/ecdsa" "errors" "fmt" "math/big" "time" + "github.com/dgraph-io/ristretto" + "github.com/eko/gocache/lib/v4/cache" "github.com/ten-protocol/go-ten/go/common/measure" - "github.com/allegro/bigcache/v3" - "github.com/eko/gocache/lib/v4/cache" - bigcache_store "github.com/eko/gocache/store/bigcache/v4" + ristretto_store "github.com/eko/gocache/store/ristretto/v4" "github.com/ten-protocol/go-ten/go/config" @@ -50,12 +49,13 @@ type storageImpl struct { // cache for the immutable blocks and batches. // this avoids a trip to the database. - blockCache *cache.Cache[[]byte] + blockCache *cache.Cache[*types.Block] // stores batches using the sequence number as key // stores a mapping between the hash and the sequence number // to fetch a batch by hash will require 2 cache hits - batchCache *cache.Cache[[]byte] + batchCache *cache.Cache[*core.Batch] + batchSeqCache *cache.Cache[*big.Int] cachedSharedSecret *crypto.SharedEnclaveSecret @@ -82,27 +82,26 @@ func NewStorage(backingDB enclavedb.EnclaveDB, chainConfig *params.ChainConfig, } // todo (tudor) figure out the context and the config - cfg := bigcache.DefaultConfig(2 * time.Minute) - cfg.Shards = 512 - // 1GB cache. Max value in a shard is 2MB. No batch or block should be larger than that - cfg.HardMaxCacheSize = cfg.Shards * 4 - bigcacheClient, err := bigcache.New(context.Background(), cfg) + ristrettoCache, err := ristretto.NewCache(&ristretto.Config{ + NumCounters: 10_000, // number of keys to track frequency of 100. + MaxCost: 1 << 30, // maximum cost of cache (1GB). + BufferItems: 64, // number of keys per Get buffer. + }) if err != nil { - logger.Crit("Could not initialise bigcache", log.ErrKey, err) + panic(err) } - - bigcacheStore := bigcache_store.NewBigcache(bigcacheClient) - + ristrettoStore := ristretto_store.NewRistretto(ristrettoCache) return &storageImpl{ db: backingDB, stateDB: state.NewDatabaseWithConfig(backingDB, &trie.Config{ Cache: cacheConfig.TrieCleanLimit, Preimages: cacheConfig.Preimages, }), - chainConfig: chainConfig, - batchCache: cache.New[[]byte](bigcacheStore), - blockCache: cache.New[[]byte](bigcacheStore), - logger: logger, + chainConfig: chainConfig, + batchCache: cache.New[*core.Batch](ristrettoStore), + batchSeqCache: cache.New[*big.Int](ristrettoStore), + blockCache: cache.New[*types.Block](ristrettoStore), + logger: logger, } } @@ -130,12 +129,12 @@ func (s *storageImpl) FetchCurrentSequencerNo() (*big.Int, error) { func (s *storageImpl) FetchBatch(hash common.L2BatchHash) (*core.Batch, error) { defer s.logDuration("FetchBatch", measure.NewStopwatch()) - seqNo, err := getCachedValue(s.batchCache, s.logger, hash, func(v any) (*big.Int, error) { + seqNo, err := common.GetCachedValue(s.batchSeqCache, s.logger, hash, func(v any) (*big.Int, error) { batch, err := enclavedb.ReadBatchByHash(s.db.GetSQLDB(), v.(common.L2BatchHash)) if err != nil { return nil, err } - cacheValue(s.batchCache, s.logger, batch.SeqNo(), batch) + common.CacheValue(s.batchCache, s.logger, batch.SeqNo(), batch) return batch.SeqNo(), nil }) if err != nil { @@ -146,18 +145,11 @@ func (s *storageImpl) FetchBatch(hash common.L2BatchHash) (*core.Batch, error) { func (s *storageImpl) FetchConvertedHash(hash common.L2BatchHash) (gethcommon.Hash, error) { defer s.logDuration("FetchConvertedHash", measure.NewStopwatch()) - seqNo, err := getCachedValue(s.batchCache, s.logger, hash, func(v any) (*big.Int, error) { - batch, err := enclavedb.ReadBatchByHash(s.db.GetSQLDB(), v.(common.L2BatchHash)) - if err != nil { - return nil, err - } - cacheValue(s.batchCache, s.logger, batch.SeqNo(), batch) - return batch.SeqNo(), nil - }) + batch, err := s.FetchBatch(hash) if err != nil { return gethcommon.Hash{}, err } - return enclavedb.FetchConvertedBatchHash(s.db.GetSQLDB(), seqNo.Uint64()) + return enclavedb.FetchConvertedBatchHash(s.db.GetSQLDB(), batch.Header.SequencerOrderNo.Uint64()) } func (s *storageImpl) FetchBatchHeader(hash common.L2BatchHash) (*common.BatchHeader, error) { @@ -198,14 +190,14 @@ func (s *storageImpl) StoreBlock(b *types.Block, chainFork *common.ChainFork) er return fmt.Errorf("3. could not store block %s. Cause: %w", b.Hash(), err) } - cacheValue(s.blockCache, s.logger, b.Hash(), b) + common.CacheValue(s.blockCache, s.logger, b.Hash(), b) return nil } func (s *storageImpl) FetchBlock(blockHash common.L1BlockHash) (*types.Block, error) { defer s.logDuration("FetchBlock", measure.NewStopwatch()) - return getCachedValue(s.blockCache, s.logger, blockHash, func(hash any) (*types.Block, error) { + return common.GetCachedValue(s.blockCache, s.logger, blockHash, func(hash any) (*types.Block, error) { return enclavedb.FetchBlock(s.db.GetSQLDB(), hash.(common.L1BlockHash)) }) } @@ -373,7 +365,7 @@ func (s *storageImpl) StoreAttestedKey(aggregator gethcommon.Address, key *ecdsa func (s *storageImpl) FetchBatchBySeqNo(seqNum uint64) (*core.Batch, error) { defer s.logDuration("FetchBatchBySeqNo", measure.NewStopwatch()) - return getCachedValue(s.batchCache, s.logger, seqNum, func(seq any) (*core.Batch, error) { + return common.GetCachedValue(s.batchCache, s.logger, seqNum, func(seq any) (*core.Batch, error) { return enclavedb.ReadBatchBySeqNo(s.db.GetSQLDB(), seq.(uint64)) }) } @@ -409,8 +401,8 @@ func (s *storageImpl) StoreBatch(batch *core.Batch, convertedHash gethcommon.Has return fmt.Errorf("could not commit batch %w", err) } - cacheValue(s.batchCache, s.logger, batch.SeqNo(), batch) - cacheValue(s.batchCache, s.logger, batch.Hash(), batch.SeqNo()) + common.CacheValue(s.batchCache, s.logger, batch.SeqNo(), batch) + common.CacheValue(s.batchSeqCache, s.logger, batch.Hash(), batch.SeqNo()) return nil } diff --git a/integration/simulation/utils.go b/integration/simulation/utils.go index e90ab18b0d..69c3744efa 100644 --- a/integration/simulation/utils.go +++ b/integration/simulation/utils.go @@ -31,7 +31,7 @@ func setupSimTestLog(simType string) { LogDir: testLogs, TestType: "sim-log", TestSubtype: simType, - LogLevel: log.LvlTrace, + LogLevel: log.LvlInfo, }) } @@ -129,5 +129,5 @@ func findRollupDups(list []*common.ExtRollup) map[common.L2BatchHash]int { } func sleepRndBtw(min time.Duration, max time.Duration) { - time.Sleep(testcommon.RndBtwTime(min, max)) + time.Sleep(testcommon.RndBtwTime(min, max) / 5) }