From c4bd76705dfa6951f126906190d2fe036f60dc16 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 03:37:15 +0300 Subject: [PATCH 01/19] try fix --- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 77 ++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 0b3a0284bdb..024293a3038 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -1,28 +1,30 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using System.Text.Json; - using Nethermind.Blockchain.Find; -using Nethermind.JsonRpc.Data; +using Nethermind.Core; +using Nethermind.Core.Crypto; namespace Nethermind.JsonRpc.Modules.Eth; public class Filter : IJsonRpcParam { - public object? Address { get; set; } + public Address[]? Address { get; set; } + + public Hash256? BlockHash { get; set; } public BlockParameter? FromBlock { get; set; } public BlockParameter? ToBlock { get; set; } - public IEnumerable? Topics { get; set; } + public IEnumerable? Topics { get; set; } public void ReadJson(JsonElement filter, JsonSerializerOptions options) { JsonDocument doc = null; - string blockHash = null; try { if (filter.ValueKind == JsonValueKind.String) @@ -31,34 +33,33 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) filter = doc.RootElement; } - if (filter.TryGetProperty("blockHash"u8, out JsonElement blockHashElement)) - { - blockHash = blockHashElement.GetString(); - } + bool hasBlockHash = filter.TryGetProperty("blockHash"u8, out JsonElement blockHashElement); + bool hasFromBlock = filter.TryGetProperty("fromBlock"u8, out JsonElement fromBlockElement); + bool hasToBlock = filter.TryGetProperty("toBlock"u8, out JsonElement toBlockElement); - if (blockHash is null) + if (hasBlockHash) { - filter.TryGetProperty("fromBlock"u8, out JsonElement fromBlockElement); - FromBlock = BlockParameterConverter.GetBlockParameter(fromBlockElement.ToString()); - filter.TryGetProperty("toBlock"u8, out JsonElement toBlockElement); - ToBlock = BlockParameterConverter.GetBlockParameter(toBlockElement.ToString()); + if (hasFromBlock || hasToBlock) + { + throw new ArgumentException("either (fromBlock and toBlock) or blockHash have to be specified"); + } + + BlockHash = new Hash256(blockHashElement.ToString()); } - else + + FromBlock = hasFromBlock ? new BlockParameter(fromBlockElement.GetInt64()) : BlockParameter.Earliest; + ToBlock = hasToBlock ? new BlockParameter(toBlockElement.GetInt64()) : BlockParameter.Latest; + + + if (filter.TryGetProperty("address"u8, out JsonElement addressElement)) { - FromBlock = ToBlock = BlockParameterConverter.GetBlockParameter(blockHash); + Address = GetAddress(addressElement, options); } - filter.TryGetProperty("address"u8, out JsonElement addressElement); - Address = GetAddress(addressElement, options); - if (filter.TryGetProperty("topics"u8, out JsonElement topicsElement) && topicsElement.ValueKind == JsonValueKind.Array) { Topics = GetTopics(topicsElement, options); } - else - { - Topics = null; - } } finally { @@ -66,9 +67,16 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) } } - private static object? GetAddress(JsonElement? token, JsonSerializerOptions options) => GetSingleOrMany(token, options); + private static Address[]? GetAddress(JsonElement token, JsonSerializerOptions options) => token switch + { + { ValueKind: JsonValueKind.Undefined } _ => null, + { ValueKind: JsonValueKind.Null } _ => null, + { ValueKind: JsonValueKind.Array } _ => token.Deserialize(options), + { ValueKind: JsonValueKind.String } _ => [token.Deserialize
()], + _ => throw new ArgumentException("invalid address field") + }; - private static IEnumerable GetTopics(JsonElement? array, JsonSerializerOptions options) + private static IEnumerable? GetTopics(JsonElement? array, JsonSerializerOptions options) { if (array is null) { @@ -77,16 +85,13 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) foreach (var token in array.GetValueOrDefault().EnumerateArray()) { - yield return GetSingleOrMany(token, options); + yield return token switch + { + { ValueKind: JsonValueKind.Undefined } _ => null, + { ValueKind: JsonValueKind.Null } _ => null, + { ValueKind: JsonValueKind.Array } _ => token.Deserialize(options), + _ => [new Hash256(token.GetString()!)], + }; } } - - private static object? GetSingleOrMany(JsonElement? token, JsonSerializerOptions options) => token switch - { - null => null, - { ValueKind: JsonValueKind.Undefined } _ => null, - { ValueKind: JsonValueKind.Null } _ => null, - { ValueKind: JsonValueKind.Array } _ => token.GetValueOrDefault().Deserialize(options), - _ => token.GetValueOrDefault().GetString(), - }; } From 3ef1c5e1cf37be24b969b871facd480415576666 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 04:03:35 +0300 Subject: [PATCH 02/19] Fix tests --- .../Nethermind.Facade/BlockchainBridge.cs | 10 ++-- .../Nethermind.Facade/Filters/FilterStore.cs | 48 ++++++------------- .../Nethermind.Facade/IBlockchainBridge.cs | 6 +-- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 13 ++--- 4 files changed, 30 insertions(+), 47 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 430ab4cb28b..8c3c172a87f 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -289,8 +289,8 @@ public ulong GetChainId() public IEnumerable GetLogs( BlockParameter fromBlock, BlockParameter toBlock, - object? address = null, - IEnumerable? topics = null, + AddressAsKey[]? address = null, + IEnumerable? topics = null, CancellationToken cancellationToken = default) { LogFilter filter = GetFilter(fromBlock, toBlock, address, topics); @@ -300,8 +300,8 @@ public IEnumerable GetLogs( public LogFilter GetFilter( BlockParameter fromBlock, BlockParameter toBlock, - object? address = null, - IEnumerable? topics = null) + AddressAsKey[]? address = null, + IEnumerable? topics = null) { return filterStore.CreateLogFilter(fromBlock, toBlock, address, topics, false); } @@ -326,7 +326,7 @@ public bool TryGetLogs(int filterId, out IEnumerable filterLogs, Canc } public int NewFilter(BlockParameter? fromBlock, BlockParameter? toBlock, - object? address = null, IEnumerable? topics = null) + AddressAsKey[]? address = null, IEnumerable? topics = null) { LogFilter filter = filterStore.CreateLogFilter(fromBlock ?? BlockParameter.Latest, toBlock ?? BlockParameter.Latest, address, topics); filterStore.SaveFilter(filter); diff --git a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs index f7b192cb42c..6dae0c013ee 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs @@ -124,7 +124,7 @@ 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) => + AddressAsKey[]? address = null, IEnumerable? topics = null, bool setId = true) => new(GetFilterId(setId), fromBlock, toBlock, @@ -165,7 +165,7 @@ private int GetFilterId(bool generateId) return 0; } - private static TopicsFilter GetTopicsFilter(IEnumerable? topics = null) + private static TopicsFilter GetTopicsFilter(IEnumerable? topics = null) { if (topics is null) { @@ -202,48 +202,30 @@ private static TopicExpression GetTopicExpression(FilterTopic? filterTopic) return AnyTopic.Instance; } - private static AddressFilter GetAddress(object? address) => - address switch + private static AddressFilter GetAddress(AddressAsKey[]? address) + { + if (address is null) { - null => AddressFilter.AnyAddress, - string s => new AddressFilter(new Address(s)), - IEnumerable e => new AddressFilter(e.Select(static a => new AddressAsKey(new Address(a))).ToHashSet()), - _ => throw new InvalidDataException("Invalid address filter format") - }; + return AddressFilter.AnyAddress; + } + + return new AddressFilter(address.ToHashSet()); + } - private static FilterTopic?[]? GetFilterTopics(IEnumerable? topics) => topics?.Select(GetTopic).ToArray(); + private static FilterTopic?[]? GetFilterTopics(IEnumerable? topics) => topics?.Select(GetTopic).ToArray(); - private static FilterTopic? GetTopic(object? obj) + private static FilterTopic? GetTopic(Hash256[]? topics) { - switch (obj) + return new FilterTopic { - case null: - return null; - case string topic: - return new FilterTopic - { - Topic = new Hash256(topic) - }; - case Hash256 keccak: - return new FilterTopic - { - Topic = keccak - }; - } - - return obj is not IEnumerable topics - ? null - : new FilterTopic - { - Topics = topics.Select(static t => new Hash256(t)).ToArray() - }; + Topics = topics + }; } private class FilterTopic { public Hash256? Topic { get; init; } public Hash256[]? Topics { get; init; } - } public void Dispose() diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index d2f41be173a..0c5dad20dc5 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -36,16 +36,16 @@ public interface IBlockchainBridge : ILogFinder int NewBlockFilter(); int NewPendingTransactionFilter(); - int NewFilter(BlockParameter? fromBlock, BlockParameter? toBlock, object? address = null, IEnumerable? topics = null); + int NewFilter(BlockParameter? fromBlock, BlockParameter? toBlock, AddressAsKey[]? address = null, IEnumerable? topics = null); void UninstallFilter(int filterId); bool FilterExists(int filterId); Hash256[] GetBlockFilterChanges(int filterId); Hash256[] GetPendingTransactionFilterChanges(int filterId); FilterLog[] GetLogFilterChanges(int filterId); FilterType GetFilterType(int filterId); - LogFilter GetFilter(BlockParameter fromBlock, BlockParameter toBlock, object? address = null, IEnumerable? topics = null); + LogFilter GetFilter(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? address = null, IEnumerable? topics = null); IEnumerable GetLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, CancellationToken cancellationToken = default); - IEnumerable GetLogs(BlockParameter fromBlock, BlockParameter toBlock, object? address = null, IEnumerable? topics = null, CancellationToken cancellationToken = default); + IEnumerable GetLogs(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? address = null, IEnumerable? topics = null, CancellationToken cancellationToken = default); bool TryGetLogs(int filterId, out IEnumerable filterLogs, CancellationToken cancellationToken = default); void RunTreeVisitor(ITreeVisitor treeVisitor, Hash256 stateRoot) where TCtx : struct, INodeContext; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 024293a3038..3673391a813 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -7,12 +7,13 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Serialization.Json; namespace Nethermind.JsonRpc.Modules.Eth; public class Filter : IJsonRpcParam { - public Address[]? Address { get; set; } + public AddressAsKey[]? Address { get; set; } public Hash256? BlockHash { get; set; } @@ -47,8 +48,8 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) BlockHash = new Hash256(blockHashElement.ToString()); } - FromBlock = hasFromBlock ? new BlockParameter(fromBlockElement.GetInt64()) : BlockParameter.Earliest; - ToBlock = hasToBlock ? new BlockParameter(toBlockElement.GetInt64()) : BlockParameter.Latest; + FromBlock = hasFromBlock ? new BlockParameter(LongConverter.FromString(fromBlockElement.ToString())) : BlockParameter.Earliest; + ToBlock = hasToBlock ? new BlockParameter(LongConverter.FromString(toBlockElement.ToString())) : BlockParameter.Latest; if (filter.TryGetProperty("address"u8, out JsonElement addressElement)) @@ -67,12 +68,12 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) } } - private static Address[]? GetAddress(JsonElement token, JsonSerializerOptions options) => token switch + private static AddressAsKey[]? GetAddress(JsonElement token, JsonSerializerOptions options) => token switch { { ValueKind: JsonValueKind.Undefined } _ => null, { ValueKind: JsonValueKind.Null } _ => null, - { ValueKind: JsonValueKind.Array } _ => token.Deserialize(options), - { ValueKind: JsonValueKind.String } _ => [token.Deserialize
()], + { ValueKind: JsonValueKind.Array } _ => token.Deserialize(options), + { ValueKind: JsonValueKind.String } _ => [token.Deserialize()], _ => throw new ArgumentException("invalid address field") }; From c0f28151ea65b0baeca8c34cd56015102d65ac88 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 05:10:07 +0300 Subject: [PATCH 03/19] Try fix --- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 3673391a813..3ca4ae4f1ca 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -68,14 +68,27 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) } } - private static AddressAsKey[]? GetAddress(JsonElement token, JsonSerializerOptions options) => token switch + private static AddressAsKey[]? GetAddress(JsonElement token, JsonSerializerOptions options) { - { ValueKind: JsonValueKind.Undefined } _ => null, - { ValueKind: JsonValueKind.Null } _ => null, - { ValueKind: JsonValueKind.Array } _ => token.Deserialize(options), - { ValueKind: JsonValueKind.String } _ => [token.Deserialize()], - _ => throw new ArgumentException("invalid address field") - }; + switch (token.ValueKind) + { + case JsonValueKind.Undefined or JsonValueKind.Null: + return null; + case JsonValueKind.String: + return [new AddressAsKey(new Address(token.ToString()))]; + case JsonValueKind.Array: + var enumerator = token.EnumerateArray(); + List result = new(); + while (enumerator.MoveNext()) + { + result.Add(new AddressAsKey(new Address(enumerator.Current.ToString()))); + } + + return result.ToArray(); + default: + throw new ArgumentException("invalid address field"); + } + } private static IEnumerable? GetTopics(JsonElement? array, JsonSerializerOptions options) { @@ -86,13 +99,27 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) foreach (var token in array.GetValueOrDefault().EnumerateArray()) { - yield return token switch + switch (token.ValueKind) { - { ValueKind: JsonValueKind.Undefined } _ => null, - { ValueKind: JsonValueKind.Null } _ => null, - { ValueKind: JsonValueKind.Array } _ => token.Deserialize(options), - _ => [new Hash256(token.GetString()!)], - }; + case JsonValueKind.Undefined or JsonValueKind.Null: + yield return null; + break; + case JsonValueKind.String: + yield return [new Hash256(token.GetString()!)]; + break; + case JsonValueKind.Array: + var enumerator = token.EnumerateArray(); + List result = new(); + while (enumerator.MoveNext()) + { + result.Add(new(enumerator.Current.ToString())); + } + + yield return result.ToArray(); + break; + default: + throw new ArgumentException("invalid topics field"); + } } } } From 17a7c269d057811bcda8406d9c4d4571aa269a3e Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 05:33:15 +0300 Subject: [PATCH 04/19] Fix --- src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 3ca4ae4f1ca..1abb1066633 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -47,10 +47,11 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) BlockHash = new Hash256(blockHashElement.ToString()); } - - FromBlock = hasFromBlock ? new BlockParameter(LongConverter.FromString(fromBlockElement.ToString())) : BlockParameter.Earliest; - ToBlock = hasToBlock ? new BlockParameter(LongConverter.FromString(toBlockElement.ToString())) : BlockParameter.Latest; - + else + { + FromBlock = hasFromBlock ? new BlockParameter(LongConverter.FromString(fromBlockElement.ToString())) : BlockParameter.Earliest; + ToBlock = hasToBlock ? new BlockParameter(LongConverter.FromString(toBlockElement.ToString())) : BlockParameter.Latest; + } if (filter.TryGetProperty("address"u8, out JsonElement addressElement)) { From 882b207c9357e6b43ebf8e711ada8776dd2c46ce Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 06:26:31 +0300 Subject: [PATCH 05/19] Fix from & to --- src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 1abb1066633..1de6381b627 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -15,8 +15,6 @@ public class Filter : IJsonRpcParam { public AddressAsKey[]? Address { get; set; } - public Hash256? BlockHash { get; set; } - public BlockParameter? FromBlock { get; set; } public BlockParameter? ToBlock { get; set; } @@ -45,7 +43,8 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) throw new ArgumentException("either (fromBlock and toBlock) or blockHash have to be specified"); } - BlockHash = new Hash256(blockHashElement.ToString()); + FromBlock = new(new Hash256(blockHashElement.ToString())); + ToBlock = FromBlock; } else { @@ -82,7 +81,7 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) List result = new(); while (enumerator.MoveNext()) { - result.Add(new AddressAsKey(new Address(enumerator.Current.ToString()))); + result.Add(new(new Address(enumerator.Current.ToString()))); } return result.ToArray(); From e1cc553acc0ac034e081b3f9c3e62abb9e38e28d Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 16:57:16 +0300 Subject: [PATCH 06/19] Fix block in the future --- .../Nethermind.Facade/Filters/AddressFilter.cs | 18 ++++++++++-------- .../Nethermind.Facade/Filters/FilterStore.cs | 2 +- .../Nethermind.Facade/Find/LogFinder.cs | 5 +++++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs index 4e71a417b8e..9fd88e904aa 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs @@ -9,19 +9,21 @@ namespace Nethermind.Blockchain.Filters { public class AddressFilter { - public static readonly AddressFilter AnyAddress = new(addresses: new HashSet()); + public static readonly AddressFilter AnyAddress = new([]); private Bloom.BloomExtract[]? _addressesBloomIndexes; private Bloom.BloomExtract? _addressBloomExtract; - public AddressFilter(Address address) + public AddressFilter(AddressAsKey[] addresses) { - Address = address; - } - - public AddressFilter(HashSet addresses) - { - Addresses = addresses; + if (addresses.Length == 1) + { + Address = addresses[0]; + } + else + { + Addresses = addresses.ToHashSet(); + } } public Address? Address { get; } diff --git a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs index 6dae0c013ee..86197ec28f1 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs @@ -209,7 +209,7 @@ private static AddressFilter GetAddress(AddressAsKey[]? address) return AddressFilter.AnyAddress; } - return new AddressFilter(address.ToHashSet()); + return new AddressFilter(address); } private static FilterTopic?[]? GetFilterTopics(IEnumerable? topics) => topics?.Select(GetTopic).ToArray(); diff --git a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs index b1eddee6df1..2eeb5ba2542 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs @@ -87,6 +87,11 @@ public IEnumerable FindLogs(LogFilter filter, BlockHeader fromBlock, } cancellationToken.ThrowIfCancellationRequested(); + if (toBlock.Number > _blockFinder.Head?.Number) + { + throw new ArgumentException("requested block range is in the future"); + } + bool shouldUseBloom = ShouldUseBloomDatabase(fromBlock, toBlock); bool canUseBloom = CanUseBloomDatabase(toBlock, fromBlock); bool useBloom = shouldUseBloom && canUseBloom; From fbe0e236a7bef1d5b8db7736a86532b5730d280b Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 17:25:23 +0300 Subject: [PATCH 07/19] Fix build --- .../Filters/AddressFilter.cs | 5 +++ .../Modules/Eth/FilterTests.cs | 31 ++++++++++--------- .../Modules/SubscribeModuleTests.cs | 16 ++++++---- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs index 9fd88e904aa..b0c6c69d8db 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs @@ -14,6 +14,11 @@ public class AddressFilter private Bloom.BloomExtract[]? _addressesBloomIndexes; private Bloom.BloomExtract? _addressBloomExtract; + public AddressFilter(Address address) + { + Address = address; + } + public AddressFilter(AddressAsKey[] addresses) { if (addresses.Length == 1) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs index 2ab35c9ae37..86a80be09e7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs @@ -6,6 +6,8 @@ using FluentAssertions; using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Serialization.Json; @@ -48,16 +50,15 @@ public static IEnumerable JsonTests { FromBlock = BlockParameter.Earliest, ToBlock = BlockParameter.Pending, - Topics = new object?[] - { + Topics = + [ null, - "0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7", - new[] - { - "0x000500002bd87daa34d8ff0daf3465c96044d8f6667614850000000000000001", - "0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7" - } - } + [new("0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7")], + [ + new Hash256("0x000500002bd87daa34d8ff0daf3465c96044d8f6667614850000000000000001"), + new Hash256("0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7") + ] + ] }); yield return new TestCaseData( @@ -77,16 +78,16 @@ public static IEnumerable JsonTests }), new Filter { - Address = "0xc2d77d118326c33bbe36ebeabf4f7ed6bc2dda5c", + Address = [new Address("0xc2d77d118326c33bbe36ebeabf4f7ed6bc2dda5c")], FromBlock = new BlockParameter(0x1143ade), ToBlock = BlockParameter.Latest, - Topics = new object?[] - { - "0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7", + Topics = + [ + [new("0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7")], null, null, - "0x000500002bd87daa34d8ff0daf3465c96044d8f6667614850000000000000001" - } + [new("0x000500002bd87daa34d8ff0daf3465c96044d8f6667614850000000000000001")] + ] }); var blockHash = "0x892a8b3ccc78359e059e67ec44c83bfed496721d48c2d1dd929d6e4cd6559d35"; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs index edf0f8bbfa5..e6467d56df1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs @@ -603,8 +603,8 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ { FromBlock = BlockParameter.Latest, ToBlock = BlockParameter.Latest, - Address = "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099", - Topics = new[] { TestItem.KeccakA } + Address = [new Address("0xb7705ae4c6f81b66cdb323c65f4e8133690fc099")], + Topics = [[TestItem.KeccakA]] }; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; @@ -651,8 +651,8 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ { FromBlock = BlockParameter.Latest, ToBlock = BlockParameter.Latest, - Address = "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099", - Topics = new[] { TestItem.KeccakA } + Address = [new Address("0xb7705ae4c6f81b66cdb323c65f4e8133690fc099")], + Topics = [[TestItem.KeccakA]] }; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; @@ -699,8 +699,12 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ { FromBlock = BlockParameter.Latest, ToBlock = BlockParameter.Latest, - Address = new[] { "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099", "0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358" }, - Topics = new[] { TestItem.KeccakA, TestItem.KeccakD } + Address = + [ + new Address("0xb7705ae4c6f81b66cdb323c65f4e8133690fc099"), + new Address("0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358") + ], + Topics = [[ TestItem.KeccakA, TestItem.KeccakD ]] }; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA, TestItem.KeccakD).WithData(TestItem.RandomDataA).TestObject; From 05ae70fe8f091974ad9563f6c8b2b283b669c558 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 21:58:16 +0300 Subject: [PATCH 08/19] Fix range in the future --- .../Nethermind.Facade/Find/LogFinder.cs | 5 -- .../Modules/Eth/EthRpcModule.cs | 67 +++++++------------ 2 files changed, 24 insertions(+), 48 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs index 2eeb5ba2542..b1eddee6df1 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs @@ -87,11 +87,6 @@ public IEnumerable FindLogs(LogFilter filter, BlockHeader fromBlock, } cancellationToken.ThrowIfCancellationRequested(); - if (toBlock.Number > _blockFinder.Head?.Number) - { - throw new ArgumentException("requested block range is in the future"); - } - bool shouldUseBloom = ShouldUseBloomDatabase(fromBlock, toBlock); bool canUseBloom = CanUseBloomDatabase(toBlock, fromBlock); bool useBloom = shouldUseBloom && canUseBloom; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 6adb304f637..79b29407947 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -591,41 +591,46 @@ public ResultWrapper> eth_getLogs(Filter filter) using CancellationTokenSource timeout = BuildTimeoutCancellationTokenSource(); CancellationToken cancellationToken = timeout.Token; - if (!TryFindBlockHeaderOrUseLatest(_blockFinder, ref toBlock, out SearchResult toBlockResult, out long? sourceToBlockNumber)) + long? headNumber = _blockFinder.Head?.Number; + if (headNumber < filter.FromBlock?.BlockNumber || headNumber < filter.ToBlock?.BlockNumber) { - return FailWithNoHeadersSyncedYet(toBlockResult); + return ResultWrapper>.Fail("requested block range is in the future", ErrorCodes.InvalidParams); + } + + SearchResult fromResult = blockFinder.SearchForHeader(fromBlock); + if (fromResult.IsError) + { + return FailWithNoHeadersSyncedYet(fromResult); } cancellationToken.ThrowIfCancellationRequested(); - SearchResult fromBlockResult; - long? sourceFromBlockNumber; + + SearchResult toResult; if (fromBlock == toBlock) { - fromBlockResult = toBlockResult; - sourceFromBlockNumber = sourceToBlockNumber; + toResult = fromResult; } - else if (!TryFindBlockHeaderOrUseLatest(_blockFinder, ref fromBlock, out fromBlockResult, out sourceFromBlockNumber)) + else { - return FailWithNoHeadersSyncedYet(fromBlockResult); + toResult = blockFinder.SearchForHeader(fromBlock); + if (toResult.IsError) + { + return FailWithNoHeadersSyncedYet(toResult); + } } - if (sourceFromBlockNumber > sourceToBlockNumber) - { - return ResultWrapper>.Fail("invalid block range params", ErrorCodes.InvalidParams); - } + cancellationToken.ThrowIfCancellationRequested(); - if (_blockFinder.Head?.Number is not null && sourceFromBlockNumber > _blockFinder.Head.Number) + BlockHeader fromBlockHeader = fromResult.Object!; + BlockHeader toBlockHeader = toResult.Object!; + + if (fromBlockHeader.Number > toBlockHeader.Number) { - return ResultWrapper>.Success([]); + return ResultWrapper>.Fail("invalid block range params", ErrorCodes.InvalidParams); } - cancellationToken.ThrowIfCancellationRequested(); - - BlockHeader fromBlockHeader = fromBlockResult.Object; - BlockHeader toBlockHeader = toBlockResult.Object; - try { LogFilter logFilter = _blockchainBridge.GetFilter(fromBlock, toBlock, filter.Address, filter.Topics); @@ -655,30 +660,6 @@ public ResultWrapper> eth_getLogs(Filter filter) ResultWrapper> FailWithNoHeadersSyncedYet(SearchResult blockResult) => GetFailureResult, BlockHeader>(blockResult, _ethSyncingInfo.SyncMode.HaveNotSyncedHeadersYet()); - - // If there is an error, we check if we seach by number and it's after the head, then try to use head instead - static bool TryFindBlockHeaderOrUseLatest(IBlockFinder blockFinder, ref BlockParameter blockParameter, out SearchResult blockResult, out long? sourceBlockNumber) - { - blockResult = blockFinder.SearchForHeader(blockParameter); - - if (blockResult.IsError) - { - if (blockParameter.Type is BlockParameterType.BlockNumber && - blockFinder.Head?.Number < blockParameter.BlockNumber) - { - blockResult = new SearchResult(blockFinder.Head.Header); - - sourceBlockNumber = blockParameter.BlockNumber.Value; - return true; - } - - sourceBlockNumber = null; - return false; - } - - sourceBlockNumber = blockResult.Object.Number; - return true; - } } // https://github.com/ethereum/EIPs/issues/1186 From 87827697cfda2adc6c28273ced0cff6db2c6d386 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 22:22:02 +0300 Subject: [PATCH 09/19] Fix block range --- .../Modules/Eth/EthRpcModule.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 79b29407947..6771c5cfbf0 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -584,18 +584,25 @@ public ResultWrapper> eth_getFilterLogs(UInt256 filterId) public ResultWrapper> eth_getLogs(Filter filter) { - BlockParameter fromBlock = filter.FromBlock; - BlockParameter toBlock = filter.ToBlock; + // FromBlock and ToBlock can be: + // number, Earliest, Latest + // blockHash if fromBlock = toBlock + BlockParameter fromBlock = filter.FromBlock!; + BlockParameter toBlock = filter.ToBlock!; // because of lazy evaluation of enumerable, we need to do the validation here first using CancellationTokenSource timeout = BuildTimeoutCancellationTokenSource(); CancellationToken cancellationToken = timeout.Token; long? headNumber = _blockFinder.Head?.Number; - if (headNumber < filter.FromBlock?.BlockNumber || headNumber < filter.ToBlock?.BlockNumber) + if (headNumber < fromBlock.BlockNumber || headNumber < toBlock.BlockNumber) { return ResultWrapper>.Fail("requested block range is in the future", ErrorCodes.InvalidParams); } + if (fromBlock.BlockNumber > toBlock.BlockNumber) + { + return ResultWrapper>.Fail("invalid block range params", ErrorCodes.InvalidParams); + } SearchResult fromResult = blockFinder.SearchForHeader(fromBlock); if (fromResult.IsError) @@ -605,9 +612,7 @@ public ResultWrapper> eth_getLogs(Filter filter) cancellationToken.ThrowIfCancellationRequested(); - SearchResult toResult; - if (fromBlock == toBlock) { toResult = fromResult; @@ -626,11 +631,6 @@ public ResultWrapper> eth_getLogs(Filter filter) BlockHeader fromBlockHeader = fromResult.Object!; BlockHeader toBlockHeader = toResult.Object!; - if (fromBlockHeader.Number > toBlockHeader.Number) - { - return ResultWrapper>.Fail("invalid block range params", ErrorCodes.InvalidParams); - } - try { LogFilter logFilter = _blockchainBridge.GetFilter(fromBlock, toBlock, filter.Address, filter.Topics); From 4e9ee5881dc3088276ef62ba5461350d11d00a70 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 22:35:16 +0300 Subject: [PATCH 10/19] to --- src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 6771c5cfbf0..c378b42f5a8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -619,7 +619,7 @@ public ResultWrapper> eth_getLogs(Filter filter) } else { - toResult = blockFinder.SearchForHeader(fromBlock); + toResult = blockFinder.SearchForHeader(toBlock); if (toResult.IsError) { return FailWithNoHeadersSyncedYet(toResult); From 001ed0ed55ea008b9dab2db77f2c7f0e5331fe1a Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 22:57:57 +0300 Subject: [PATCH 11/19] Fix tests --- .../Builders/FilterBuilder.cs | 2 +- .../Filters/AddressFilterTests.cs | 32 +++++++++---------- .../Filters/FilterStoreTests.cs | 24 ++++++++------ .../Nethermind.Facade/Filters/FilterStore.cs | 16 ++++++++-- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs b/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs index 86c7706fe3f..44f7cf1cf19 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs @@ -125,7 +125,7 @@ public FilterBuilder WithAddress(Address address) public FilterBuilder WithAddresses(params Address[] addresses) { - _address = new AddressFilter(addresses.Select(static a => new AddressAsKey(a)).ToHashSet()); + _address = new AddressFilter(addresses.Select(static a => new AddressAsKey(a)).ToArray()); return this; } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs index cbedcef98a5..36fac9f623f 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs @@ -73,7 +73,7 @@ public void Accepts_any_address_by_ref() [Test] public void Accepts_any_address_when_set_is_empty() { - HashSet addresses = new(); + AddressAsKey[] addresses = []; AddressFilter filter = new AddressFilter(addresses); filter.Accepts(TestItem.AddressA).Should().BeTrue(); @@ -84,7 +84,7 @@ public void Accepts_any_address_when_set_is_empty() [Test] public void Accepts_any_address_when_set_is_empty_by_ref() { - HashSet addresses = new(); + AddressAsKey[] addresses = []; AddressFilter filter = new AddressFilter(addresses); AddressStructRef addressARef = TestItem.AddressA.ToStructRef(); @@ -98,10 +98,10 @@ public void Accepts_any_address_when_set_is_empty_by_ref() [Test] public void Accepts_only_addresses_in_a_set() { - HashSet addresses = new() - { + AddressAsKey[] addresses = + [ TestItem.AddressA, TestItem.AddressC - }; + ]; AddressFilter filter = new AddressFilter(addresses); filter.Accepts(TestItem.AddressA).Should().BeTrue(); @@ -112,10 +112,10 @@ public void Accepts_only_addresses_in_a_set() [Test] public void Accepts_only_addresses_in_a_set_by_ref() { - HashSet addresses = new() - { + AddressAsKey[] addresses = + [ TestItem.AddressA, TestItem.AddressC - }; + ]; AddressFilter filter = new AddressFilter(addresses); AddressStructRef addressARef = TestItem.AddressA.ToStructRef(); @@ -187,7 +187,7 @@ public void Matches_bloom_using_any_address_by_ref() [Test] public void Matches_any_bloom_when_set_is_empty() { - HashSet addresses = new(); + AddressAsKey[] addresses = []; AddressFilter filter = new AddressFilter(addresses); filter.Matches(BloomFromAddress(TestItem.AddressA)).Should().BeTrue(); @@ -198,7 +198,7 @@ public void Matches_any_bloom_when_set_is_empty() [Test] public void Matches_any_bloom_when_set_is_empty_by_ref() { - HashSet addresses = new(); + AddressAsKey[] addresses = []; AddressFilter filter = new AddressFilter(addresses); BloomStructRef bloomARef = BloomFromAddress(TestItem.AddressA).ToStructRef(); @@ -235,10 +235,10 @@ public void Matches_any_bloom_when_set_is_forced_null_by_ref() [Test] public void Matches_any_bloom_using_addresses_set() { - HashSet addresses = new() - { + AddressAsKey[] addresses = + [ TestItem.AddressA, TestItem.AddressC - }; + ]; AddressFilter filter = new AddressFilter(addresses); filter.Matches(BloomFromAddress(TestItem.AddressA)).Should().BeTrue(); @@ -249,10 +249,10 @@ public void Matches_any_bloom_using_addresses_set() [Test] public void Matches_any_bloom_using_addresses_set_by_ref() { - HashSet addresses = new() - { + AddressAsKey[] addresses = + [ TestItem.AddressA, TestItem.AddressC - }; + ]; AddressFilter filter = new AddressFilter(addresses); BloomStructRef bloomARef = BloomFromAddress(TestItem.AddressA).ToStructRef(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs index 20d90ed8c3f..51e67845edd 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/FilterStoreTests.cs @@ -11,6 +11,7 @@ using Nethermind.Blockchain.Filters.Topics; using Nethermind.Blockchain.Find; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Core.Test.Builders; using Nethermind.Core.Timers; using NSubstitute; @@ -102,14 +103,14 @@ public static IEnumerable CorrectlyCreatesAddressFilterTestCases get { yield return new TestCaseData(null, AddressFilter.AnyAddress); - yield return new TestCaseData(TestItem.AddressA.ToString(), new AddressFilter(TestItem.AddressA)); - yield return new TestCaseData(new[] { TestItem.AddressA.ToString(), TestItem.AddressB.ToString() }, - new AddressFilter(new HashSet() { TestItem.AddressA, TestItem.AddressB })); + yield return new TestCaseData(new[] { new AddressAsKey(TestItem.AddressA) }, new AddressFilter(TestItem.AddressA)); + yield return new TestCaseData(new[] { new AddressAsKey(TestItem.AddressA), new AddressAsKey(TestItem.AddressB) }, + new AddressFilter([TestItem.AddressA, TestItem.AddressB])); } } [TestCaseSource(nameof(CorrectlyCreatesAddressFilterTestCases))] - public void Correctly_creates_address_filter(object address, AddressFilter expected) + public void Correctly_creates_address_filter(AddressAsKey[] address, AddressFilter expected) { BlockParameter from = new(100); BlockParameter to = new(BlockParameterType.Latest); @@ -124,22 +125,25 @@ public static IEnumerable CorrectlyCreatesTopicsFilterTestCases { yield return new TestCaseData(null, SequenceTopicsFilter.AnyTopic); - yield return new TestCaseData(new[] { TestItem.KeccakA.ToString() }, + yield return new TestCaseData(new[] { new[] { TestItem.KeccakA } }, new SequenceTopicsFilter(new SpecificTopic(TestItem.KeccakA))); - yield return new TestCaseData(new[] { TestItem.KeccakA.ToString(), TestItem.KeccakB.ToString() }, + yield return new TestCaseData(new[] { new[] { TestItem.KeccakA }, new[] { TestItem.KeccakB } }, new SequenceTopicsFilter(new SpecificTopic(TestItem.KeccakA), new SpecificTopic(TestItem.KeccakB))); - yield return new TestCaseData(new[] { null, TestItem.KeccakB.ToString() }, + yield return new TestCaseData(new[] { null, new[] { TestItem.KeccakB } }, new SequenceTopicsFilter(AnyTopic.Instance, new SpecificTopic(TestItem.KeccakB))); - yield return new TestCaseData(new object[] { new[] { TestItem.KeccakA.ToString(), TestItem.KeccakB.ToString(), TestItem.KeccakC.ToString() }, TestItem.KeccakD.ToString() }, - new SequenceTopicsFilter(new OrExpression(new SpecificTopic(TestItem.KeccakA), new SpecificTopic(TestItem.KeccakB), new SpecificTopic(TestItem.KeccakC)), new SpecificTopic(TestItem.KeccakD))); + yield return new TestCaseData( + new[] { new[] { TestItem.KeccakA, TestItem.KeccakB, TestItem.KeccakC }, new[] { TestItem.KeccakD } }, + new SequenceTopicsFilter( + new OrExpression(new SpecificTopic(TestItem.KeccakA), new SpecificTopic(TestItem.KeccakB), + new SpecificTopic(TestItem.KeccakC)), new SpecificTopic(TestItem.KeccakD))); } } [TestCaseSource(nameof(CorrectlyCreatesTopicsFilterTestCases))] - public void Correctly_creates_topics_filter(IEnumerable topics, TopicsFilter expected) + public void Correctly_creates_topics_filter(Hash256[]?[]? topics, TopicsFilter expected) { BlockParameter from = new(100); BlockParameter to = new(BlockParameterType.Latest); diff --git a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs index 86197ec28f1..af53393d987 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs @@ -216,10 +216,20 @@ private static AddressFilter GetAddress(AddressAsKey[]? address) private static FilterTopic? GetTopic(Hash256[]? topics) { - return new FilterTopic + if (topics?.Length == 1) { - Topics = topics - }; + return new FilterTopic + { + Topic = topics[0] + }; + } + else + { + return new FilterTopic() + { + Topics = topics + }; + } } private class FilterTopic From 1ac706034424a039d378abe5f31baf2826c9ef94 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 23:47:15 +0300 Subject: [PATCH 12/19] Fix json rpc tests --- .../Nethermind.Facade/BlockchainBridge.cs | 4 ++-- .../JsonRpcServiceTests.cs | 1 - .../Modules/Eth/EthRpcModuleTests.cs | 22 +++++++++---------- .../Modules/Eth/FilterTests.cs | 7 ++---- .../Modules/SubscribeModuleTests.cs | 4 ++-- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 4 ++-- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 8c3c172a87f..f9e91fce595 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -325,10 +325,10 @@ public bool TryGetLogs(int filterId, out IEnumerable filterLogs, Canc return filter is not null; } - public int NewFilter(BlockParameter? fromBlock, BlockParameter? toBlock, + public int NewFilter(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? address = null, IEnumerable? topics = null) { - LogFilter filter = filterStore.CreateLogFilter(fromBlock ?? BlockParameter.Latest, toBlock ?? BlockParameter.Latest, address, topics); + LogFilter filter = filterStore.CreateLogFilter(fromBlock, toBlock, address, topics); filterStore.SaveFilter(filter); return filter.Id; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 782ad11ecfa..53007060e3f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -150,7 +150,6 @@ public void GetNewFilterTest() var parameters = new { fromBlock = "0x1", - toBlock = "latest", address = "0x1f88f1f195afa192cfee860698584c030f4c9db2", topics = new List { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs index 0e6b8f73d9c..d6c249cd0a5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs @@ -369,7 +369,7 @@ void handleNewBlock(object? sender, BlockEventArgs e) } test.BlockTree.NewHeadBlock += handleNewBlock; - using JsonRpcResponse newFilterResp = await RpcTest.TestRequest(test.EthRpcModule, "eth_newFilter", new { fromBlock = "latest" }); + using JsonRpcResponse newFilterResp = await RpcTest.TestRequest(test.EthRpcModule, "eth_newFilter", new { }); string getFilterLogsSerialized1 = await test.TestEthRpc("eth_getFilterChanges", (newFilterResp as JsonRpcSuccessResponse)!.Result?.ToString() ?? "0x0"); //expect empty - no changes so far @@ -579,9 +579,9 @@ void HandleNewBlock(object? sender, BlockReplacementEventArgs e) await test.AddBlock(createCodeTx); - string getLogsSerialized = await test.TestEthRpc("eth_getLogs", $"{{\"fromBlock\":\"{blockHash}\"}}"); + string getLogsSerialized = await test.TestEthRpc("eth_getLogs", $"{{\"blockHash\":\"{blockHash}\"}}"); - using JsonRpcResponse? newFilterResp = await RpcTest.TestRequest(test.EthRpcModule, "eth_newFilter", new { fromBlock = blockHash }); + using JsonRpcResponse? newFilterResp = await RpcTest.TestRequest(test.EthRpcModule, "eth_newFilter", new { blockHash = blockHash }); Assert.That(newFilterResp is not null && newFilterResp is JsonRpcSuccessResponse, Is.True); @@ -591,13 +591,13 @@ void HandleNewBlock(object? sender, BlockReplacementEventArgs e) } [TestCase("{}", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"fromBlock":"0x2","toBlock":"latest","address":"0x00000000000000000001","topics":["0x00000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"fromBlock":"earliest","toBlock":"pending","address":["0x00000000000000000001", "0x00000000000000000001"],"topics":["0x00000000000000000000000000000001", "0x00000000000000000000000000000002"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"topics":[null, ["0x00000000000000000000000000000001", "0x00000000000000000000000000000002"]]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"fromBlock":"0x10","toBlock":"latest","address":"0x00000000000000000001","topics":["0x00000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid block range params"},"id":67}""")] - [TestCase("""{"fromBlock":"0x2","toBlock":"0x11","address":"0x00000000000000000001","topics":["0x00000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"fromBlock":"0x2","toBlock":"0x1","address":"0x00000000000000000001","topics":["0x00000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid block range params"},"id":67}""")] - [TestCase("""{"fromBlock":"0x11","toBlock":"0x12","address":"0x00000000000000000001","topics":["0x00000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[],"id":67}""")] + [TestCase("""{"fromBlock":"0x2","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] + [TestCase("""{"address":["0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000001"],"topics":["0x0000000000000000000000000000000000000001", "0x00000000000000000000000000000002"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] + [TestCase("""{"topics":[null, ["0x0000000000000000000000000000000000000001", "0x00000000000000000000000000000002"]]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] + [TestCase("""{"fromBlock":"0x10","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"requested block range is in the future"},"id":67}""")] + [TestCase("""{"fromBlock":"0x2","toBlock":"0x3","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] + [TestCase("""{"fromBlock":"0x2","toBlock":"0x1","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid block range params"},"id":67}""")] + [TestCase("""{"fromBlock":"0x11","toBlock":"0x12","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"requested block range is in the future"},"id":67}""")] public async Task Eth_get_logs(string parameter, string expected) { using Context ctx = await Context.Create(); @@ -638,7 +638,7 @@ static IEnumerable GetLogs(CancellationToken ct) serialized.Should().Be("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32016,\"message\":\"eth_getLogs request was canceled due to enabled timeout.\"},\"id\":67}"); } - [TestCase("{\"fromBlock\":\"earliest\",\"toBlock\":\"latest\"}", "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"resource not found message\"},\"id\":67}")] + [TestCase("{}", "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"resource not found message\"},\"id\":67}")] public async Task Eth_get_logs_with_resourceNotFound(string parameter, string expected) { using Context ctx = await Context.Create(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs index 86a80be09e7..af06485f1bd 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/FilterTests.cs @@ -25,7 +25,7 @@ public static IEnumerable JsonTests yield return new TestCaseData("{}", new Filter { - FromBlock = BlockParameter.Latest, + FromBlock = BlockParameter.Earliest, ToBlock = BlockParameter.Latest, }); @@ -33,8 +33,6 @@ public static IEnumerable JsonTests JsonSerializer.Serialize( new { - fromBlock = "earliest", - toBlock = "pending", topics = new object?[] { null, @@ -49,7 +47,7 @@ public static IEnumerable JsonTests new Filter { FromBlock = BlockParameter.Earliest, - ToBlock = BlockParameter.Pending, + ToBlock = BlockParameter.Latest, Topics = [ null, @@ -67,7 +65,6 @@ public static IEnumerable JsonTests { address = "0xc2d77d118326c33bbe36ebeabf4f7ed6bc2dda5c", fromBlock = "0x1143ade", - toBlock = "latest", topics = new object?[] { "0xe194ef610f9150a2db4110b3db5116fd623175dca3528d7ae7046a1042f84fe7", diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs index e6467d56df1..fd91889dfa7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs @@ -456,7 +456,7 @@ public async Task LogsSubscription_with_null_arguments_creating_result() [Test] public async Task LogsSubscription_with_valid_arguments_creating_result() { - string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"fromBlock\":\"latest\",\"toBlock\":\"latest\",\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"topics\":\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"}"); + string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"topics\":\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"}"); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"result\":\"", serialized.Substring(serialized.Length - 44, 34), "\",\"id\":67}"); expectedResult.Should().Be(serialized); } @@ -464,7 +464,7 @@ public async Task LogsSubscription_with_valid_arguments_creating_result() [Test] public async Task LogsSubscription_dispose_regression() { - string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"address\":[\"0x0000000000000000000000000000000000000314\"],\"fromBlock\":\"0x0\",\"toBlock\":\"latest\",\"topics\":[]}"); + string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"address\":[\"0x0000000000000000000000000000000000000314\"],\"fromBlock\":\"0x0\",\"topics\":[]}"); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"result\":\"", serialized.Substring(serialized.Length - 44, 34), "\",\"id\":67}"); expectedResult.Should().Be(serialized); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 1de6381b627..1b194d056f8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -15,9 +15,9 @@ public class Filter : IJsonRpcParam { public AddressAsKey[]? Address { get; set; } - public BlockParameter? FromBlock { get; set; } + public BlockParameter FromBlock { get; set; } - public BlockParameter? ToBlock { get; set; } + public BlockParameter ToBlock { get; set; } public IEnumerable? Topics { get; set; } From e36b6daafb6c390b1bfe036f6317445a7f53f1f8 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Fri, 5 Dec 2025 23:53:43 +0300 Subject: [PATCH 13/19] Fix formatting --- .../Modules/SubscribeModuleTests.cs | 30 +++++++++++-------- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs index fd91889dfa7..b410941fbda 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs @@ -704,7 +704,7 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ new Address("0xb7705ae4c6f81b66cdb323c65f4e8133690fc099"), new Address("0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358") ], - Topics = [[ TestItem.KeccakA, TestItem.KeccakD ]] + Topics = [[TestItem.KeccakA, TestItem.KeccakD]] }; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA, TestItem.KeccakD).WithData(TestItem.RandomDataA).TestObject; @@ -926,12 +926,14 @@ public async Task MultipleSubscriptions_concurrent_fast_messages(int messages) Task subA = Task.Run(() => { ITxPool txPool = Substitute.For(); - using NewPendingTransactionsSubscription subscription = new( - // ReSharper disable once AccessToDisposedClosure - jsonRpcDuplexClient: client, - txPool: txPool, - specProvider: _specProvider, - logManager: LimboLogs.Instance); + using NewPendingTransactionsSubscription subscription = + new( + // ReSharper disable once AccessToDisposedClosure + jsonRpcDuplexClient: client, + txPool: txPool, + specProvider: _specProvider, + logManager: LimboLogs.Instance + ); for (int i = 0; i < messages; i++) { @@ -942,12 +944,14 @@ public async Task MultipleSubscriptions_concurrent_fast_messages(int messages) Task subB = Task.Run(() => { IBlockTree blockTree = Substitute.For(); - using NewHeadSubscription subscription = new( - // ReSharper disable once AccessToDisposedClosure - jsonRpcDuplexClient: client, - blockTree: blockTree, - specProvider: new TestSpecProvider(new ReleaseSpec()), - logManager: LimboLogs.Instance); + using NewHeadSubscription subscription = + new( + // ReSharper disable once AccessToDisposedClosure + jsonRpcDuplexClient: client, + blockTree: blockTree, + specProvider: new TestSpecProvider(new ReleaseSpec()), + logManager: LimboLogs.Instance + ); for (int i = 0; i < messages; i++) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 1b194d056f8..68be024a44a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -101,7 +101,7 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) { switch (token.ValueKind) { - case JsonValueKind.Undefined or JsonValueKind.Null: + case JsonValueKind.Undefined or JsonValueKind.Null: yield return null; break; case JsonValueKind.String: From 2f6dee699f40faeacdf06bb520c4f9c28c29f830 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Sat, 6 Dec 2025 00:00:20 +0300 Subject: [PATCH 14/19] Fix blockchain tests --- .../Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs index 36fac9f623f..69d73ec8c18 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/AddressFilterTests.cs @@ -212,7 +212,7 @@ public void Matches_any_bloom_when_set_is_empty_by_ref() [Test] public void Matches_any_bloom_when_set_is_forced_null() { - AddressFilter filter = new AddressFilter(addresses: null!); + AddressFilter filter = new AddressFilter([]); filter.Matches(BloomFromAddress(TestItem.AddressA)).Should().BeTrue(); filter.Matches(BloomFromAddress(TestItem.AddressB)).Should().BeTrue(); @@ -222,7 +222,7 @@ public void Matches_any_bloom_when_set_is_forced_null() [Test] public void Matches_any_bloom_when_set_is_forced_null_by_ref() { - AddressFilter filter = new AddressFilter(addresses: null!); + AddressFilter filter = new AddressFilter([]); BloomStructRef bloomARef = BloomFromAddress(TestItem.AddressA).ToStructRef(); BloomStructRef bloomBRef = BloomFromAddress(TestItem.AddressB).ToStructRef(); From 097b6b0c1e819e1480101160e5004ee5fe95982d Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Sun, 7 Dec 2025 21:41:57 +0300 Subject: [PATCH 15/19] Fix suggestions --- src/Nethermind/Nethermind.Facade/BlockchainBridge.cs | 8 ++++---- .../Nethermind.Facade/Filters/FilterStore.cs | 10 +++++----- src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs | 4 ++-- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index f9e91fce595..80305a26023 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -289,21 +289,21 @@ public ulong GetChainId() public IEnumerable GetLogs( BlockParameter fromBlock, BlockParameter toBlock, - AddressAsKey[]? address = null, + AddressAsKey[]? addresses = null, IEnumerable? topics = null, CancellationToken cancellationToken = default) { - LogFilter filter = GetFilter(fromBlock, toBlock, address, topics); + LogFilter filter = GetFilter(fromBlock, toBlock, addresses, topics); return logFinder.FindLogs(filter, cancellationToken); } public LogFilter GetFilter( BlockParameter fromBlock, BlockParameter toBlock, - AddressAsKey[]? address = null, + AddressAsKey[]? addresses = null, IEnumerable? topics = null) { - return filterStore.CreateLogFilter(fromBlock, toBlock, address, topics, false); + return filterStore.CreateLogFilter(fromBlock, toBlock, addresses, topics, false); } public IEnumerable GetLogs( diff --git a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs index af53393d987..d7603a778b8 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/FilterStore.cs @@ -124,11 +124,11 @@ public PendingTransactionFilter CreatePendingTransactionFilter(bool setId = true new(GetFilterId(setId)); public LogFilter CreateLogFilter(BlockParameter fromBlock, BlockParameter toBlock, - AddressAsKey[]? address = null, IEnumerable? topics = null, bool setId = true) => + AddressAsKey[]? addresses = null, IEnumerable? topics = null, bool setId = true) => new(GetFilterId(setId), fromBlock, toBlock, - GetAddress(address), + GetAddress(addresses), GetTopicsFilter(topics)); public void RemoveFilter(int filterId) @@ -202,14 +202,14 @@ private static TopicExpression GetTopicExpression(FilterTopic? filterTopic) return AnyTopic.Instance; } - private static AddressFilter GetAddress(AddressAsKey[]? address) + private static AddressFilter GetAddress(AddressAsKey[]? addresses) { - if (address is null) + if (addresses is null) { return AddressFilter.AnyAddress; } - return new AddressFilter(address); + return new AddressFilter(addresses); } private static FilterTopic?[]? GetFilterTopics(IEnumerable? topics) => topics?.Select(GetTopic).ToArray(); diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 0c5dad20dc5..ba5c19c9ad7 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -43,9 +43,9 @@ public interface IBlockchainBridge : ILogFinder Hash256[] GetPendingTransactionFilterChanges(int filterId); FilterLog[] GetLogFilterChanges(int filterId); FilterType GetFilterType(int filterId); - LogFilter GetFilter(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? address = null, IEnumerable? topics = null); + LogFilter GetFilter(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? addresses = null, IEnumerable? topics = null); IEnumerable GetLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, CancellationToken cancellationToken = default); - IEnumerable GetLogs(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? address = null, IEnumerable? topics = null, CancellationToken cancellationToken = default); + IEnumerable GetLogs(BlockParameter fromBlock, BlockParameter toBlock, AddressAsKey[]? addresses = null, IEnumerable? topics = null, CancellationToken cancellationToken = default); bool TryGetLogs(int filterId, out IEnumerable filterLogs, CancellationToken cancellationToken = default); void RunTreeVisitor(ITreeVisitor treeVisitor, Hash256 stateRoot) where TCtx : struct, INodeContext; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index 68be024a44a..ebde6b6ded4 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -40,7 +40,7 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) { if (hasFromBlock || hasToBlock) { - throw new ArgumentException("either (fromBlock and toBlock) or blockHash have to be specified"); + throw new ArgumentException("cannot specify both BlockHash and FromBlock/ToBlock, choose one or the other"); } FromBlock = new(new Hash256(blockHashElement.ToString())); From afd2a2413036e4d2ccfd62c1e9e50281c64b5ff0 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Sun, 7 Dec 2025 23:35:18 +0300 Subject: [PATCH 16/19] Fix tags --- .../Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs | 3 --- .../Nethermind.JsonRpc/Modules/Eth/Filter.cs | 12 ++++++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index c378b42f5a8..2dffcfa9733 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -584,9 +584,6 @@ public ResultWrapper> eth_getFilterLogs(UInt256 filterId) public ResultWrapper> eth_getLogs(Filter filter) { - // FromBlock and ToBlock can be: - // number, Earliest, Latest - // blockHash if fromBlock = toBlock BlockParameter fromBlock = filter.FromBlock!; BlockParameter toBlock = filter.ToBlock!; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs index ebde6b6ded4..f8d9a7bfe85 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Filter.cs @@ -7,7 +7,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Serialization.Json; +using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Eth; @@ -36,7 +36,7 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) bool hasFromBlock = filter.TryGetProperty("fromBlock"u8, out JsonElement fromBlockElement); bool hasToBlock = filter.TryGetProperty("toBlock"u8, out JsonElement toBlockElement); - if (hasBlockHash) + if (hasBlockHash && blockHashElement.ValueKind != JsonValueKind.Null) { if (hasFromBlock || hasToBlock) { @@ -48,8 +48,12 @@ public void ReadJson(JsonElement filter, JsonSerializerOptions options) } else { - FromBlock = hasFromBlock ? new BlockParameter(LongConverter.FromString(fromBlockElement.ToString())) : BlockParameter.Earliest; - ToBlock = hasToBlock ? new BlockParameter(LongConverter.FromString(toBlockElement.ToString())) : BlockParameter.Latest; + FromBlock = hasFromBlock && fromBlockElement.ValueKind != JsonValueKind.Null + ? BlockParameterConverter.GetBlockParameter(fromBlockElement.ToString()) + : BlockParameter.Earliest; + ToBlock = hasToBlock && toBlockElement.ValueKind != JsonValueKind.Null + ? BlockParameterConverter.GetBlockParameter(toBlockElement.ToString()) + : BlockParameter.Latest; } if (filter.TryGetProperty("address"u8, out JsonElement addressElement)) From 845b607c7606569d7d3deed2e9ab36e00bb057e7 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Sun, 7 Dec 2025 23:44:15 +0300 Subject: [PATCH 17/19] Remove address from AddressFilter --- .../Filters/AddressFilter.cs | 81 ++++++------------- 1 file changed, 23 insertions(+), 58 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs index b0c6c69d8db..f5874e1b7e9 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs @@ -12,43 +12,24 @@ public class AddressFilter public static readonly AddressFilter AnyAddress = new([]); private Bloom.BloomExtract[]? _addressesBloomIndexes; - private Bloom.BloomExtract? _addressBloomExtract; - public AddressFilter(Address address) + public AddressFilter(Address address) : this([address]) { - Address = address; } - public AddressFilter(AddressAsKey[] addresses) + public AddressFilter(IEnumerable addresses) { - if (addresses.Length == 1) - { - Address = addresses[0]; - } - else - { - Addresses = addresses.ToHashSet(); - } + Addresses = addresses.ToHashSet(); } - public Address? Address { get; } - public HashSet? Addresses { get; } + public HashSet Addresses { get; } private Bloom.BloomExtract[] AddressesBloomExtracts => _addressesBloomIndexes ??= CalculateBloomExtracts(); - private Bloom.BloomExtract AddressBloomExtract => _addressBloomExtract ??= Bloom.GetExtract(Address); - public bool Accepts(Address address) - { - if (Addresses?.Count > 0) - { - return Addresses.Contains(address); - } - - return Address is null || Address == address; - } + public bool Accepts(Address address) => Addresses.Contains(address); public bool Accepts(ref AddressStructRef address) { - if (Addresses?.Count > 0) + if (Addresses.Count > 0) { foreach (var a in Addresses) { @@ -58,55 +39,39 @@ public bool Accepts(ref AddressStructRef address) return false; } - return Address is null || Address == address; + return true; } public bool Matches(Bloom bloom) { - if (Addresses is not null) + bool result = true; + var indexes = AddressesBloomExtracts; + for (var i = 0; i < indexes.Length; i++) { - bool result = true; - var indexes = AddressesBloomExtracts; - for (var i = 0; i < indexes.Length; i++) + result = bloom.Matches(indexes[i]); + if (result) { - result = bloom.Matches(indexes[i]); - if (result) - { - break; - } + break; } - - return result; - } - if (Address is null) - { - return true; } - return bloom.Matches(AddressBloomExtract); + + return result; } public bool Matches(ref BloomStructRef bloom) { - if (Addresses is not null) + bool result = true; + var indexes = AddressesBloomExtracts; + for (var i = 0; i < indexes.Length; i++) { - bool result = true; - var indexes = AddressesBloomExtracts; - for (var i = 0; i < indexes.Length; i++) + result = bloom.Matches(indexes[i]); + if (result) { - result = bloom.Matches(indexes[i]); - if (result) - { - break; - } + break; } - - return result; - } - if (Address is null) - { - return true; } - return bloom.Matches(AddressBloomExtract); + + return result; } private Bloom.BloomExtract[] CalculateBloomExtracts() => Addresses.Select(static a => Bloom.GetExtract(a)).ToArray(); From dda430554c6cd815528174090b60e9701768ce07 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Sun, 7 Dec 2025 23:57:19 +0300 Subject: [PATCH 18/19] Fix tests --- .../Builders/FilterBuilder.cs | 2 +- .../Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs | 1 + .../Modules/Eth/EthRpcModuleTests.cs | 10 +++++----- .../Modules/SubscribeModuleTests.cs | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs b/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs index 44f7cf1cf19..ee7cc539f26 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs @@ -125,7 +125,7 @@ public FilterBuilder WithAddress(Address address) public FilterBuilder WithAddresses(params Address[] addresses) { - _address = new AddressFilter(addresses.Select(static a => new AddressAsKey(a)).ToArray()); + _address = new AddressFilter(addresses.Select(static a => new AddressAsKey(a))); return this; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 53007060e3f..782ad11ecfa 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -150,6 +150,7 @@ public void GetNewFilterTest() var parameters = new { fromBlock = "0x1", + toBlock = "latest", address = "0x1f88f1f195afa192cfee860698584c030f4c9db2", topics = new List { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs index d6c249cd0a5..98d795f7cb7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs @@ -369,7 +369,7 @@ void handleNewBlock(object? sender, BlockEventArgs e) } test.BlockTree.NewHeadBlock += handleNewBlock; - using JsonRpcResponse newFilterResp = await RpcTest.TestRequest(test.EthRpcModule, "eth_newFilter", new { }); + using JsonRpcResponse newFilterResp = await RpcTest.TestRequest(test.EthRpcModule, "eth_newFilter", new { fromBlock = "latest" }); string getFilterLogsSerialized1 = await test.TestEthRpc("eth_getFilterChanges", (newFilterResp as JsonRpcSuccessResponse)!.Result?.ToString() ?? "0x0"); //expect empty - no changes so far @@ -591,10 +591,10 @@ void HandleNewBlock(object? sender, BlockReplacementEventArgs e) } [TestCase("{}", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"fromBlock":"0x2","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"address":["0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000001"],"topics":["0x0000000000000000000000000000000000000001", "0x00000000000000000000000000000002"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] + [TestCase("""{"fromBlock":"0x2","toBlock":"latest","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] + [TestCase("""{"fromBlock":"earliest","toBlock":"pending","address":["0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000001"],"topics":["0x0000000000000000000000000000000000000001", "0x00000000000000000000000000000002"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] [TestCase("""{"topics":[null, ["0x0000000000000000000000000000000000000001", "0x00000000000000000000000000000002"]]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] - [TestCase("""{"fromBlock":"0x10","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"requested block range is in the future"},"id":67}""")] + [TestCase("""{"fromBlock":"0x10","toBlock":"latest","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"requested block range is in the future"},"id":67}""")] [TestCase("""{"fromBlock":"0x2","toBlock":"0x3","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","result":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","blockHash":"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760","blockNumber":"0x1","blockTimestamp":"0x1","data":"0x010203","logIndex":"0x1","removed":false,"topics":["0x017e667f4b8c174291d1543c466717566e206df1bfd6f30271055ddafdb18f72","0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2"],"transactionHash":"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111","transactionIndex":"0x1"}],"id":67}""")] [TestCase("""{"fromBlock":"0x2","toBlock":"0x1","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid block range params"},"id":67}""")] [TestCase("""{"fromBlock":"0x11","toBlock":"0x12","address":"0x0000000000000000000000000000000000000001","topics":["0x0000000000000000000000000000000000000001"]}""", """{"jsonrpc":"2.0","error":{"code":-32602,"message":"requested block range is in the future"},"id":67}""")] @@ -638,7 +638,7 @@ static IEnumerable GetLogs(CancellationToken ct) serialized.Should().Be("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32016,\"message\":\"eth_getLogs request was canceled due to enabled timeout.\"},\"id\":67}"); } - [TestCase("{}", "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"resource not found message\"},\"id\":67}")] + [TestCase("{\"fromBlock\":\"earliest\",\"toBlock\":\"latest\"}", "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"resource not found message\"},\"id\":67}")] public async Task Eth_get_logs_with_resourceNotFound(string parameter, string expected) { using Context ctx = await Context.Create(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs index b410941fbda..4a988139e3b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs @@ -456,7 +456,7 @@ public async Task LogsSubscription_with_null_arguments_creating_result() [Test] public async Task LogsSubscription_with_valid_arguments_creating_result() { - string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"topics\":\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"}"); + string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"fromBlock\":\"latest\",\"toBlock\":\"latest\",\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"topics\":\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"}"); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"result\":\"", serialized.Substring(serialized.Length - 44, 34), "\",\"id\":67}"); expectedResult.Should().Be(serialized); } @@ -464,7 +464,7 @@ public async Task LogsSubscription_with_valid_arguments_creating_result() [Test] public async Task LogsSubscription_dispose_regression() { - string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"address\":[\"0x0000000000000000000000000000000000000314\"],\"fromBlock\":\"0x0\",\"topics\":[]}"); + string serialized = await RpcTest.TestSerializedRequest(_subscribeRpcModule, "eth_subscribe", "logs", "{\"address\":[\"0x0000000000000000000000000000000000000314\"],\"fromBlock\":\"0x0\",\"toBlock\":\"latest\",\"topics\":[]}"); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"result\":\"", serialized.Substring(serialized.Length - 44, 34), "\",\"id\":67}"); expectedResult.Should().Be(serialized); } From 28df9d8291eb4416f1c30d178038f0f7982553b3 Mon Sep 17 00:00:00 2001 From: Nikita Meshcheriakov Date: Mon, 8 Dec 2025 00:14:16 +0300 Subject: [PATCH 19/19] Fix address filter --- src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs index f5874e1b7e9..e3d3b76a058 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs @@ -25,7 +25,7 @@ public AddressFilter(IEnumerable addresses) public HashSet Addresses { get; } private Bloom.BloomExtract[] AddressesBloomExtracts => _addressesBloomIndexes ??= CalculateBloomExtracts(); - public bool Accepts(Address address) => Addresses.Contains(address); + public bool Accepts(Address address) => Addresses.Count == 0 || Addresses.Contains(address); public bool Accepts(ref AddressStructRef address) {