Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERA history import/export start #6173

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
301180c
ERA history import/export start
ak88 Sep 26, 2023
5a0b8c4
Rename in unit test
ak88 Oct 9, 2023
04209fb
Fix block index not set
ak88 Oct 9, 2023
4b10a61
Start export
ak88 Oct 10, 2023
bfcbfb5
Era builder
ak88 Oct 13, 2023
e9d91b6
Accumulator calculation
ak88 Oct 17, 2023
7b88e17
ERA history import/export
ak88 Sep 26, 2023
1543a39
Rename in unit test
ak88 Oct 9, 2023
e07cca5
Fix block index not set
ak88 Oct 9, 2023
42131e6
Start export
ak88 Oct 10, 2023
551d974
Era builder
ak88 Oct 13, 2023
aba6cfb
Accumulator calculation
ak88 Oct 17, 2023
65a9225
Builder finalize
ak88 Oct 18, 2023
d0741e5
Merge branch 'feature/era-history' of https://github.com/ak88/netherm…
ak88 Oct 18, 2023
508f1ae
Unit tests
ak88 Oct 23, 2023
c7636c2
Unit tests
ak88 Oct 24, 2023
ee53da7
import geth files
ak88 Nov 1, 2023
8503f08
Reader with netty
ak88 Nov 2, 2023
66eacd1
1mb read buffer
ak88 Nov 2, 2023
8d48264
refactor test and use of netty
ak88 Nov 3, 2023
904ecab
Big blocks test
ak88 Nov 4, 2023
74d14ad
Change to IByteBuffer
ak88 Nov 4, 2023
e1e86ae
buffer allocater injected
ak88 Nov 4, 2023
d8f4ad8
Merge branch 'NettyBuffers' into feature/era-history
ak88 Nov 4, 2023
c27adf6
Squashed commit of the following:
ak88 Nov 5, 2023
27fc5cd
Merge from master
ak88 Nov 5, 2023
756b170
assert files exist
ak88 Nov 5, 2023
e3a6647
reverted
ak88 Nov 6, 2023
f18e742
rollback gitbook
ak88 Nov 6, 2023
7066e64
Merge branch 'master' into feature/era-history
ak88 Nov 6, 2023
d2656d8
revert gitbook
ak88 Nov 6, 2023
5d43047
revert launchsettings
ak88 Nov 6, 2023
dedba82
Delete from this pr
ak88 Nov 6, 2023
f2f03db
format whitespace
ak88 Nov 6, 2023
58f8a06
small fix
ak88 Nov 7, 2023
f089911
accumulator test
ak88 Nov 7, 2023
5c9f698
Squashed commit of the following:
ak88 Nov 9, 2023
ce691f0
ReceiptMessageDecoder cleanup
ak88 Nov 9, 2023
c618d97
Squashed commit of the following:
ak88 Nov 10, 2023
c3e6df8
no seeking to index
ak88 Nov 10, 2023
c0640ed
reuse compression streams
ak88 Nov 10, 2023
85dfb85
format
ak88 Nov 10, 2023
6330162
Performance optimization
ak88 Nov 10, 2023
3fed302
avoid a copy and dispose on ex
ak88 Nov 11, 2023
1900b69
Merge branch 'feature/era-history' of https://github.com/ak88/netherm…
ak88 Nov 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Nethermind/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<PackageVersion Include="Colorful.Console" Version="1.2.15" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="ConcurrentHashSet" Version="1.3.0" />
<PackageVersion Include="Cortex.SimpleSerialize" Version="0.2.0" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not newer Nethermind.Serialization.Ssz?
@flcl42 Can you advise?

<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
<PackageVersion Include="Crc32.NET" Version="1.2.0" />
Expand Down Expand Up @@ -68,6 +69,7 @@
<PackageVersion Include="Seq.Api" Version="2023.3.0" />
<PackageVersion Include="SharpCompress" Version="0.34.1" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="Snappier" Version="1.1.2" />
<PackageVersion Include="Snappy.Standard" Version="0.2.0" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
<PackageVersion Include="System.Diagnostics.TextWriterTraceListener" Version="4.3.0" />
Expand All @@ -83,4 +85,4 @@
<PackageVersion Include="Websocket.Client" Version="4.6.1" />
<PackageVersion Include="YamlDotNet" Version="13.1.1" />
</ItemGroup>
</Project>
</Project>
7 changes: 7 additions & 0 deletions src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,12 @@ public static byte[] GenerateIndexedAccountRlp(int index, AccountDecoder? accoun
byte[] value = accountDecoder.Encode(account).Bytes;
return value;
}

public static UInt256 GetRandomAmount(Random? random = null)
{
Span<byte> buffer = stackalloc byte[32];
(random ?? Random).NextBytes(buffer);
return new UInt256(buffer);
}
}
}
2 changes: 2 additions & 0 deletions src/Nethermind/Nethermind.Core/Collections/ArrayPoolList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,6 @@ public void Dispose()
}

public Span<T> AsSpan() => _array.AsSpan(0, _count);
public Span<T> AsSpan(int start, int count) => _array.AsSpan(start, count);
public Memory<T> AsMemory(int start, int length) => _array.AsMemory(start, length);
}
46 changes: 46 additions & 0 deletions src/Nethermind/Nethermind.Era.Test/AccumulatorCalculatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Intrinsics.Arm;
using System.Text;
using System.Threading.Tasks;
using Nethermind.Core.Crypto;

namespace Nethermind.Era1.Test;
public class AccumulatorCalculatorTests
{
[Test]
public void Add_AddOneHashAndUInt256_DoesNotThrow()
{
using var sut = new AccumulatorCalculator();

Assert.That(() => sut.Add(Keccak.Zero, 0), Throws.Nothing);
}
[Test]
public void ComputeRoot_AddValues_ReturnsExpectedResult()
{
using var sut = new AccumulatorCalculator();
sut.Add(Keccak.Zero, 1);
sut.Add(Keccak.MaxValue, 2);

var result = sut.ComputeRoot().ToArray();

Assert.That(result, Is.EquivalentTo(new[] { 0x3E, 0xD6, 0x26, 0x52, 0xDF, 0xB7, 0xE1, 0x07, 0x2D, 0x0F, 0x04, 0x0F, 0xEB, 0x6D, 0x00, 0x2A, 0x9F, 0x7C, 0xE3, 0x7C, 0xF8, 0xDD, 0xB1, 0x65, 0x49, 0xA7, 0xAC, 0x5C, 0xF8, 0xE3, 0xB7, 0x91 }));
}

[Test]
public void ComputeRoot_AddOneHashAndUInt256_DoesNotThrow()
{
using var sut = new AccumulatorCalculator();
sut.Add(Keccak.Zero, 1);
sut.Add(Keccak.MaxValue, 2);

var result = sut.ComputeRoot().ToArray();

Assert.That(result, Is.EquivalentTo(new[] { 0x3E, 0xD6, 0x26, 0x52, 0xDF, 0xB7, 0xE1, 0x07, 0x2D, 0x0F, 0x04, 0x0F, 0xEB, 0x6D, 0x00, 0x2A, 0x9F, 0x7C, 0xE3, 0x7C, 0xF8, 0xDD, 0xB1, 0x65, 0x49, 0xA7, 0xAC, 0x5C, 0xF8, 0xE3, 0xB7, 0x91 }));
}
}
258 changes: 258 additions & 0 deletions src/Nethermind/Nethermind.Era.Test/E2StoreTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetty.Buffers;
using FluentAssertions;
using Nethermind.Serialization.Rlp;
using Snappier;

namespace Nethermind.Era1.Test;
internal class E2StoreTests
{
[TestCase(EntryTypes.Version)]
[TestCase(EntryTypes.CompressedHeader)]
[TestCase(EntryTypes.CompressedBody)]
[TestCase(EntryTypes.CompressedReceipts)]
[TestCase(EntryTypes.Accumulator)]
[TestCase(EntryTypes.BlockIndex)]
public async Task WriteEntry_WritingAnEntry_WritesCorrectHeaderType(ushort type)
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);

await sut.WriteEntry(type, Array.Empty<byte>());

Assert.That(BitConverter.ToInt16(stream.ToArray()), Is.EqualTo(type));
}

[TestCase(6)]
[TestCase(20)]
[TestCase(32)]
public async Task WriteEntry_WritingAnEntry_WritesCorrectLengthInHeader(int length)
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);

await sut.WriteEntry(EntryTypes.CompressedHeader, new byte[length]);

Assert.That(BitConverter.ToInt32(stream.ToArray(), 2), Is.EqualTo(length));
}

[TestCase(1)]
[TestCase(5)]
[TestCase(12)]
public async Task WriteEntry_WritingAnEntry_ReturnCorrectNumberofBytesWritten(int length)
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);

int result = await sut.WriteEntry(EntryTypes.CompressedHeader, new byte[length]);

Assert.That(result, Is.EqualTo(length + E2Store.HeaderSize));
}


[Test]
public async Task WriteEntry_WritingAnEntry_ZeroesAtCorrectIndexesInHeader()
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);

await sut.WriteEntry(EntryTypes.CompressedHeader, new byte[] { 0xff, 0xff, 0xff, 0xff });
byte[] bytes = stream.ToArray();

Assert.That(bytes[6], Is.EqualTo(0));
Assert.That(bytes[7], Is.EqualTo(0));
}

[Test]
public async Task WriteEntry_WritingEntryValue_BytesAreWrittenToStream()
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);

byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };
await sut.WriteEntry(EntryTypes.CompressedHeader, bytes);
byte[] result = stream.ToArray();

Assert.That(new ArraySegment<byte>(result, E2Store.HeaderSize, bytes.Length), Is.EquivalentTo(bytes));
}

[Test]
public async Task WriteEntryAsSnappy_WritingEntryValue_WritesEncodedBytesToStream()
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };

await sut.WriteEntryAsSnappy(EntryTypes.CompressedHeader, bytes);
stream.Position = E2Store.HeaderSize;
using var snappy = new SnappyStream(stream, System.IO.Compression.CompressionMode.Decompress);
byte[] buffer = new byte[32];

Assert.That(() => snappy.Read(buffer), Throws.Nothing);
}

[Test]
public async Task WriteEntryAsSnappy_WritingEntryValue_ReturnsCompressedSize()
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };

int result = await sut.WriteEntryAsSnappy(EntryTypes.CompressedHeader, bytes);

Assert.That(result, Is.EqualTo(stream.Length));
}

[Test]
public async Task ReadEntryValue_ReadingValueBytesOfEntry_ReturnsBytes()
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };
await sut.WriteEntry(EntryTypes.Accumulator, bytes);
IByteBuffer buffer = UnpooledByteBufferAllocator.Default.Buffer(bytes.Length);
try
{
int read = await sut.ReadEntryValue(buffer, new Entry(EntryTypes.Accumulator, 0, bytes.Length));

Assert.That(new ArraySegment<byte>(buffer.Array, buffer.ArrayOffset, read), Is.EquivalentTo(bytes));
}
finally
{
buffer.Release();
}
}

[Test]
public async Task ReadEntryValue_ReadingValueBytesOfEntry_ReturnsBytesRead()
{
using MemoryStream stream = new MemoryStream();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };
await sut.WriteEntry(EntryTypes.Accumulator, bytes);
IByteBuffer buffer = UnpooledByteBufferAllocator.Default.Buffer(bytes.Length);

int result = await sut.ReadEntryValue(buffer, new Entry(EntryTypes.Accumulator, 0, bytes.Length));

Assert.That(result, Is.EqualTo(bytes.Length));
}

[Test]
public async Task ReadEntryValueAsSnappy_ReadingValueBytesOfEntry_ReturnsDecompressedBytes()
{
using MemoryStream stream = new();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };
MemoryStream compressed = new();
using SnappyStream snappy = new SnappyStream(compressed, System.IO.Compression.CompressionMode.Compress);
snappy.Write(bytes);
snappy.Flush();
byte[] compressedBytes = compressed.ToArray();
await sut.WriteEntry(EntryTypes.CompressedHeader, compressedBytes);
IByteBuffer buffer = UnpooledByteBufferAllocator.Default.Buffer(32);
try
{
int read = await sut.ReadEntryValueAsSnappy(buffer, new Entry(EntryTypes.CompressedHeader, 0, compressedBytes.Length));

Assert.That(new ArraySegment<byte>(buffer.Array, 0, read), Is.EquivalentTo(bytes));
}
finally
{
buffer.Release();
}
}


[TestCase(0)]
[TestCase(8)]
[TestCase(16)]
public async Task ReadValueAt_ReadingValueAtDifferentOffset_ReturnsCorrectValue(int offset)
{
using MemoryStream stream = new();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 };
stream.Write(bytes, 0, bytes.Length);

long result = await sut.ReadValueAt(offset);

Assert.That(result, Is.EqualTo(BitConverter.ToInt64(bytes, offset)));
}

[TestCase(6)]
[TestCase(14)]
[TestCase(24)]
public async Task ReadEntryAt_ReadingEntryAtDifferentOffset_ReturnsCorrectEntry(int offset)
{
using MemoryStream stream = new();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0xff, 0xff, 0xff, 0xff };
stream.SetLength(offset);
stream.Seek(0, SeekOrigin.End);
await sut.WriteEntry(EntryTypes.CompressedHeader, bytes);

Entry result = await sut.ReadEntryAt(offset);

Assert.That(result.Type, Is.EqualTo(EntryTypes.CompressedHeader));
Assert.That(result.Length, Is.EqualTo(bytes.Length));
Assert.That(result.Offset, Is.EqualTo(offset));
}

[TestCase(12)]
[TestCase(20)]
[TestCase(32)]
public async Task ReadEntryHeaderAt_ReadingEntryHeaderAtDifferentOffset_ReturnsCorrectEntryHeader(int offset)
{
using MemoryStream stream = new();
using E2Store sut = new E2Store(stream);
byte[] bytes = new byte[] { 0xff, 0xff, 0xff, 0xff };
stream.SetLength(offset);
stream.Seek(0, SeekOrigin.End);
await sut.WriteEntry(EntryTypes.CompressedHeader, bytes);

HeaderData result = await sut.ReadEntryHeaderAt(offset);

Assert.That(result.Type, Is.EqualTo(EntryTypes.CompressedHeader));
Assert.That(result.Length, Is.EqualTo(bytes.Length));
}

[Test]
public void Test()
{
//TODO possible optimization avoid alloc snappy stream by not disposing the stream and reusing like this
using MemoryStream stream = new();
byte[] bytes = new byte[] { 0x0f, 0xf0, 0xff, 0xff };
byte[] bytes1 = new byte[] { 0x1, 0x2, 0x3, 0x4 };
MemoryStream compressed = new();
using SnappyStream snappy = new SnappyStream(compressed, System.IO.Compression.CompressionMode.Compress);
snappy.Write(bytes);
snappy.Flush();
byte[] compressedBytes = compressed.ToArray();
compressed.Seek(0, SeekOrigin.Begin);
using SnappyStream snappyDecom = new SnappyStream(compressed, System.IO.Compression.CompressionMode.Decompress);
var decomBytes = new byte[bytes.Length];
snappyDecom.Read(decomBytes, 0, decomBytes.Length);
decomBytes.Should().BeEquivalentTo(bytes);

compressed.SetLength(0);
var snappyHeader = new byte[]
{
0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59
};
compressed.Write(snappyHeader, 0, snappyHeader.Length);
snappy.Write(bytes1);
snappy.Flush();
compressed.Seek(0, SeekOrigin.Begin);

snappyDecom.Read(decomBytes, 0, decomBytes.Length);
decomBytes.Should().BeEquivalentTo(bytes1);

}

}