Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d6276bf
feat: add engine blockchain test fixtures and fix BAL gas budget trac…
benaadams Mar 24, 2026
db97571
fix: version-aware ExecutionPayload creation and engine test improvem…
benaadams Mar 24, 2026
fae0fe9
fix: restructure CreateExecutionPayload to explicit switch on derived…
benaadams Mar 24, 2026
9ef3678
fix: only set ExecutionRequests=[] on V4 payloads, not V3 - caused 'E…
benaadams Mar 24, 2026
97cae8b
refactor: use two if-checks instead of switch to avoid duplicating V3…
benaadams Mar 24, 2026
2250759
refactor: add HexToNumber/HexToNullableNumber helpers, document versi…
benaadams Mar 24, 2026
e001c42
fix: handle both JSON object and RLP hex string formats for withdrawa…
benaadams Mar 24, 2026
b88f206
fix: default ExecutionRequests to empty array for V4 engine tests on …
benaadams Mar 24, 2026
3599e8d
fix: parse executionRequests from params[3] for engine_newPayloadV4/V5
benaadams Mar 24, 2026
7e17d02
fixes
benaadams Mar 24, 2026
344a726
fix
benaadams Mar 24, 2026
6dbdec1
feedback
benaadams Mar 24, 2026
196f8bd
fix: remove pre-merge engine test fixtures to fix CI timeout
benaadams Mar 25, 2026
c1eed51
fix: remove brittle hardcoded engine test name
benaadams Mar 25, 2026
46b01bc
fix: add timeout to ProcessHelper.RunAndReadOutput
benaadams Mar 25, 2026
0ec1043
fix: restrict engine and Amsterdam tests to Linux only
benaadams Mar 25, 2026
b3fa285
refactor: route engine tests through JsonRpcService instead of reflec…
benaadams Mar 25, 2026
45aa7ed
fix: BAL memory leak and shared reference bug
benaadams Mar 25, 2026
b1cbc08
fix: skip heavy engine/Amsterdam tests in checked and no-intrinsics CI
benaadams Mar 25, 2026
4f29556
Single spec look up
benaadams Mar 25, 2026
60f2ee6
fix: cancel uncancelled Task.Delays that prevent GC of disposed conta…
benaadams Mar 25, 2026
8e9833f
fix: guard GCKeeper.Dispose against double-dispose of CTS
benaadams Mar 25, 2026
f348063
refactor: address PR review feedback
benaadams Mar 25, 2026
0077b3a
fix: handle RPC-level errors in engine test negative cases
benaadams Mar 25, 2026
3268340
fix: dispose PeriodicTimer instances to prevent resource leaks
benaadams Mar 25, 2026
bddd60d
fix: cancel MultiSyncModeSelector timer on Dispose
benaadams Mar 25, 2026
200ebe6
fix: skip heavy engine/Amsterdam tests in Flat DB CI jobs
benaadams Mar 25, 2026
8ef7f32
perf: use NullTxPool and disable prewarmer in blockchain tests
benaadams Mar 25, 2026
4e5f9bb
perf: disable prewarmer and revert ProcessHelper to original
benaadams Mar 25, 2026
0749b6d
refactor: address PR review feedback on Task.Delay and Dispose patterns
benaadams Mar 25, 2026
e5d2431
chore: remove codex-dotnet.ps1 and AGENTS.md changes
benaadams Mar 25, 2026
5b4afa3
refactor: remove Convert engine payload tests
benaadams Mar 25, 2026
5d17e09
refactor: simplify after code review
benaadams Mar 25, 2026
a370431
refactor: DelaySafe returns bool to indicate cancellation
benaadams Mar 25, 2026
9a8e226
fix: remove Setup() calls from runner projects after method removal
benaadams Mar 25, 2026
f68f832
refactor: use CancelDisposeAndClear for CTS cleanup
benaadams Mar 25, 2026
84d9a04
refactor: address automated code review feedback
benaadams Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/nethermind-tests-checked.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ jobs:
env:
TEST_CHUNK: ${{ matrix.test.chunk }}
DOTNET_EnableHWIntrinsic: ${{ matrix.variant.hw-intrinsic }}
TEST_SKIP_HEAVY: 1
run: |
dotnet test --project ${{ matrix.test.project }}.csproj -c release \
${{ matrix.variant.dotnet-args }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/nethermind-tests-flat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ jobs:
working-directory: src/Nethermind/${{ matrix.project }}
env:
TEST_CHUNK: ${{ matrix.chunk }}
TEST_SKIP_HEAVY: 1
run: |
dotnet test --project ${{ matrix.project }}.csproj -c release

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/nethermind-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ jobs:
working-directory: src/Nethermind/${{ matrix.test.project }}
env:
TEST_CHUNK: ${{ matrix.test.chunk }}
TEST_SKIP_HEAVY: 1
run: |
set +e
dotnet test --project ${{ matrix.test.project }}.csproj -c release
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,4 @@ keystore/

# Worktrees
.worktrees/
/.dotnet-cli
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"ignoreRandomStrings": true,
"unknownWords": "report-common-typos",
"ignorePaths": [
".gitignore",
"**/*.json",
"**/*.zst",
"**/artifacts/**",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ namespace Ethereum.Blockchain.Pyspec.Test.Amsterdam;
/// <summary>
/// Generic base for Amsterdam EIP blockchain tests.
/// Wildcard is read from <see cref="EipWildcardAttribute"/> on <typeparamref name="TSelf"/>.
/// In CI, only runs on Linux x64 to stay within the job timeout budget.
/// </summary>
[TestFixture]
[Parallelizable(ParallelScope.All)]
public abstract class AmsterdamBlockChainTestFixture<TSelf> : BlockchainTestBase
{
[SetUp]
public void SkipInCiOnSlowRunners() => CiRunnerGuard.SkipIfNotLinuxX64();

[TestCaseSource(nameof(LoadTests))]
public async Task Test(BlockchainTest test) => await RunTest(test);
public async Task Test(BlockchainTest test) => (await RunTest(test)).Pass.Should().BeTrue();

public static IEnumerable<BlockchainTest> LoadTests() =>
new TestsSourceLoader(new LoadPyspecTestsStrategy
Expand All @@ -29,6 +33,29 @@ public static IEnumerable<BlockchainTest> LoadTests() =>
}, "fixtures/blockchain_tests/for_amsterdam", typeof(TSelf).GetCustomAttribute<EipWildcardAttribute>()!.Wildcard).LoadTests<BlockchainTest>();
}

/// <summary>
/// Generic base for Amsterdam EIP engine blockchain tests.
/// Wildcard is read from <see cref="EipWildcardAttribute"/> on <typeparamref name="TSelf"/>.
/// In CI, only runs on Linux x64 to stay within the job timeout budget.
/// </summary>
[TestFixture]
[Parallelizable(ParallelScope.All)]
public abstract class AmsterdamEngineBlockChainTestFixture<TSelf> : BlockchainTestBase
{
[SetUp]
public void SkipInCiOnSlowRunners() => CiRunnerGuard.SkipIfNotLinuxX64();

[TestCaseSource(nameof(LoadTests))]
public async Task Test(BlockchainTest test) => (await RunTest(test)).Pass.Should().BeTrue();

public static IEnumerable<BlockchainTest> LoadTests() =>
new TestsSourceLoader(new LoadPyspecTestsStrategy
{
ArchiveVersion = Constants.BalArchiveVersion,
ArchiveName = Constants.BalArchiveName
}, "fixtures/blockchain_tests_engine/for_amsterdam", typeof(TSelf).GetCustomAttribute<EipWildcardAttribute>()!.Wildcard).LoadTests<BlockchainTest>();
}

/// <summary>
/// Generic base for Amsterdam EIP state tests.
/// Wildcard is read from <see cref="EipWildcardAttribute"/> on <typeparamref name="TSelf"/>.
Expand Down
21 changes: 21 additions & 0 deletions src/Nethermind/Ethereum.Blockchain.Pyspec.Test/Amsterdam/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,45 @@ namespace Ethereum.Blockchain.Pyspec.Test.Amsterdam;
[EipWildcard("eip7708_eth_transfer_logs")]
public class Eip7708BlockChainTests : AmsterdamBlockChainTestFixture<Eip7708BlockChainTests>;

[EipWildcard("eip7708_eth_transfer_logs")]
public class Eip7708EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip7708EngineBlockChainTests>;

[EipWildcard("eip7778_block_gas_accounting_without_refunds")]
public class Eip7778BlockChainTests : AmsterdamBlockChainTestFixture<Eip7778BlockChainTests>;

[EipWildcard("eip7778_block_gas_accounting_without_refunds")]
public class Eip7778EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip7778EngineBlockChainTests>;

[EipWildcard("eip7843_slotnum")]
public class Eip7843BlockChainTests : AmsterdamBlockChainTestFixture<Eip7843BlockChainTests>;

[EipWildcard("eip7843_slotnum")]
public class Eip7843EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip7843EngineBlockChainTests>;

[EipWildcard("eip7928_block_level_access_lists")]
public class Eip7928BlockChainTests : AmsterdamBlockChainTestFixture<Eip7928BlockChainTests>;

[EipWildcard("eip7928_block_level_access_lists")]
public class Eip7928EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip7928EngineBlockChainTests>;

[EipWildcard("eip7954_increase_max_contract_size")]
public class Eip7954BlockChainTests : AmsterdamBlockChainTestFixture<Eip7954BlockChainTests>;

[EipWildcard("eip7954_increase_max_contract_size")]
public class Eip7954EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip7954EngineBlockChainTests>;

[EipWildcard("eip8024_dupn_swapn_exchange")]
public class Eip8024BlockChainTests : AmsterdamBlockChainTestFixture<Eip8024BlockChainTests>;

[EipWildcard("eip8024_dupn_swapn_exchange")]
public class Eip8024EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip8024EngineBlockChainTests>;

[EipWildcard("eip8037_state_creation_gas_cost_increase")]
public class Eip8037BlockChainTests : AmsterdamBlockChainTestFixture<Eip8037BlockChainTests>;

[EipWildcard("eip8037_state_creation_gas_cost_increase")]
public class Eip8037EngineBlockChainTests : AmsterdamEngineBlockChainTestFixture<Eip8037EngineBlockChainTests>;

// State tests

[EipWildcard("eip7708_eth_transfer_logs")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: 2026 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Ethereum.Test.Base;
using FluentAssertions;
Expand All @@ -25,6 +27,26 @@ public static IEnumerable<BlockchainTest> LoadTests() =>
$"fixtures/blockchain_tests/for_{TestDirectoryHelper.GetDirectoryByConvention<TSelf>("BlockchainTests")}").LoadTests<BlockchainTest>();
}

/// <summary>
/// Generic base for pyspec engine blockchain tests using <see cref="LoadPyspecTestsStrategy"/>.
/// Directory is derived by convention: strip "EngineBlockchainTests" suffix, lowercase.
/// In CI (TEST_CHUNK set), only runs on Linux x64 to stay within the job timeout budget.
/// </summary>
[TestFixture]
[Parallelizable(ParallelScope.All)]
public abstract class PyspecEngineBlockchainTestFixture<TSelf> : BlockchainTestBase
{
[SetUp]
public void SkipInCiOnSlowRunners() => CiRunnerGuard.SkipIfNotLinuxX64();

[TestCaseSource(nameof(LoadTests))]
public async Task Test(BlockchainTest test) => (await RunTest(test)).Pass.Should().BeTrue();

public static IEnumerable<BlockchainTest> LoadTests() =>
new TestsSourceLoader(new LoadPyspecTestsStrategy(),
$"fixtures/blockchain_tests_engine/for_{TestDirectoryHelper.GetDirectoryByConvention<TSelf>("EngineBlockchainTests")}").LoadTests<BlockchainTest>();
}

/// <summary>
/// Generic base for pyspec state tests using <see cref="LoadPyspecTestsStrategy"/>.
/// Directory is derived by convention: strip "StateTests" suffix, lowercase.
Expand All @@ -40,3 +62,23 @@ public static IEnumerable<GeneralStateTest> LoadTests() =>
new TestsSourceLoader(new LoadPyspecTestsStrategy(),
$"fixtures/state_tests/for_{TestDirectoryHelper.GetDirectoryByConvention<TSelf>("StateTests")}").LoadTests<GeneralStateTest>();
}

/// <summary>
/// Skips heavy tests in CI on runners that are too slow or running variant builds.
/// Only active when TEST_CHUNK is set (CI). Local runs always execute.
/// Set TEST_SKIP_HEAVY=1 to unconditionally skip (used by checked/no-intrinsics variants).
/// </summary>
internal static class CiRunnerGuard
{
private static readonly bool s_isCi = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TEST_CHUNK"));
private static readonly bool s_isLinuxX64 = OperatingSystem.IsLinux() && RuntimeInformation.ProcessArchitecture == Architecture.X64;
private static readonly bool s_skipHeavy = Environment.GetEnvironmentVariable("TEST_SKIP_HEAVY") == "1";

public static void SkipIfNotLinuxX64()
{
if (s_skipHeavy)
Assert.Ignore("Skipped — TEST_SKIP_HEAVY is set");
if (s_isCi && !s_isLinuxX64)
Assert.Ignore("Skipped in CI — engine/Amsterdam tests only run on Linux x64");
}
}
10 changes: 10 additions & 0 deletions src/Nethermind/Ethereum.Blockchain.Pyspec.Test/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ public class PragueBlockchainTests : PyspecBlockchainTestFixture<PragueBlockchai

public class OsakaBlockchainTests : PyspecBlockchainTestFixture<OsakaBlockchainTests>;

// Engine blockchain tests — only forks with meaningful Engine API differences
// (e.g. blobs, execution requests, BAL). Regular BlockchainTests cover earlier forks.
// Directory derived from class name by convention (strip "EngineBlockchainTests", lowercase)

public class CancunEngineBlockchainTests : PyspecEngineBlockchainTestFixture<CancunEngineBlockchainTests>;

public class PragueEngineBlockchainTests : PyspecEngineBlockchainTestFixture<PragueEngineBlockchainTests>;

public class OsakaEngineBlockchainTests : PyspecEngineBlockchainTestFixture<OsakaEngineBlockchainTests>;

// State tests - directory derived from class name by convention (strip "StateTests", lowercase)

public class FrontierStateTests : PyspecStateTestFixture<FrontierStateTests>;
Expand Down
Loading
Loading