Skip to content

Commit

Permalink
Add engine_getClientVersionV1 interface + ability to get commit hash (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanBratanov authored Mar 13, 2024
1 parent 3824d24 commit be4dfc0
Show file tree
Hide file tree
Showing 23 changed files with 462 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.assertj.core.api.Assumptions.assumeThat;
import static org.assertj.core.api.InstanceOfAssertFactories.INTEGER;
import static org.assertj.core.api.InstanceOfAssertFactories.LIST;
import static org.assertj.core.api.InstanceOfAssertFactories.MAP;
import static org.assertj.core.api.InstanceOfAssertFactories.STRING;
import static org.mockito.Mockito.mock;
import static tech.pegasys.teku.spec.SpecMilestone.CAPELLA;
Expand Down Expand Up @@ -46,6 +47,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestTemplate;
import tech.pegasys.teku.ethereum.executionclient.events.ExecutionClientEventsChannel;
import tech.pegasys.teku.ethereum.executionclient.schema.ClientVersionV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
Expand All @@ -54,6 +56,7 @@
import tech.pegasys.teku.ethereum.executionclient.schema.Response;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.bytes.Bytes20;
import tech.pegasys.teku.infrastructure.bytes.Bytes4;
import tech.pegasys.teku.infrastructure.json.JsonTestUtil;
import tech.pegasys.teku.infrastructure.time.StubTimeProvider;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
Expand Down Expand Up @@ -204,6 +207,36 @@ public void exchangeCapabilities_shouldBuildRequestAndResponseSuccessfully() thr
assertThat(requestData.get("params")).asInstanceOf(LIST).containsExactly(consensusCapabilities);
}

@TestTemplate
public void getClientVersionV1_shouldBuildRequestAndResponseSuccessfully() throws Exception {
final ClientVersionV1 consensusClientVersion =
new ClientVersionV1("TK", "teku", "1.0.0", Bytes4.fromHexString("87fa8ca7"));
final ClientVersionV1 executionClientVersion =
new ClientVersionV1("BU", "besu", "1.0.0", Bytes4.fromHexString("8dba2981"));

final JsonRpcResponse responseBody = new JsonRpcResponse(List.of(executionClientVersion));
mockSuccessfulResponse(objectMapper.writeValueAsString(responseBody));

final SafeFuture<Response<List<ClientVersionV1>>> response =
eeClient.getClientVersionV1(consensusClientVersion);
assertThat(response)
.succeedsWithin(1, TimeUnit.SECONDS)
.isEqualTo(new Response<>(List.of(executionClientVersion)));

final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_getClientVersionV1");
assertThat(requestData.get("params"))
.asInstanceOf(LIST)
.hasSize(1)
.first()
.asInstanceOf(MAP)
.hasSize(4)
.containsEntry("code", "TK")
.containsEntry("name", "teku")
.containsEntry("version", "1.0.0")
.containsEntry("commit", "0x87fa8ca7");
}

@TestTemplate
@SuppressWarnings("unchecked")
public void newPayloadV3_shouldBuildRequestAndResponseSuccessfully() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.ethereum.executionclient.schema.ClientVersionV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
Expand Down Expand Up @@ -65,4 +66,6 @@ SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV3(
ForkChoiceStateV1 forkChoiceState, Optional<PayloadAttributesV3> payloadAttributes);

SafeFuture<Response<List<String>>> exchangeCapabilities(List<String> capabilities);

SafeFuture<Response<List<ClientVersionV1>>> getClientVersionV1(ClientVersionV1 clientVersion);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import tech.pegasys.teku.ethereum.executionclient.schema.ClientVersionV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
Expand Down Expand Up @@ -127,4 +128,10 @@ public SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV3(
public SafeFuture<Response<List<String>>> exchangeCapabilities(final List<String> capabilities) {
return taskQueue.queueTask(() -> delegate.exchangeCapabilities(capabilities));
}

@Override
public SafeFuture<Response<List<ClientVersionV1>>> getClientVersionV1(
final ClientVersionV1 clientVersion) {
return taskQueue.queueTask(() -> delegate.getClientVersionV1(clientVersion));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.apache.tuweni.bytes.Bytes32;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient;
import tech.pegasys.teku.ethereum.executionclient.schema.ClientVersionV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
Expand Down Expand Up @@ -59,6 +60,8 @@ public class MetricRecordingExecutionEngineClient extends MetricRecordingAbstrac
"forkchoice_updated_with_attributesV3";
public static final String GET_PAYLOAD_V3_METHOD = "get_payloadV3";
public static final String NEW_PAYLOAD_V3_METHOD = "new_payloadV3";
public static final String EXCHANGE_CAPABILITIES_METHOD = "exchange_capabilities";
public static final String GET_CLIENT_VERSION_V1_METHOD = "get_client_versionV1";

private final ExecutionEngineClient delegate;

Expand Down Expand Up @@ -160,6 +163,14 @@ public SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV3(

@Override
public SafeFuture<Response<List<String>>> exchangeCapabilities(final List<String> capabilities) {
return delegate.exchangeCapabilities(capabilities);
return countRequest(
() -> delegate.exchangeCapabilities(capabilities), EXCHANGE_CAPABILITIES_METHOD);
}

@Override
public SafeFuture<Response<List<ClientVersionV1>>> getClientVersionV1(
final ClientVersionV1 clientVersion) {
return countRequest(
() -> delegate.getClientVersionV1(clientVersion), GET_CLIENT_VERSION_V1_METHOD);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright Consensys Software Inc., 2024
*
* 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.
*/

package tech.pegasys.teku.ethereum.executionclient.schema;

import static com.google.common.base.Preconditions.checkNotNull;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.MoreObjects;
import java.util.Objects;
import tech.pegasys.teku.ethereum.executionclient.serialization.Bytes4Deserializer;
import tech.pegasys.teku.ethereum.executionclient.serialization.Bytes4Serializer;
import tech.pegasys.teku.infrastructure.bytes.Bytes4;
import tech.pegasys.teku.spec.datastructures.execution.ClientVersion;

public class ClientVersionV1 {

public final String code;
public final String name;
public final String version;

@JsonSerialize(using = Bytes4Serializer.class)
@JsonDeserialize(using = Bytes4Deserializer.class)
public final Bytes4 commit;

public ClientVersionV1(
@JsonProperty("code") String code,
@JsonProperty("name") String name,
@JsonProperty("version") String version,
@JsonProperty("commit") Bytes4 commit) {
checkNotNull(code, "code");
checkNotNull(name, "name");
checkNotNull(version, "version");
checkNotNull(commit, "commit");
this.code = code;
this.name = name;
this.version = version;
this.commit = commit;
}

public static ClientVersionV1 fromInternalClientVersion(final ClientVersion clientVersion) {
return new ClientVersionV1(
clientVersion.code(),
clientVersion.name(),
clientVersion.version(),
clientVersion.commit());
}

public static ClientVersion asInternalClientVersion(final ClientVersionV1 clientVersionV1) {
return new ClientVersion(
clientVersionV1.code,
clientVersionV1.name,
clientVersionV1.version,
clientVersionV1.commit);
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ClientVersionV1 that = (ClientVersionV1) o;
return Objects.equals(code, that.code)
&& Objects.equals(name, that.name)
&& Objects.equals(version, that.version)
&& Objects.equals(commit, that.commit);
}

@Override
public int hashCode() {
return Objects.hash(code, name, version, commit);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("code", code)
.add("name", name)
.add("version", version)
.add("commit", commit)
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Consensys Software Inc., 2022
*
* 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.
*/

package tech.pegasys.teku.ethereum.executionclient.serialization;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import tech.pegasys.teku.infrastructure.bytes.Bytes4;

public class Bytes4Deserializer extends JsonDeserializer<Bytes4> {

@Override
public Bytes4 deserialize(final JsonParser p, final DeserializationContext ctxt)
throws IOException {
return Bytes4.fromHexString(p.getValueAsString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Consensys Software Inc., 2022
*
* 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.
*/

package tech.pegasys.teku.ethereum.executionclient.serialization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.util.Locale;
import tech.pegasys.teku.infrastructure.bytes.Bytes4;

public class Bytes4Serializer extends JsonSerializer<Bytes4> {
@Override
public void serialize(
final Bytes4 value, final JsonGenerator gen, final SerializerProvider serializers)
throws IOException {
gen.writeString(value.toHexString().toLowerCase(Locale.ROOT));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private synchronized void buildClient() {
.jwtConfigOpt(jwtConfig)
.timeProvider(timeProvider)
.executionClientEventsPublisher(executionClientEventsPublisher)
.nonCriticalMethods("engine_exchangeCapabilities")
.nonCriticalMethods("engine_exchangeCapabilities", "engine_getClientVersionV1")
.build();
this.alreadyBuilt = true;
}
Expand Down
Loading

0 comments on commit be4dfc0

Please sign in to comment.