Skip to content

Commit 2f48f02

Browse files
committed
Return all forks if needed
1 parent e5daa15 commit 2f48f02

File tree

6 files changed

+61
-16
lines changed

6 files changed

+61
-16
lines changed

src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,27 @@ public async Task Eth_get_transaction_by_block_number_and_index_out_of_bounds()
186186
Assert.That(serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":67}"));
187187
}
188188

189+
[Test]
190+
public async Task Eth_config_does_not_include_all_by_default()
191+
{
192+
using Context ctx = await Context.Create();
193+
string serialized = await ctx.Test.TestEthRpc("eth_config");
194+
JToken result = JToken.Parse(serialized)["result"]!;
195+
result.Should().NotBeNull();
196+
result["all"].Should().BeNull();
197+
}
198+
199+
[Test]
200+
public async Task Eth_config_returns_all_forks_when_requested()
201+
{
202+
using Context ctx = await Context.Create();
203+
string serialized = await ctx.Test.TestEthRpc("eth_config", true);
204+
JToken result = JToken.Parse(serialized)["result"]!;
205+
result.Should().NotBeNull();
206+
JArray allForks = (JArray)result["all"]!;
207+
allForks.Count.Should().BeGreaterThan(0);
208+
}
209+
189210
[TestCase(false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xa2a9f03b9493046696099d27b2612b99497aa1f392ec966716ab393c715a5bb6\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"totalDifficulty\":\"0x0\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")]
190211
[TestCase(true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xa2a9f03b9493046696099d27b2612b99497aa1f392ec966716ab393c715a5bb6\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"totalDifficulty\":\"0x0\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")]
191212
public async Task Eth_get_uncle_by_block_number_and_index(bool eip1559, string expectedJson)

src/Nethermind/Nethermind.JsonRpc/Data/ForkConfigSummary.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public class ForkConfigSummary
1313

1414
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
1515
public required ForkConfig? Last { get; init; }
16+
17+
public IReadOnlyList<ForkConfig>? All { get; init; }
1618
}
1719

1820
public class ForkConfig

src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -802,38 +802,51 @@ private ResultWrapper<TResult> GetStateFailureResult<TResult>(BlockHeader header
802802
};
803803
}
804804

805-
public ResultWrapper<JsonNode> eth_config()
805+
public ResultWrapper<JsonNode> eth_config(bool? showAllForks = null)
806806
{
807807
ForkActivationsSummary forks = forkInfo.GetForkActivationsSummary(_blockFinder.Head?.Header);
808+
IReadOnlyList<ForkConfig>? allForkConfigs = null;
808809

809-
return ResultWrapper<JsonNode>.Success(JsonNode.Parse(JsonSerializer.Serialize((new ForkConfigSummary
810+
if (showAllForks is true)
810811
{
811-
Current = GetForkConfig(forks.Current, _specProvider)!,
812-
Next = GetForkConfig(forks.Next, _specProvider),
813-
Last = GetForkConfig(forks.Last, _specProvider)
814-
}), UnchangedDictionaryKeyOptions)));
812+
IReadOnlyList<Fork> forkSchedule = forkInfo.GetAllForks();
813+
List<ForkConfig> forkConfigs = new(forkSchedule.Count);
815814

816-
static ForkConfig? GetForkConfig(Fork? fork, ISpecProvider specProvider)
817-
{
818-
if (fork is null)
815+
foreach (Fork scheduledFork in forkSchedule)
819816
{
820-
return null;
817+
forkConfigs.Add(BuildForkConfig(scheduledFork, _specProvider));
821818
}
822819

823-
IReleaseSpec? spec = specProvider.GetSpec(fork.Value.Activation.BlockNumber, fork.Value.Activation.Timestamp);
820+
allForkConfigs = forkConfigs;
821+
}
822+
823+
return ResultWrapper<JsonNode>.Success(JsonNode.Parse(JsonSerializer.Serialize(new ForkConfigSummary
824+
{
825+
Current = BuildForkConfig(forks.Current, _specProvider),
826+
Next = GetForkConfigOrNull(forks.Next, _specProvider),
827+
Last = GetForkConfigOrNull(forks.Last, _specProvider),
828+
All = allForkConfigs
829+
}, UnchangedDictionaryKeyOptions)));
830+
831+
static ForkConfig? GetForkConfigOrNull(Fork? fork, ISpecProvider specProvider) =>
832+
fork is null ? null : BuildForkConfig(fork.Value, specProvider);
833+
834+
static ForkConfig BuildForkConfig(Fork fork, ISpecProvider specProvider)
835+
{
836+
IReleaseSpec spec = specProvider.GetSpec(fork.Activation.BlockNumber, fork.Activation.Timestamp);
824837

825838
return new ForkConfig
826839
{
827-
ActivationTime = fork.Value.Activation.Timestamp is not null ? (int)fork.Value.Activation.Timestamp : null,
828-
ActivationBlock = fork.Value.Activation.Timestamp is null ? (int)fork.Value.Activation.BlockNumber : null,
840+
ActivationTime = fork.Activation.Timestamp is not null ? (int)fork.Activation.Timestamp : null,
841+
ActivationBlock = fork.Activation.Timestamp is null ? (int)fork.Activation.BlockNumber : null,
829842
BlobSchedule = spec.IsEip4844Enabled ? new BlobScheduleSettingsForRpc
830843
{
831844
BaseFeeUpdateFraction = (int)spec.BlobBaseFeeUpdateFraction,
832845
Max = (int)spec.MaxBlobCount,
833846
Target = (int)spec.TargetBlobCount,
834847
} : null,
835848
ChainId = specProvider.ChainId,
836-
ForkId = fork.Value.Id.HashBytes,
849+
ForkId = fork.Id.HashBytes,
837850
Precompiles = spec.ListPrecompiles(),
838851
SystemContracts = spec.ListSystemContracts(),
839852
};

src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ ResultWrapper<TransactionForRpc> eth_getTransactionByBlockNumberAndIndex(
289289
[JsonRpcMethod(IsImplemented = true, Description = "Retrieves Account with code and no storageRoot via Address and Blocknumber", IsSharable = true)]
290290
ResultWrapper<AccountInfoForRpc?> eth_getAccountInfo([JsonRpcParameter(ExampleValue = "[\"0xaa00000000000000000000000000000000000000\", \"latest\"]")] Address accountAddress, BlockParameter? blockParameter = null);
291291

292-
[JsonRpcMethod(IsImplemented = true, Description = "Provides configuration data for the current and next fork", IsSharable = true)]
293-
ResultWrapper<JsonNode> eth_config();
292+
[JsonRpcMethod(IsImplemented = true, Description = "Provides configuration data for the current and next fork or the full fork schedule", IsSharable = true)]
293+
ResultWrapper<JsonNode> eth_config([JsonRpcParameter(Description = "Returns every known fork when true", ExampleValue = "[true]")] bool? showAllForks = null);
294294
}
295295
}

src/Nethermind/Nethermind.Network/ForkInfo.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,11 @@ public ForkActivationsSummary GetForkActivationsSummary(BlockHeader? head)
176176
Last = isNextPresent ? new Fork(Forks[^1].Activation, Forks[^1].Id) : null,
177177
};
178178
}
179+
180+
public IReadOnlyList<Fork> GetAllForks()
181+
{
182+
EnsureInitialized();
183+
return Forks;
184+
}
179185
}
180186
}

src/Nethermind/Nethermind.Network/IForkInfo.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
22
// SPDX-License-Identifier: LGPL-3.0-only
33

4+
using System.Collections.Generic;
45
using Nethermind.Core;
56
using Nethermind.Core.Specs;
67

@@ -19,6 +20,8 @@ public interface IForkInfo
1920
ValidationResult ValidateForkId(ForkId peerId, BlockHeader? head);
2021

2122
ForkActivationsSummary GetForkActivationsSummary(BlockHeader? head);
23+
24+
IReadOnlyList<Fork> GetAllForks();
2225
}
2326

2427
public readonly record struct Fork(ForkActivation Activation, ForkId Id);

0 commit comments

Comments
 (0)