diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs index 1a31a80062a..70b187d852a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs @@ -17,6 +17,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using FluentAssertions; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Filters.Topics; @@ -98,8 +99,8 @@ public void Can_get_filters_by_type() LogFilter filter2 = store.CreateLogFilter(new BlockParameter(1), new BlockParameter(2)); store.SaveFilter(filter2); - LogFilter[] logFilters = store.GetFilters(); - BlockFilter[] blockFilters = store.GetFilters(); + LogFilter[] logFilters = store.GetFilters().ToArray(); + BlockFilter[] blockFilters = store.GetFilters().ToArray(); Assert.AreEqual(1, logFilters.Length, "log filters length"); Assert.AreEqual(1, logFilters[0].Id, "log filters ids"); diff --git a/src/Nethermind/Nethermind.Blockchain/Filters/FilterManager.cs b/src/Nethermind/Nethermind.Blockchain/Filters/FilterManager.cs index d9dfe1651a6..ef397960d09 100644 --- a/src/Nethermind/Nethermind.Blockchain/Filters/FilterManager.cs +++ b/src/Nethermind/Nethermind.Blockchain/Filters/FilterManager.cs @@ -84,35 +84,28 @@ private void OnTransactionProcessed(object sender, TxProcessedEventArgs e) private void OnNewPendingTransaction(object sender, TxPool.TxEventArgs e) { - var filters = _filterStore.GetFilters(); - if (filters == null || filters.Length == 0) + IEnumerable filters = _filterStore.GetFilters(); + foreach (PendingTransactionFilter filter in filters) { - return; - } - - for (var i = 0; i < filters.Length; i++) - { - var filterId = filters[i].Id; - var transactions = _pendingTransactions.GetOrAdd(filterId, _ => new List()); + int filterId = filter.Id; + List transactions = _pendingTransactions.GetOrAdd(filterId, _ => new List()); transactions.Add(e.Transaction.Hash); if (_logger.IsDebug) _logger.Debug($"Filter with id: '{filterId}' contains {transactions.Count} transactions."); + } } private void OnRemovedPendingTransaction(object sender, TxPool.TxEventArgs e) { - var filters = _filterStore.GetFilters(); - if (filters == null || filters.Length == 0) - { - return; - } + IEnumerable filters = _filterStore.GetFilters(); - for (var i = 0; i < filters.Length; i++) + foreach (PendingTransactionFilter filter in filters) { - var filterId = filters[i].Id; - var transactions = _pendingTransactions.GetOrAdd(filterId, _ => new List()); + int filterId = filter.Id; + List transactions = _pendingTransactions.GetOrAdd(filterId, _ => new List()); transactions.Remove(e.Transaction.Hash); if (_logger.IsDebug) _logger.Debug($"Filter with id: '{filterId}' contains {transactions.Count} transactions."); + } } @@ -187,15 +180,13 @@ private void AddReceipts(params TxReceipt[] txReceipts) return; } - var filters = _filterStore.GetFilters(); - if (filters == null || filters.Length == 0) + IEnumerable filters = _filterStore.GetFilters(); + foreach (LogFilter filter in filters) { - return; - } - - for (var i = 0; i < txReceipts.Length; i++) - { - StoreLogs(filters, txReceipts[i], ref _logIndex); + for (int i = 0; i < txReceipts.Length; i++) + { + StoreLogs(filter, txReceipts[i], ref _logIndex); + } } } @@ -206,20 +197,11 @@ private void AddBlock(Block block) throw new ArgumentNullException(nameof(block)); } - var filters = _filterStore.GetFilters(); - if (filters == null || filters.Length == 0) + IEnumerable filters = _filterStore.GetFilters(); + + foreach (BlockFilter filter in filters) { - return; - } - - StoreBlock(filters, block); - } - - private void StoreBlock(BlockFilter[] filters, Block block) - { - for (var i = 0; i < filters.Length; i++) - { - StoreBlock(filters[i], block); + StoreBlock(filter, block); } } @@ -230,19 +212,11 @@ private void StoreBlock(BlockFilter filter, Block block) throw new InvalidOperationException("Cannot filter on blocks without calculated hashes"); } - var blocks = _blockHashes.GetOrAdd(filter.Id, i => new List()); + List blocks = _blockHashes.GetOrAdd(filter.Id, i => new List()); blocks.Add(block.Hash); if (_logger.IsDebug) _logger.Debug($"Filter with id: '{filter.Id}' contains {blocks.Count} blocks."); } - private void StoreLogs(LogFilter[] filters, TxReceipt txReceipt, ref long logIndex) - { - for (var i = 0; i < filters.Length; i++) - { - StoreLogs(filters[i], txReceipt, ref logIndex); - } - } - private void StoreLogs(LogFilter filter, TxReceipt txReceipt, ref long logIndex) { if (txReceipt.Logs == null || txReceipt.Logs.Length == 0) @@ -250,8 +224,8 @@ private void StoreLogs(LogFilter filter, TxReceipt txReceipt, ref long logIndex) return; } - var logs = _logs.GetOrAdd(filter.Id, i => new List()); - for (var i = 0; i < txReceipt.Logs.Length; i++) + List logs = _logs.GetOrAdd(filter.Id, i => new List()); + for (int i = 0; i < txReceipt.Logs.Length; i++) { var logEntry = txReceipt.Logs[i]; var filterLog = CreateLog(filter, txReceipt, logEntry, logIndex++, i); diff --git a/src/Nethermind/Nethermind.Blockchain/Filters/FilterStore.cs b/src/Nethermind/Nethermind.Blockchain/Filters/FilterStore.cs index 0c0520ec785..b386d970350 100644 --- a/src/Nethermind/Nethermind.Blockchain/Filters/FilterStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Filters/FilterStore.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; using Nethermind.Blockchain.Filters.Topics; using Nethermind.Blockchain.Find; using Nethermind.Core; @@ -28,7 +29,8 @@ namespace Nethermind.Blockchain.Filters { public class FilterStore : IFilterStore { - private int _nextFilterId; + private int _currentFilterId = -1; + private object _locker = new object(); private readonly ConcurrentDictionary _filters = new(); @@ -51,34 +53,22 @@ public FilterType GetFilterType(int filterId) } } - public T[] GetFilters() where T : FilterBase - { - return _filters.Select(f => f.Value).OfType().ToArray(); - } + public IEnumerable GetFilters() where T : FilterBase => + _filters.Select(f => f.Value).OfType(); - public BlockFilter CreateBlockFilter(long startBlockNumber, bool setId = true) - { - var filterId = setId ? GetFilterId() : 0; - var blockFilter = new BlockFilter(filterId, startBlockNumber); - return blockFilter; - } + public BlockFilter CreateBlockFilter(long startBlockNumber, bool setId = true) => + new(GetFilterId(setId), startBlockNumber); - public PendingTransactionFilter CreatePendingTransactionFilter(bool setId = true) - { - var filterId = setId ? GetFilterId() : 0; - var pendingTransactionFilter = new PendingTransactionFilter(filterId); - return pendingTransactionFilter; - } + public PendingTransactionFilter CreatePendingTransactionFilter(bool setId = true) => + new(GetFilterId(setId)); public LogFilter CreateLogFilter(BlockParameter fromBlock, BlockParameter toBlock, - object? address = null, IEnumerable? topics = null, bool setId = true) - { - var filterId = setId ? GetFilterId() : 0; - var filter = new LogFilter(filterId, fromBlock, toBlock, - GetAddress(address), GetTopicsFilter(topics)); - - return filter; - } + object? address = null, IEnumerable? topics = null, bool setId = true) => + new(GetFilterId(setId), + fromBlock, + toBlock, + GetAddress(address), + GetTopicsFilter(topics)); public void RemoveFilter(int filterId) { @@ -95,11 +85,26 @@ public void SaveFilter(FilterBase filter) throw new InvalidOperationException($"Filter with ID {filter.Id} already exists"); } - _nextFilterId = Math.Max(filter.Id + 1, _nextFilterId); + lock (_locker) + { + _currentFilterId = Math.Max(filter.Id, _currentFilterId); + } + _filters[filter.Id] = filter; } - private int GetFilterId() => _nextFilterId++; + private int GetFilterId(bool generateId) + { + if (generateId) + { + lock (_locker) + { + return ++_currentFilterId; + } + } + + return 0; + } private TopicsFilter GetTopicsFilter(IEnumerable? topics = null) { diff --git a/src/Nethermind/Nethermind.Blockchain/Filters/IFilterStore.cs b/src/Nethermind/Nethermind.Blockchain/Filters/IFilterStore.cs index 39aa2dd098a..f4cb6c8ca20 100644 --- a/src/Nethermind/Nethermind.Blockchain/Filters/IFilterStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Filters/IFilterStore.cs @@ -23,12 +23,16 @@ namespace Nethermind.Blockchain.Filters public interface IFilterStore { bool FilterExists(int filterId); - T[] GetFilters() where T : FilterBase; + IEnumerable GetFilters() where T : FilterBase; BlockFilter CreateBlockFilter(long startBlockNumber, bool setId = true); PendingTransactionFilter CreatePendingTransactionFilter(bool setId = true); - LogFilter CreateLogFilter(BlockParameter fromBlock, BlockParameter toBlock, object address = null, - IEnumerable topics = null, bool setId = true); + LogFilter CreateLogFilter( + BlockParameter fromBlock, + BlockParameter toBlock, + object? address = null, + IEnumerable? topics = null, + bool setId = true); void SaveFilter(FilterBase filter); void RemoveFilter(int filterId); diff --git a/src/Nethermind/Nethermind.Blockchain/Filters/NullFilterStore.cs b/src/Nethermind/Nethermind.Blockchain/Filters/NullFilterStore.cs index f288763d14f..f0077d6e2d9 100644 --- a/src/Nethermind/Nethermind.Blockchain/Filters/NullFilterStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Filters/NullFilterStore.cs @@ -33,7 +33,7 @@ public bool FilterExists(int filterId) return false; } - public T[] GetFilters() where T : FilterBase + public IEnumerable GetFilters() where T : FilterBase { return Array.Empty(); } @@ -48,7 +48,7 @@ public PendingTransactionFilter CreatePendingTransactionFilter(bool setId = true throw new InvalidOperationException($"{nameof(NullFilterStore)} does not support filter creation"); } - public LogFilter CreateLogFilter(BlockParameter fromBlock, BlockParameter toBlock, object address = null, IEnumerable topics = null, bool setId = true) + public LogFilter CreateLogFilter(BlockParameter fromBlock, BlockParameter toBlock, object? address = null, IEnumerable? topics = null, bool setId = true) { throw new InvalidOperationException($"{nameof(NullFilterStore)} does not support filter creation"); }