Skip to content

Commit

Permalink
Use single getExecutionPayloadSchema method (Consensys#6419)
Browse files Browse the repository at this point in the history
Avoids the risk of getting the Bellatrix schema definition back from Capella because the getExecutionPayloadSchemaBellatrix method was used and ensures the right schema is used for blocks.
Gets ssz_static reference tests passing for everything except BeaconState (being fixed separately).

Make BuilderBid schemas handle generic execution payload versions.
  • Loading branch information
ajsutton authored Nov 10, 2022
1 parent ed4bc35 commit 5d7a987
Show file tree
Hide file tree
Showing 29 changed files with 454 additions and 357 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public ExecutionPayloadBellatrix(
schema ->
schema
.getExecutionPayloadSchema()
.toVersionBellatrix()
.orElseThrow()
.create(
parentHash,
feeRecipient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
package tech.pegasys.teku.api.schema.capella;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.stream.Collectors.toList;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.api.schema.Attestation;
import tech.pegasys.teku.api.schema.AttesterSlashing;
Expand Down Expand Up @@ -84,7 +84,7 @@ public BeaconBlockBodyCapella(
this.blsToExecutionChanges =
message.getBlsToExecutionChanges().stream()
.map(SignedBlsToExecutionChange::new)
.collect(Collectors.toList());
.collect(toList());
}

@Override
Expand Down Expand Up @@ -124,7 +124,12 @@ public BeaconBlockBody asInternalBeaconBlockBody(final SpecVersion spec) {
executionPayload.baseFeePerGas,
executionPayload.blockHash,
executionPayload.transactions,
executionPayload.withdrawals)));
executionPayload.withdrawals.stream()
.map(
withdrawal ->
withdrawal.asInternalWithdrawal(
executionPayloadSchemaCapella.getWithdrawalSchema()))
.collect(toList()))));
builder.blsToExecutionChanges(
() ->
this.blsToExecutionChanges.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

package tech.pegasys.teku.api.schema.capella;

import static java.util.stream.Collectors.toList;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects;
Expand All @@ -22,7 +24,6 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
Expand All @@ -31,13 +32,13 @@
import tech.pegasys.teku.infrastructure.bytes.Bytes20;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsCapella;

public class ExecutionPayloadCapella extends ExecutionPayloadBellatrix implements ExecutionPayload {

@JsonProperty("withdrawals")
@ArraySchema(schema = @Schema(type = "string", format = "byte"))
public final List<Bytes> withdrawals;
public final List<Withdrawal> withdrawals;

@JsonCreator
public ExecutionPayloadCapella(
Expand All @@ -55,7 +56,7 @@ public ExecutionPayloadCapella(
@JsonProperty("base_fee_per_gas") UInt256 baseFeePerGas,
@JsonProperty("block_hash") Bytes32 blockHash,
@JsonProperty("transactions") List<Bytes> transactions,
@JsonProperty("withdrawals") List<Bytes> withdrawals) {
@JsonProperty("withdrawals") List<Withdrawal> withdrawals) {
super(
parentHash,
feeRecipient,
Expand All @@ -79,8 +80,8 @@ public ExecutionPayloadCapella(
super(executionPayload);
this.withdrawals =
executionPayload.getOptionalWithdrawals().orElseThrow().stream()
.map(Withdrawal::sszSerialize)
.collect(Collectors.toList());
.map(Withdrawal::new)
.collect(toList());
}

@Override
Expand All @@ -97,9 +98,11 @@ public ExecutionPayloadCapella(
}

return maybeSchema.map(
schema ->
schema
.getExecutionPayloadSchemaCapella()
schemaDefinitionsCapella ->
schemaDefinitionsCapella
.getExecutionPayloadSchema()
.toVersionCapella()
.orElseThrow()
.create(
parentHash,
feeRecipient,
Expand All @@ -115,7 +118,12 @@ public ExecutionPayloadCapella(
baseFeePerGas,
blockHash,
transactions,
withdrawals));
withdrawals.stream()
.map(
withdrawal ->
withdrawal.asInternalWithdrawal(
schemaDefinitionsCapella.getWithdrawalSchema()))
.collect(toList())));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.api.schema.capella;

import com.fasterxml.jackson.annotation.JsonProperty;
import tech.pegasys.teku.ethereum.execution.types.Eth1Address;
import tech.pegasys.teku.infrastructure.bytes.Bytes20;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.datastructures.execution.versions.capella.WithdrawalSchema;

public class Withdrawal {

@JsonProperty("index")
private final UInt64 index;

@JsonProperty("validator_index")
private final UInt64 validatorIndex;

@JsonProperty("address")
private final Eth1Address address;

@JsonProperty("amount")
private final UInt64 amount;

public Withdrawal(
@JsonProperty("index") final UInt64 index,
@JsonProperty("validator_index") final UInt64 validatorIndex,
@JsonProperty("address") final Eth1Address address,
@JsonProperty("amount") final UInt64 amount) {
this.index = index;
this.validatorIndex = validatorIndex;
this.address = address;
this.amount = amount;
}

public Withdrawal(
final tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal
withdrawal) {
this.index = withdrawal.getIndex();
this.validatorIndex = withdrawal.getValidatorIndex();
this.address = Eth1Address.fromBytes(withdrawal.getAddress().getWrappedBytes());
this.amount = withdrawal.getAmount();
}

public tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal
asInternalWithdrawal(final WithdrawalSchema schema) {
return schema.create(index, validatorIndex, new Bytes20(address.getWrappedBytes()), amount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBid;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.builder.versions.bellatrix.SignedBuilderBidBellatrix;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload;
import tech.pegasys.teku.spec.datastructures.execution.versions.bellatrix.ExecutionPayloadBellatrix;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix;

Expand Down Expand Up @@ -371,10 +369,9 @@ private SszList<SignedValidatorRegistration> createSignedValidatorRegistrations(
}

private void verifySignedBuilderBidResponse(SignedBuilderBid actual) {
DeserializableTypeDefinition<BuilderApiResponse<SignedBuilderBidBellatrix>>
responseTypeDefinition =
BuilderApiResponse.createTypeDefinition(
schemaDefinitionsBellatrix.getSignedBuilderBidSchema().getJsonTypeDefinition());
DeserializableTypeDefinition<BuilderApiResponse<SignedBuilderBid>> responseTypeDefinition =
BuilderApiResponse.createTypeDefinition(
schemaDefinitionsBellatrix.getSignedBuilderBidSchema().getJsonTypeDefinition());
try {
SignedBuilderBid expected =
JsonUtil.parse(EXECUTION_PAYLOAD_HEADER_RESPONSE, responseTypeDefinition).getData();
Expand All @@ -395,7 +392,7 @@ private SignedBeaconBlock createSignedBlindedBeaconBlock() {
}

private void verifyExecutionPayloadResponse(ExecutionPayload actual) {
DeserializableTypeDefinition<BuilderApiResponse<ExecutionPayloadBellatrix>>
DeserializableTypeDefinition<? extends BuilderApiResponse<? extends ExecutionPayload>>
responseTypeDefinition =
BuilderApiResponse.createTypeDefinition(
schemaDefinitionsBellatrix.getExecutionPayloadSchema().getJsonTypeDefinition());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,22 @@
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBid;
import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBidSchema;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.builder.versions.bellatrix.SignedBuilderBidBellatrix;
import tech.pegasys.teku.spec.datastructures.builder.versions.bellatrix.SignedBuilderBidSchemaBellatrix;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload;
import tech.pegasys.teku.spec.datastructures.execution.versions.bellatrix.ExecutionPayloadBellatrix;
import tech.pegasys.teku.spec.datastructures.execution.versions.bellatrix.ExecutionPayloadSchemaBellatrix;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSchema;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionCache;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix;

public class RestBuilderClient implements BuilderClient {

private final Map<
SpecMilestone,
DeserializableTypeDefinition<BuilderApiResponse<ExecutionPayloadBellatrix>>>
DeserializableTypeDefinition<? extends BuilderApiResponse<? extends ExecutionPayload>>>
cachedBuilderApiExecutionPayloadResponseType = new ConcurrentHashMap<>();

private final Map<
SpecMilestone,
DeserializableTypeDefinition<BuilderApiResponse<SignedBuilderBidBellatrix>>>
SpecMilestone, DeserializableTypeDefinition<BuilderApiResponse<SignedBuilderBid>>>
cachedBuilderApiSignedBuilderBidResponseType = new ConcurrentHashMap<>();

private final RestClient restClient;
Expand Down Expand Up @@ -102,14 +99,14 @@ public SafeFuture<Response<Optional<SignedBuilderBid>>> getHeader(

final SpecMilestone milestone = schemaDefinitionCache.milestoneAtSlot(slot);

final DeserializableTypeDefinition<BuilderApiResponse<SignedBuilderBidBellatrix>>
final DeserializableTypeDefinition<BuilderApiResponse<SignedBuilderBid>>
responseTypeDefinition =
cachedBuilderApiSignedBuilderBidResponseType.computeIfAbsent(
milestone,
__ -> {
final SchemaDefinitionsBellatrix schemaDefinitionsBellatrix =
getSchemaDefinitionsBellatrix(milestone);
final SignedBuilderBidSchemaBellatrix signedBuilderBidSchema =
final SignedBuilderBidSchema signedBuilderBidSchema =
schemaDefinitionsBellatrix.getSignedBuilderBidSchema();
return BuilderApiResponse.createTypeDefinition(
signedBuilderBidSchema.getJsonTypeDefinition());
Expand Down Expand Up @@ -137,16 +134,12 @@ public SafeFuture<Response<ExecutionPayload>> getPayload(
final DeserializableTypeDefinition<SignedBeaconBlock> requestTypeDefinition =
schemaDefinitionsBellatrix.getSignedBlindedBeaconBlockSchema().getJsonTypeDefinition();

final DeserializableTypeDefinition<BuilderApiResponse<ExecutionPayloadBellatrix>>
final DeserializableTypeDefinition<? extends BuilderApiResponse<? extends ExecutionPayload>>
responseTypeDefinition =
cachedBuilderApiExecutionPayloadResponseType.computeIfAbsent(
milestone,
__ -> {
final ExecutionPayloadSchemaBellatrix executionPayloadSchema =
schemaDefinitionsBellatrix.getExecutionPayloadSchema();
return BuilderApiResponse.createTypeDefinition(
executionPayloadSchema.getJsonTypeDefinition());
});
__ ->
payloadTypeDefinition(schemaDefinitionsBellatrix.getExecutionPayloadSchema()));

return restClient
.postAsync(
Expand All @@ -158,6 +151,13 @@ public SafeFuture<Response<ExecutionPayload>> getPayload(
.orTimeout(BUILDER_GET_PAYLOAD_TIMEOUT);
}

private <T extends ExecutionPayload>
DeserializableTypeDefinition<BuilderApiResponse<T>> payloadTypeDefinition(
final ExecutionPayloadSchema<T> schema) {
final DeserializableTypeDefinition<T> typeDefinition = schema.getJsonTypeDefinition();
return BuilderApiResponse.createTypeDefinition(typeDefinition);
}

private <T extends SignedBuilderBid> SignedBuilderBid extractSignedBuilderBid(
final BuilderApiResponse<T> builderApiResponse) {
return builderApiResponse.getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.SpecVersion;
import tech.pegasys.teku.spec.TestSpecFactory;
import tech.pegasys.teku.spec.datastructures.builder.BuilderBid;
import tech.pegasys.teku.spec.datastructures.builder.SignedBuilderBid;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.builder.versions.bellatrix.BuilderBidBellatrix;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadHeader;
import tech.pegasys.teku.spec.datastructures.execution.versions.bellatrix.ExecutionPayloadHeaderBellatrix;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
Expand Down Expand Up @@ -170,8 +170,7 @@ void shouldLogEventIfGasLimitDoesNotIncrease() throws BuilderBidValidationExcept

private void prepareValidSignedBuilderBid() {
final BLSKeyPair keyPair = BLSTestUtil.randomKeyPair(1);
final BuilderBidBellatrix builderBid =
dataStructureUtil.randomBuilderBid(keyPair.getPublicKey());
final BuilderBid builderBid = dataStructureUtil.randomBuilderBid(keyPair.getPublicKey());

final Bytes signingRoot =
spec.computeBuilderApplicationSigningRoot(state.getSlot(), builderBid);
Expand Down Expand Up @@ -236,6 +235,8 @@ private ExecutionPayloadHeaderBellatrix createExecutionPayloadHeaderWithGasLimit
SchemaDefinitionsBellatrix schemaDefinitions, UInt64 gasLimit) {
return schemaDefinitions
.getExecutionPayloadHeaderSchema()
.toVersionBellatrix()
.orElseThrow()
.create(
Bytes32.random(),
Bytes20.ZERO,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ private BlindedBeaconBlockBodySchemaBellatrixImpl(
public static BlindedBeaconBlockBodySchemaBellatrixImpl create(
final SpecConfigBellatrix specConfig,
final AttesterSlashingSchema attesterSlashingSchema,
final String containerName) {
final String containerName,
final ExecutionPayloadHeaderSchemaBellatrix executionPayloadHeaderSchema) {
return new BlindedBeaconBlockBodySchemaBellatrixImpl(
containerName,
namedSchema(BlockBodyFields.RANDAO_REVEAL, SszSignatureSchema.INSTANCE),
Expand All @@ -113,9 +114,7 @@ public static BlindedBeaconBlockBodySchemaBellatrixImpl create(
namedSchema(
BlockBodyFields.SYNC_AGGREGATE,
SyncAggregateSchema.create(specConfig.getSyncCommitteeSize())),
namedSchema(
BlockBodyFields.EXECUTION_PAYLOAD_HEADER,
new ExecutionPayloadHeaderSchemaBellatrix(specConfig)));
namedSchema(BlockBodyFields.EXECUTION_PAYLOAD_HEADER, executionPayloadHeaderSchema));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import tech.pegasys.teku.infrastructure.ssz.SszList;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.bellatrix.BeaconBlockBodyBellatrix;
import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadCapella;
import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange;

public interface BeaconBlockBodyCapella extends BeaconBlockBodyBellatrix {
Expand All @@ -33,6 +34,9 @@ static BeaconBlockBodyCapella required(final BeaconBlockBody body) {
@Override
BeaconBlockBodySchemaCapella<?> getSchema();

@Override
ExecutionPayloadCapella getExecutionPayload();

@Override
default Optional<BeaconBlockBodyCapella> toVersionCapella() {
return Optional.of(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode;
import tech.pegasys.teku.spec.datastructures.blocks.Eth1Data;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload;
import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadCapella;
import tech.pegasys.teku.spec.datastructures.execution.versions.capella.ExecutionPayloadCapellaImpl;
import tech.pegasys.teku.spec.datastructures.operations.Attestation;
import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing;
Expand Down Expand Up @@ -140,7 +140,7 @@ public SyncAggregate getSyncAggregate() {
}

@Override
public ExecutionPayload getExecutionPayload() {
public ExecutionPayloadCapella getExecutionPayload() {
return getField9();
}

Expand Down
Loading

0 comments on commit 5d7a987

Please sign in to comment.