Skip to content

Commit

Permalink
Add engine get inclusion list exeution api method (#9069)
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdi-aouadi authored Jan 31, 2025
1 parent e43e71a commit 01be1ab
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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.GetInclusionListV1Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV3Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV4Response;
Expand Down Expand Up @@ -81,4 +82,6 @@ SafeFuture<Response<ForkChoiceUpdatedResult>> forkChoiceUpdatedV3(
SafeFuture<Response<List<ClientVersionV1>>> getClientVersionV1(ClientVersionV1 clientVersion);

SafeFuture<Response<List<BlobAndProofV1>>> getBlobsV1(List<VersionedHash> blobVersionedHashes);

SafeFuture<Response<GetInclusionListV1Response>> getInclusionListV1(Bytes32 parentHash);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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.GetInclusionListV1Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV3Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV4Response;
Expand Down Expand Up @@ -160,4 +161,10 @@ public SafeFuture<Response<List<BlobAndProofV1>>> getBlobsV1(
final List<VersionedHash> blobVersionedHashes) {
return taskQueue.queueTask(() -> delegate.getBlobsV1(blobVersionedHashes));
}

@Override
public SafeFuture<Response<GetInclusionListV1Response>> getInclusionListV1(
final Bytes32 parentHash) {
return taskQueue.queueTask(() -> delegate.getInclusionListV1(parentHash));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
public enum EngineApiMethod {
ENGINE_NEW_PAYLOAD("engine_newPayload"),
ENGINE_GET_PAYLOAD("engine_getPayload"),
ENGINE_FORK_CHOICE_UPDATED("engine_forkchoiceUpdated");
ENGINE_FORK_CHOICE_UPDATED("engine_forkchoiceUpdated"),
ENGINE_GET_INCLUSION_LIST("engine_getInclusionList");

private final String name;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright Consensys Software Inc., 2025
*
* 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.methods;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.GetInclusionListV1Response;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.spec.datastructures.execution.versions.eip7805.GetInclusionListResponse;

public class EngineGetInclusionListV1
extends AbstractEngineJsonRpcMethod<GetInclusionListResponse> {

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

public EngineGetInclusionListV1(final ExecutionEngineClient executionEngineClient) {
super(executionEngineClient);
}

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

@Override
public int getVersion() {
return 1;
}

@Override
public SafeFuture<GetInclusionListResponse> execute(final JsonRpcRequestParams params) {
final Bytes32 parentHash = params.getRequiredParameter(0, Bytes32.class);
LOG.trace("Calling {}(parentHash={})", getVersionedName(), parentHash);
return executionEngineClient
.getInclusionListV1(parentHash)
.thenApply(ResponseUnwrapper::unwrapExecutionClientResponseOrThrow)
.thenApply(GetInclusionListV1Response::asInternalInclusionListResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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.GetInclusionListV1Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV3Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV4Response;
Expand Down Expand Up @@ -68,6 +69,7 @@ public class MetricRecordingExecutionEngineClient extends MetricRecordingAbstrac
public static final String EXCHANGE_CAPABILITIES_METHOD = "exchange_capabilities";
public static final String GET_CLIENT_VERSION_V1_METHOD = "get_client_versionV1";
public static final String GET_BLOBS_V1_METHOD = "get_blobs_versionV1";
public static final String GET_INCLUSION_LIST_V1_METHOD = "get_inclusion_list_versionV1";

private final ExecutionEngineClient delegate;

Expand Down Expand Up @@ -203,4 +205,11 @@ public SafeFuture<Response<List<BlobAndProofV1>>> getBlobsV1(
final List<VersionedHash> blobVersionedHashes) {
return countRequest(() -> delegate.getBlobsV1(blobVersionedHashes), GET_BLOBS_V1_METHOD);
}

@Override
public SafeFuture<Response<GetInclusionListV1Response>> getInclusionListV1(
final Bytes32 parentHash) {
return countRequest(
() -> delegate.getInclusionListV1(parentHash), GET_INCLUSION_LIST_V1_METHOD);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright Consensys Software Inc., 2025
*
* 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 com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.List;
import org.apache.tuweni.bytes.Bytes;
import tech.pegasys.teku.ethereum.executionclient.serialization.BytesDeserializer;
import tech.pegasys.teku.spec.datastructures.execution.versions.eip7805.GetInclusionListResponse;

public class GetInclusionListV1Response {

@JsonDeserialize(contentUsing = BytesDeserializer.class)
public final List<Bytes> transactions;

public GetInclusionListV1Response(final @JsonProperty("transactions") List<Bytes> transactions) {
this.transactions = transactions;
}

public GetInclusionListResponse asInternalInclusionListResponse() {
return new GetInclusionListResponse(transactions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
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.GetInclusionListV1Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV2Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV3Response;
import tech.pegasys.teku.ethereum.executionclient.schema.GetPayloadV4Response;
Expand All @@ -54,6 +55,7 @@ public class Web3JExecutionEngineClient implements ExecutionEngineClient {
private static final Duration EXCHANGE_CAPABILITIES_TIMEOUT = Duration.ofSeconds(1);
private static final Duration GET_CLIENT_VERSION_TIMEOUT = Duration.ofSeconds(1);
private static final Duration GET_BLOBS_TIMEOUT = Duration.ofSeconds(1);
private static final Duration GET_INCLUSION_LIST_TIMEOUT = Duration.ofSeconds(1);

private final Web3JClient web3JClient;

Expand Down Expand Up @@ -275,6 +277,18 @@ public SafeFuture<Response<List<BlobAndProofV1>>> getBlobsV1(
return web3JClient.doRequest(web3jRequest, GET_BLOBS_TIMEOUT);
}

@Override
public SafeFuture<Response<GetInclusionListV1Response>> getInclusionListV1(
final Bytes32 parentHash) {
final Request<?, GetnclusionListVersionV1Web3jResponse> web3jRequest =
new Request<>(
"engine_getInclusionListV1",
list(parentHash),
web3JClient.getWeb3jService(),
GetnclusionListVersionV1Web3jResponse.class);
return web3JClient.doRequest(web3jRequest, GET_INCLUSION_LIST_TIMEOUT);
}

static class ExecutionPayloadV1Web3jResponse
extends org.web3j.protocol.core.Response<ExecutionPayloadV1> {}

Expand Down Expand Up @@ -302,6 +316,9 @@ static class GetClientVersionV1Web3jResponse
static class GetBlobsVersionV1Web3jResponse
extends org.web3j.protocol.core.Response<List<BlobAndProofV1>> {}

static class GetnclusionListVersionV1Web3jResponse
extends org.web3j.protocol.core.Response<GetInclusionListV1Response> {}

/**
* Returns a list that supports null items.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse;
import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest;
import tech.pegasys.teku.spec.datastructures.execution.PowBlock;
import tech.pegasys.teku.spec.datastructures.execution.Transaction;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceState;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceUpdatedResult;
import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes;
Expand All @@ -49,4 +50,6 @@ SafeFuture<GetPayloadResponse> engineGetPayload(

SafeFuture<List<BlobAndProof>> engineGetBlobs(
List<VersionedHash> blobVersionedHashes, UInt64 slot);

SafeFuture<List<Transaction>> engineGetInclusionList(Bytes32 parentHash, UInt64 slot);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse;
import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest;
import tech.pegasys.teku.spec.datastructures.execution.PowBlock;
import tech.pegasys.teku.spec.datastructures.execution.Transaction;
import tech.pegasys.teku.spec.datastructures.execution.TransactionSchema;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceState;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceUpdatedResult;
import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes;
Expand Down Expand Up @@ -154,4 +156,23 @@ public SafeFuture<List<BlobAndProof>> engineGetBlobs(
.toList();
});
}

@Override
public SafeFuture<List<Transaction>> engineGetInclusionList(
final Bytes32 parentHash, final UInt64 slot) {
return executionEngineClient
.getInclusionListV1(parentHash)
.thenApply(ResponseUnwrapper::unwrapExecutionClientResponseOrThrow)
.thenApply(
response -> {
final TransactionSchema transactionSchema =
spec.atSlot(slot)
.getSchemaDefinitions()
.toVersionEip7805()
.orElseThrow()
.getInclusionListSchema()
.getTransactionSchema();
return response.transactions.stream().map(transactionSchema::fromBytes).toList();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse;
import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest;
import tech.pegasys.teku.spec.datastructures.execution.PowBlock;
import tech.pegasys.teku.spec.datastructures.execution.Transaction;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceState;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceUpdatedResult;
Expand Down Expand Up @@ -230,6 +231,14 @@ public SafeFuture<List<Optional<BlobAndProof>>> engineGetBlobs(
.thenApply(blobsAndProofs -> blobsAndProofs.stream().map(Optional::ofNullable).toList());
}

@Override
public SafeFuture<List<Transaction>> engineGetInclusionList(
final Bytes32 parentHash, final UInt64 slot) {
LOG.trace(
"calling engineGetInclusionList(engineGetInclusionList={}, slot={})", parentHash, slot);
return executionClientHandler.engineGetInclusionList(parentHash, slot);
}

@Override
public SafeFuture<Void> builderRegisterValidators(
final SszList<SignedValidatorRegistration> signedValidatorRegistrations, final UInt64 slot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package tech.pegasys.teku.ethereum.executionlayer;

import static tech.pegasys.teku.ethereum.executionclient.methods.EngineApiMethod.ENGINE_FORK_CHOICE_UPDATED;
import static tech.pegasys.teku.ethereum.executionclient.methods.EngineApiMethod.ENGINE_GET_INCLUSION_LIST;
import static tech.pegasys.teku.ethereum.executionclient.methods.EngineApiMethod.ENGINE_GET_PAYLOAD;
import static tech.pegasys.teku.ethereum.executionclient.methods.EngineApiMethod.ENGINE_NEW_PAYLOAD;

Expand All @@ -29,6 +30,7 @@
import tech.pegasys.teku.ethereum.executionclient.methods.EngineForkChoiceUpdatedV1;
import tech.pegasys.teku.ethereum.executionclient.methods.EngineForkChoiceUpdatedV2;
import tech.pegasys.teku.ethereum.executionclient.methods.EngineForkChoiceUpdatedV3;
import tech.pegasys.teku.ethereum.executionclient.methods.EngineGetInclusionListV1;
import tech.pegasys.teku.ethereum.executionclient.methods.EngineGetPayloadV1;
import tech.pegasys.teku.ethereum.executionclient.methods.EngineGetPayloadV2;
import tech.pegasys.teku.ethereum.executionclient.methods.EngineGetPayloadV3;
Expand Down Expand Up @@ -73,9 +75,12 @@ public MilestoneBasedEngineJsonRpcMethodsResolver(
case DENEB:
methodsByMilestone.put(milestone, denebSupportedMethods());
break;
case ELECTRA, EIP7805:
case ELECTRA:
methodsByMilestone.put(milestone, electraSupportedMethods());
break;
case EIP7805:
methodsByMilestone.put(milestone, eip7805SupportedMethods());
break;
}
});
}
Expand Down Expand Up @@ -120,6 +125,17 @@ private Map<EngineApiMethod, EngineJsonRpcMethod<?>> electraSupportedMethods() {
return methods;
}

private Map<EngineApiMethod, EngineJsonRpcMethod<?>> eip7805SupportedMethods() {
final Map<EngineApiMethod, EngineJsonRpcMethod<?>> methods = new HashMap<>();

methods.put(ENGINE_NEW_PAYLOAD, new EngineNewPayloadV4(executionEngineClient));
methods.put(ENGINE_GET_PAYLOAD, new EngineGetPayloadV4(executionEngineClient, spec));
methods.put(ENGINE_FORK_CHOICE_UPDATED, new EngineForkChoiceUpdatedV3(executionEngineClient));
methods.put(ENGINE_GET_INCLUSION_LIST, new EngineGetInclusionListV1(executionEngineClient));

return methods;
}

@Override
@SuppressWarnings({"unchecked", "unused"})
public <T> EngineJsonRpcMethod<T> getMethod(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Consensys Software Inc., 2025
*
* 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.spec.datastructures.execution.versions.eip7805;

import java.util.List;
import org.apache.tuweni.bytes.Bytes;

public record GetInclusionListResponse(List<Bytes> transactions) {}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public InclusionList createFromBackingNode(final TreeNode node) {

@SuppressWarnings("unchecked")
public SszListSchema<Transaction, ?> getTransactionsSchema() {
return (SszListSchema<Transaction, ?>) getChildSchema(getFieldIndex(FIELD_TRANSACTIONS));
return (SszListSchema<Transaction, ?>) getFieldSchema3();
}

public TransactionSchema getTransactionSchema() {
return (TransactionSchema) getTransactionsSchema().getElementSchema();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

package tech.pegasys.teku.spec.executionlayer;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
Expand All @@ -34,6 +35,7 @@
import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse;
import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest;
import tech.pegasys.teku.spec.datastructures.execution.PowBlock;
import tech.pegasys.teku.spec.datastructures.execution.Transaction;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash;

Expand Down Expand Up @@ -85,6 +87,12 @@ public SafeFuture<List<Optional<BlobAndProof>>> engineGetBlobs(
blobVersionedHashes.stream().map(e -> Optional.<BlobAndProof>empty()).toList());
}

@Override
public SafeFuture<List<Transaction>> engineGetInclusionList(
final Bytes32 parentHash, final UInt64 slot) {
return SafeFuture.completedFuture(Collections.emptyList());
}

@Override
public SafeFuture<Void> builderRegisterValidators(
final SszList<SignedValidatorRegistration> signedValidatorRegistrations,
Expand Down Expand Up @@ -127,6 +135,8 @@ SafeFuture<ForkChoiceUpdatedResult> engineForkChoiceUpdated(
SafeFuture<List<Optional<BlobAndProof>>> engineGetBlobs(
List<VersionedHash> blobVersionedHashes, UInt64 slot);

SafeFuture<List<Transaction>> engineGetInclusionList(Bytes32 parentHash, UInt64 slot);

/**
* This is low level method, use {@link
* ExecutionLayerBlockProductionManager#initiateBlockProduction(ExecutionPayloadContext,
Expand Down
Loading

0 comments on commit 01be1ab

Please sign in to comment.