Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added executionRequestsHash to EngineNewPayloadV4 #8666

Merged
merged 1 commit into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix;

// TODO Re-enable electra as part of https://github.com/Consensys/teku/issues/8620
// TODO Re-enable electra as part of https://github.com/Consensys/teku/issues/8624
@TestSpecContext(
milestone = {BELLATRIX, CAPELLA, DENEB},
network = Eth2Network.MAINNET)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
import tech.pegasys.teku.ethereum.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.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV1;
Expand Down Expand Up @@ -317,14 +316,16 @@ public void newPayloadV4_shouldBuildRequestAndResponseSuccessfully() {
mockSuccessfulResponse(bodyResponse);

final ExecutionPayload executionPayload = dataStructureUtil.randomExecutionPayload();
final ExecutionPayloadV4 executionPayloadV4 =
ExecutionPayloadV4.fromInternalExecutionPayload(executionPayload);
final ExecutionPayloadV3 executionPayloadV3 =
ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload);

final List<VersionedHash> blobVersionedHashes = dataStructureUtil.randomVersionedHashes(3);
final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32();
final Bytes32 executionRequestHash = dataStructureUtil.randomBytes32();

final SafeFuture<Response<PayloadStatusV1>> futureResponse =
eeClient.newPayloadV4(executionPayloadV4, blobVersionedHashes, parentBeaconBlockRoot);
eeClient.newPayloadV4(
executionPayloadV3, blobVersionedHashes, parentBeaconBlockRoot, executionRequestHash);

assertThat(futureResponse)
.succeedsWithin(1, TimeUnit.SECONDS)
Expand All @@ -335,13 +336,13 @@ public void newPayloadV4_shouldBuildRequestAndResponseSuccessfully() {
final Map<String, Object> requestData = takeRequest();
verifyJsonRpcMethodCall(requestData, "engine_newPayloadV4");

final Map<String, Object> executionPayloadV4Parameter =
final Map<String, Object> executionPayloadV3Parameter =
(Map<String, Object>) ((List<Object>) requestData.get("params")).get(0);
// 17 fields in ExecutionPayloadV4
assertThat(executionPayloadV4Parameter).hasSize(17);
assertThat(executionPayloadV3Parameter).hasSize(17);
// sanity check
assertThat(executionPayloadV4Parameter.get("parentHash"))
.isEqualTo(executionPayloadV4.parentHash.toHexString());
assertThat(executionPayloadV3Parameter.get("parentHash"))
.isEqualTo(executionPayloadV3.parentHash.toHexString());

assertThat(((List<Object>) requestData.get("params")).get(1))
.asInstanceOf(LIST)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
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.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
Expand Down Expand Up @@ -61,9 +60,10 @@ SafeFuture<Response<PayloadStatusV1>> newPayloadV3(
Bytes32 parentBeaconBlockRoot);

SafeFuture<Response<PayloadStatusV1>> newPayloadV4(
ExecutionPayloadV4 executionPayload,
ExecutionPayloadV3 executionPayload,
List<VersionedHash> blobVersionedHashes,
Bytes32 parentBeaconBlockRoot);
Bytes32 parentBeaconBlockRoot,
Bytes32 executionRequestHash);

SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV1(
ForkChoiceStateV1 forkChoiceState, Optional<PayloadAttributesV1> payloadAttributes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
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.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
Expand Down Expand Up @@ -109,11 +108,17 @@ public SafeFuture<Response<PayloadStatusV1>> newPayloadV3(

@Override
public SafeFuture<Response<PayloadStatusV1>> newPayloadV4(
final ExecutionPayloadV4 executionPayload,
final ExecutionPayloadV3 executionPayload,
final List<VersionedHash> blobVersionedHashes,
final Bytes32 parentBeaconBlockRoot) {
final Bytes32 parentBeaconBlockRoot,
final Bytes32 executionRequestHash) {
return taskQueue.queueTask(
() -> delegate.newPayloadV4(executionPayload, blobVersionedHashes, parentBeaconBlockRoot));
() ->
delegate.newPayloadV4(
executionPayload,
blobVersionedHashes,
parentBeaconBlockRoot,
executionRequestHash));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient;
import tech.pegasys.teku.ethereum.executionclient.response.ResponseUnwrapper;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadStatusV1;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload;
Expand Down Expand Up @@ -51,18 +51,21 @@ public SafeFuture<PayloadStatus> execute(final JsonRpcRequestParams params) {
final List<VersionedHash> blobVersionedHashes =
params.getRequiredListParameter(1, VersionedHash.class);
final Bytes32 parentBeaconBlockRoot = params.getRequiredParameter(2, Bytes32.class);
final Bytes32 executionRequestHash = params.getRequiredParameter(3, Bytes32.class);

LOG.trace(
"Calling {}(executionPayload={}, blobVersionedHashes={}, parentBeaconBlockRoot={})",
"Calling {}(executionPayload={}, blobVersionedHashes={}, parentBeaconBlockRoot={}, executionRequestHash={})",
getVersionedName(),
executionPayload,
blobVersionedHashes,
parentBeaconBlockRoot);
parentBeaconBlockRoot,
executionRequestHash);

final ExecutionPayloadV4 executionPayloadV4 =
ExecutionPayloadV4.fromInternalExecutionPayload(executionPayload);
final ExecutionPayloadV3 executionPayloadV3 =
ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload);
return executionEngineClient
.newPayloadV4(executionPayloadV4, blobVersionedHashes, parentBeaconBlockRoot)
.newPayloadV4(
executionPayloadV3, blobVersionedHashes, parentBeaconBlockRoot, executionRequestHash)
.thenApply(ResponseUnwrapper::unwrapExecutionClientResponseOrThrow)
.thenApply(PayloadStatusV1::asInternalExecutionPayload)
.thenPeek(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
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.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
Expand Down Expand Up @@ -139,11 +138,14 @@ public SafeFuture<Response<PayloadStatusV1>> newPayloadV3(

@Override
public SafeFuture<Response<PayloadStatusV1>> newPayloadV4(
final ExecutionPayloadV4 executionPayload,
final ExecutionPayloadV3 executionPayload,
final List<VersionedHash> blobVersionedHashes,
final Bytes32 parentBeaconBlockRoot) {
final Bytes32 parentBeaconBlockRoot,
final Bytes32 executionRequestHash) {
return countRequest(
() -> delegate.newPayloadV4(executionPayload, blobVersionedHashes, parentBeaconBlockRoot),
() ->
delegate.newPayloadV4(
executionPayload, blobVersionedHashes, parentBeaconBlockRoot, executionRequestHash),
NEW_PAYLOAD_V4_METHOD);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
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.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
Expand Down Expand Up @@ -176,16 +175,20 @@ public SafeFuture<Response<PayloadStatusV1>> newPayloadV3(

@Override
public SafeFuture<Response<PayloadStatusV1>> newPayloadV4(
final ExecutionPayloadV4 executionPayload,
final ExecutionPayloadV3 executionPayload,
final List<VersionedHash> blobVersionedHashes,
final Bytes32 parentBeaconBlockRoot) {
final Bytes32 parentBeaconBlockRoot,
final Bytes32 executionRequestHash) {
final List<String> expectedBlobVersionedHashes =
blobVersionedHashes.stream().map(VersionedHash::toHexString).toList();
final Request<?, PayloadStatusV1Web3jResponse> web3jRequest =
new Request<>(
"engine_newPayloadV4",
list(
executionPayload, expectedBlobVersionedHashes, parentBeaconBlockRoot.toHexString()),
executionPayload,
expectedBlobVersionedHashes,
parentBeaconBlockRoot.toHexString(),
executionRequestHash.toHexString()),
web3JClient.getWeb3jService(),
PayloadStatusV1Web3jResponse.class);
return web3JClient.doRequest(web3jRequest, EL_ENGINE_BLOCK_EXECUTION_TIMEOUT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.ethereum.executionclient.ExecutionEngineClient;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV4;
import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV3;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadStatusV1;
import tech.pegasys.teku.ethereum.executionclient.schema.Response;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
Expand Down Expand Up @@ -71,21 +71,66 @@ public void executionPayloadParamIsRequired() {
verifyNoInteractions(executionEngineClient);
}

@Test
public void blobVersionedHashesParamIsRequired() {
final JsonRpcRequestParams params =
new JsonRpcRequestParams.Builder().add(dataStructureUtil.randomExecutionPayload()).build();

assertThatThrownBy(() -> jsonRpcMethod.execute(params))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Missing required parameter at index 1");

verifyNoInteractions(executionEngineClient);
}

@Test
public void parentBeaconBlockRootParamIsRequired() {
final JsonRpcRequestParams params =
new JsonRpcRequestParams.Builder()
.add(dataStructureUtil.randomExecutionPayload())
.add(dataStructureUtil.randomVersionedHashes(3))
.build();

assertThatThrownBy(() -> jsonRpcMethod.execute(params))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Missing required parameter at index 2");

verifyNoInteractions(executionEngineClient);
}

@Test
public void executionRequestHashParamIsRequired() {
final JsonRpcRequestParams params =
new JsonRpcRequestParams.Builder()
.add(dataStructureUtil.randomExecutionPayload())
.add(dataStructureUtil.randomVersionedHashes(3))
.add(dataStructureUtil.randomBytes32())
.build();

assertThatThrownBy(() -> jsonRpcMethod.execute(params))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Missing required parameter at index 3");

verifyNoInteractions(executionEngineClient);
}

@Test
public void shouldReturnFailedExecutionWhenEngineClientRequestFails() {
final ExecutionPayload executionPayload = dataStructureUtil.randomExecutionPayload();
final List<VersionedHash> blobVersionedHashes = dataStructureUtil.randomVersionedHashes(3);
final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32();
final Bytes32 executionRequestHash = dataStructureUtil.randomBytes32();
final String errorResponseFromClient = "error!";

when(executionEngineClient.newPayloadV4(any(), any(), any()))
when(executionEngineClient.newPayloadV4(any(), any(), any(), any()))
.thenReturn(dummyFailedResponse(errorResponseFromClient));

final JsonRpcRequestParams params =
new JsonRpcRequestParams.Builder()
.add(executionPayload)
.add(blobVersionedHashes)
.add(parentBeaconBlockRoot)
.add(executionRequestHash)
.build();

assertThat(jsonRpcMethod.execute(params))
Expand All @@ -94,32 +139,41 @@ public void shouldReturnFailedExecutionWhenEngineClientRequestFails() {
}

@Test
public void shouldCallNewPayloadV4WithExecutionPayloadV4AndBlobVersionedHashes() {
public void shouldCallNewPayloadV4WithExecutionPayloadV3AndCorrectParameters() {
final ExecutionPayload executionPayload = dataStructureUtil.randomExecutionPayload();
final List<VersionedHash> blobVersionedHashes = dataStructureUtil.randomVersionedHashes(4);
final Bytes32 parentBeaconBlockRoot = dataStructureUtil.randomBytes32();
final Bytes32 executionRequestHash = dataStructureUtil.randomBytes32();

final ExecutionPayloadV4 executionPayloadV4 =
ExecutionPayloadV4.fromInternalExecutionPayload(executionPayload);
assertThat(executionPayloadV4).isExactlyInstanceOf(ExecutionPayloadV4.class);
final ExecutionPayloadV3 executionPayloadV3 =
ExecutionPayloadV3.fromInternalExecutionPayload(executionPayload);
assertThat(executionPayloadV3).isExactlyInstanceOf(ExecutionPayloadV3.class);

jsonRpcMethod = new EngineNewPayloadV4(executionEngineClient);

when(executionEngineClient.newPayloadV4(
executionPayloadV4, blobVersionedHashes, parentBeaconBlockRoot))
eq(executionPayloadV3),
eq(blobVersionedHashes),
eq(parentBeaconBlockRoot),
eq(executionRequestHash)))
.thenReturn(dummySuccessfulResponse());

final JsonRpcRequestParams params =
new JsonRpcRequestParams.Builder()
.add(executionPayload)
.add(blobVersionedHashes)
.add(parentBeaconBlockRoot)
.add(executionRequestHash)
.build();

assertThat(jsonRpcMethod.execute(params)).isCompleted();

verify(executionEngineClient)
.newPayloadV4(eq(executionPayloadV4), eq(blobVersionedHashes), eq(parentBeaconBlockRoot));
.newPayloadV4(
eq(executionPayloadV3),
eq(blobVersionedHashes),
eq(parentBeaconBlockRoot),
eq(executionRequestHash));
verifyNoMoreInteractions(executionEngineClient);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ SafeFuture<ForkChoiceUpdatedResult> engineForkChoiceUpdated(
SafeFuture<GetPayloadResponse> engineGetPayload(
ExecutionPayloadContext executionPayloadContext, UInt64 slot);

SafeFuture<PayloadStatus> engineNewPayload(NewPayloadRequest newPayloadRequest);
SafeFuture<PayloadStatus> engineNewPayload(NewPayloadRequest newPayloadRequest, UInt64 slot);

SafeFuture<List<ClientVersion>> engineGetClientVersion(ClientVersion clientVersion);
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,21 @@ public SafeFuture<GetPayloadResponse> engineGetPayload(
}

@Override
public SafeFuture<PayloadStatus> engineNewPayload(final NewPayloadRequest newPayloadRequest) {
public SafeFuture<PayloadStatus> engineNewPayload(
final NewPayloadRequest newPayloadRequest, final UInt64 slot) {
final ExecutionPayload executionPayload = newPayloadRequest.getExecutionPayload();
final JsonRpcRequestParams.Builder paramsBuilder =
new JsonRpcRequestParams.Builder()
.add(executionPayload)
.addOptional(newPayloadRequest.getVersionedHashes())
.addOptional(newPayloadRequest.getParentBeaconBlockRoot());
.addOptional(newPayloadRequest.getParentBeaconBlockRoot())
.addOptional(newPayloadRequest.getExecutionRequestsHash());

return engineMethodsResolver
.getMethod(
EngineApiMethod.ENGINE_NEW_PAYLOAD, executionPayload::getMilestone, PayloadStatus.class)
EngineApiMethod.ENGINE_NEW_PAYLOAD,
() -> spec.atSlot(slot).getMilestone(),
PayloadStatus.class)
.execute(paramsBuilder.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,10 @@ private SafeFuture<GetPayloadResponse> engineGetPayload(
}

@Override
public SafeFuture<PayloadStatus> engineNewPayload(final NewPayloadRequest newPayloadRequest) {
public SafeFuture<PayloadStatus> engineNewPayload(
final NewPayloadRequest newPayloadRequest, final UInt64 slot) {
LOG.trace("calling engineNewPayload(newPayloadRequest={})", newPayloadRequest);
return executionClientHandler.engineNewPayload(newPayloadRequest);
return executionClientHandler.engineNewPayload(newPayloadRequest, slot);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void engineNewPayload_shouldCallNewPayloadV1() {
new PayloadStatusV1(
ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null)));
when(executionEngineClient.newPayloadV1(payloadV1)).thenReturn(dummyResponse);
handler.engineNewPayload(newPayloadRequest);
handler.engineNewPayload(newPayloadRequest, UInt64.ZERO);
verify(executionEngineClient).newPayloadV1(payloadV1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ void engineNewPayload_shouldCallNewPayloadV2() {
new PayloadStatusV1(
ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null)));
when(executionEngineClient.newPayloadV2(payloadV2)).thenReturn(dummyResponse);
final SafeFuture<PayloadStatus> future = handler.engineNewPayload(newPayloadRequest);
final SafeFuture<PayloadStatus> future =
handler.engineNewPayload(newPayloadRequest, UInt64.ZERO);
verify(executionEngineClient).newPayloadV2(payloadV2);
assertThat(future).isCompleted();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ void engineNewPayload_shouldCallNewPayloadV3() {
ExecutionPayloadStatus.ACCEPTED, dataStructureUtil.randomBytes32(), null)));
when(executionEngineClient.newPayloadV3(payloadV3, versionedHashes, parentBeaconBlockRoot))
.thenReturn(dummyResponse);
final SafeFuture<PayloadStatus> future = handler.engineNewPayload(newPayloadRequest);
final SafeFuture<PayloadStatus> future =
handler.engineNewPayload(newPayloadRequest, UInt64.ZERO);
verify(executionEngineClient).newPayloadV3(payloadV3, versionedHashes, parentBeaconBlockRoot);
assertThat(future).isCompleted();
}
Expand Down
Loading