diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c31d55fb7d..c00417cab69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) - Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) +- Implement engine_getClientVersionV1 ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) diff --git a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java index 54447a59600..aa5163c2af4 100644 --- a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java +++ b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java @@ -17,6 +17,8 @@ import org.hyperledger.besu.util.platform.PlatformDetector; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Represent Besu information such as version, OS etc. Used with --version option and during Besu @@ -24,9 +26,29 @@ */ public final class BesuInfo { private static final String CLIENT = "besu"; - private static final String VERSION = BesuInfo.class.getPackage().getImplementationVersion(); private static final String OS = PlatformDetector.getOS(); private static final String VM = PlatformDetector.getVM(); + private static final String VERSION; + private static final String COMMIT; + + static { + String projectVersion = BesuInfo.class.getPackage().getImplementationVersion(); + if (projectVersion == null) { + // protect against unset project version (e.g. unit tests being run, etc) + VERSION = null; + COMMIT = null; + } else { + Pattern pattern = + Pattern.compile("(?\\d+\\.\\d+\\.?\\d?-?\\w*)-(?[0-9a-fA-F]{8})"); + Matcher matcher = pattern.matcher(projectVersion); + if (matcher.find()) { + VERSION = matcher.group("version"); + COMMIT = matcher.group("commit"); + } else { + throw new RuntimeException("Invalid project version: " + projectVersion); + } + } + } private BesuInfo() {} @@ -46,7 +68,7 @@ public static String shortVersion() { * or "besu/v23.1.0/osx-aarch_64/corretto-java-19" */ public static String version() { - return String.format("%s/v%s/%s/%s", CLIENT, VERSION, OS, VM); + return String.format("%s/v%s-%s/%s/%s", CLIENT, VERSION, COMMIT, OS, VM); } /** @@ -57,7 +79,18 @@ public static String version() { */ public static String nodeName(final Optional maybeIdentity) { return maybeIdentity - .map(identity -> String.format("%s/%s/v%s/%s/%s", CLIENT, identity, VERSION, OS, VM)) + .map( + identity -> + String.format("%s/%s/v%s-%s/%s/%s", CLIENT, identity, VERSION, COMMIT, OS, VM)) .orElse(version()); } + + /** + * Generate the commit hash for this besu version + * + * @return the commit hash for this besu version + */ + public static String commit() { + return COMMIT; + } } diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index e34c0115fea..9eaf254bbfc 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -1291,6 +1291,8 @@ private Map jsonRpcMethods( new JsonRpcMethodsFactory() .methods( BesuInfo.nodeName(identityString), + BesuInfo.shortVersion(), + BesuInfo.commit(), ethNetworkConfig.networkId(), besuController.getGenesisConfigOptions(), network, diff --git a/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java b/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java index 5a1cec440c1..b7799f5ac30 100644 --- a/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java +++ b/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java @@ -33,7 +33,8 @@ public final class BesuInfoTest { */ @Test public void versionStringIsEthstatsFriendly() { - assertThat(BesuInfo.version()).matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); + assertThat(BesuInfo.version()) + .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); } /** @@ -45,7 +46,7 @@ public void versionStringIsEthstatsFriendly() { @Test public void noIdentityNodeNameIsEthstatsFriendly() { assertThat(BesuInfo.nodeName(Optional.empty())) - .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); + .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); } /** @@ -58,6 +59,6 @@ public void noIdentityNodeNameIsEthstatsFriendly() { @Test public void userIdentityNodeNameIsEthstatsFriendly() { assertThat(BesuInfo.nodeName(Optional.of("TestUserIdentity"))) - .matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); + .matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); } } diff --git a/build.gradle b/build.gradle index 6a4f279666a..003f6d63c60 100644 --- a/build.gradle +++ b/build.gradle @@ -820,7 +820,7 @@ task distDocker { dockerPlatform = "--platform ${project.getProperty('docker-platform')}" println "Building for platform ${project.getProperty('docker-platform')}" } - def gitDetails = getGitCommitDetails(7) + def gitDetails = getGitCommitDetails() executable shell workingDir dockerBuildDir args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ." @@ -988,17 +988,13 @@ def buildTime() { def calculateVersion() { // Regex pattern for basic calendar versioning, with provision to omit patch rev def calVerPattern = ~/\d+\.\d+(\.\d+)?(-.*)?/ - + def gitDetails = getGitCommitDetails() // Adjust length as needed if (project.hasProperty('version') && (project.version =~ calVerPattern)) { - if (project.hasProperty('versionappendcommit') && project.versionappendcommit == "true") { - def gitDetails = getGitCommitDetails(7) // Adjust length as needed - return "${project.version}-${gitDetails.hash}" - } - return "${project.version}" + println("Generating project version using supplied version: ${project.version}-${gitDetails.hash}") + return "${project.version}-${gitDetails.hash}" } else { // If no version is supplied or it doesn't match the semantic versioning, calculate from git - println("Generating project version as supplied is version not semver: ${project.version}") - def gitDetails = getGitCommitDetails(7) // Adjust length as needed + println("Generating project version using date (${gitDetails.date}-develop-${gitDetails.hash}), as supplied version is not semver: ${project.version}") return "${gitDetails.date}-develop-${gitDetails.hash}" } } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java index a8226a6a697..b5f65e6d4b5 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java @@ -64,7 +64,9 @@ /** Provides a facade to construct the JSON-RPC component. */ public class JsonRpcTestMethodsFactory { - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + private static final String CLIENT_VERSION = "0.1.0"; + private static final String CLIENT_COMMIT = "12345678"; private static final BigInteger NETWORK_ID = BigInteger.valueOf(123); private final BlockchainImporter importer; @@ -175,7 +177,9 @@ public Map methods() { return new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscovery, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 63fa5b3ce55..75da090480d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -63,6 +63,7 @@ public enum RpcMethod { ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"), ENGINE_FORKCHOICE_UPDATED_V3("engine_forkchoiceUpdatedV3"), ENGINE_EXCHANGE_TRANSITION_CONFIGURATION("engine_exchangeTransitionConfigurationV1"), + ENGINE_GET_CLIENT_VERSION_V1("engine_getClientVersionV1"), ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1("engine_getPayloadBodiesByHashV1"), ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"), ENGINE_EXCHANGE_CAPABILITIES("engine_exchangeCapabilities"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java new file mode 100644 index 00000000000..5b1142eee0a --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java @@ -0,0 +1,57 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; + +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; + +import io.vertx.core.Vertx; + +public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { + private static final String ENGINE_CLIENT_CODE = "BU"; + private static final String ENGINE_CLIENT_NAME = "Besu"; + + private final String clientVersion; + private final String commit; + + public EngineGetClientVersionV1( + final Vertx vertx, + final ProtocolContext protocolContext, + final EngineCallListener engineCallListener, + final String clientVersion, + final String commit) { + super(vertx, protocolContext, engineCallListener); + this.clientVersion = clientVersion; + this.commit = commit; + } + + @Override + public String getName() { + return RpcMethod.ENGINE_GET_CLIENT_VERSION_V1.getMethodName(); + } + + @Override + public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { + return new JsonRpcSuccessResponse( + request.getRequest().getId(), + new EngineGetClientVersionResultV1( + ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, commit)); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java new file mode 100644 index 00000000000..8251de6dc50 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java @@ -0,0 +1,52 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results; + +import com.fasterxml.jackson.annotation.JsonGetter; + +public class EngineGetClientVersionResultV1 { + private final String code; + private final String name; + private final String version; + private final String commit; + + public EngineGetClientVersionResultV1( + final String code, final String name, final String version, final String commit) { + this.code = code; + this.name = name; + this.version = version; + this.commit = commit; + } + + @JsonGetter(value = "code") + public String getCode() { + return code; + } + + @JsonGetter(value = "name") + public String getName() { + return name; + } + + @JsonGetter(value = "version") + public String getVersion() { + return version; + } + + @JsonGetter(value = "commit") + public String getCommit() { + return commit; + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java index ca66926656e..6dda09bce98 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV3; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetClientVersionV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1; @@ -57,13 +58,17 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { private final ProtocolContext protocolContext; private final EthPeers ethPeers; private final Vertx consensusEngineServer; + private final String clientVersion; + private final String commit; ExecutionEngineJsonRpcMethods( final MiningCoordinator miningCoordinator, final ProtocolSchedule protocolSchedule, final ProtocolContext protocolContext, final EthPeers ethPeers, - final Vertx consensusEngineServer) { + final Vertx consensusEngineServer, + final String clientVersion, + final String commit) { this.mergeCoordinator = Optional.ofNullable(miningCoordinator) .filter(mc -> mc.isCompatibleWithEngineApi()) @@ -72,6 +77,8 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { this.protocolContext = protocolContext; this.ethPeers = ethPeers; this.consensusEngineServer = consensusEngineServer; + this.clientVersion = clientVersion; + this.commit = commit; } @Override @@ -147,7 +154,9 @@ protected Map create() { new EngineExchangeCapabilities( consensusEngineServer, protocolContext, engineQosTimer), new EnginePreparePayloadDebug( - consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()))); + consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()), + new EngineGetClientVersionV1( + consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit))); if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("cancun"))) { executionEngineApisSupported.add( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java index 924889ef47a..41227c2ca82 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java @@ -54,7 +54,9 @@ public class JsonRpcMethodsFactory { public Map methods( + final String clientNodeName, final String clientVersion, + final String commit, final BigInteger networkId, final GenesisConfigOptions genesisConfigOptions, final P2PNetwork p2pNetwork, @@ -89,7 +91,7 @@ public Map methods( final List availableApiGroups = List.of( new AdminJsonRpcMethods( - clientVersion, + clientNodeName, networkId, genesisConfigOptions, p2pNetwork, @@ -115,7 +117,9 @@ public Map methods( protocolSchedule, protocolContext, ethPeers, - consensusEngineServer), + consensusEngineServer, + clientVersion, + commit), new EthJsonRpcMethods( blockchainQueries, synchronizer, @@ -141,7 +145,7 @@ public Map methods( filterManager), new PrivxJsonRpcMethods( blockchainQueries, protocolSchedule, transactionPool, privacyParameters), - new Web3JsonRpcMethods(clientVersion), + new Web3JsonRpcMethods(clientNodeName), new TraceJsonRpcMethods( blockchainQueries, protocolSchedule, protocolContext, apiConfiguration), new TxPoolJsonRpcMethods(transactionPool), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java index 9193574c45b..862e17b890c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java @@ -75,7 +75,9 @@ public abstract class AbstractJsonRpcHttpServiceTest { protected BlockchainSetupUtil blockchainSetupUtil; - protected static String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger NETWORK_ID = BigInteger.valueOf(123); protected static final Collection JSON_RPC_APIS = Arrays.asList( @@ -168,7 +170,9 @@ protected Map getRpcMethods( return new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java index 061d2a2d6a3..4a03b2eb938 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java @@ -58,13 +58,13 @@ public void getPeers() throws Exception { final List peerList = new ArrayList<>(); final PeerInfo info1 = new PeerInfo( - 4, CLIENT_VERSION, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); + 4, CLIENT_NODE_NAME, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); final PeerInfo info2 = new PeerInfo( - 4, CLIENT_VERSION, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); + 4, CLIENT_NODE_NAME, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); final PeerInfo info3 = new PeerInfo( - 4, CLIENT_VERSION, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); + 4, CLIENT_NODE_NAME, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); final InetSocketAddress addr30301 = new InetSocketAddress("localhost", 30301); final InetSocketAddress addr30302 = new InetSocketAddress("localhost", 30302); final InetSocketAddress addr60301 = new InetSocketAddress("localhost", 60301); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java index 80626ef2fc6..25077bbf82f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java @@ -79,7 +79,9 @@ public class JsonRpcHttpServiceHostAllowlistTest { private static OkHttpClient client; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + private static final String CLIENT_VERSION = "0.1.0"; + private static final String CLIENT_COMMIT = "12345678"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); @@ -100,7 +102,9 @@ public void initServerAndClient() throws Exception { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java index 0fb55fdf344..eb23b054d07 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java @@ -100,7 +100,9 @@ public class JsonRpcHttpServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -131,7 +133,9 @@ public static void initServerAndClient() throws Exception { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java index 8323f61b2c5..f35893490ae 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java @@ -94,7 +94,9 @@ public class JsonRpcHttpServiceRpcApisTest { private JsonRpcHttpService service; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + private static final String CLIENT_VERSION = "0.1.0"; + private static final String CLIENT_COMMIT = "12345678"; private static final BigInteger NETWORK_ID = BigInteger.valueOf(123); private JsonRpcConfiguration configuration; private static final List netServices = @@ -202,7 +204,9 @@ private JsonRpcHttpService createJsonRpcHttpServiceWithRpcApis(final JsonRpcConf final Map rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), mock(P2PNetwork.class), @@ -310,7 +314,9 @@ private JsonRpcHttpService createJsonRpcHttpService( final Map rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), p2pNetwork, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index bb5cb68a2ae..52f2ee050cd 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -202,7 +202,7 @@ public void web3ClientVersionSuccessful() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1127,7 +1127,7 @@ public void extraneousParameters() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1143,7 +1143,7 @@ public void requestMissingVersionFieldShouldSucceed() throws Exception { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1175,7 +1175,7 @@ public void nullId() throws Exception { testHelper.assertValidJsonRpcResult(json, null); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1197,7 +1197,7 @@ public void emptyStringIdField() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1218,7 +1218,7 @@ public void negativeNumericId() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1242,7 +1242,7 @@ public void largeNumericId() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1268,7 +1268,7 @@ public void largeStringId() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1289,7 +1289,7 @@ public void fractionalNumericId() throws Exception { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1353,7 +1353,7 @@ public void requestWithWrongVersionShouldSucceed() throws Exception { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1485,7 +1485,7 @@ public void batchRequest() throws Exception { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check result unknown method final JsonObject jsonError = responses.get(brokenRequestId); @@ -1540,7 +1540,7 @@ public void batchRequestContainingInvalidRequest() throws Exception { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check invalid request final JsonObject jsonError = responses.get(invalidId); @@ -1605,7 +1605,7 @@ public void batchRequestWithNotifications() throws Exception { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check result net_version final JsonObject jsonNetVersion = responses.get(netVersionRequestId); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java index a2a856333ea..5e5dc36bb01 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java @@ -78,7 +78,9 @@ public class JsonRpcHttpServiceTestBase { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static EthPeers ethPeersMock; @@ -108,7 +110,9 @@ public static void initServerAndClient() throws Exception { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index 1d3a3a087a7..5cf13a45762 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -85,7 +85,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + private static final String CLIENT_VERSION = "0.1.0"; + private static final String CLIENT_COMMIT = "12345678"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); @@ -114,7 +116,9 @@ public void initServer() throws Exception { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java index 684f843d2fb..c2661141a4c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java @@ -75,7 +75,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { protected static final Vertx vertx = Vertx.vertx(); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + private static final String CLIENT_VERSION = "0.1.0"; + private static final String CLIENT_COMMIT = "12345678"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private final SelfSignedP12Certificate besuCertificate = SelfSignedP12Certificate.create(); @@ -102,7 +104,9 @@ public void beforeEach() { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java index b6d7fa67f81..c0846ed9f26 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java @@ -81,7 +81,9 @@ public class JsonRpcHttpServiceTlsTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + private static final String CLIENT_VERSION = "0.1.0"; + private static final String CLIENT_COMMIT = "12345678"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private JsonRpcHttpService service; @@ -103,7 +105,9 @@ public void initServer() throws Exception { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java new file mode 100644 index 00000000000..1aa0def7e27 --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java @@ -0,0 +1,72 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; + +import io.vertx.core.Vertx; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class EngineGetClientVersionV1Test { + + private static final String ENGINE_CLIENT_CODE = "BU"; + private static final String ENGINE_CLIENT_NAME = "Besu"; + + private static final String CLIENT_VERSION = "v25.6.7-dev-abcdef12"; + private static final String COMMIT = "abcdef12"; + + private EngineGetClientVersionV1 getClientVersion; + + @BeforeEach + void before() { + getClientVersion = + new EngineGetClientVersionV1( + Mockito.mock(Vertx.class), + Mockito.mock(ProtocolContext.class), + Mockito.mock(EngineCallListener.class), + CLIENT_VERSION, + COMMIT); + } + + @Test + void testGetName() { + assertThat(getClientVersion.getName()).isEqualTo("engine_getClientVersionV1"); + } + + @Test + void testSyncResponse() { + JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("v", "m", null)); + JsonRpcResponse actualResult = getClientVersion.syncResponse(request); + + assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class); + JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult; + assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class); + EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 = + (EngineGetClientVersionResultV1) successResponse.getResult(); + assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME); + assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE); + assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION); + assertThat(actualEngineGetClientVersionResultV1.getCommit()).isEqualTo(COMMIT); + } +} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java index 75927c45130..342941d0e9c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -115,7 +115,9 @@ public class WebSocketServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -167,7 +169,9 @@ public void before() throws URISyntaxException { spy( new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock,