diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs index 3a901bfaafdf..6614273d8697 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs @@ -21,38 +21,38 @@ namespace Nethermind.Blockchain.Test.Filters; [Parallelizable(ParallelScope.All)] public class LogIndexFilterVisitorTests { - private record Ranges(Dictionary> Address, Dictionary>[] Topic) + private record Ranges(Dictionary> Address, Dictionary>[] Topic) { - public List this[Address address] => Address[address]; - public List this[int topicIndex, Hash256 hash] => Topic[topicIndex][hash]; + public List this[Address address] => Address[address]; + public List this[int topicIndex, Hash256 hash] => Topic[topicIndex][hash]; } - public class EnumeratorWrapper(int[] array) : IEnumerator + public class EnumeratorWrapper(uint[] array) : IEnumerator { - private readonly IEnumerator _enumerator = array.Cast().GetEnumerator(); + private readonly IEnumerator _enumerator = array.Cast().GetEnumerator(); public bool MoveNext() => _enumerator.MoveNext(); public void Reset() => _enumerator.Reset(); - public int Current => _enumerator.Current; + public uint Current => _enumerator.Current; object IEnumerator.Current => Current; public virtual void Dispose() => _enumerator.Dispose(); } [TestCase( - new[] { 1, 3, 5, 7, 9, }, - new[] { 0, 2, 4, 6, 8 }, + new uint[] { 1, 3, 5, 7, 9, }, + new uint[] { 0, 2, 4, 6, 8 }, TestName = "Non-intersecting, but similar ranges" )] [TestCase( - new[] { 1, 2, 3, 4, 5, }, - new[] { 5, 6, 7, 8, 9 }, + new uint[] { 1, 2, 3, 4, 5, }, + new uint[] { 5, 6, 7, 8, 9 }, TestName = "Intersects on first/last" )] [TestCase( - new[] { 1, 2, 3, 4, 5, }, - new[] { 6, 7, 8, 9, 10 }, + new uint[] { 1, 2, 3, 4, 5, }, + new uint[] { 6, 7, 8, 9, 10 }, TestName = "Non-intersecting ranges" )] - public void IntersectEnumerator(int[] s1, int[] s2) + public void IntersectEnumerator(uint[] s1, uint[] s2) { var expected = s1.Intersect(s2).Order().ToArray(); @@ -83,29 +83,29 @@ public void IntersectEnumerator_Random(int len1, int len2) [TestCase(0, 10)] public void IntersectEnumerator_SomeEmpty(int len1, int len2) { - var s1 = Enumerable.Range(0, len1).ToArray(); - var s2 = Enumerable.Range(0, len2).ToArray(); + var s1 = Enumerable.Range(0, len1).Select(i => (uint)i).ToArray(); + var s2 = Enumerable.Range(0, len2).Select(i => (uint)i).ToArray(); VerifyEnumerator(s1, s2, []); VerifyEnumerator(s2, s1, []); } [TestCase( - new[] { 1, 2, 3, 4, 5, }, - new[] { 2, 3, 4 }, + new uint[] { 1, 2, 3, 4, 5, }, + new uint[] { 2, 3, 4 }, TestName = "Contained" )] [TestCase( - new[] { 1, 2, 3, 4, 5, }, - new[] { 1, 2, 3, 4, 5, }, + new uint[] { 1, 2, 3, 4, 5, }, + new uint[] { 1, 2, 3, 4, 5, }, TestName = "Identical" )] [TestCase( - new[] { 1, 3, 5, 7, 9, }, - new[] { 2, 4, 6, 8, 10 }, + new uint[] { 1, 3, 5, 7, 9, }, + new uint[] { 2, 4, 6, 8, 10 }, TestName = "Complementary" )] - public void UnionEnumerator(int[] s1, int[] s2) + public void UnionEnumerator(uint[] s1, uint[] s2) { var expected = s1.Union(s2).Distinct().Order().ToArray(); @@ -135,8 +135,8 @@ public void UnionEnumerator_Random(int len1, int len2) [TestCase(0, 10)] public void UnionEnumerator_SomeEmpty(int len1, int len2) { - var s1 = Enumerable.Range(0, len1).ToArray(); - var s2 = Enumerable.Range(0, len2).ToArray(); + var s1 = Enumerable.Range(0, len1).Select(i => (uint)i).ToArray(); + var s2 = Enumerable.Range(0, len2).Select(i => (uint)i).ToArray(); var expected = s1.Union(s2).Distinct().Order().ToArray(); @@ -145,28 +145,28 @@ public void UnionEnumerator_SomeEmpty(int len1, int len2) } [TestCaseSource(nameof(FilterTestData))] - public void FilterEnumerator(string name, LogFilter filter, List expected) + public void FilterEnumerator(string name, LogFilter filter, List expected) { Assert.That(expected, - Has.Count.InRange(from: 1, to: ToBlock - FromBlock - 1), + Has.Count.InRange(from: 1, to: (int)(ToBlock - FromBlock - 1)), "Unreliable test: none or all blocks are selected." ); ILogIndexStorage storage = Substitute.For(); - foreach ((Address address, List range) in LogIndexRanges.Address) + foreach ((Address address, List range) in LogIndexRanges.Address) { storage - .GetEnumerator(address, Arg.Any(), Arg.Any()) - .Returns(info => range.SkipWhile(x => x < info.ArgAt(1)).TakeWhile(x => x <= info.ArgAt(2)).GetEnumerator()); + .GetEnumerator(address, Arg.Any(), Arg.Any()) + .Returns(info => range.SkipWhile(x => x < info.ArgAt(1)).TakeWhile(x => x <= info.ArgAt(2)).GetEnumerator()); } for (var i = 0; i < LogIndexRanges.Topic.Length; i++) { - foreach ((Hash256 topic, List range) in LogIndexRanges.Topic[i]) + foreach ((Hash256 topic, List range) in LogIndexRanges.Topic[i]) { storage - .GetEnumerator(Arg.Is(i), topic, Arg.Any(), Arg.Any()) - .Returns(info => range.SkipWhile(x => x < info.ArgAt(2)).TakeWhile(x => x <= info.ArgAt(3)).GetEnumerator()); + .GetEnumerator(Arg.Is(i), topic, Arg.Any(), Arg.Any()) + .Returns(info => range.SkipWhile(x => x < info.ArgAt(2)).TakeWhile(x => x <= info.ArgAt(3)).GetEnumerator()); } } @@ -174,22 +174,22 @@ public void FilterEnumerator(string name, LogFilter filter, List expected) } [TestCaseSource(nameof(FilterTestData))] - public void FilterEnumerator_Dispose(string name, LogFilter filter, List _) + public void FilterEnumerator_Dispose(string name, LogFilter filter, List _) { - int[] blockNumbers = [1, 2, 3, 4, 5]; - List> enumerators = []; + uint[] blockNumbers = [1, 2, 3, 4, 5]; + List> enumerators = []; ILogIndexStorage storage = Substitute.For(); - storage.GetEnumerator(Arg.Any
(), Arg.Any(), Arg.Any()).Returns(_ => MockEnumerator()); - storage.GetEnumerator(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()).Returns(_ => MockEnumerator()); + storage.GetEnumerator(Arg.Any
(), Arg.Any(), Arg.Any()).Returns(_ => MockEnumerator()); + storage.GetEnumerator(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()).Returns(_ => MockEnumerator()); storage.EnumerateBlockNumbersFor(filter, FromBlock, ToBlock).ForEach(_ => { }); enumerators.ForEach(enumerator => enumerator.Received().Dispose()); - IEnumerator MockEnumerator() + IEnumerator MockEnumerator() { - IEnumerator? enumerator = Substitute.ForPartsOf(blockNumbers); + IEnumerator? enumerator = Substitute.ForPartsOf(blockNumbers); enumerators.Add(enumerator); return enumerator; } @@ -344,39 +344,39 @@ public static IEnumerable FilterTestData } } - private static int[] RandomAscending(Random random, int count, int maxDelta) + private static uint[] RandomAscending(Random random, int count, int maxDelta) { - var result = new int[count]; + var result = new uint[count]; for (var i = 0; i < result.Length; i++) { - var min = i > 0 ? result[i - 1] : -1; - result[i] = random.Next(min + 1, min + 1 + maxDelta); + int min = i > 0 ? (int)result[i - 1] : -1; + result[i] = (uint)random.Next(min + 1, min + 1 + maxDelta); } return result; } - private static void VerifyEnumerator(int[] s1, int[] s2, int[] ex) - where T : IEnumerator + private static void VerifyEnumerator(uint[] s1, uint[] s2, uint[] ex) + where T : IEnumerator { using var enumerator = (T)Activator.CreateInstance( typeof(T), - s1.Cast().GetEnumerator(), - s2.Cast().GetEnumerator() + s1.Cast().GetEnumerator(), + s2.Cast().GetEnumerator() )!; Assert.That(EnumerateOnce(enumerator), Is.EqualTo(ex)); } - private static IEnumerable EnumerateOnce(IEnumerator enumerator) + private static IEnumerable EnumerateOnce(IEnumerator enumerator) { while (enumerator.MoveNext()) yield return enumerator.Current; } - private const long FromBlock = 0; - private const long ToBlock = 99; + private const uint FromBlock = 0; + private const uint ToBlock = 99; private static readonly Ranges LogIndexRanges = GenerateLogIndexRanges(); @@ -384,22 +384,22 @@ private static Ranges GenerateLogIndexRanges() { var random = new Random(42); - var addressRanges = new Dictionary>(); + var addressRanges = new Dictionary>(); foreach (Address address in new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD, TestItem.AddressE }) { - var range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.3).ToList(); + var range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.3).Select(i => (uint)i).ToList(); addressRanges.Add(address, range); } - Dictionary>[] topicRanges = Enumerable + Dictionary>[] topicRanges = Enumerable .Range(0, LogIndexStorage.MaxTopics) - .Select(_ => new Dictionary>()).ToArray(); + .Select(_ => new Dictionary>()).ToArray(); - foreach (Dictionary> ranges in topicRanges) + foreach (Dictionary> ranges in topicRanges) { foreach (Hash256 topic in new[] { TestItem.KeccakA, TestItem.KeccakB, TestItem.KeccakC, TestItem.KeccakD, TestItem.KeccakE }) { - var range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.2).ToList(); + var range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.2).Select(i => (uint)i).ToList(); ranges.Add(topic, range); } } @@ -408,6 +408,6 @@ private static Ranges GenerateLogIndexRanges() } private static FilterBuilder BuildFilter() => FilterBuilder.New() - .FromBlock(FromBlock) - .ToBlock(ToBlock); + .FromBlock((long)FromBlock) + .ToBlock((long)ToBlock); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs index ae11d8419b65..c49915675e55 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs @@ -411,10 +411,10 @@ public void query_intersected_range_from_log_index(string name, var logIndexStorage = Substitute.For(); logIndexStorage.Enabled.Returns(true); - logIndexStorage.MinBlockNumber.Returns(indexFrom); - logIndexStorage.MaxBlockNumber.Returns(indexTo); - logIndexStorage.GetEnumerator(Arg.Any
(), Arg.Any(), Arg.Any()) - .Returns(_ => Array.Empty().Cast().GetEnumerator()); + logIndexStorage.MinBlockNumber.Returns(indexFrom is { } minVal ? (uint?)minVal : null); + logIndexStorage.MaxBlockNumber.Returns(indexTo is { } maxVal ? (uint?)maxVal : null); + logIndexStorage.GetEnumerator(Arg.Any
(), Arg.Any(), Arg.Any()) + .Returns(_ => Array.Empty().Cast().GetEnumerator()); Address address = TestItem.AddressA; BlockHeader fromHeader = Build.A.BlockHeader.WithNumber(from).TestObject; @@ -431,9 +431,9 @@ public void query_intersected_range_from_log_index(string name, _ = logFinder.FindLogs(filter, fromHeader, toHeader).ToArray(); if (exTo is not null && exFrom is not null) - logIndexStorage.Received(1).GetEnumerator(address, exFrom.Value, exTo.Value); + logIndexStorage.Received(1).GetEnumerator(address, (uint)exFrom.Value, (uint)exTo.Value); else - logIndexStorage.DidNotReceiveWithAnyArgs().GetEnumerator(Arg.Any
(), Arg.Any(), Arg.Any()); + logIndexStorage.DidNotReceiveWithAnyArgs().GetEnumerator(Arg.Any
(), Arg.Any(), Arg.Any()); } private static FilterBuilder AllBlockFilter() => FilterBuilder.New().FromEarliestBlock().ToPendingBlock(); diff --git a/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs b/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs index 7c5f1d80f44a..e85cc7b88ccb 100644 --- a/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs @@ -33,7 +33,7 @@ namespace Nethermind.Db.Test.LogIndex // TODO: test for concurrent reorg and backward sync // TODO: test for background job failure [TestFixtureSource(nameof(TestCases))] - [Parallelizable(ParallelScope.All)] + [Parallelizable(ParallelScope.Children)] [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] public class LogIndexStorageIntegrationTests(LogIndexStorageIntegrationTests.TestData testData) { @@ -49,6 +49,7 @@ public class LogIndexStorageIntegrationTests(LogIndexStorageIntegrationTests.Tes [ new(new TestData(10, 100) { Compression = CompressionAlgorithm.Best.Key }), new(new TestData(5, 200) { Compression = nameof(TurboPFor.p4nd1enc128v32) }), + new(new TestData(5, 100, startNum: (uint)int.MaxValue - 200) { Compression = CompressionAlgorithm.Best.Key }), new(new TestData(10, 100) { Compression = CompressionAlgorithm.Best.Key, ExtendedGetRanges = true }) { RunState = RunState.Explicit }, new(new TestData(100, 100) { Compression = nameof(TurboPFor.p4nd1enc128v32) }) { RunState = RunState.Explicit }, new(new TestData(100, 200) { Compression = CompressionAlgorithm.Best.Key }) { RunState = RunState.Explicit } @@ -59,8 +60,8 @@ public class LogIndexStorageIntegrationTests(LogIndexStorageIntegrationTests.Tes private readonly List _createdStorages = []; private ILogIndexStorage CreateLogIndexStorage( - int compactionDistance = 262_144, int compressionParallelism = 16, int maxReorgDepth = 64, IDbFactory? dbFactory = null, - string? compressionAlgo = null, int? failOnBlock = null, int? failOnCallN = null + uint compactionDistance = 262_144, int compressionParallelism = 16, int maxReorgDepth = 64, IDbFactory? dbFactory = null, + string? compressionAlgo = null, uint? failOnBlock = null, int? failOnCallN = null ) { LogIndexConfig config = new() @@ -140,7 +141,7 @@ public static void RemoveRootFolder() [Combinatorial] public async Task Set_Get_Test( - [Values(100, 200, int.MaxValue)] int compactionDistance, + [Values(100u, 200u, uint.MaxValue)] uint compactionDistance, [Values(1, 8, 16)] byte ioParallelism, [Values] bool isBackwardsSync, [Values] bool compact @@ -159,7 +160,7 @@ [Values] bool compact [Combinatorial] public async Task SetIntersecting_Get_Test( - [Values(100, 200, int.MaxValue)] int compactionDistance, + [Values(100u, 200u, uint.MaxValue)] uint compactionDistance, [Values(1, 8, 16)] byte ioParallelism, [Values] bool isBackwardsSync, [Values] bool compact @@ -179,7 +180,7 @@ [Values] bool compact [Combinatorial] public async Task BackwardsSet_Set_Get_Test( - [Values(100, 200, int.MaxValue)] int compactionDistance + [Values(100u, 200u, uint.MaxValue)] uint compactionDistance ) { var logIndexStorage = CreateLogIndexStorage(compactionDistance); @@ -202,7 +203,7 @@ public async Task BackwardsSet_Set_Get_Test( [Repeat(RaceConditionTestRepeat)] [SuppressMessage("ReSharper", "AccessToDisposedClosure")] public async Task Concurrent_BackwardsSet_Set_Get_Test( - [Values(100, int.MaxValue)] int compactionDistance + [Values(100u, uint.MaxValue)] uint compactionDistance ) { await using (var setStorage = CreateLogIndexStorage(compactionDistance)) @@ -248,7 +249,7 @@ public async Task Concurrent_BackwardsSet_Set_Get_Test( [Combinatorial] public async Task Set_ReorgLast_Get_Test( [Values(1, 5, 20)] int reorgDepth, - [Values(100, int.MaxValue)] int compactionDistance + [Values(100u, uint.MaxValue)] uint compactionDistance ) { var logIndexStorage = CreateLogIndexStorage(compactionDistance); @@ -265,7 +266,7 @@ public async Task Set_ReorgLast_Get_Test( [Combinatorial] public async Task Set_ReorgAndSetLast_Get_Test( [Values(1, 5, 20)] int reorgDepth, - [Values(100, int.MaxValue)] int compactionDistance + [Values(100u, uint.MaxValue)] uint compactionDistance ) { var logIndexStorage = CreateLogIndexStorage(compactionDistance); @@ -285,7 +286,7 @@ public async Task Set_ReorgAndSetLast_Get_Test( [Combinatorial] public async Task Set_ReorgLast_SetLast_Get_Test( [Values(1, 5, 20)] int reorgDepth, - [Values(100, int.MaxValue)] int compactionDistance + [Values(100u, uint.MaxValue)] uint compactionDistance ) { var logIndexStorage = CreateLogIndexStorage(compactionDistance); @@ -305,7 +306,7 @@ public async Task Set_ReorgLast_SetLast_Get_Test( [Combinatorial] public async Task Set_ReorgNonexistent_Get_Test( [Values(1, 5)] int reorgDepth, - [Values(100, int.MaxValue)] int compactionDistance + [Values(100u, uint.MaxValue)] uint compactionDistance ) { var logIndexStorage = CreateLogIndexStorage(compactionDistance); @@ -313,12 +314,12 @@ public async Task Set_ReorgNonexistent_Get_Test( await AddReceiptsAsync(logIndexStorage, testData.Batches); var lastBlock = testData.Batches[^1][^1].BlockNumber; - BlockReceipts[] reorgBlocks = GenerateBlocks(new Random(4242), lastBlock - reorgDepth + 1, reorgDepth); + BlockReceipts[] reorgBlocks = GenerateBlocks(new Random(4242), lastBlock - (uint)reorgDepth + 1, reorgDepth); foreach (BlockReceipts block in reorgBlocks) await logIndexStorage.RemoveReorgedAsync(block); // Need custom check because Reorg updates the last block even if it's "nonexistent" - Assert.That(logIndexStorage.MaxBlockNumber, Is.EqualTo(lastBlock - reorgDepth)); + Assert.That(logIndexStorage.MaxBlockNumber, Is.EqualTo(lastBlock - (uint)reorgDepth)); VerifyReceipts(logIndexStorage, testData, excludedBlocks: reorgBlocks, validateMinMax: false); } @@ -339,7 +340,7 @@ public async Task Set_Compact_ReorgLast_Get_Test(int reorgDepth, int maxReorgDep await logIndexStorage.RemoveReorgedAsync(block); var lastBlock = testData.Batches[^1][^1].BlockNumber; - VerifyReceipts(logIndexStorage, testData, maxBlock: lastBlock - reorgDepth); + VerifyReceipts(logIndexStorage, testData, maxBlock: lastBlock - (uint)reorgDepth); } [Combinatorial] @@ -355,7 +356,7 @@ [Values] bool compactAfter var allReorgBlocks = new List(); var allAddedBlocks = new List(); - foreach (BlockReceipts[][] batches in testData.Batches.GroupBy(b => b[0].BlockNumber / reorgFrequency).Select(g => g.ToArray())) + foreach (BlockReceipts[][] batches in testData.Batches.GroupBy(b => b[0].BlockNumber / (uint)reorgFrequency).Select(g => g.ToArray())) { await AddReceiptsAsync(logIndexStorage, batches); @@ -400,12 +401,12 @@ [Values] bool compactBetween await CompactAsync(logIndexStorage); } - VerifyReceipts(logIndexStorage, testData, maxBlock: testBlocks[^1].BlockNumber - reorgDepths.Max()); + VerifyReceipts(logIndexStorage, testData, maxBlock: testBlocks[^1].BlockNumber - (uint)reorgDepths.Max()); } [Combinatorial] public async Task SetMultiInstance_Get_Test( - [Values(100, int.MaxValue)] int compactionDistance, + [Values(100u, uint.MaxValue)] uint compactionDistance, [Values] bool isBackwardsSync ) { @@ -423,7 +424,7 @@ [Values] bool isBackwardsSync [Combinatorial] public async Task RepeatedSet_Get_Test( - [Values(100, int.MaxValue)] int compactionDistance, + [Values(100u, uint.MaxValue)] uint compactionDistance, [Values] bool isBackwardsSync ) { @@ -437,7 +438,7 @@ [Values] bool isBackwardsSync [Combinatorial] public async Task RepeatedSetMultiInstance_Get_Test( - [Values(100, int.MaxValue)] int compactionDistance, + [Values(100u, uint.MaxValue)] uint compactionDistance, [Values] bool isBackwardsSync ) { @@ -454,7 +455,7 @@ [Values] bool isBackwardsSync [Combinatorial] public async Task Set_NewInstance_Get_Test( [Values(1, 8)] int ioParallelism, - [Values(100, int.MaxValue)] int compactionDistance, + [Values(100u, uint.MaxValue)] uint compactionDistance, [Values] bool isBackwardsSync ) { @@ -469,7 +470,7 @@ [Values] bool isBackwardsSync [Repeat(RaceConditionTestRepeat)] [SuppressMessage("ReSharper", "AccessToDisposedClosure")] public async Task Set_ConcurrentGet_Test( - [Values(1, 200, int.MaxValue)] int compactionDistance, + [Values(1u, 200u, uint.MaxValue)] uint compactionDistance, [Values] bool isBackwardsSync ) { @@ -555,7 +556,7 @@ public async Task Set_AlgoChange_Test() Assert.That(exception, Has.Message.Contain(oldAlgo).And.Message.Contain(newAlgo)); } - private static BlockReceipts[] GenerateBlocks(Random random, int from, int count) => + private static BlockReceipts[] GenerateBlocks(Random random, uint from, int count) => new TestData(random, 1, count, startNum: from).Batches[0]; private static async Task AddReceiptsAsync(ILogIndexStorage logIndexStorage, IEnumerable batches, bool isBackwardsSync = false) @@ -585,11 +586,11 @@ await TestContext.Out.WriteLineAsync( } private static void VerifyReceipts(ILogIndexStorage logIndexStorage, TestData testData, - Dictionary>? excludedAddresses = null, - Dictionary>>? excludedTopics = null, - Dictionary>? addedAddresses = null, - Dictionary>>? addedTopics = null, - int? minBlock = null, int? maxBlock = null, + Dictionary>? excludedAddresses = null, + Dictionary>>? excludedTopics = null, + Dictionary>? addedAddresses = null, + Dictionary>>? addedTopics = null, + uint? minBlock = null, uint? maxBlock = null, bool validateMinMax = true ) { @@ -607,12 +608,12 @@ private static void VerifyReceipts(ILogIndexStorage logIndexStorage, TestData te foreach (var (address, blocks) in testData.AddressMap) { - IEnumerable expectedBlocks = blocks; + IEnumerable expectedBlocks = blocks; - if (excludedAddresses != null && excludedAddresses.TryGetValue(address, out HashSet addressExcludedBlocks)) + if (excludedAddresses != null && excludedAddresses.TryGetValue(address, out HashSet addressExcludedBlocks)) expectedBlocks = expectedBlocks.Except(addressExcludedBlocks); - if (addedAddresses != null && addedAddresses.TryGetValue(address, out HashSet addressAddedBlocks)) + if (addedAddresses != null && addedAddresses.TryGetValue(address, out HashSet addressAddedBlocks)) expectedBlocks = expectedBlocks.Concat(addressAddedBlocks); expectedBlocks = expectedBlocks.Order(); @@ -639,12 +640,12 @@ private static void VerifyReceipts(ILogIndexStorage logIndexStorage, TestData te { foreach (var (topic, blocks) in byTopic) { - IEnumerable expectedBlocks = blocks; + IEnumerable expectedBlocks = blocks; - if (excludedTopics != null && excludedTopics[idx].TryGetValue(topic, out HashSet topicExcludedBlocks)) + if (excludedTopics != null && excludedTopics[idx].TryGetValue(topic, out HashSet topicExcludedBlocks)) expectedBlocks = expectedBlocks.Except(topicExcludedBlocks); - if (addedTopics != null && addedTopics[idx].TryGetValue(topic, out HashSet topicAddedBlocks)) + if (addedTopics != null && addedTopics[idx].TryGetValue(topic, out HashSet topicAddedBlocks)) expectedBlocks = expectedBlocks.Concat(topicAddedBlocks); expectedBlocks = expectedBlocks.Order(); @@ -671,7 +672,7 @@ private static void VerifyReceipts(ILogIndexStorage logIndexStorage, TestData te private static void VerifyReceipts(ILogIndexStorage logIndexStorage, TestData testData, IEnumerable? excludedBlocks, IEnumerable? addedBlocks = null, - int? minBlock = null, int? maxBlock = null, + uint? minBlock = null, uint? maxBlock = null, bool validateMinMax = true) { var excludeMaps = excludedBlocks == null ? default : TestData.GenerateMaps(excludedBlocks); @@ -782,7 +783,7 @@ public class TestData { private readonly int _batchCount; private readonly int _blocksPerBatch; - private readonly int _startNum; + private readonly uint _startNum; // Lazy avoids generating all the data just to display test cases in the runner private readonly Lazy _batches; @@ -791,11 +792,11 @@ public class TestData private List
? _addresses; private List<(int, Hash256)>? _topics; - private readonly Lazy> _ranges; - public IEnumerable<(int from, int to)> Ranges => _ranges.Value; + private readonly Lazy> _ranges; + public IEnumerable<(uint from, uint to)> Ranges => _ranges.Value; - public Dictionary> AddressMap { get; private set; } = new(); - public Dictionary>> TopicMap { get; private set; } = new(); + public Dictionary> AddressMap { get; private set; } = new(); + public Dictionary>> TopicMap { get; private set; } = new(); public List
Addresses { @@ -818,7 +819,7 @@ public List
Addresses public bool ExtendedGetRanges { get; init; } public string? Compression { get; init; } - public TestData(Random random, int batchCount, int blocksPerBatch, int startNum = 0) + public TestData(Random random, int batchCount, int blocksPerBatch, uint startNum = 0) { _batchCount = batchCount; _blocksPerBatch = blocksPerBatch; @@ -828,9 +829,9 @@ public TestData(Random random, int batchCount, int blocksPerBatch, int startNum _ranges = new(() => ExtendedGetRanges ? GenerateExtendedRanges() : GenerateSimpleRanges()); } - public TestData(int batchCount, int blocksPerBatch, int startNum = 0) : this(new(42), batchCount, blocksPerBatch, startNum) { } + public TestData(int batchCount, int blocksPerBatch, uint startNum = 0) : this(new(42), batchCount, blocksPerBatch, startNum) { } - private BlockReceipts[][] GenerateBatches(Random random, int batchCount, int blocksPerBatch, int startNum = 0) + private BlockReceipts[][] GenerateBatches(Random random, int batchCount, int blocksPerBatch, uint startNum = 0) { var batches = new BlockReceipts[batchCount][]; var blocksCount = batchCount * blocksPerBatch; @@ -882,11 +883,11 @@ private BlockReceipts[][] GenerateBatches(Random random, int batchCount, int blo return batches; } - public static (Dictionary> address, Dictionary>> topic) GenerateMaps( + public static (Dictionary> address, Dictionary>> topic) GenerateMaps( IEnumerable blocks) { - var address = new Dictionary>(); - var topic = new Dictionary>>(); + var address = new Dictionary>(); + var topic = new Dictionary>>(); foreach (var block in blocks) { @@ -938,39 +939,39 @@ private static TxReceipt[] GenerateReceipts(Random random, Address[] addresses, return receipts.ToArray(); } - private static HashSet<(int from, int to)> GenerateSimpleRanges(int min, int max) + private static HashSet<(uint from, uint to)> GenerateSimpleRanges(uint min, uint max) { var quarter = (max - min) / 4; - return [(0, int.MaxValue), (min, max), (min + quarter, max - quarter)]; + return [(0, uint.MaxValue), (min, max), (min + quarter, max - quarter)]; } - private static HashSet<(int from, int to)> GenerateExtendedRanges(int min, int max) + private static HashSet<(uint from, uint to)> GenerateExtendedRanges(uint min, uint max) { - var ranges = new HashSet<(int, int)>(); + var ranges = new HashSet<(uint, uint)>(); - var edges = new[] { min - 1, min, min + 1, max - 1, max + 1 }; + var edges = new[] { min > 0 ? min - 1 : 0, min, min + 1, max > 0 ? max - 1 : 0, max + 1 }; ranges.AddRange(edges.SelectMany(_ => edges, static (x, y) => (x, y))); - const int step = 100; + const uint step = 100; for (var i = min; i <= max; i += step) { - var middles = new[] { i - step, i - 1, i, i + 1, i + step }; + var middles = new[] { i > step ? i - step : 0, i > 0 ? i - 1 : 0, i, i + 1, i + step }; ranges.AddRange(middles.SelectMany(_ => middles, static (x, y) => (x, y))); } return ranges; } - private HashSet<(int from, int to)> GenerateSimpleRanges() => GenerateSimpleRanges( - _startNum, _startNum + _batchCount * _blocksPerBatch - 1 + private HashSet<(uint from, uint to)> GenerateSimpleRanges() => GenerateSimpleRanges( + _startNum, _startNum + (uint)(_batchCount * _blocksPerBatch) - 1 ); - private HashSet<(int from, int to)> GenerateExtendedRanges() => GenerateExtendedRanges( - _startNum, _startNum + _batchCount * _blocksPerBatch - 1 + private HashSet<(uint from, uint to)> GenerateExtendedRanges() => GenerateExtendedRanges( + _startNum, _startNum + (uint)(_batchCount * _blocksPerBatch) - 1 ); public override string ToString() => - $"{_batchCount} * {_blocksPerBatch} blocks (ex-ranges: {ExtendedGetRanges}, compression: {Compression})"; + $"{_batchCount} * {_blocksPerBatch} blocks (start: {_startNum}, ex-ranges: {ExtendedGetRanges}, compression: {Compression})"; } private class SaveFailingLogIndexStorage(IDbFactory dbFactory, ILogManager logManager, ILogIndexConfig config) @@ -978,12 +979,12 @@ private class SaveFailingLogIndexStorage(IDbFactory dbFactory, ILogManager logMa { public const string FailMessage = "Test exception."; - public int FailOnBlock { get; init; } + public uint FailOnBlock { get; init; } public int FailOnCallN { get; init; } private int _count; - protected override void MergeBlockNumbers(IWriteBatch dbBatch, ReadOnlySpan key, List numbers, bool isBackwardSync, LogIndexUpdateStats? stats) + protected override void MergeBlockNumbers(IWriteBatch dbBatch, ReadOnlySpan key, List numbers, bool isBackwardSync, LogIndexUpdateStats? stats) { var isFailBlock = FailOnBlock >= Math.Min(numbers[0], numbers[^1]) && diff --git a/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageTestExtensions.cs b/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageTestExtensions.cs index dccf8578a996..27233be132a8 100644 --- a/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageTestExtensions.cs +++ b/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageTestExtensions.cs @@ -13,10 +13,10 @@ public static class LogIndexStorageTestExtensions { extension(ILogIndexStorage storage) { - public List GetBlockNumbersFor(Address address, int from, int to) + public List GetBlockNumbersFor(Address address, uint from, uint to) { - var result = new List(); - using IEnumerator enumerator = storage.GetEnumerator(address, from, to); + var result = new List(); + using IEnumerator enumerator = storage.GetEnumerator(address, from, to); while (enumerator.MoveNext()) result.Add(enumerator.Current); @@ -24,10 +24,10 @@ public List GetBlockNumbersFor(Address address, int from, int to) return result; } - public List GetBlockNumbersFor(int index, Hash256 topic, int from, int to) + public List GetBlockNumbersFor(int index, Hash256 topic, uint from, uint to) { - var result = new List(); - using IEnumerator enumerator = storage.GetEnumerator(index, topic, from, to); + var result = new List(); + using IEnumerator enumerator = storage.GetEnumerator(index, topic, from, to); while (enumerator.MoveNext()) result.Add(enumerator.Current); diff --git a/src/Nethermind/Nethermind.Db.Test/LogIndex/MergeOperatorTests.cs b/src/Nethermind/Nethermind.Db.Test/LogIndex/MergeOperatorTests.cs index a7d9386face6..f514f6b7c9a3 100644 --- a/src/Nethermind/Nethermind.Db.Test/LogIndex/MergeOperatorTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/LogIndex/MergeOperatorTests.cs @@ -89,7 +89,7 @@ public void FullMergeForward(string? existing, string[] operands, string expecte using ArrayPoolList merged = op.FullMerge(key, enumerator); Assert.That( Deserialize(merged?.ToArray()), - Is.EqualTo(expected.Split(',').Select(int.Parse).ToArray()) + Is.EqualTo(expected.Split(',').Select(s => uint.Parse(s.Trim())).ToArray()) ); } @@ -137,7 +137,7 @@ public void FullMergeBackward(string? existing, string[] operands, string expect ArrayPoolList merged = op.FullMerge(key, enumerator); Assert.That( Deserialize(merged?.ToArray()), - Is.EqualTo(expected.Split(',').Select(int.Parse).ToArray()) + Is.EqualTo(expected.Split(',').Select(s => uint.Parse(s.Trim())).ToArray()) ); } @@ -158,7 +158,7 @@ public void PartialMergeForward(string[] operands, string expected) using ArrayPoolList merged = op.PartialMerge(key, enumerator); Assert.That( Deserialize(merged?.ToArray()), - Is.EqualTo(expected.Split(',').Select(int.Parse).ToArray()) + Is.EqualTo(expected.Split(',').Select(s => uint.Parse(s.Trim())).ToArray()) ); } @@ -179,7 +179,7 @@ public void PartialMergeBackward(string[] operands, string expected) using ArrayPoolList merged = op.PartialMerge(key, enumerator); Assert.That( Deserialize(merged?.ToArray()), - Is.EqualTo(expected.Split(',').Select(int.Parse).ToArray()) + Is.EqualTo(expected.Split(',').Select(s => uint.Parse(s.Trim())).ToArray()) ); } @@ -223,7 +223,7 @@ private static byte[] GenerateKey(int prefixSize, bool isBackward) => Random.Sha private static byte[]? Serialize(string? input) => input is null ? null : Bytes.Concat(input.Split(',').Select(s => s.Trim()).Select(s => s switch { - _ when int.TryParse(s, out int blockNum) => blockNum.ToLittleEndianByteArray(), + _ when uint.TryParse(s, out uint blockNum) => blockNum.ToLittleEndianByteArray(), _ when TryParseMergeOp(s, out Span op) => op.ToArray(), _ => throw new FormatException($"Invalid operand: \"{input}\".") }).ToArray()); @@ -236,12 +236,12 @@ private static bool TryParseMergeOp(string input, out Span bytes) if (parts.Length != 2) return false; if (!Enum.TryParse(parts[0], out LogIndexStorage.MergeOp op)) return false; - if (!int.TryParse(parts[1], out int blockNum)) return false; + if (!uint.TryParse(parts[1], out uint blockNum)) return false; var buffer = new byte[LogIndexStorage.MergeOps.Size]; bytes = LogIndexStorage.MergeOps.Create(op, blockNum, buffer); return true; } - private static int[]? Deserialize(byte[]? input) => input is null ? null : MemoryMarshal.Cast(input).ToArray(); + private static uint[]? Deserialize(byte[]? input) => input is null ? null : MemoryMarshal.Cast(input).ToArray(); } diff --git a/src/Nethermind/Nethermind.Db/LogIndex/BlockReceipts.cs b/src/Nethermind/Nethermind.Db/LogIndex/BlockReceipts.cs index 332c17e88ea2..982f5005d1f6 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/BlockReceipts.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/BlockReceipts.cs @@ -5,4 +5,4 @@ namespace Nethermind.Db.LogIndex; -public readonly record struct BlockReceipts(int BlockNumber, TxReceipt[] Receipts); +public readonly record struct BlockReceipts(uint BlockNumber, TxReceipt[] Receipts); diff --git a/src/Nethermind/Nethermind.Db/LogIndex/Compactor.cs b/src/Nethermind/Nethermind.Db/LogIndex/Compactor.cs index d5ed2dde970d..994425410942 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/Compactor.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/Compactor.cs @@ -17,13 +17,13 @@ partial class LogIndexStorage /// private class Compactor : ICompactor { - private int? _lastAtMin; - private int? _lastAtMax; + private uint? _lastAtMin; + private uint? _lastAtMax; private CompactingStats _stats = new(); private readonly LogIndexStorage _storage; private readonly ILogger _logger; - private readonly int _compactionDistance; + private readonly uint _compactionDistance; // TODO: simplify concurrency handling private readonly AutoResetEvent _runOnceEvent = new(false); @@ -32,7 +32,7 @@ private class Compactor : ICompactor private readonly ManualResetEvent _compactionEndedEvent = new(true); private readonly Task _compactionTask; - public Compactor(LogIndexStorage storage, ILogger logger, int compactionDistance) + public Compactor(LogIndexStorage storage, ILogger logger, uint compactionDistance) { _storage = storage; _logger = logger; @@ -57,7 +57,7 @@ public bool TryEnqueue() _lastAtMin ??= _storage.MinBlockNumber; _lastAtMax ??= _storage.MaxBlockNumber; - var uncompacted = 0; + uint uncompacted = 0; if (_storage.MinBlockNumber is { } storageMin && storageMin < _lastAtMin) uncompacted += _lastAtMin.Value - storageMin; if (_storage.MaxBlockNumber is { } storageMax && storageMax > _lastAtMax) diff --git a/src/Nethermind/Nethermind.Db/LogIndex/CompressionAlgorithm.cs b/src/Nethermind/Nethermind.Db/LogIndex/CompressionAlgorithm.cs index 3c0a3b83280b..a5733812326e 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/CompressionAlgorithm.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/CompressionAlgorithm.cs @@ -19,8 +19,8 @@ public class CompressionAlgorithm( CompressionAlgorithm.DecompressFunc decompressionFunc ) { - public delegate nuint CompressFunc(ReadOnlySpan @in, nuint n, Span @out); - public delegate nuint DecompressFunc(ReadOnlySpan @in, nuint n, Span @out); + public delegate nuint CompressFunc(ReadOnlySpan @in, nuint n, Span @out); + public delegate nuint DecompressFunc(ReadOnlySpan @in, nuint n, Span @out); private static readonly Dictionary SupportedMap = new(); @@ -50,9 +50,9 @@ static CompressionAlgorithm() public string Name => name; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public nuint Compress(ReadOnlySpan @in, nuint n, Span @out) => compressionFunc(@in, n, @out); + public nuint Compress(ReadOnlySpan @in, nuint n, Span @out) => compressionFunc(@in, n, @out); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public nuint Decompress(ReadOnlySpan @in, nuint n, Span @out) => decompressionFunc(@in, n, @out); + public nuint Decompress(ReadOnlySpan @in, nuint n, Span @out) => decompressionFunc(@in, n, @out); } } diff --git a/src/Nethermind/Nethermind.Db/LogIndex/Compressor.cs b/src/Nethermind/Nethermind.Db/LogIndex/Compressor.cs index 5a24b1a13adc..9d84c43aaa3d 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/Compressor.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/Compressor.cs @@ -123,11 +123,11 @@ private void CompressValue(int? topicIndex, byte[] dbKey) if (dbValue.Length < MinLengthToCompress) return; - int truncateBlock = ReadLastBlockNumber(dbValue); + uint truncateBlock = ReadLastBlockNumber(dbValue); ReverseBlocksIfNeeded(dbValue); - int postfixBlock = ReadBlockNumber(dbValue); + uint postfixBlock = ReadBlockNumber(dbValue); ReadOnlySpan key = ExtractKey(dbKey); Span dbKeyComp = stackalloc byte[key.Length + BlockNumberSize]; diff --git a/src/Nethermind/Nethermind.Db/LogIndex/DisabledLogIndexStorage.cs b/src/Nethermind/Nethermind.Db/LogIndex/DisabledLogIndexStorage.cs index 6f03542dc83b..478b8994949f 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/DisabledLogIndexStorage.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/DisabledLogIndexStorage.cs @@ -17,13 +17,13 @@ public sealed class DisabledLogIndexStorage : ILogIndexStorage public string GetDbSize() => "0 B"; - public int? MaxBlockNumber => null; - public int? MinBlockNumber => null; + public uint? MaxBlockNumber => null; + public uint? MinBlockNumber => null; - public IEnumerator GetEnumerator(Address address, int from, int to) => + public IEnumerator GetEnumerator(Address address, uint from, uint to) => throw new NotSupportedException(); - public IEnumerator GetEnumerator(int topicIndex, Hash256 topic, int from, int to) => + public IEnumerator GetEnumerator(int topicIndex, Hash256 topic, uint from, uint to) => throw new NotSupportedException(); public LogIndexAggregate Aggregate(IReadOnlyList batch, bool isBackwardSync, LogIndexUpdateStats? stats = null) => diff --git a/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs b/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs index 005f011ddf1c..b10d73af4542 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs @@ -81,7 +81,7 @@ public interface ILogIndexConfig : IConfig DefaultValue = "262,144", HiddenFromDocs = true )] - public int CompactionDistance { get; set; } + public uint CompactionDistance { get; set; } [ConfigItem( Description = "Compression algorithm to use for block numbers.", diff --git a/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexStorage.cs b/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexStorage.cs index 6e55c4f80c72..8f6a90c21c0c 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexStorage.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexStorage.cs @@ -17,24 +17,24 @@ public interface ILogIndexStorage : IAsyncDisposable, IStoppableService /// /// Max block number added to the index. /// - int? MaxBlockNumber { get; } + uint? MaxBlockNumber { get; } /// /// Min block number added to the index. /// - int? MinBlockNumber { get; } + uint? MinBlockNumber { get; } /// /// Gets enumerator of block numbers between and /// where given has occurred. /// - IEnumerator GetEnumerator(Address address, int from, int to); + IEnumerator GetEnumerator(Address address, uint from, uint to); /// /// Gets enumerator of block numbers between and /// where given has occurred at the given . /// - IEnumerator GetEnumerator(int topicIndex, Hash256 topic, int from, int to); + IEnumerator GetEnumerator(int topicIndex, Hash256 topic, uint from, uint to); /// /// Aggregates receipts from the into in-memory . diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexAggregate.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexAggregate.cs index bd0f40280484..c2f8084c46b8 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexAggregate.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexAggregate.cs @@ -12,18 +12,18 @@ namespace Nethermind.Db.LogIndex; /// Set of in-memory dictionaries mapping each address/topic to a sequence of block numbers /// from the - range. /// -public struct LogIndexAggregate(int firstBlockNum, int lastBlockNum) +public struct LogIndexAggregate(uint firstBlockNum, uint lastBlockNum) { - private Dictionary>? _address; - private Dictionary>[]? _topic; + private Dictionary>? _address; + private Dictionary>[]? _topic; - public int FirstBlockNum { get; } = firstBlockNum; - public int LastBlockNum { get; } = lastBlockNum; + public uint FirstBlockNum { get; } = firstBlockNum; + public uint LastBlockNum { get; } = lastBlockNum; - public Dictionary> Address => _address ??= new(); + public Dictionary> Address => _address ??= new(); - public Dictionary>[] Topic => _topic ??= Enumerable.Range(0, LogIndexStorage.MaxTopics) - .Select(static _ => new Dictionary>()) + public Dictionary>[] Topic => _topic ??= Enumerable.Range(0, LogIndexStorage.MaxTopics) + .Select(static _ => new Dictionary>()) .ToArray(); public bool IsEmpty => (_address is null || _address.Count == 0) && (_topic is null || _topic[0].Count == 0); diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs index ed8674a1070e..a54d62134eb3 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs @@ -23,7 +23,7 @@ public class LogIndexConfig : ILogIndexConfig public int MaxCompressionParallelism { get; set; } = Math.Max(Environment.ProcessorCount / 2, 1); public int CompressionDistance { get; set; } = 128; - public int CompactionDistance { get; set; } = 262_144; + public uint CompactionDistance { get; set; } = 262_144; public string? CompressionAlgorithm { get; set; } = LogIndexStorage.CompressionAlgorithm.Best.Key; diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexEnumerator.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexEnumerator.cs index 9e648deecd8e..7e3333388c66 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexEnumerator.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexEnumerator.cs @@ -16,22 +16,21 @@ public partial class LogIndexStorage /// Enumerates block numbers from for the given key, /// within the specified from/to range. /// - public sealed class LogIndexEnumerator : IEnumerator + public sealed class LogIndexEnumerator : IEnumerator { private const int CompletedIndex = int.MinValue; private readonly LogIndexStorage _storage; private readonly byte[] _key; - private readonly int _from; - private readonly int _to; + private readonly uint _from; + private readonly uint _to; private readonly ISortedView _view; - private ArrayPoolList? _value; + private ArrayPoolList? _value; private int _index; - public LogIndexEnumerator(LogIndexStorage storage, ISortedKeyValueStore db, byte[] key, int from, int to) + public LogIndexEnumerator(LogIndexStorage storage, ISortedKeyValueStore db, byte[] key, uint from, uint to) { - if (from < 0) from = 0; if (to < from) throw new ArgumentException("To must be greater or equal to from.", nameof(to)); _storage = storage; @@ -45,7 +44,7 @@ public LogIndexEnumerator(LogIndexStorage storage, ISortedKeyValueStore db, byte private bool IsWithinRange() { - int current = Current; + uint current = Current; return current >= _from && current <= _to; } @@ -115,13 +114,14 @@ private void SetValue() { _value?.Dispose(); + ReadOnlySpan viewKey = _view.CurrentKey; ReadOnlySpan viewValue = _view.CurrentValue; - if (IsCompressed(viewValue, out var length)) + if (IsCompressed(viewKey, viewValue, out var length)) { // +1 fixes TurboPFor reading outside of array bounds _value = new(capacity: length + 1, count: length); - _storage.DecompressDbValue(viewValue, _value.AsSpan()); + _storage.DecompressDbValue(viewKey, viewValue, _value.AsSpan()); } else { @@ -141,7 +141,7 @@ private int FindFromIndex() public void Reset() => throw new NotSupportedException($"{nameof(LogIndexEnumerator)} can not be reset."); - public int Current => _value is not null && _index >= 0 && _index < _value.Count ? _value[_index] : -1; + public uint Current => _value is not null && _index >= 0 && _index < _value.Count ? _value[_index] : 0u; object? IEnumerator.Current => Current; public void Dispose() diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs index 826c21446cb3..a0f2ba3d5091 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs @@ -19,7 +19,6 @@ namespace Nethermind.Db.LogIndex { - // TODO: use uint instead of int for block number? /// /// Database for log index, mapping addresses/topics to a set of blocks they occur in. /// @@ -40,12 +39,12 @@ namespace Nethermind.Db.LogIndex /// /// 1 for newly coming numbers from backward sync;
/// key here is formed as filter || ;
- /// value is a sequence of concatenated block numbers in strictly descending order using little-endian encoding; + /// value is a sequence of concatenated block numbers in strictly descending order using little-endian encoding; ///
/// /// 1 for newly coming numbers from forward sync;
/// key is filter || ;
- /// value is a sequence of concatenated block numbers in strictly ascending order using little-endian encoding; + /// value is a sequence of concatenated block numbers in strictly ascending order using little-endian encoding; ///
/// /// any number of "finalized" mappings, storing block numbers in strictly ascending order, compressed via TurboPFor;
@@ -75,7 +74,7 @@ namespace Nethermind.Db.LogIndex /// /// /// - /// Fetching block numbers for the given filters (see ) + /// Fetching block numbers for the given filters (see ) /// is done by iterating keys via (with the provided filter as a prefix), /// decomposing DB values back into block number sequences, and returning obtained numbers in ascending order. /// Check for details. @@ -161,7 +160,7 @@ public void Dispose() public bool Enabled { get; } - public const int BlockNumberSize = sizeof(int); + public const int BlockNumberSize = sizeof(uint); private const int MaxKeyLength = Hash256.Size + 1; // Math.Max(Address.Size, Hash256.Size) private const int MaxDbKeyLength = MaxKeyLength + BlockNumberSize; @@ -195,11 +194,11 @@ private IEnumerable DBColumns private readonly Lock _rangeInitLock = new(); - private int? _maxBlock; - private int? _minBlock; + private uint? _maxBlock; + private uint? _minBlock; - public int? MaxBlockNumber => _maxBlock; - public int? MinBlockNumber => _minBlock; + public uint? MaxBlockNumber => _maxBlock; + public uint? MinBlockNumber => _minBlock; private Exception? _lastBackgroundError; public bool HasBackgroundError => _lastBackgroundError is not null; @@ -467,7 +466,7 @@ private void DisposeCore() _rootDb?.Dispose(); } - private int? LoadRangeBound(ReadOnlySpan key) + private uint? LoadRangeBound(ReadOnlySpan key) { Span value = _metaDb.GetSpan(key); try @@ -480,7 +479,7 @@ private void DisposeCore() } } - private void UpdateRange(int minBlock, int maxBlock, bool isBackwardSync) + private void UpdateRange(uint minBlock, uint maxBlock, bool isBackwardSync) { if (!FirstBlockAdded) { @@ -495,7 +494,7 @@ private void UpdateRange(int minBlock, int maxBlock, bool isBackwardSync) else _maxBlock = maxBlock; } - private static int SaveRangeBound(IWriteOnlyKeyValueStore dbBatch, byte[] key, int value) + private static uint SaveRangeBound(IWriteOnlyKeyValueStore dbBatch, byte[] key, uint value) { Span buffer = stackalloc byte[BlockNumberSize]; WriteBlockNumber(buffer, value); @@ -503,13 +502,13 @@ private static int SaveRangeBound(IWriteOnlyKeyValueStore dbBatch, byte[] key, i return value; } - private (int min, int max) SaveRange(DbBatches batches, int firstBlock, int lastBlock, bool isBackwardSync, bool isReorg = false) + private (uint min, uint max) SaveRange(DbBatches batches, uint firstBlock, uint lastBlock, bool isBackwardSync, bool isReorg = false) { - int batchMin = Math.Min(firstBlock, lastBlock); - int batchMax = Math.Max(firstBlock, lastBlock); + uint batchMin = Math.Min(firstBlock, lastBlock); + uint batchMax = Math.Max(firstBlock, lastBlock); - int min = _minBlock ?? SaveRangeBound(batches.Meta, SpecialKey.MinBlockNum, batchMin); - int max = _maxBlock ?? SaveRangeBound(batches.Meta, SpecialKey.MaxBlockNum, batchMax); + uint min = _minBlock ?? SaveRangeBound(batches.Meta, SpecialKey.MinBlockNum, batchMin); + uint max = _maxBlock ?? SaveRangeBound(batches.Meta, SpecialKey.MaxBlockNum, batchMax); if (isBackwardSync) { @@ -527,24 +526,24 @@ private static int SaveRangeBound(IWriteOnlyKeyValueStore dbBatch, byte[] key, i return (min, max); } - private int? GetLastReorgableBlockNumber() => _maxBlock - _maxReorgDepth; + private uint? GetLastReorgableBlockNumber() => _maxBlock is { } max && max >= (uint)_maxReorgDepth ? max - (uint)_maxReorgDepth : null; - private static bool IsBlockNewer(int next, int? lastMin, int? lastMax, bool isBackwardSync) => isBackwardSync + private static bool IsBlockNewer(uint next, uint? lastMin, uint? lastMax, bool isBackwardSync) => isBackwardSync ? lastMin is null || next < lastMin : lastMax is null || next > lastMax; - private bool IsBlockNewer(int next, bool isBackwardSync) => + private bool IsBlockNewer(uint next, bool isBackwardSync) => IsBlockNewer(next, _minBlock, _maxBlock, isBackwardSync); public string GetDbSize() => _rootDb.GatherMetric().Size.SizeToString(useSi: true, addSpace: true); - public IEnumerator GetEnumerator(Address address, int from, int to) => + public IEnumerator GetEnumerator(Address address, uint from, uint to) => GetEnumerator(null, address.Bytes, from, to); - public IEnumerator GetEnumerator(int topicIndex, Hash256 topic, int from, int to) => + public IEnumerator GetEnumerator(int topicIndex, Hash256 topic, uint from, uint to) => GetEnumerator(topicIndex, topic.BytesToArray(), from, to); - public IEnumerator GetEnumerator(int? topicIndex, byte[] key, int from, int to) + public IEnumerator GetEnumerator(int? topicIndex, byte[] key, uint from, uint to) { IDb db = GetDb(topicIndex); ISortedKeyValueStore? sortedDb = db as ISortedKeyValueStore @@ -568,7 +567,7 @@ public LogIndexAggregate Aggregate(IReadOnlyList batch, bool isBa long timestamp = Stopwatch.GetTimestamp(); LogIndexAggregate aggregate = new(batch); - foreach ((int blockNumber, TxReceipt[] receipts) in batch) + foreach ((uint blockNumber, TxReceipt[] receipts) in batch) { if (!IsBlockNewer(blockNumber, isBackwardSync)) continue; @@ -585,7 +584,7 @@ public LogIndexAggregate Aggregate(IReadOnlyList batch, bool isBa { stats?.IncrementLogs(); - List addressBlocks = aggregate.Address.GetOrAdd(log.Address, static _ => new(1)); + List addressBlocks = aggregate.Address.GetOrAdd(log.Address, static _ => new(1)); if (addressBlocks.Count == 0 || addressBlocks[^1] != blockNumber) addressBlocks.Add(blockNumber); @@ -595,7 +594,7 @@ public LogIndexAggregate Aggregate(IReadOnlyList batch, bool isBa { stats?.IncrementTopics(); - List topicBlocks = aggregate.Topic[topicIndex].GetOrAdd(log.Topics[topicIndex], static _ => new(1)); + List topicBlocks = aggregate.Topic[topicIndex].GetOrAdd(log.Topics[topicIndex], static _ => new(1)); if (topicBlocks.Count == 0 || topicBlocks[^1] != blockNumber) topicBlocks.Add(blockNumber); @@ -671,9 +670,9 @@ private void RemoveReorgedCore(BlockReceipts block) } // Need to update the last block number so that new-receipts comparison won't fail when rewriting it - int blockNum = block.BlockNumber - 1; + uint blockNum = block.BlockNumber > 0 ? block.BlockNumber - 1 : 0; - (int minBlock, int maxBlock) = SaveRange(batches, blockNum, blockNum, isBackwardSync, isReorg: true); + (uint minBlock, uint maxBlock) = SaveRange(batches, blockNum, blockNum, isBackwardSync, isReorg: true); batches.Commit(); @@ -741,7 +740,7 @@ public async Task AddReceiptsAsync(LogIndexAggregate aggregate, LogIndexUpdateSt timestamp = Stopwatch.GetTimestamp(); // Add addresses - foreach ((Address address, List blocks) in aggregate.Address) + foreach ((Address address, List blocks) in aggregate.Address) { MergeBlockNumbers(batches.Address, address.Bytes, blocks, isBackwardSync, stats); } @@ -749,9 +748,9 @@ public async Task AddReceiptsAsync(LogIndexAggregate aggregate, LogIndexUpdateSt // Add topics for (var topicIndex = 0; topicIndex < aggregate.Topic.Length; topicIndex++) { - Dictionary> topics = aggregate.Topic[topicIndex]; + Dictionary> topics = aggregate.Topic[topicIndex]; - foreach ((Hash256 topic, List blocks) in topics) + foreach ((Hash256 topic, List blocks) in topics) { MergeBlockNumbers(batches.Topics[topicIndex], topic.Bytes, blocks, isBackwardSync, stats); } @@ -761,7 +760,7 @@ public async Task AddReceiptsAsync(LogIndexAggregate aggregate, LogIndexUpdateSt } timestamp = Stopwatch.GetTimestamp(); - (int addressRange, int topicRanges) = SaveRange(batches, aggregate.FirstBlockNum, aggregate.LastBlockNum, isBackwardSync); + (uint addressRange, uint topicRanges) = SaveRange(batches, aggregate.FirstBlockNum, aggregate.LastBlockNum, isBackwardSync); stats?.UpdatingMeta.Include(Stopwatch.GetElapsedTime(timestamp)); // Submit batches @@ -790,7 +789,7 @@ public async Task AddReceiptsAsync(LogIndexAggregate aggregate, LogIndexUpdateSt } protected virtual void MergeBlockNumbers( - IWriteBatch dbBatch, ReadOnlySpan key, List numbers, + IWriteBatch dbBatch, ReadOnlySpan key, List numbers, bool isBackwardSync, LogIndexUpdateStats? stats ) { @@ -822,7 +821,7 @@ private static ReadOnlySpan WriteKey(ReadOnlySpan key, Span bu /// /// Generates a key consisting of the key || block-number byte array. /// / - private static ReadOnlySpan CreateDbKey(ReadOnlySpan key, int blockNumber, Span buffer) + private static ReadOnlySpan CreateDbKey(ReadOnlySpan key, uint blockNumber, Span buffer) { key = WriteKey(key, buffer); WriteKeyBlockNumber(buffer[key.Length..], blockNumber); @@ -848,43 +847,63 @@ private static ReadOnlySpan CreateMergeDbKey(ReadOnlySpan key, Span< // RocksDB uses big-endian (lexicographic) ordering // +1 is needed as 0 is used for the backward-merge key - private static void WriteKeyBlockNumber(Span dbKeyEnd, int number) => BinaryPrimitives.WriteInt32BigEndian(dbKeyEnd, number + 1); + private static void WriteKeyBlockNumber(Span dbKeyEnd, uint number) => BinaryPrimitives.WriteUInt32BigEndian(dbKeyEnd, number + 1); private static bool UseBackwardSyncFor(ReadOnlySpan dbKey) => dbKey.EndsWith(Postfix.BackwardMerge); - private static int BinarySearch(ReadOnlySpan blocks, int from) + private static int BinarySearch(ReadOnlySpan blocks, uint from) { - int index = blocks.BinarySearch(from); - return index < 0 ? ~index : index; + int lo = 0, hi = blocks.Length - 1; + while (lo <= hi) + { + int mid = lo + (hi - lo) / 2; + uint midVal = blocks[mid]; + if (midVal == from) return mid; + if (midVal < from) lo = mid + 1; + else hi = mid - 1; + } + return ~lo; } private ReadOnlySpan Compress(Span data, Span buffer) { - ReadOnlySpan blockNumbers = MemoryMarshal.Cast(data); + ReadOnlySpan blockNumbers = MemoryMarshal.Cast(data); int length = (int)_compressionAlgorithm.Compress(blockNumbers, (nuint)blockNumbers.Length, buffer); return buffer[..length]; } - private static int ReadCompressionMarker(ReadOnlySpan source) => -BinaryPrimitives.ReadInt32LittleEndian(source); - private static void WriteCompressionMarker(Span source, int len) => BinaryPrimitives.WriteInt32LittleEndian(source, -len); + private static int ReadCompressionMarker(ReadOnlySpan source) => + (int)BinaryPrimitives.ReadUInt32LittleEndian(source); + + private static void WriteCompressionMarker(Span source, int len) => + BinaryPrimitives.WriteUInt32LittleEndian(source, (uint)len); - private static bool IsCompressed(ReadOnlySpan source, out int len) + /// + /// Determines whether a DB value is compressed based on its key postfix. + /// Transient keys (BackwardMerge / ForwardMerge) are never compressed; + /// finalized keys (postfix = first_block_number + 1) are always compressed. + /// + /// + /// Finalized key postfix collides with BackwardMerge at block 0xFFFFFFFF and + /// ForwardMerge at block 0xFFFFFFFE — ~13.6 years away at 100ms/block. + /// + private static bool IsCompressed(ReadOnlySpan key, ReadOnlySpan value, out int len) { - if (source.Length == 0) + if (value.Length == 0 || key.EndsWith(Postfix.ForwardMerge) || key.EndsWith(Postfix.BackwardMerge)) { len = 0; return false; } - len = ReadCompressionMarker(source); - return len > 0; + len = ReadCompressionMarker(value); + return true; } - private static void WriteBlockNumber(Span destination, int number) => BinaryPrimitives.WriteInt32LittleEndian(destination, number); - private static int ReadBlockNumber(ReadOnlySpan source) => BinaryPrimitives.ReadInt32LittleEndian(source); - private static int ReadLastBlockNumber(ReadOnlySpan source) => ReadBlockNumber(source[^BlockNumberSize..]); + private static void WriteBlockNumber(Span destination, uint number) => BinaryPrimitives.WriteUInt32LittleEndian(destination, number); + private static uint ReadBlockNumber(ReadOnlySpan source) => BinaryPrimitives.ReadUInt32LittleEndian(source); + private static uint ReadLastBlockNumber(ReadOnlySpan source) => ReadBlockNumber(source[^BlockNumberSize..]); - private static void ReadBlockNumbers(ReadOnlySpan source, Span buffer) + private static void ReadBlockNumbers(ReadOnlySpan source, Span buffer) { if (source.Length % BlockNumberSize != 0) throw new LogIndexStateException("Invalid length for array of block numbers."); @@ -894,8 +913,8 @@ private static void ReadBlockNumbers(ReadOnlySpan source, Span buffer if (BitConverter.IsLittleEndian) { - ReadOnlySpan sourceInt = MemoryMarshal.Cast(source); - sourceInt.CopyTo(buffer); + ReadOnlySpan sourceUint = MemoryMarshal.Cast(source); + sourceUint.CopyTo(buffer); } else { @@ -904,10 +923,10 @@ private static void ReadBlockNumbers(ReadOnlySpan source, Span buffer } } - private static byte[] CreateDbValue(List numbers) + private static byte[] CreateDbValue(List numbers) { byte[] value = new byte[numbers.Count * BlockNumberSize]; - numbers.CopyTo(MemoryMarshal.Cast(value.AsSpan())); + numbers.CopyTo(MemoryMarshal.Cast(value.AsSpan())); return value; } @@ -917,7 +936,7 @@ private static byte[] CreateDbValue(List numbers) private byte[] CompressDbValue(ReadOnlySpan key, Span data) { - if (IsCompressed(data, out _)) + if (IsCompressed(key, data, out _)) throw new LogIndexStateException("Attempt to compress already compressed data.", key); if (data.Length % BlockNumberSize != 0) throw new LogIndexStateException($"Invalid length of data to compress: {data.Length}.", key); @@ -936,9 +955,9 @@ private byte[] CompressDbValue(ReadOnlySpan key, Span data) } } - private void DecompressDbValue(ReadOnlySpan data, Span buffer) + private void DecompressDbValue(ReadOnlySpan key, ReadOnlySpan data, Span buffer) { - if (!IsCompressed(data, out int len)) + if (!IsCompressed(key, data, out int len)) throw new ValidationException("Data is not compressed"); if (buffer.Length < len) @@ -963,16 +982,16 @@ private Span RemoveReorgableBlocks(Span data) private static void ReverseBlocksIfNeeded(Span data) { if (data.Length != 0 && ReadBlockNumber(data) > ReadLastBlockNumber(data)) - MemoryMarshal.Cast(data).Reverse(); + MemoryMarshal.Cast(data).Reverse(); } - private static void ReverseBlocksIfNeeded(Span blocks) + private static void ReverseBlocksIfNeeded(Span blocks) { if (blocks.Length != 0 && blocks[0] > blocks[^1]) blocks.Reverse(); } - private static int LastBlockSearch(ReadOnlySpan operand, int block, bool isBackward) + private static int LastBlockSearch(ReadOnlySpan operand, uint block, bool isBackward) { if (operand.IsEmpty) return 0; @@ -980,7 +999,7 @@ private static int LastBlockSearch(ReadOnlySpan operand, int block, bool i int i = operand.Length - BlockNumberSize; for (; i >= 0; i -= BlockNumberSize) { - int currentBlock = ReadBlockNumber(operand[i..]); + uint currentBlock = ReadBlockNumber(operand[i..]); if (currentBlock == block) return i; @@ -1002,16 +1021,18 @@ private static int LastBlockSearch(ReadOnlySpan operand, int block, bool i private static bool IsSeqAsc(IReadOnlyList blocks) { int j = blocks.Count - 1; - int i = 1, d = blocks[0].BlockNumber; - while (i <= j && blocks[i].BlockNumber - i == d) i++; + int i = 1; + uint d = blocks[0].BlockNumber; + while (i <= j && blocks[i].BlockNumber - (uint)i == d) i++; return i > j; } private static bool IsSeqDesc(IReadOnlyList blocks) { int j = blocks.Count - 1; - int i = 1, d = blocks[0].BlockNumber; - while (i <= j && blocks[i].BlockNumber + i == d) i++; + int i = 1; + uint d = blocks[0].BlockNumber; + while (i <= j && blocks[i].BlockNumber + (uint)i == d) i++; return i > j; } } diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexUpdateStats.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexUpdateStats.cs index 22651564ed8b..f9ef84082885 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexUpdateStats.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexUpdateStats.cs @@ -21,8 +21,8 @@ public class LogIndexUpdateStats(ILogIndexStorage storage) : IFormattable public long LogsAdded => _logsAdded; public long TopicsAdded => _topicsAdded; - public long? MaxBlockNumber => storage.MaxBlockNumber; - public long? MinBlockNumber => storage.MinBlockNumber; + public uint? MaxBlockNumber => storage.MaxBlockNumber; + public uint? MinBlockNumber => storage.MinBlockNumber; public ExecTimeStats Adding { get; } = new(); public ExecTimeStats Aggregating { get; } = new(); diff --git a/src/Nethermind/Nethermind.Db/LogIndex/MergeOperator.cs b/src/Nethermind/Nethermind.Db/LogIndex/MergeOperator.cs index a9f30b6fe4e7..0e9aae0b2b7f 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/MergeOperator.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/MergeOperator.cs @@ -25,7 +25,7 @@ partial class LogIndexStorage /// Supports 2 different use cases depending on the incoming operand: /// /// - /// In case if operand is a sequence of block numbers - + /// In case if operand is a sequence of block numbers - /// directly concatenates with the existing DB value, validating order remains correct (see ).
/// If value size grows to or over block numbers - /// queues it for compression (via ). @@ -51,7 +51,7 @@ public class MergeOperator(ILogIndexStorage storage, ICompressor compressor, int public ArrayPoolList? PartialMerge(ReadOnlySpan key, RocksDbMergeEnumerator enumerator) => Merge(key, enumerator, isPartial: true); - private static bool IsBlockNewer(int next, int? last, bool isBackwardSync) => + private static bool IsBlockNewer(uint next, uint? last, bool isBackwardSync) => LogIndexStorage.IsBlockNewer(next, last, last, isBackwardSync); // Validate we are merging non-intersecting segments - to prevent data corruption @@ -60,8 +60,8 @@ private static void AddEnsureSorted(ReadOnlySpan key, ArrayPoolList if (value.Length == 0) return; - int nextBlock = ReadBlockNumber(value); - int? lastBlock = result.Count > 0 ? ReadLastBlockNumber(result.AsSpan()) : (int?)null; + uint nextBlock = ReadBlockNumber(value); + uint? lastBlock = result.Count > 0 ? ReadLastBlockNumber(result.AsSpan()) : (uint?)null; if (!IsBlockNewer(next: nextBlock, last: lastBlock, isBackward)) throw new LogIndexStateException($"Invalid order during merge: {lastBlock} -> {nextBlock} (backward: {isBackward}).", key); @@ -104,7 +104,7 @@ private static void AddEnsureSorted(ReadOnlySpan key, ArrayPoolList result = new(resultLength); // For truncate - just use max/min for all operands - int? truncateAggregate = Aggregate(MergeOp.Truncate, enumerator, isBackwards); + uint? truncateAggregate = Aggregate(MergeOp.Truncate, enumerator, isBackwards); int iReorg = 0; for (int i = 0; i < enumerator.TotalCount; i++) @@ -146,19 +146,19 @@ private static void AddEnsureSorted(ReadOnlySpan key, ArrayPoolList } } - private static int? FindNext(MergeOp op, RocksDbMergeEnumerator enumerator, ref int i) + private static uint? FindNext(MergeOp op, RocksDbMergeEnumerator enumerator, ref int i) { while (i < enumerator.TotalCount && !MergeOps.Is(op, enumerator.Get(i))) i++; - return i < enumerator.TotalCount && MergeOps.Is(op, enumerator.Get(i), out int block) + return i < enumerator.TotalCount && MergeOps.Is(op, enumerator.Get(i), out uint block) ? block : null; } - private static int? Aggregate(MergeOp op, RocksDbMergeEnumerator enumerator, bool isBackwardSync) + private static uint? Aggregate(MergeOp op, RocksDbMergeEnumerator enumerator, bool isBackwardSync) { - int? result = null; + uint? result = null; for (var i = 0; i < enumerator.OperandsCount; i++) { if (!MergeOps.Is(op, enumerator.GetOperand(i), out var next)) diff --git a/src/Nethermind/Nethermind.Db/LogIndex/MergeOps.cs b/src/Nethermind/Nethermind.Db/LogIndex/MergeOps.cs index 74d494cd5d0f..d080e9084d11 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/MergeOps.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/MergeOps.cs @@ -42,7 +42,7 @@ public static class MergeOps public static bool Is(MergeOp op, ReadOnlySpan operand) => operand.Length == Size && operand[0] == (byte)op; - public static bool Is(MergeOp op, ReadOnlySpan operand, out int fromBlock) + public static bool Is(MergeOp op, ReadOnlySpan operand, out uint fromBlock) { if (operand.Length == Size && operand[0] == (byte)op) { @@ -58,7 +58,7 @@ public static bool IsAny(ReadOnlySpan operand) => Is(MergeOp.Reorg, operand, out _) || Is(MergeOp.Truncate, operand, out _); - public static Span Create(MergeOp op, int fromBlock, Span buffer) + public static Span Create(MergeOp op, uint fromBlock, Span buffer) { Span dbValue = buffer[..Size]; dbValue[0] = (byte)op; @@ -66,7 +66,7 @@ public static Span Create(MergeOp op, int fromBlock, Span buffer) return dbValue; } - public static Span ApplyTo(Span operand, MergeOp op, int block, bool isBackward) + public static Span ApplyTo(Span operand, MergeOp op, uint block, bool isBackward) { // In most cases the searched block will be near or at the end of the operand, if present there int i = LastBlockSearch(operand, block, isBackward); diff --git a/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs b/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs index 322e4d54542f..a3da1d6ecab1 100644 --- a/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs @@ -28,30 +28,30 @@ public class LogIndexBuilderTests { private class TestLogIndexStorage : ILogIndexStorage { - private int? _minBlockNumber; - private int? _maxBlockNumber; + private uint? _minBlockNumber; + private uint? _maxBlockNumber; public bool Enabled => true; - public event EventHandler? NewMaxBlockNumber; - public event EventHandler? NewMinBlockNumber; + public event EventHandler? NewMaxBlockNumber; + public event EventHandler? NewMinBlockNumber; - public int? MinBlockNumber + public uint? MinBlockNumber { get => _minBlockNumber; init => _minBlockNumber = value; } - public int? MaxBlockNumber + public uint? MaxBlockNumber { get => _maxBlockNumber; init => _maxBlockNumber = value; } - public IEnumerator GetEnumerator(Address address, int from, int to) => + public IEnumerator GetEnumerator(Address address, uint from, uint to) => throw new NotImplementedException(); - public IEnumerator GetEnumerator(int topicIndex, Hash256 topic, int from, int to) => + public IEnumerator GetEnumerator(int topicIndex, Hash256 topic, uint from, uint to) => throw new NotImplementedException(); public string GetDbSize() => 0L.SizeToString(); @@ -181,16 +181,16 @@ CancellationToken cancellation _syncConfig.AncientReceiptsBarrier = minBarrier; Assert.That(_syncConfig.AncientReceiptsBarrierCalc, Is.EqualTo(minBarrier)); - var expectedMin = minBarrier <= 1 ? 0 : synced[0] < 0 ? minBarrier : Math.Min(synced[0], minBarrier); + var expectedMin = (uint)(minBarrier <= 1 ? 0 : synced[0] < 0 ? minBarrier : Math.Min(synced[0], minBarrier)); var storage = new TestLogIndexStorage { - MinBlockNumber = synced[0] < 0 ? null : synced[0], - MaxBlockNumber = synced[1] < 0 ? null : synced[1] + MinBlockNumber = synced[0] < 0 ? null : (uint)synced[0], + MaxBlockNumber = synced[1] < 0 ? null : (uint)synced[1] }; LogIndexBuilder builder = GetService(storage); - Task completion = WaitBlocksAsync(storage, expectedMin, MaxSyncBlock, cancellation); + Task completion = WaitBlocksAsync(storage, expectedMin, (uint)MaxSyncBlock, cancellation); await builder.StartAsync(); await completion; @@ -199,7 +199,7 @@ CancellationToken cancellation Assert.That(builder.LastError, Is.Null); Assert.That(storage.MinBlockNumber, Is.EqualTo(expectedMin)); - Assert.That(storage.MaxBlockNumber, Is.EqualTo(MaxSyncBlock)); + Assert.That(storage.MaxBlockNumber, Is.EqualTo((uint)MaxSyncBlock)); } } @@ -233,8 +233,8 @@ public async Task Should_CompleteImmediately_IfAlreadySynced( _syncConfig.AncientReceiptsBarrier = minBarrier; LogIndexBuilder builder = GetService(new FailingLogIndexStorage(0, new("Should not set new receipts.")) { - MinBlockNumber = minBlock, - MaxBlockNumber = MaxSyncBlock + MinBlockNumber = (uint)minBlock, + MaxBlockNumber = (uint)MaxSyncBlock }); await builder.StartAsync(); @@ -247,12 +247,12 @@ public async Task Should_CompleteImmediately_IfAlreadySynced( } } - private static Task WaitMaxBlockAsync(TestLogIndexStorage storage, int blockNumber, CancellationToken cancellation) + private static Task WaitMaxBlockAsync(TestLogIndexStorage storage, uint blockNumber, CancellationToken cancellation) { if (storage.MaxBlockNumber >= blockNumber) return Task.CompletedTask; - return Wait.ForEventCondition( + return Wait.ForEventCondition( cancellation, e => storage.NewMaxBlockNumber += e, e => storage.NewMaxBlockNumber -= e, @@ -260,12 +260,12 @@ private static Task WaitMaxBlockAsync(TestLogIndexStorage storage, int blockNumb ); } - private static Task WaitMinBlockAsync(TestLogIndexStorage storage, int blockNumber, CancellationToken cancellation) + private static Task WaitMinBlockAsync(TestLogIndexStorage storage, uint blockNumber, CancellationToken cancellation) { if (storage.MinBlockNumber <= blockNumber) return Task.CompletedTask; - return Wait.ForEventCondition( + return Wait.ForEventCondition( cancellation, e => storage.NewMinBlockNumber += e, e => storage.NewMinBlockNumber -= e, @@ -273,7 +273,7 @@ private static Task WaitMinBlockAsync(TestLogIndexStorage storage, int blockNumb ); } - private static Task WaitBlocksAsync(TestLogIndexStorage storage, int minBlock, int maxBlock, CancellationToken cancellation) => Task.WhenAll( + private static Task WaitBlocksAsync(TestLogIndexStorage storage, uint minBlock, uint maxBlock, CancellationToken cancellation) => Task.WhenAll( WaitMinBlockAsync(storage, minBlock, cancellation), WaitMaxBlockAsync(storage, maxBlock, cancellation) ); diff --git a/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs b/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs index 824c21538065..5e1f71bfd90f 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs @@ -20,9 +20,9 @@ namespace Nethermind.Facade.Filters; /// Converts tree and block range into an enumerator of block numbers from , /// by building corresponding "tree of enumerators". /// -public class LogIndexFilterVisitor(ILogIndexStorage storage, LogFilter filter, int fromBlock, int toBlock) : IEnumerable +public class LogIndexFilterVisitor(ILogIndexStorage storage, LogFilter filter, uint fromBlock, uint toBlock) : IEnumerable { - internal sealed class IntersectEnumerator(IEnumerator e1, IEnumerator e2) : IEnumerator + internal sealed class IntersectEnumerator(IEnumerator e1, IEnumerator e2) : IEnumerator { public bool MoveNext() { @@ -31,8 +31,8 @@ public bool MoveNext() while (has1 && has2) { - int c1 = e1.Current; - int c2 = e2.Current; + uint c1 = e1.Current; + uint c2 = e2.Current; if (c1 == c2) { Current = c1; @@ -52,7 +52,7 @@ public void Reset() e2.Reset(); } - public int Current { get; private set; } + public uint Current { get; private set; } object? IEnumerator.Current => Current; @@ -63,7 +63,7 @@ public void Dispose() } } - internal sealed class UnionEnumerator(IEnumerator e1, IEnumerator e2) : IEnumerator + internal sealed class UnionEnumerator(IEnumerator e1, IEnumerator e2) : IEnumerator { private bool _has1 = e1.MoveNext(); private bool _has2 = e2.MoveNext(); @@ -82,7 +82,7 @@ public bool MoveNext() => (false, false) => false }; - private bool MoveNext(IEnumerator enumerator, out bool has) + private bool MoveNext(IEnumerator enumerator, out bool has) { Current = enumerator.Current; has = enumerator.MoveNext(); @@ -97,7 +97,7 @@ public void Reset() _has2 = e2.MoveNext(); } - public int Current { get; private set; } + public uint Current { get; private set; } object? IEnumerator.Current => Current; @@ -110,10 +110,10 @@ public void Dispose() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { - IEnumerator? addressEnumerator = Visit(filter.AddressFilter); - IEnumerator? topicEnumerator = Visit(filter.TopicsFilter); + IEnumerator? addressEnumerator = Visit(filter.AddressFilter); + IEnumerator? topicEnumerator = Visit(filter.TopicsFilter); if (addressEnumerator is not null && topicEnumerator is not null) return new IntersectEnumerator(addressEnumerator, topicEnumerator); @@ -121,22 +121,22 @@ public IEnumerator GetEnumerator() return addressEnumerator ?? topicEnumerator ?? throw new InvalidOperationException("Provided filter covers whole block range."); } - private IEnumerator? Visit(AddressFilter addressFilter) + private IEnumerator? Visit(AddressFilter addressFilter) { - IEnumerator? result = null; + IEnumerator? result = null; foreach (AddressAsKey address in addressFilter.Addresses) { - IEnumerator next = Visit(address); + IEnumerator next = Visit(address); result = result is null ? next : new UnionEnumerator(result, next); } return result; } - private IEnumerator? Visit(TopicsFilter topicsFilter) + private IEnumerator? Visit(TopicsFilter topicsFilter) { - IEnumerator result = null; + IEnumerator result = null; var topicIndex = 0; foreach (TopicExpression expression in topicsFilter.Expressions) @@ -150,7 +150,7 @@ public IEnumerator GetEnumerator() return result; } - private IEnumerator? Visit(int topicIndex, TopicExpression expression) => expression switch + private IEnumerator? Visit(int topicIndex, TopicExpression expression) => expression switch { AnyTopic => null, OrExpression orExpression => Visit(topicIndex, orExpression), @@ -158,9 +158,9 @@ public IEnumerator GetEnumerator() _ => throw new ArgumentOutOfRangeException($"Unknown topic expression type: {expression.GetType().Name}.") }; - private IEnumerator? Visit(int topicIndex, OrExpression orExpression) + private IEnumerator? Visit(int topicIndex, OrExpression orExpression) { - IEnumerator? result = null; + IEnumerator? result = null; foreach (TopicExpression expression in orExpression.SubExpressions) { @@ -173,15 +173,15 @@ public IEnumerator GetEnumerator() return result; } - private IEnumerator Visit(Address address) => + private IEnumerator Visit(Address address) => storage.GetEnumerator(address, fromBlock, toBlock); - private IEnumerator Visit(int topicIndex, Hash256 topic) => + private IEnumerator Visit(int topicIndex, Hash256 topic) => storage.GetEnumerator(topicIndex, topic, fromBlock, toBlock); } public static class LogIndexFilterVisitorExtensions { - public static IEnumerable EnumerateBlockNumbersFor(this ILogIndexStorage storage, LogFilter filter, long fromBlock, long toBlock) => - new LogIndexFilterVisitor(storage, filter, (int)fromBlock, (int)toBlock).Select(static i => (long)i); + public static IEnumerable EnumerateBlockNumbersFor(this ILogIndexStorage storage, LogFilter filter, uint fromBlock, uint toBlock) => + new LogIndexFilterVisitor(storage, filter, fromBlock, toBlock).Select(static i => (long)i); } diff --git a/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs b/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs index 3f898f360640..c6bcdcecac53 100644 --- a/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs @@ -12,8 +12,8 @@ public interface ILogIndexBuilder : IAsyncDisposable, IStoppableService Task StartAsync(); bool IsRunning { get; } - int MaxTargetBlockNumber { get; } - int MinTargetBlockNumber { get; } + uint MaxTargetBlockNumber { get; } + uint MinTargetBlockNumber { get; } DateTimeOffset? LastUpdate { get; } Exception? LastError { get; } diff --git a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs index 0d7ff37d0ae4..4d968150f877 100644 --- a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs @@ -39,9 +39,9 @@ public override IEnumerable FindLogs(LogFilter filter, BlockHeader fr ? base.FindLogs(filter, fromBlock, toBlock, cancellationToken) : FindIndexedLogs(filter, fromBlock, toBlock, indexRange, cancellationToken); - private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, (int from, int to) indexRange, CancellationToken cancellationToken) + private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, (uint from, uint to) indexRange, CancellationToken cancellationToken) { - if (indexRange.from > fromBlock.Number && FindHeaderOrLogError(indexRange.from - 1, cancellationToken) is { } beforeIndex) + if (indexRange.from > (uint)fromBlock.Number && FindHeaderOrLogError(indexRange.from - 1, cancellationToken) is { } beforeIndex) { foreach (FilterLog log in base.FindLogs(filter, fromBlock, beforeIndex, cancellationToken)) yield return log; @@ -54,14 +54,14 @@ private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fro cancellationToken.ThrowIfCancellationRequested(); - if (indexRange.to < toBlock.Number && FindHeaderOrLogError(indexRange.to + 1, cancellationToken) is { } afterIndex) + if (indexRange.to < (uint)toBlock.Number && FindHeaderOrLogError(indexRange.to + 1, cancellationToken) is { } afterIndex) { foreach (FilterLog log in base.FindLogs(filter, afterIndex, toBlock, cancellationToken)) yield return log; } } - private (int from, int to)? GetLogIndexRange(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock) + private (uint from, uint to)? GetLogIndexRange(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock) { bool tryUseIndex = filter.UseIndex; filter.UseIndex = false; @@ -72,15 +72,15 @@ private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fro if (_logIndexStorage.MinBlockNumber is not { } indexFrom || _logIndexStorage.MaxBlockNumber is not { } indexTo) return null; - (int from, int to) range = ( - Math.Max((int)fromBlock.Number, indexFrom), - Math.Min((int)toBlock.Number, indexTo) + (uint from, uint to) range = ( + Math.Max((uint)fromBlock.Number, indexFrom), + Math.Min((uint)toBlock.Number, indexTo) ); if (range.from > range.to) return null; - if (range.to - range.from + 1 < minBlocksToUseIndex) + if (range.to - range.from + 1 < (uint)minBlocksToUseIndex) return null; filter.UseIndex = true; diff --git a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs index 51a9fe703252..59773a280665 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs @@ -60,8 +60,8 @@ private struct DirectionStates private readonly ILogManager _logManager; private Timer? _progressLoggerTimer; - private readonly TaskCompletionSource _pivotSource = new(RunContinuationsAsynchronously); - private readonly Task _pivotTask; + private readonly TaskCompletionSource _pivotSource = new(RunContinuationsAsynchronously); + private readonly Task _pivotTask; private readonly List _tasks = new(); @@ -127,7 +127,7 @@ public async Task StartAsync() _receiptStorage.ReceiptsInserted += OnReceiptsInserted; TrySetPivot(_logIndexStorage.MaxBlockNumber); - TrySetPivot((int)_blockTree.SyncPivot.BlockNumber); + TrySetPivot((uint)_blockTree.SyncPivot.BlockNumber); if (!_pivotTask.IsCompleted && _logger.IsInfo) _logger.Info($"{GetLogPrefix()}: waiting for the first block..."); @@ -212,7 +212,7 @@ private void LogProgress() Direction(true).Progress?.LogProgress(); } - private bool TrySetPivot(int? blockNumber) + private bool TrySetPivot(uint? blockNumber) { if (blockNumber is not { } number || number is 0) return false; @@ -238,15 +238,15 @@ private bool TrySetPivot(int? blockNumber) private void OnReceiptsInserted(object? sender, ReceiptsEventArgs args) { - int next = (int)args.BlockHeader.Number; + uint next = (uint)args.BlockHeader.Number; if (TrySetPivot(next)) _receiptStorage.ReceiptsInserted -= OnReceiptsInserted; } - public int MaxTargetBlockNumber => (int)Math.Max(_blockTree.BestKnownNumber - MaxReorgDepth, 0); + public uint MaxTargetBlockNumber => (uint)Math.Max(_blockTree.BestKnownNumber - MaxReorgDepth, 0); // Block 0 should always be present - public int MinTargetBlockNumber => (int)(_syncConfig.AncientReceiptsBarrierCalc <= 1 ? 0 : _syncConfig.AncientReceiptsBarrierCalc); + public uint MinTargetBlockNumber => (uint)(_syncConfig.AncientReceiptsBarrierCalc <= 1 ? 0 : _syncConfig.AncientReceiptsBarrierCalc); public bool IsRunning { get; private set; } public DateTimeOffset? LastUpdate { get; private set; } @@ -326,27 +326,29 @@ private async Task DoQueueBlocks(bool isForward) { try { - int pivotNumber = await _pivotTask; + uint pivotNumber = await _pivotTask; ProcessingQueue queue = Direction(isForward).Queue!; - int? next = GetNextBlockNumber(isForward); - if (next is not { } start) + uint? next = GetNextBlockNumber(isForward); + uint? start; + if (next is not null) { - if (isForward) - { - start = pivotNumber; - } - else - { - start = pivotNumber - 1; - } + start = next; + } + else if (isForward) + { + start = pivotNumber; + } + else + { + start = pivotNumber > 0 ? pivotNumber - 1 : null; } BlockReceipts[] buffer = new BlockReceipts[_config.MaxBatchSize]; while (!CancellationToken.IsCancellationRequested) { - if (!isForward && start < MinTargetBlockNumber) + if (start is not { } startVal || (!isForward && startVal < MinTargetBlockNumber)) { if (_logger.IsTrace) _logger.Trace($"{GetLogPrefix(isForward)}: queued last block"); @@ -354,15 +356,17 @@ private async Task DoQueueBlocks(bool isForward) return; } - int batchSize = _config.MaxBatchSize; - int end = isForward ? start + batchSize - 1 : start - batchSize + 1; + uint batchSize = (uint)_config.MaxBatchSize; + uint end = isForward + ? Math.Min(startVal + batchSize - 1, MaxTargetBlockNumber) + : Math.Max(startVal >= batchSize ? startVal - batchSize + 1 : 0, MinTargetBlockNumber); end = Math.Max(end, MinTargetBlockNumber); end = Math.Min(end, MaxTargetBlockNumber); // from - inclusive, to - exclusive var (from, to) = isForward - ? (start, end + 1) - : (end, start + 1); + ? (startVal, end + 1) + : (end, startVal + 1); var timestamp = Stopwatch.GetTimestamp(); Array.Clear(buffer); @@ -424,34 +428,36 @@ private void MarkCompleted(bool isForward) _logger.Info($"{GetLogPrefix(isForward)}: completed."); } - private static int? GetNextBlockNumber(ILogIndexStorage storage, bool isForward) => isForward ? storage.MaxBlockNumber + 1 : storage.MinBlockNumber - 1; + private static uint? GetNextBlockNumber(ILogIndexStorage storage, bool isForward) => isForward + ? storage.MaxBlockNumber + 1 + : storage.MinBlockNumber is > 0 and var min ? min - 1 : null; - private int? GetNextBlockNumber(bool isForward) => GetNextBlockNumber(_logIndexStorage, isForward); + private uint? GetNextBlockNumber(bool isForward) => GetNextBlockNumber(_logIndexStorage, isForward); - private static int GetNextBlockNumber(int last, bool isForward) => isForward ? last + 1 : last - 1; + private static uint? GetNextBlockNumber(uint last, bool isForward) => isForward ? last + 1 : last > 0 ? last - 1 : null; - private ReadOnlySpan GetNextBatch(int from, int to, BlockReceipts[] buffer, bool isForward, CancellationToken token) + private ReadOnlySpan GetNextBatch(uint from, uint to, BlockReceipts[] buffer, bool isForward, CancellationToken token) { if (to <= from) return ReadOnlySpan.Empty; - if (to - from > buffer.Length) + if (to - from > (uint)buffer.Length) throw new InvalidOperationException($"{GetLogPrefix()}: buffer size is too small: {buffer.Length} / {to - from}"); // Check the immediate next block first - int nextIndex = isForward ? from : to - 1; + uint nextIndex = isForward ? from : to - 1; if (!TryGetBlockReceipts(nextIndex, out buffer[0])) return ReadOnlySpan.Empty; - Parallel.For(from, to, new() + Parallel.For((long)from, (long)to, new() { CancellationToken = token, MaxDegreeOfParallelism = _config.MaxReceiptsParallelism }, i => { - int bufferIndex = isForward ? i - from : to - 1 - i; + int bufferIndex = isForward ? (int)(i - from) : (int)(to - 1 - i); if (buffer[bufferIndex] == default) - TryGetBlockReceipts(i, out buffer[bufferIndex]); + TryGetBlockReceipts((uint)i, out buffer[bufferIndex]); }); int endIndex = Array.IndexOf(buffer, default); @@ -459,11 +465,11 @@ private ReadOnlySpan GetNextBatch(int from, int to, BlockReceipts } // TODO: move to IReceiptStorage? - private bool TryGetBlockReceipts(int i, out BlockReceipts blockReceipts) + private bool TryGetBlockReceipts(uint i, out BlockReceipts blockReceipts) { blockReceipts = default; - if (_blockTree.FindBlock(i, BlockTreeLookupOptions.ExcludeTxHashes) is not { Hash: not null } block) + if (_blockTree.FindBlock((long)i, BlockTreeLookupOptions.ExcludeTxHashes) is not { Hash: not null } block) { return false; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs index 94c4a48272ba..cab91bc9ae46 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs @@ -25,7 +25,7 @@ public ResultWrapper> logIndex_blockNumbers(Filter filter) if (GetBlockNumber(logFilter.ToBlock) is not { } to) return ResultWrapper>.Fail($"Block {logFilter.ToBlock} is not found.", ErrorCodes.UnknownBlockError); - return ResultWrapper>.Success(storage.EnumerateBlockNumbersFor(logFilter, from, to)); + return ResultWrapper>.Success(storage.EnumerateBlockNumbersFor(logFilter, (uint)from, (uint)to)); } public ResultWrapper logIndex_status() diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs index 47a7d1b10180..4295a9be0c1c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs @@ -7,7 +7,7 @@ namespace Nethermind.JsonRpc.Modules.LogIndex; public class LogIndexStatus { - public readonly record struct Range(int? FromBlock, int? ToBlock); + public readonly record struct Range(uint? FromBlock, uint? ToBlock); public required Range Current { get; init; } public required Range Target { get; init; }