1414 */
1515package org .hyperledger .besu .ethereum .api .jsonrpc .internal .methods ;
1616
17+ import static org .hyperledger .besu .ethereum .mainnet .ParentBeaconBlockRootHelper .BEACON_ROOTS_ADDRESS ;
18+
1719import org .hyperledger .besu .ethereum .api .jsonrpc .RpcMethod ;
1820import org .hyperledger .besu .ethereum .api .jsonrpc .internal .JsonRpcRequestContext ;
1921import org .hyperledger .besu .ethereum .api .jsonrpc .internal .response .JsonRpcResponse ;
2022import org .hyperledger .besu .ethereum .api .jsonrpc .internal .response .JsonRpcSuccessResponse ;
2123import org .hyperledger .besu .ethereum .api .query .BlockchainQueries ;
24+ import org .hyperledger .besu .ethereum .core .BlockHeader ;
2225import org .hyperledger .besu .ethereum .mainnet .ProtocolSchedule ;
2326import org .hyperledger .besu .ethereum .mainnet .ProtocolSpec ;
27+ import org .hyperledger .besu .ethereum .mainnet .ScheduledProtocolSpec .Hardfork ;
2428import org .hyperledger .besu .ethereum .mainnet .requests .RequestProcessorCoordinator ;
29+ import org .hyperledger .besu .evm .EvmSpecVersion ;
2530import org .hyperledger .besu .evm .precompile .PrecompileContractRegistry ;
2631
2732import java .nio .charset .StandardCharsets ;
2833import java .util .Map ;
34+ import java .util .Optional ;
2935import java .util .TreeMap ;
3036import java .util .function .Supplier ;
3137import java .util .zip .CRC32 ;
@@ -54,29 +60,33 @@ public String getName() {
5460
5561 @ Override
5662 public JsonRpcResponse response (final JsonRpcRequestContext requestContext ) {
57- var header = blockchain .getBlockchain ().getChainHeadHeader ();
58- var current = protocolSchedule .getForNextBlockHeader (header , System .currentTimeMillis () / 1000 );
59- var next = protocolSchedule .getNextProtocolSpec (current );
60-
61- var currentConfig = generateConfig (current );
62- var nextConfig = next .map (this ::generateConfig ).orElse (null );
63+ BlockHeader header = blockchain .getBlockchain ().getChainHeadHeader ();
64+ ProtocolSpec current =
65+ protocolSchedule .getForNextBlockHeader (header , System .currentTimeMillis () / 1000 );
66+ Optional <ProtocolSpec > next = protocolSchedule .getNextProtocolSpec (current );
6367
6468 ObjectNode result = mapperSupplier .get ().createObjectNode ();
65- result .put ("current" , currentConfig );
66- result .put ("currentHash" , configHash (currentConfig ));
67- result .put ("next" , nextConfig );
68- result .put ("nextHash" , configHash (nextConfig ));
69+ ObjectNode currentNode = result .putObject ("current" );
70+ generateConfig (currentNode , current );
71+ result .put ("currentHash" , configHash (currentNode ));
72+ if (next .isPresent ()) {
73+ ObjectNode nextNode = result .putObject ("next" );
74+ generateConfig (nextNode , next .get ());
75+ result .put ("nextHash" , configHash (nextNode ));
76+ } else {
77+ result .putNull ("next" );
78+ result .putNull ("nextHash" );
79+ }
6980
7081 return new JsonRpcSuccessResponse (requestContext .getRequest ().getId (), result );
7182 }
7283
73- JsonNode generateConfig (final ProtocolSpec spec ) {
74- var result = mapperSupplier .get ().createObjectNode ();
75- var forkId = protocolSchedule .hardforkFor (x -> x .spec () == spec ).orElseThrow ();
84+ void generateConfig (final ObjectNode result , final ProtocolSpec spec ) {
85+ Hardfork forkId = protocolSchedule .hardforkFor (x -> x .spec () == spec ).orElseThrow ();
7686
77- result .put ("activation " , forkId .milestone ());
87+ result .put ("activationTime " , forkId .milestone ());
7888
79- var blobs = result .putObject ("blobs " );
89+ ObjectNode blobs = result .putObject ("blobSchedule " );
8090 blobs .put (
8191 "baseFeeUpdateFraction" , spec .getFeeMarket ().getBaseFeeUpdateFraction ().longValueExact ());
8292 blobs .put ("max" , spec .getGasLimitCalculator ().currentBlobGasLimit () / (128 * 1024 ));
@@ -85,26 +95,27 @@ JsonNode generateConfig(final ProtocolSpec spec) {
8595 result .put (
8696 "chainId" , protocolSchedule .getChainId ().map (c -> "0x" + c .toString (16 )).orElse (null ));
8797
88- var contracts =
98+ PrecompileContractRegistry registry = spec .getPrecompileContractRegistry ();
99+ ObjectNode precompiles = result .putObject ("precompiles" );
100+ registry .getPrecompileAddresses ().stream ()
101+ .sorted ()
102+ .forEach (a -> precompiles .put (a .toHexString (), registry .get (a ).getName ()));
103+
104+ TreeMap <String , String > systemContracts =
89105 new TreeMap <>(
90106 spec .getRequestProcessorCoordinator ()
91107 .map (RequestProcessorCoordinator ::getContractConfigs )
92108 .orElse (Map .of ()));
93109 spec .getBlockHashProcessor ()
94110 .getHistoryContract ()
95- .ifPresent (a -> contracts .put ("HISTORY" , a .toHexString ()));
96- if (!contracts .isEmpty ()) {
97- var jsonContracts = result .putObject ("contracts" );
98- contracts .forEach (jsonContracts ::put );
111+ .ifPresent (a -> systemContracts .put ("HISTORY_STORAGE_ADDRESS" , a .toHexString ()));
112+ if (spec .getEvm ().getEvmVersion ().compareTo (EvmSpecVersion .CANCUN ) >= 0 ) {
113+ systemContracts .put ("BEACON_ROOTS_ADDRESS" , BEACON_ROOTS_ADDRESS .toHexString ());
114+ }
115+ if (!systemContracts .isEmpty ()) {
116+ ObjectNode jsonContracts = result .putObject ("systemContracts" );
117+ systemContracts .forEach (jsonContracts ::put );
99118 }
100-
101- PrecompileContractRegistry registry = spec .getPrecompileContractRegistry ();
102- var precompiles = result .putObject ("precompiles" );
103- registry .getPrecompileAddresses ().stream ()
104- .sorted ()
105- .forEach (a -> precompiles .put (a .toHexString (), registry .get (a ).getName ()));
106-
107- return result ;
108119 }
109120
110121 String configHash (final JsonNode node ) {
0 commit comments