Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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)));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void Accepts_any_address_by_ref()
[Test]
public void Accepts_any_address_when_set_is_empty()
{
HashSet<AddressAsKey> addresses = new();
AddressAsKey[] addresses = [];
AddressFilter filter = new AddressFilter(addresses);

filter.Accepts(TestItem.AddressA).Should().BeTrue();
Expand All @@ -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<AddressAsKey> addresses = new();
AddressAsKey[] addresses = [];
AddressFilter filter = new AddressFilter(addresses);

AddressStructRef addressARef = TestItem.AddressA.ToStructRef();
Expand All @@ -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<AddressAsKey> addresses = new()
{
AddressAsKey[] addresses =
[
TestItem.AddressA, TestItem.AddressC
};
];
AddressFilter filter = new AddressFilter(addresses);

filter.Accepts(TestItem.AddressA).Should().BeTrue();
Expand All @@ -112,10 +112,10 @@ public void Accepts_only_addresses_in_a_set()
[Test]
public void Accepts_only_addresses_in_a_set_by_ref()
{
HashSet<AddressAsKey> addresses = new()
{
AddressAsKey[] addresses =
[
TestItem.AddressA, TestItem.AddressC
};
];
AddressFilter filter = new AddressFilter(addresses);

AddressStructRef addressARef = TestItem.AddressA.ToStructRef();
Expand Down Expand Up @@ -187,7 +187,7 @@ public void Matches_bloom_using_any_address_by_ref()
[Test]
public void Matches_any_bloom_when_set_is_empty()
{
HashSet<AddressAsKey> addresses = new();
AddressAsKey[] addresses = [];
AddressFilter filter = new AddressFilter(addresses);

filter.Matches(BloomFromAddress(TestItem.AddressA)).Should().BeTrue();
Expand All @@ -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<AddressAsKey> addresses = new();
AddressAsKey[] addresses = [];
AddressFilter filter = new AddressFilter(addresses);

BloomStructRef bloomARef = BloomFromAddress(TestItem.AddressA).ToStructRef();
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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<AddressAsKey> addresses = new()
{
AddressAsKey[] addresses =
[
TestItem.AddressA, TestItem.AddressC
};
];
AddressFilter filter = new AddressFilter(addresses);

filter.Matches(BloomFromAddress(TestItem.AddressA)).Should().BeTrue();
Expand All @@ -249,10 +249,10 @@ public void Matches_any_bloom_using_addresses_set()
[Test]
public void Matches_any_bloom_using_addresses_set_by_ref()
{
HashSet<AddressAsKey> addresses = new()
{
AddressAsKey[] addresses =
[
TestItem.AddressA, TestItem.AddressC
};
];
AddressFilter filter = new AddressFilter(addresses);

BloomStructRef bloomARef = BloomFromAddress(TestItem.AddressA).ToStructRef();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<AddressAsKey>() { 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);
Expand All @@ -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<object> topics, TopicsFilter expected)
public void Correctly_creates_topics_filter(Hash256[]?[]? topics, TopicsFilter expected)
{
BlockParameter from = new(100);
BlockParameter to = new(BlockParameterType.Latest);
Expand Down
18 changes: 9 additions & 9 deletions src/Nethermind/Nethermind.Facade/BlockchainBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,21 +289,21 @@ public ulong GetChainId()
public IEnumerable<FilterLog> GetLogs(
BlockParameter fromBlock,
BlockParameter toBlock,
object? address = null,
IEnumerable<object>? topics = null,
AddressAsKey[]? addresses = null,
IEnumerable<Hash256[]?>? 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,
object? address = null,
IEnumerable<object>? topics = null)
AddressAsKey[]? addresses = null,
IEnumerable<Hash256[]?>? topics = null)
{
return filterStore.CreateLogFilter(fromBlock, toBlock, address, topics, false);
return filterStore.CreateLogFilter(fromBlock, toBlock, addresses, topics, false);
}

public IEnumerable<FilterLog> GetLogs(
Expand All @@ -325,10 +325,10 @@ public bool TryGetLogs(int filterId, out IEnumerable<FilterLog> filterLogs, Canc
return filter is not null;
}

public int NewFilter(BlockParameter? fromBlock, BlockParameter? toBlock,
object? address = null, IEnumerable<object>? topics = null)
public int NewFilter(BlockParameter fromBlock, BlockParameter toBlock,
AddressAsKey[]? address = null, IEnumerable<Hash256[]?>? 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;
}
Expand Down
76 changes: 24 additions & 52 deletions src/Nethermind/Nethermind.Facade/Filters/AddressFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,27 @@ namespace Nethermind.Blockchain.Filters
{
public class AddressFilter
{
public static readonly AddressFilter AnyAddress = new(addresses: new HashSet<AddressAsKey>());
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(HashSet<AddressAsKey> addresses)
public AddressFilter(IEnumerable<AddressAsKey> addresses)
{
Addresses = addresses;
Addresses = addresses.ToHashSet();
}

public Address? Address { get; }
public HashSet<AddressAsKey>? Addresses { get; }
public HashSet<AddressAsKey> 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.Count == 0 || Addresses.Contains(address);

public bool Accepts(ref AddressStructRef address)
{
if (Addresses?.Count > 0)
if (Addresses.Count > 0)
{
foreach (var a in Addresses)
{
Expand All @@ -51,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();
Expand Down
Loading