From f39ee546c46947bfe2daa9f9dfb6742ea7cee3c0 Mon Sep 17 00:00:00 2001 From: Marcin Gorzynski Date: Tue, 15 Aug 2023 14:39:40 +0200 Subject: [PATCH 1/3] New Lazy struct & deferred ChainID get in ethmonitor --- ethmonitor/ethmonitor.go | 21 +++++++++++++-------- types.go | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/ethmonitor/ethmonitor.go b/ethmonitor/ethmonitor.go index 689fb7e1..b895bf44 100644 --- a/ethmonitor/ethmonitor.go +++ b/ethmonitor/ethmonitor.go @@ -9,6 +9,7 @@ import ( "sync/atomic" "time" + "github.com/0xsequence/ethkit" "github.com/0xsequence/ethkit/ethrpc" "github.com/0xsequence/ethkit/go-ethereum" "github.com/0xsequence/ethkit/go-ethereum/common" @@ -94,7 +95,7 @@ type Monitor struct { provider ethrpc.Interface chain *Chain - chainID *big.Int + chainID *ethkit.Lazy[*big.Int] nextBlockNumber *big.Int blockCache cachestore.Store[*types.Block] logCache cachestore.Store[[]types.Log] @@ -133,14 +134,18 @@ func NewMonitor(provider ethrpc.Interface, options ...Options) (*Monitor, error) } } - chainID, err := getChainID(provider) - if err != nil { - return nil, err - } + chainID := ethkit.NewLazy(func() *big.Int { + chainId, err := getChainID(provider) + if err != nil { + return big.NewInt(-1) + } + return chainId + }) var ( blockCache cachestore.Store[*types.Block] logCache cachestore.Store[[]types.Log] + err error ) if opts.CacheBackend != nil { blockCache, err = cachestorectl.Open[*types.Block](opts.CacheBackend, cachestore.WithLockExpiry(4*time.Second)) @@ -468,7 +473,7 @@ func (m *Monitor) filterLogs(ctx context.Context, blockHash common.Hash, topics topicsDigest.Write([]byte{'\n'}) } - key := fmt.Sprintf("ethmonitor:%s:Logs:hash=%s;topics=%d", m.chainID.String(), blockHash.String(), topicsDigest.Sum64()) + key := fmt.Sprintf("ethmonitor:%s:Logs:hash=%s;topics=%d", m.chainID.Get().String(), blockHash.String(), topicsDigest.Sum64()) return m.logCache.GetOrSetWithLockEx(ctx, key, getter, m.options.CacheExpiry) } @@ -531,7 +536,7 @@ func (m *Monitor) fetchNextBlock(ctx context.Context) (*types.Block, bool, error } if m.blockCache != nil { - key := fmt.Sprintf("ethmonitor:%s:BlockNum:%s", m.chainID.String(), m.nextBlockNumber.String()) + key := fmt.Sprintf("ethmonitor:%s:BlockNum:%s", m.chainID.Get().String(), m.nextBlockNumber.String()) nextBlock, err := m.blockCache.GetOrSetWithLockEx(ctx, key, getter, m.options.CacheExpiry) return nextBlock, miss, err } @@ -620,7 +625,7 @@ func (m *Monitor) fetchBlockByHash(ctx context.Context, hash common.Hash) (*type } if m.blockCache != nil { - key := fmt.Sprintf("ethmonitor:%s:BlockHash:%s", m.chainID.String(), hash.String()) + key := fmt.Sprintf("ethmonitor:%s:BlockHash:%s", m.chainID.Get().String(), hash.String()) return m.blockCache.GetOrSetWithLockEx(ctx, key, getter, m.options.CacheExpiry) } return getter(ctx, "") diff --git a/types.go b/types.go index c8f7ade7..1d8fdfc5 100644 --- a/types.go +++ b/types.go @@ -27,3 +27,19 @@ func ToSliceValues[T any](in []*T) []T { } return out } + +type Lazy[T any] struct { + once func() T + val T +} + +func NewLazy[T any](once func() T) *Lazy[T] { + return &Lazy[T]{once: once} +} + +func (l *Lazy[T]) Get() T { + if l.val == nil { + l.val = l.once() + } + return l.val +} From 5da30cff9d5370bef6672a2663e64d0b1b4cb344 Mon Sep 17 00:00:00 2001 From: Marcin Gorzynski Date: Tue, 15 Aug 2023 14:46:21 +0200 Subject: [PATCH 2/3] If initial get chain id fails retry --- ethmonitor/ethmonitor.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ethmonitor/ethmonitor.go b/ethmonitor/ethmonitor.go index b895bf44..d9388ef0 100644 --- a/ethmonitor/ethmonitor.go +++ b/ethmonitor/ethmonitor.go @@ -137,7 +137,7 @@ func NewMonitor(provider ethrpc.Interface, options ...Options) (*Monitor, error) chainID := ethkit.NewLazy(func() *big.Int { chainId, err := getChainID(provider) if err != nil { - return big.NewInt(-1) + return nil } return chainId }) @@ -473,7 +473,7 @@ func (m *Monitor) filterLogs(ctx context.Context, blockHash common.Hash, topics topicsDigest.Write([]byte{'\n'}) } - key := fmt.Sprintf("ethmonitor:%s:Logs:hash=%s;topics=%d", m.chainID.Get().String(), blockHash.String(), topicsDigest.Sum64()) + key := fmt.Sprintf("ethmonitor:%s:Logs:hash=%s;topics=%d", m.getChainID().String(), blockHash.String(), topicsDigest.Sum64()) return m.logCache.GetOrSetWithLockEx(ctx, key, getter, m.options.CacheExpiry) } @@ -536,7 +536,7 @@ func (m *Monitor) fetchNextBlock(ctx context.Context) (*types.Block, bool, error } if m.blockCache != nil { - key := fmt.Sprintf("ethmonitor:%s:BlockNum:%s", m.chainID.Get().String(), m.nextBlockNumber.String()) + key := fmt.Sprintf("ethmonitor:%s:BlockNum:%s", m.getChainID().String(), m.nextBlockNumber.String()) nextBlock, err := m.blockCache.GetOrSetWithLockEx(ctx, key, getter, m.options.CacheExpiry) return nextBlock, miss, err } @@ -625,7 +625,7 @@ func (m *Monitor) fetchBlockByHash(ctx context.Context, hash common.Hash) (*type } if m.blockCache != nil { - key := fmt.Sprintf("ethmonitor:%s:BlockHash:%s", m.chainID.Get().String(), hash.String()) + key := fmt.Sprintf("ethmonitor:%s:BlockHash:%s", m.getChainID().String(), hash.String()) return m.blockCache.GetOrSetWithLockEx(ctx, key, getter, m.options.CacheExpiry) } return getter(ctx, "") @@ -775,6 +775,14 @@ func (m *Monitor) PurgeHistory() { } } +func (m *Monitor) getChainID() *big.Int { + if val := m.chainID.Get(); val == nil { + return big.NewInt(-1) + } else { + return val + } +} + func getChainID(provider ethrpc.Interface) (*big.Int, error) { var chainID *big.Int err := breaker.Do(context.Background(), func() error { From 8b88fe65c5627b24518ff6931e1ad76705302736 Mon Sep 17 00:00:00 2001 From: Marcin Gorzynski Date: Tue, 15 Aug 2023 15:04:05 +0200 Subject: [PATCH 3/3] Fix Lazy types --- ethmonitor/ethmonitor.go | 2 +- types.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ethmonitor/ethmonitor.go b/ethmonitor/ethmonitor.go index d9388ef0..68bcccfa 100644 --- a/ethmonitor/ethmonitor.go +++ b/ethmonitor/ethmonitor.go @@ -95,7 +95,7 @@ type Monitor struct { provider ethrpc.Interface chain *Chain - chainID *ethkit.Lazy[*big.Int] + chainID *ethkit.Lazy[big.Int] nextBlockNumber *big.Int blockCache cachestore.Store[*types.Block] logCache cachestore.Store[[]types.Log] diff --git a/types.go b/types.go index 1d8fdfc5..34e29c0b 100644 --- a/types.go +++ b/types.go @@ -29,15 +29,15 @@ func ToSliceValues[T any](in []*T) []T { } type Lazy[T any] struct { - once func() T - val T + once func() *T + val *T } -func NewLazy[T any](once func() T) *Lazy[T] { +func NewLazy[T any](once func() *T) *Lazy[T] { return &Lazy[T]{once: once} } -func (l *Lazy[T]) Get() T { +func (l *Lazy[T]) Get() *T { if l.val == nil { l.val = l.once() }