22// SPDX-License-Identifier: LGPL-3.0-only
33
44using System ;
5+ using System . Collections . Concurrent ;
56using System . Collections . Generic ;
67using System . Linq ;
78using System . Security ;
@@ -67,6 +68,8 @@ public partial class EthRpcModule(
6768 IForkInfo forkInfo ,
6869 ulong ? secondsPerSlot ) : IEthRpcModule
6970{
71+ private static readonly ConcurrentDictionary < ForkId , ForkConfig > forkConfigCache = [ ] ;
72+
7073 protected readonly Encoding _messageEncoding = Encoding . UTF8 ;
7174 protected readonly IJsonRpcConfig _rpcConfig = rpcConfig ?? throw new ArgumentNullException ( nameof ( rpcConfig ) ) ;
7275 protected readonly IBlockchainBridge _blockchainBridge = blockchainBridge ?? throw new ArgumentNullException ( nameof ( blockchainBridge ) ) ;
@@ -805,19 +808,17 @@ private ResultWrapper<TResult> GetStateFailureResult<TResult>(BlockHeader header
805808 public ResultWrapper < JsonNode > eth_config ( bool showAllForks = false )
806809 {
807810 ForkActivationsSummary forks = forkInfo . GetForkActivationsSummary ( _blockFinder . Head ? . Header ) ;
808- IReadOnlyList < ForkConfig > ? allForkConfigs = null ;
811+ List < ForkConfig > ? allForkConfigs = null ;
809812
810813 if ( showAllForks )
811814 {
812- Fork [ ] forkSchedule = forkInfo . GetAllForks ( ) ;
813- List < ForkConfig > forkConfigs = new ( forkSchedule . Length ) ;
815+ ReadOnlySpan < Fork > forkSchedule = forkInfo . GetAllForks ( ) ;
816+ allForkConfigs = new ( forkSchedule . Length ) ;
814817
815818 foreach ( Fork scheduledFork in forkSchedule )
816819 {
817- forkConfigs . Add ( BuildForkConfig ( scheduledFork , _specProvider ) ) ;
820+ allForkConfigs . Add ( BuildForkConfig ( scheduledFork , _specProvider ) ) ;
818821 }
819-
820- allForkConfigs = forkConfigs ;
821822 }
822823
823824 return ResultWrapper < JsonNode > . Success ( JsonNode . Parse ( JsonSerializer . Serialize ( new ForkConfigSummary
@@ -833,9 +834,14 @@ public ResultWrapper<JsonNode> eth_config(bool showAllForks = false)
833834
834835 static ForkConfig BuildForkConfig ( Fork fork , ISpecProvider specProvider )
835836 {
837+ if ( forkConfigCache . TryGetValue ( fork . Id , out ForkConfig config ) )
838+ {
839+ return config ;
840+ }
841+
836842 IReleaseSpec spec = specProvider . GetSpec ( fork . Activation . BlockNumber , fork . Activation . Timestamp ) ;
837843
838- return new ForkConfig
844+ return forkConfigCache [ fork . Id ] = new ForkConfig
839845 {
840846 ActivationTime = fork . Activation . Timestamp is not null ? ( int ) fork . Activation . Timestamp : null ,
841847 ActivationBlock = fork . Activation . Timestamp is null ? ( int ) fork . Activation . BlockNumber : null ,
0 commit comments