From c0e69ff1d0355aa16d46a16a8f465e37cbfbbb40 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 31 May 2021 22:24:07 +0300 Subject: [PATCH] Implement GetAllTxs function in mempool --- blockchain/pool/mempool.go | 51 +++++++++++--------------------------- cache/cache.go | 1 + cache/inmemory_cache.go | 10 +++++++- cache/redis_cache.go | 4 +++ 4 files changed, 28 insertions(+), 38 deletions(-) diff --git a/blockchain/pool/mempool.go b/blockchain/pool/mempool.go index 0d7fe5d..4d7697e 100644 --- a/blockchain/pool/mempool.go +++ b/blockchain/pool/mempool.go @@ -3,7 +3,6 @@ package pool import ( "encoding/hex" "sort" - "sync" "time" types2 "github.com/Secured-Finance/dione/blockchain/types" @@ -19,58 +18,26 @@ const ( ) type Mempool struct { - m sync.RWMutex - cache cache.Cache - txDescriptors []string // list of txs in cache + cache cache.Cache } -func NewMempool(c cache.Cache) (*Mempool, error) { +func NewMempool() (*Mempool, error) { mp := &Mempool{ - cache: c, + cache: cache.NewInMemoryCache(), // here we need to use separate cache } - var txDesc []string - err := c.Get("tx_list", &txDesc) - if err != nil || err != cache.ErrNilValue { - return nil, err - } - mp.txDescriptors = txDesc - return mp, nil } func (mp *Mempool) StoreTx(tx *types2.Transaction) error { - mp.m.Lock() - defer mp.m.Unlock() - hashStr := hex.EncodeToString(tx.Hash) err := mp.cache.StoreWithTTL(DefaultTxPrefix+hashStr, tx, DefaultTxTTL) - mp.txDescriptors = append(mp.txDescriptors, hashStr) - mp.cache.Store("tx_list", mp.txDescriptors) // update tx list in cache return err } func (mp *Mempool) GetTxsForNewBlock() []*types2.Transaction { - mp.m.Lock() - defer mp.m.Unlock() - var txForBlock []*types2.Transaction - var allTxs []*types2.Transaction - - for i, v := range mp.txDescriptors { - var tx types2.Transaction - err := mp.cache.Get(DefaultTxPrefix+v, &tx) - if err != nil { - if err == cache.ErrNilValue { - // descriptor is broken - // delete it and update list - mp.txDescriptors = removeItemFromStringSlice(mp.txDescriptors, i) - mp.cache.Store("tx_list", mp.txDescriptors) // update tx list in cache - } - continue - } - allTxs = append(allTxs, &tx) - } + allTxs := mp.GetAllTxs() sort.Slice(allTxs, func(i, j int) bool { return allTxs[i].Timestamp.Before(allTxs[j].Timestamp) }) @@ -87,6 +54,16 @@ func (mp *Mempool) GetTxsForNewBlock() []*types2.Transaction { return txForBlock } +func (mp *Mempool) GetAllTxs() []*types2.Transaction { + var allTxs []*types2.Transaction + + for _, v := range mp.cache.Items() { + tx := v.(types2.Transaction) + allTxs = append(allTxs, &tx) + } + return allTxs +} + func removeItemFromStringSlice(s []string, i int) []string { s[len(s)-1], s[i] = s[i], s[len(s)-1] return s[:len(s)-1] diff --git a/cache/cache.go b/cache/cache.go index 1c155f8..5af78e3 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -12,4 +12,5 @@ type Cache interface { StoreWithTTL(key string, value interface{}, ttl time.Duration) error Get(key string, value interface{}) error Delete(key string) + Items() map[string]interface{} } diff --git a/cache/inmemory_cache.go b/cache/inmemory_cache.go index 828a9df..fd4333f 100644 --- a/cache/inmemory_cache.go +++ b/cache/inmemory_cache.go @@ -15,7 +15,7 @@ type InMemoryCache struct { cache *cache.Cache } -func NewInMemoryCache() *InMemoryCache { +func NewInMemoryCache() Cache { return &InMemoryCache{ cache: cache.New(DefaultCacheExpiration, DefaultGCInterval), } @@ -45,3 +45,11 @@ func (imc *InMemoryCache) Get(key string, value interface{}) error { func (imc *InMemoryCache) Delete(key string) { imc.cache.Delete(key) } + +func (imc *InMemoryCache) Items() map[string]interface{} { + m := make(map[string]interface{}) + for k, v := range imc.cache.Items() { + m[k] = v.Object + } + return m +} diff --git a/cache/redis_cache.go b/cache/redis_cache.go index ca06b0a..3f7ace3 100644 --- a/cache/redis_cache.go +++ b/cache/redis_cache.go @@ -81,3 +81,7 @@ func (rc *RedisCache) Get(key string, value interface{}) error { func (rc *RedisCache) Delete(key string) { rc.Client.Del(rc.ctx, key) } + +func (rc *RedisCache) Items() map[string]interface{} { + return nil // TODO +}