Skip to content

Commit

Permalink
Employ one milestone one method approach for engine api calls (Consen…
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanBratanov authored Jul 4, 2023
1 parent 8748293 commit 576cb2a
Show file tree
Hide file tree
Showing 57 changed files with 412 additions and 1,979 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ For information on changes in released versions of Teku, see the [releases page]

### Breaking Changes

- `--exchange-capabilities-enabled` option has been removed since it is no longer applicable because of [execution-apis](https://github.com/ethereum/execution-apis/pull/418) spec change.

### Additions and Improvements

- `--validators-external-signer-public-keys` parameter now accepts `external-signer` value. It will enable public key retrieval from external signer standard API, making sure that configured keystore and trustStore will be used, if any.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
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.STRING;
Expand Down Expand Up @@ -206,7 +207,7 @@ public void exchangeCapabilities_shouldBuildRequestAndResponseSuccessfully() thr
@TestTemplate
@SuppressWarnings("unchecked")
public void newPayloadV3_shouldBuildRequestAndResponseSuccessfully() {
final boolean isDeneb = spec.isMilestoneSupported(DENEB);
assumeThat(specMilestone).isGreaterThanOrEqualTo(DENEB);
final Bytes32 latestValidHash = dataStructureUtil.randomBytes32();
final PayloadStatus payloadStatusResponse =
PayloadStatus.valid(Optional.of(latestValidHash), Optional.empty());
Expand All @@ -223,8 +224,7 @@ public void newPayloadV3_shouldBuildRequestAndResponseSuccessfully() {
final ExecutionPayloadV3 executionPayloadV3 =
ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload);

final Optional<List<VersionedHash>> blobVersionedHashes =
isDeneb ? Optional.of(dataStructureUtil.randomVersionedHashes(3)) : Optional.empty();
final List<VersionedHash> blobVersionedHashes = dataStructureUtil.randomVersionedHashes(3);

final SafeFuture<Response<PayloadStatusV1>> futureResponse =
eeClient.newPayloadV3(executionPayloadV3, blobVersionedHashes);
Expand All @@ -246,25 +246,19 @@ public void newPayloadV3_shouldBuildRequestAndResponseSuccessfully() {
assertThat(executionPayloadV3Parameter.get("parentHash"))
.isEqualTo(executionPayloadV3.parentHash.toHexString());

if (isDeneb) {
assertThat(executionPayloadV3Parameter.get("dataGasUsed"))
.isEqualTo(
Bytes.ofUnsignedLong(executionPayloadV3.dataGasUsed.longValue())
.toQuantityHexString());
assertThat(executionPayloadV3Parameter.get("excessDataGas"))
.isEqualTo(
Bytes.ofUnsignedLong(executionPayloadV3.excessDataGas.longValue())
.toQuantityHexString());
assertThat(((List<Object>) requestData.get("params")).get(1))
.asInstanceOf(LIST)
.containsExactlyElementsOf(
blobVersionedHashes.get().stream()
.map(VersionedHash::toHexString)
.collect(Collectors.toList()));
} else {
// pre-deneb versionedHashes param must be null
assertThat(((List<Object>) requestData.get("params")).get(1)).isNull();
}
assertThat(executionPayloadV3Parameter.get("dataGasUsed"))
.isEqualTo(
Bytes.ofUnsignedLong(executionPayloadV3.dataGasUsed.longValue()).toQuantityHexString());
assertThat(executionPayloadV3Parameter.get("excessDataGas"))
.isEqualTo(
Bytes.ofUnsignedLong(executionPayloadV3.excessDataGas.longValue())
.toQuantityHexString());
assertThat(((List<Object>) requestData.get("params")).get(1))
.asInstanceOf(LIST)
.containsExactlyElementsOf(
blobVersionedHashes.stream()
.map(VersionedHash::toHexString)
.collect(Collectors.toList()));
}

private void mockSuccessfulResponse(final String responseBody) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV3Response;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV1;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV2;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadStatusV1;
import tech.pegasys.teku.ethereum.executionclient.schema.Response;
import tech.pegasys.teku.ethereum.executionclient.schema.TransitionConfigurationV1;
Expand All @@ -45,16 +48,16 @@ public interface ExecutionEngineClient {

SafeFuture<Response<PayloadStatusV1>> newPayloadV1(ExecutionPayloadV1 executionPayload);

SafeFuture<Response<PayloadStatusV1>> newPayloadV2(ExecutionPayloadV1 executionPayload);
SafeFuture<Response<PayloadStatusV1>> newPayloadV2(ExecutionPayloadV2 executionPayload);

SafeFuture<Response<PayloadStatusV1>> newPayloadV3(
ExecutionPayloadV1 executionPayload, Optional<List<VersionedHash>> blobVersionedHashes);
ExecutionPayloadV3 executionPayload, List<VersionedHash> blobVersionedHashes);

SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV1(
ForkChoiceStateV1 forkChoiceState, Optional<PayloadAttributesV1> payloadAttributes);

SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV2(
ForkChoiceStateV1 forkChoiceState, Optional<PayloadAttributesV1> payloadAttributes);
ForkChoiceStateV1 forkChoiceState, Optional<PayloadAttributesV2> payloadAttributes);

SafeFuture<Response<TransitionConfigurationV1>> exchangeTransitionConfiguration(
TransitionConfigurationV1 transitionConfiguration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
import org.apache.tuweni.bytes.Bytes32;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV3Response;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV1;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV2;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadStatusV1;
import tech.pegasys.teku.ethereum.executionclient.schema.Response;
import tech.pegasys.teku.ethereum.executionclient.schema.TransitionConfigurationV1;
Expand Down Expand Up @@ -83,14 +86,13 @@ public SafeFuture<Response<PayloadStatusV1>> newPayloadV1(

@Override
public SafeFuture<Response<PayloadStatusV1>> newPayloadV2(
final ExecutionPayloadV1 executionPayload) {
final ExecutionPayloadV2 executionPayload) {
return taskQueue.queueTask(() -> delegate.newPayloadV2(executionPayload));
}

@Override
public SafeFuture<Response<PayloadStatusV1>> newPayloadV3(
final ExecutionPayloadV1 executionPayload,
final Optional<List<VersionedHash>> blobVersionedHashes) {
final ExecutionPayloadV3 executionPayload, final List<VersionedHash> blobVersionedHashes) {
return taskQueue.queueTask(() -> delegate.newPayloadV3(executionPayload, blobVersionedHashes));
}

Expand All @@ -105,7 +107,7 @@ public SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV1(
@Override
public SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV2(
final ForkChoiceStateV1 forkChoiceState,
final Optional<PayloadAttributesV1> payloadAttributes) {
final Optional<PayloadAttributesV2> payloadAttributes) {
return taskQueue.queueTask(
() -> delegate.forkChoiceUpdatedV2(forkChoiceState, payloadAttributes));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
package tech.pegasys.teku.ethereum.executionclient.methods;

import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient;
import tech.pegasys.teku.infrastructure.async.SafeFuture;

public abstract class AbstractEngineJsonRpcMethod<T> implements EngineJsonRpcMethod<T> {

Expand All @@ -23,18 +22,4 @@ public abstract class AbstractEngineJsonRpcMethod<T> implements EngineJsonRpcMet
public AbstractEngineJsonRpcMethod(final ExecutionEngineClient executionEngineClient) {
this.executionEngineClient = executionEngineClient;
}

@Override
public abstract String getName();

@Override
public abstract int getVersion();

@Override
public final String getVersionedName() {
return getVersion() == 0 ? getName() : getName() + "V" + getVersion();
}

@Override
public abstract SafeFuture<T> execute(JsonRpcRequestParams params);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

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

public enum EngineApiMethods {
public enum EngineApiMethod {
ETH_GET_BLOCK_BY_HASH("eth_getBlockByHash"),
ETH_GET_BLOCK_BY_NUMBER("eth_getBlockByNumber"),
ENGINE_NEW_PAYLOAD("engine_newPayload"),
Expand All @@ -23,7 +23,7 @@ public enum EngineApiMethods {

private final String name;

EngineApiMethods(final String name) {
EngineApiMethod(final String name) {
this.name = name;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public EngineExchangeTransitionConfigurationV1(

@Override
public String getName() {
return EngineApiMethods.ENGINE_EXCHANGE_TRANSITION_CONFIGURATION.getName();
return EngineApiMethod.ENGINE_EXCHANGE_TRANSITION_CONFIGURATION.getName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public EngineForkChoiceUpdatedV1(final ExecutionEngineClient executionEngineClie

@Override
public String getName() {
return EngineApiMethods.ENGINE_FORK_CHOICE_UPDATED.getName();
return EngineApiMethod.ENGINE_FORK_CHOICE_UPDATED.getName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@
import tech.pegasys.teku.ethereum.executionclient.response.ResponseUnwrapper;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV1;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV2;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceState;
import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes;

Expand All @@ -33,17 +30,14 @@ public class EngineForkChoiceUpdatedV2
tech.pegasys.teku.spec.executionlayer.ForkChoiceUpdatedResult> {

private static final Logger LOG = LogManager.getLogger();
private final Spec spec;

public EngineForkChoiceUpdatedV2(
final ExecutionEngineClient executionEngineClient, final Spec spec) {
public EngineForkChoiceUpdatedV2(final ExecutionEngineClient executionEngineClient) {
super(executionEngineClient);
this.spec = spec;
}

@Override
public String getName() {
return EngineApiMethods.ENGINE_FORK_CHOICE_UPDATED.getName();
return EngineApiMethod.ENGINE_FORK_CHOICE_UPDATED.getName();
}

@Override
Expand All @@ -64,16 +58,11 @@ public SafeFuture<tech.pegasys.teku.spec.executionlayer.ForkChoiceUpdatedResult>
forkChoiceState,
payloadBuildingAttributes);

final Optional<PayloadAttributesV1> maybePayloadAttributes =
final Optional<PayloadAttributesV2> maybePayloadAttributes =
payloadBuildingAttributes.flatMap(
attributes ->
spec.atSlot(attributes.getBlockSlot())
.getMilestone()
.isGreaterThanOrEqualTo(SpecMilestone.CAPELLA)
? PayloadAttributesV2.fromInternalPayloadBuildingAttributesV2(
payloadBuildingAttributes)
: PayloadAttributesV1.fromInternalPayloadBuildingAttributes(
payloadBuildingAttributes));
PayloadAttributesV2.fromInternalPayloadBuildingAttributesV2(
payloadBuildingAttributes));

return executionEngineClient
.forkChoiceUpdatedV2(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public EngineGetPayloadV1(final ExecutionEngineClient executionEngineClient, fin

@Override
public String getName() {
return EngineApiMethods.ENGINE_GET_PAYLOAD.getName();
return EngineApiMethod.ENGINE_GET_PAYLOAD.getName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public EngineGetPayloadV2(final ExecutionEngineClient executionEngineClient, fin

@Override
public String getName() {
return EngineApiMethods.ENGINE_GET_PAYLOAD.getName();
return EngineApiMethod.ENGINE_GET_PAYLOAD.getName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

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

import java.util.Optional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient;
Expand All @@ -22,6 +21,7 @@
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema;
import tech.pegasys.teku.spec.datastructures.execution.BlobsBundle;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadContext;
Expand All @@ -44,7 +44,7 @@ public EngineGetPayloadV3(final ExecutionEngineClient executionEngineClient, fin

@Override
public String getName() {
return EngineApiMethods.ENGINE_GET_PAYLOAD.getName();
return EngineApiMethod.ENGINE_GET_PAYLOAD.getName();
}

@Override
Expand Down Expand Up @@ -75,12 +75,8 @@ public SafeFuture<GetPayloadResponse> execute(final JsonRpcRequestParams params)
.getExecutionPayloadSchema();
final ExecutionPayload executionPayload =
response.executionPayload.asInternalExecutionPayload(payloadSchema);
return getBlobsBundle(response, schemaDefinitions)
.map(
blobsBundle ->
new GetPayloadResponse(
executionPayload, response.blockValue, blobsBundle))
.orElse(new GetPayloadResponse(executionPayload, response.blockValue));
final BlobsBundle blobsBundle = getBlobsBundle(response, schemaDefinitions);
return new GetPayloadResponse(executionPayload, response.blockValue, blobsBundle);
})
.thenPeek(
getPayloadResponse ->
Expand All @@ -92,14 +88,10 @@ public SafeFuture<GetPayloadResponse> execute(final JsonRpcRequestParams params)
getPayloadResponse));
}

private Optional<BlobsBundle> getBlobsBundle(
private BlobsBundle getBlobsBundle(
final GetPayloadV3Response response, final SchemaDefinitions schemaDefinitions) {
return schemaDefinitions
.toVersionDeneb()
.map(SchemaDefinitionsDeneb::getBlobSchema)
.flatMap(
blobSchema ->
Optional.ofNullable(response.blobsBundle)
.map(blobsBundleV1 -> blobsBundleV1.asInternalBlobsBundle(blobSchema)));
final BlobSchema blobSchema =
SchemaDefinitionsDeneb.required(schemaDefinitions).getBlobSchema();
return response.blobsBundle.asInternalBlobsBundle(blobSchema);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ public interface EngineJsonRpcMethod<T> {

int getVersion();

String getVersionedName();

SafeFuture<T> execute(JsonRpcRequestParams params);

default boolean isNegotiable() {
return getVersion() != 0;
default String getVersionedName() {
return getVersion() == 0 ? getName() : getName() + "V" + getVersion();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public EngineNewPayloadV1(final ExecutionEngineClient executionEngineClient) {

@Override
public String getName() {
return EngineApiMethods.ENGINE_NEW_PAYLOAD.getName();
return EngineApiMethod.ENGINE_NEW_PAYLOAD.getName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.apache.logging.log4j.Logger;
import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient;
import tech.pegasys.teku.ethereum.executionclient.response.ResponseUnwrapper;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadStatusV1;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
Expand All @@ -34,7 +33,7 @@ public EngineNewPayloadV2(final ExecutionEngineClient executionEngineClient) {

@Override
public String getName() {
return EngineApiMethods.ENGINE_NEW_PAYLOAD.getName();
return EngineApiMethod.ENGINE_NEW_PAYLOAD.getName();
}

@Override
Expand All @@ -50,10 +49,7 @@ public SafeFuture<PayloadStatus> execute(final JsonRpcRequestParams params) {
LOG.trace("Calling {}(executionPayload={})", getVersionedName(), executionPayload);

return executionEngineClient
.newPayloadV2(
executionPayload.toVersionCapella().isPresent()
? ExecutionPayloadV2.fromInternalExecutionPayload(executionPayload)
: ExecutionPayloadV1.fromInternalExecutionPayload(executionPayload))
.newPayloadV2(ExecutionPayloadV2.fromInternalExecutionPayload(executionPayload))
.thenApply(ResponseUnwrapper::unwrapExecutionClientResponseOrThrow)
.thenApply(PayloadStatusV1::asInternalExecutionPayload)
.thenPeek(
Expand Down
Loading

0 comments on commit 576cb2a

Please sign in to comment.