-
Notifications
You must be signed in to change notification settings - Fork 709
Feature - EIP-4444 EraE Support #10812
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
Merged
Merged
Changes from 69 commits
Commits
Show all changes
158 commits
Select commit
Hold shift + click to select a range
ce5f612
Initial commit
svlachakis 722f9ba
namespace
svlachakis 0761875
more work
svlachakis 683e51f
E2StoreReader verification & Validator correctness audit & Historical…
svlachakis 14a9f87
AccumulatorCalculator.GetProof & EraWriter proof entries
svlachakis b74b468
Post-merge beacon roots & EraReader Validator integration
svlachakis 1db4d61
Post-merge beacon roots & EraReader Validator integration
svlachakis 5f65d65
EraExporter.DoExport — epoch boundary
svlachakis 7968c1e
EraWriter.Add fixes & tests
svlachakis b881bb0
more fixes & tests
svlachakis 553c31f
Tests & Wiring
svlachakis 01090c2
Improvements
svlachakis 1e25ca5
fixes
svlachakis 14dce4c
Era1 & EraE file format cross tests
svlachakis b50b22c
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis 01a9c02
slnx fix
svlachakis 193a0dd
fixes
svlachakis 992d955
step module update
svlachakis 9d1b4f7
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis 37294f4
format
svlachakis 0049c82
revert evm format changes
svlachakis 5be4c07
revert packages.lock.json
svlachakis 2273508
fix header
svlachakis 6970ac0
add erae to cspell.json
svlachakis 52369c6
packages.lock.json
svlachakis 8979223
Config properties (RemoteBaseUrl, RemoteDownloadDirectory, RemoteChe…
svlachakis bae6429
IRemoteEraClient + HttpRemoteEraClient
svlachakis 2e486c7
RemoteEraStoreDecorator
svlachakis c1ba449
Wire in EraStoreFactory and EraEModule & Unit tests
svlachakis 651fdd6
Integration tests with data.ethpandaops.io
svlachakis cc877ac
Fix 1 — receipt decoder:
svlachakis 862a0f8
ethpandaops to cspell.json
svlachakis 776f8fa
Merge branch 'master' into feature/erae
svlachakis 12cecb8
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis 57e6c64
- Validator:
svlachakis a161557
Refactoring and cleanup
svlachakis e0ccf54
fix build
svlachakis 96c62d5
Refactor EraE infrastructure and remove duplicated logic
svlachakis 758eba5
Merge branch 'master' into feature/erae
svlachakis 4e70c88
Performance, async safety, and cleanup improvements
svlachakis 39d4e94
Improve epoch verification concurrency and standardize AdminEraServic…
svlachakis 60f5148
remove hot-path allocations in proof verification and epoch writing
svlachakis ba33d01
style - record BlockHeaderProof, remove XML docs, trim redundant comm…
svlachakis f69b42f
format
svlachakis fc78693
HasEpoch, EraJobRunner fire-and-forget helper, cleanup
svlachakis 9a99c58
named tuples, SectionName, shared TestEraFile, for-loop workers, cleanup
svlachakis 370983e
cspell.json
svlachakis b3d0c3f
comments
svlachakis a816bc9
cleanup
svlachakis 0e26177
concurrency fixes & comments
svlachakis e50ef6a
Merge branch 'master' into feature/erae
svlachakis 21324e9
postmerge blocks tests
svlachakis ae6f8b5
Merge branch 'master' into feature/erae
svlachakis ca19796
eraimport autocreate directory
svlachakis 927ed3c
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis d24c60a
throw error when prunning & erae import is set simultaneously
svlachakis e083bc8
fixes
svlachakis abed488
fixes
svlachakis e92f393
throw specific exception when eraE fails with block bodies not found …
svlachakis c0989c8
Merge branch 'master' into feature/erae
svlachakis 40b8e5c
Merge branch 'master' into feature/erae
svlachakis 489798b
Merge branch 'master' into feature/erae
svlachakis ad07dda
Merge branch 'master' into feature/erae
svlachakis 28a7159
BlockTreeInsertHeaderOptions fix
svlachakis dd297ba
Merge remote-tracking branch 'origin/feature/erae' into feature/erae
svlachakis b8c3374
else if branch - when a block already exists but it's pre-merge with …
svlachakis 0bc941c
less strict condition
svlachakis c1ce4e3
postmerge blocks fix
svlachakis ab1953b
Merge branch 'master' into feature/erae
svlachakis 193a661
fix filename for postmerge
svlachakis 54be5f8
fix filename
svlachakis cfbe793
snappy change - proofs comment out - possible revert
svlachakis 80dc370
revert custom SnappyFrameWritter
svlachakis de8cea5
Merge branch 'master' into feature/erae
svlachakis 418467d
Merge branch 'master' into feature/erae
svlachakis 47b3aa4
damian review comments
svlachakis 1559f37
ssz fix
svlachakis cef6866
Marc PR review
svlachakis a08df5d
claude review
svlachakis 24fbe67
Merge branch 'master' into feature/erae
svlachakis 8f89d80
remove proofs logic
svlachakis 18fb8cd
Merge branch 'master' into feature/erae
svlachakis 65ed675
Merge branch 'master' into feature/erae
svlachakis 31e47e5
Merge branch 'master' into feature/erae
svlachakis 23acc49
Merge branch 'master' into feature/erae
svlachakis f7a24c7
Merge branch 'master' into feature/erae
svlachakis 6b06613
fixes
svlachakis 628b59a
add EraE module to CODEOWNERS
svlachakis 14835f5
fixes
svlachakis df70629
maxsize defensive check
svlachakis 1b421af
fix remote url
svlachakis 9544749
Merge branch 'master' into feature/erae
svlachakis a314978
Merge branch 'master' into feature/erae
svlachakis 863cddb
era exporter improvements
svlachakis 1c5ce72
memory tweaks
svlachakis a4b376b
stream epoch data to disk in Add() instead of buffering to eliminate …
svlachakis ffc8742
build fix
svlachakis a6ea3ec
cache
svlachakis 8eca363
reduce memory footprint, remove temp file approach
svlachakis 37fe096
receipts fix
svlachakis d84c80d
receipts fix
svlachakis 38e1618
revert era reader
svlachakis 0516ac8
Merge branch 'master' into feature/erae
svlachakis dd15cc4
fix importer
svlachakis 5edfde8
fix test format
svlachakis 077e0c5
different approach for memory efficiency
svlachakis 40d19d6
prefetch implementation
svlachakis 6b34142
revert prefetch
svlachakis 5510099
export receipts guard
svlachakis 25c5100
slimreceiptdecoder changes, erawriter fixes
svlachakis 40b3fca
Merge branch 'master' into feature/erae
svlachakis 222e7ea
fix build
svlachakis 791b25c
remove orphaned block validation
svlachakis 7decc86
geth compatibility
svlachakis 6a062b5
unused import
svlachakis 39c3a7d
delete nm format
svlachakis 5c4f54e
Merge branch 'master' into feature/erae
svlachakis 3368e41
add checksums.txt
svlachakis bcb4c10
minor renames
svlachakis 11795d5
Merge branch 'master' into feature/erae
svlachakis 0bed96e
claude review
svlachakis f7d1a58
Merge remote-tracking branch 'origin/feature/erae' into feature/erae
svlachakis 93090f6
fix build
svlachakis b643035
tests refactoring
svlachakis e4ca580
Merge branch 'master' into feature/erae
svlachakis b3d1229
claude review
svlachakis d035f69
fix 2026 on spdx
svlachakis aed3bda
logger wiring
svlachakis 7fd1690
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis a833987
merge conflicts
svlachakis c192380
Merge branch 'master' into feature/erae
svlachakis b9f8f7e
build fix
svlachakis ac1d1d1
Merge remote-tracking branch 'origin/feature/erae' into feature/erae
svlachakis f73d71e
build fixes
svlachakis dbb6b11
more build fixes
svlachakis b208a4f
fix races
svlachakis 94a5d4e
Merge branch 'master' into feature/erae
svlachakis 271919c
remove cache
svlachakis b73c1dc
use Polly
svlachakis 883e789
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis 11ff346
fix build
svlachakis 3e16707
fix build
svlachakis 8e3fb94
fix build
svlachakis 3e97eb6
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis 3393efa
Merge remote-tracking branch 'origin/master' into feature/erae
svlachakis 7591f0f
fix conflicts
svlachakis 7eb5ff7
Merge branch 'master' into feature/erae
svlachakis 11cd694
ssz changes
svlachakis 19689d9
fix build
svlachakis 83ad666
unused import
svlachakis 3674eba
ssz fixes
svlachakis ad940b9
claude review
svlachakis bc2a55d
Merge branch 'master' into feature/erae
svlachakis 684a914
EraE refactor: simplify interfaces, deduplicate tests (#11165)
LukaszRozmej a7f0751
Fix BeaconApiRetry maxAttempts semantics, use Span SequenceEqual
LukaszRozmej 0d803dd
Seal concrete classes, make HistoricalSummary readonly struct
LukaszRozmej c6cf536
Fix dispose leak, field-to-property, thread CancellationToken
LukaszRozmej 70eb16c
refactor
LukaszRozmej File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
| // SPDX-License-Identifier: LGPL-3.0-only | ||
| using Nethermind.Core.Crypto; | ||
|
|
||
| namespace Nethermind.Core; | ||
|
|
||
| public enum BlockHeaderProofType : byte | ||
| { | ||
| BlockProofHistoricalHashesAccumulator = 0, | ||
| BlockProofHistoricalRoots = 1, | ||
| BlockProofHistoricalSummaries = 2 | ||
| } | ||
|
|
||
| public record BlockHeaderProof | ||
| { | ||
| public BlockHeaderProofType? ProofType { get; init; } | ||
| public ValueHash256[]? HashesAccumulator { get; init; } | ||
| public ValueHash256[]? BeaconBlockProof { get; init; } | ||
| public ValueHash256[]? ExecutionBlockProof { get; init; } | ||
| public ValueHash256? BeaconBlockRoot { get; init; } | ||
| public long? Slot { get; init; } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/Nethermind/Nethermind.EraE.Test/Admin/AdminEraServiceTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
| // SPDX-License-Identifier: LGPL-3.0-only | ||
|
|
||
| using Nethermind.Config; | ||
| using Nethermind.Core; | ||
| using Nethermind.EraE.Admin; | ||
| using Nethermind.EraE.Export; | ||
| using Nethermind.EraE.Import; | ||
| using Nethermind.JsonRpc; | ||
| using Nethermind.Logging; | ||
| using NSubstitute; | ||
| using NUnit.Framework; | ||
|
|
||
| namespace Nethermind.EraE.Test.Admin; | ||
|
|
||
| public class AdminEraServiceTests | ||
| { | ||
| [Test] | ||
| public void ImportHistory_WhenCalled_DelegatesToImporter() | ||
| { | ||
| IEraImporter importer = Substitute.For<IEraImporter>(); | ||
| AdminEraService sut = new( | ||
| importer, | ||
| Substitute.For<IEraExporter>(), | ||
| Substitute.For<IProcessExitSource>(), | ||
| LimboLogs.Instance); | ||
|
|
||
| sut.ImportHistory("somewhere", 99, 999, null); | ||
|
|
||
| importer.Received().Import("somewhere", 99, 999, null, Arg.Any<CancellationToken>()); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ImportHistory_WhenImportAlreadyRunning_ReturnsFailure() | ||
| { | ||
| IEraImporter importer = Substitute.For<IEraImporter>(); | ||
| TaskCompletionSource tcs = new(); | ||
| importer.Import("somewhere", 99, 999, null, Arg.Any<CancellationToken>()).Returns(tcs.Task); | ||
|
|
||
| AdminEraService sut = new( | ||
| importer, | ||
| Substitute.For<IEraExporter>(), | ||
| Substitute.For<IProcessExitSource>(), | ||
| LimboLogs.Instance); | ||
|
|
||
| sut.ImportHistory("somewhere", 99, 999, null); | ||
|
|
||
| ResultWrapper<string> result = sut.ImportHistory("somewhere", 99, 999, null); | ||
| Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); | ||
|
|
||
| tcs.TrySetResult(); | ||
|
|
||
| Assert.That(() => sut.ImportHistory("somewhere", 99, 999, null), Throws.Nothing); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ExportHistory_WhenCalled_DelegatesToExporter() | ||
| { | ||
| IEraExporter exporter = Substitute.For<IEraExporter>(); | ||
| AdminEraService sut = new( | ||
| Substitute.For<IEraImporter>(), | ||
| exporter, | ||
| Substitute.For<IProcessExitSource>(), | ||
| LimboLogs.Instance); | ||
|
|
||
| sut.ExportHistory("somewhere", 99, 999); | ||
|
|
||
| exporter.Received().Export("somewhere", 99, 999, Arg.Any<CancellationToken>()); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ExportHistory_WhenExportAlreadyRunning_ReturnsFailure() | ||
| { | ||
| IEraExporter exporter = Substitute.For<IEraExporter>(); | ||
| TaskCompletionSource tcs = new(); | ||
| exporter.Export("somewhere", 99, 999, Arg.Any<CancellationToken>()).Returns(tcs.Task); | ||
|
|
||
| AdminEraService sut = new( | ||
| Substitute.For<IEraImporter>(), | ||
| exporter, | ||
| Substitute.For<IProcessExitSource>(), | ||
| LimboLogs.Instance); | ||
|
|
||
| sut.ExportHistory("somewhere", 99, 999); | ||
|
|
||
| ResultWrapper<string> result = sut.ExportHistory("somewhere", 99, 999); | ||
| Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); | ||
|
|
||
| tcs.TrySetResult(); | ||
|
|
||
| Assert.That(() => sut.ExportHistory("somewhere", 99, 999), Throws.Nothing); | ||
| } | ||
| } |
154 changes: 154 additions & 0 deletions
154
src/Nethermind/Nethermind.EraE.Test/Archive/AccumulatorCalculatorTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
| // SPDX-License-Identifier: LGPL-3.0-only | ||
|
|
||
| using Nethermind.Core; | ||
| using Nethermind.Core.Crypto; | ||
| using Nethermind.Core.Specs; | ||
| using Nethermind.Core.Test.Builders; | ||
| using AccumulatorCalculator = Nethermind.Era1.AccumulatorCalculator; | ||
| using Nethermind.EraE.Proofs; | ||
| using Nethermind.Int256; | ||
| using NSubstitute; | ||
| using NUnit.Framework; | ||
|
|
||
| namespace Nethermind.EraE.Test.Archive; | ||
|
|
||
| public class AccumulatorCalculatorTests | ||
| { | ||
| [Test] | ||
| public void Add_WhenCalled_DoesNotThrow() | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| Assert.That(() => sut.Add(Keccak.Zero, 0), Throws.Nothing); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ComputeRoot_WithKnownValues_ReturnsExpectedResult() | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| sut.Add(Keccak.Zero, 1); | ||
| sut.Add(Keccak.MaxValue, 2); | ||
|
|
||
| byte[] result = sut.ComputeRoot().ToByteArray(); | ||
|
|
||
| Assert.That(result, Is.EquivalentTo(new byte[] | ||
| { | ||
| 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_WithSameInputInTwoInstances_ReturnsSameResult() | ||
| { | ||
| using AccumulatorCalculator sut1 = new(); | ||
| using AccumulatorCalculator sut2 = new(); | ||
|
|
||
| sut1.Add(Keccak.Zero, 100); | ||
| sut2.Add(Keccak.Zero, 100); | ||
|
|
||
| Assert.That(sut1.ComputeRoot(), Is.EqualTo(sut2.ComputeRoot())); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ComputeRoot_WithDifferentInputs_ReturnsDifferentResults() | ||
| { | ||
| using AccumulatorCalculator sut1 = new(); | ||
| using AccumulatorCalculator sut2 = new(); | ||
|
|
||
| sut1.Add(Keccak.Zero, 1); | ||
| sut2.Add(Keccak.MaxValue, 1); | ||
|
|
||
| Assert.That(sut1.ComputeRoot(), Is.Not.EqualTo(sut2.ComputeRoot())); | ||
| } | ||
|
|
||
| [Test] | ||
| public void GetProof_WithNegativeIndex_ThrowsArgumentOutOfRangeException() | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| sut.Add(Keccak.Zero, 1); | ||
|
|
||
| Assert.That(() => sut.GetProof(-1), Throws.TypeOf<ArgumentOutOfRangeException>()); | ||
| } | ||
|
|
||
| [Test] | ||
| public void GetProof_WithIndexAtCount_ThrowsArgumentOutOfRangeException() | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| sut.Add(Keccak.Zero, 1); | ||
|
|
||
| Assert.That(() => sut.GetProof(1), Throws.TypeOf<ArgumentOutOfRangeException>()); | ||
| } | ||
|
|
||
| [Test] | ||
| public void GetProof_WhenCalled_Returns15Elements() | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| sut.Add(Keccak.Zero, 42); | ||
|
|
||
| Assert.That(sut.GetProof(0), Has.Length.EqualTo(15)); | ||
| } | ||
|
|
||
| [TestCase(0)] | ||
| [TestCase(1)] | ||
| [TestCase(7)] | ||
| public void GetProof_WhenCalled_ProofZeroIsTotalDifficultyLE(int blockIndex) | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| for (int i = 0; i <= blockIndex; i++) | ||
| sut.Add(Keccak.Zero, (ulong)(i + 1)); | ||
|
|
||
| byte[] expected = new byte[32]; | ||
| expected[0] = (byte)(blockIndex + 1); | ||
| Assert.That(sut.GetProof(blockIndex)[0].ToByteArray(), Is.EqualTo(expected)); | ||
| } | ||
|
|
||
| [TestCase(0, 1)] | ||
| [TestCase(0, 3)] | ||
| [TestCase(2, 5)] | ||
| public Task GetProof_WhenValidatedByValidator_Succeeds(int blockIndex, int totalBlocks) | ||
| { | ||
| Block[] blocks = Enumerable.Range(0, totalBlocks) | ||
| .Select(i => Build.A.Block | ||
| .WithNumber(i) | ||
| .WithTotalDifficulty((UInt256)(i * 100 + 1)) | ||
| .TestObject) | ||
| .ToArray(); | ||
|
|
||
| using AccumulatorCalculator sut = new(); | ||
| for (int i = 0; i < totalBlocks; i++) | ||
| sut.Add(blocks[i].Hash!, blocks[i].TotalDifficulty!.Value); | ||
|
|
||
| ValueHash256 root = sut.ComputeRoot(); | ||
| ValueHash256[] proof = sut.GetProof(blockIndex); | ||
|
|
||
| Validator validator = BuildValidator(root); | ||
| BlockHeaderProof headerProof = new() { ProofType = BlockHeaderProofType.BlockProofHistoricalHashesAccumulator, HashesAccumulator = proof }; | ||
|
|
||
| Assert.That(async () => await validator.VerifyContent(blocks[blockIndex], headerProof), Throws.Nothing); | ||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
| [Test] | ||
| public void GetProof_WithDifferentIndices_ReturnDifferentProofs() | ||
| { | ||
| using AccumulatorCalculator sut = new(); | ||
| sut.Add(Keccak.Zero, 1); | ||
| sut.Add(Keccak.MaxValue, 2); | ||
|
|
||
| ValueHash256[] proof0 = sut.GetProof(0); | ||
| ValueHash256[] proof1 = sut.GetProof(1); | ||
|
|
||
| Assert.That(proof0[0], Is.Not.EqualTo(proof1[0])); | ||
| Assert.That(proof0[1], Is.Not.EqualTo(proof1[1])); | ||
| } | ||
|
|
||
| private static Validator BuildValidator(ValueHash256 trustedRoot) | ||
| { | ||
| ISpecProvider specProvider = Substitute.For<ISpecProvider>(); | ||
| specProvider.BeaconChainGenesisTimestamp.Returns((ulong?)1606824023UL); | ||
| return new Validator(specProvider, new List<ValueHash256> { trustedRoot }, null, null); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.