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

Add executionRequestHash to NewPayloadRequest as part of block validation flow #8700

Merged
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 @@ -30,6 +30,7 @@
import tech.pegasys.teku.bls.BLSSignature;
import tech.pegasys.teku.ethereum.execution.types.Eth1Address;
import tech.pegasys.teku.infrastructure.bytes.Bytes20;
import tech.pegasys.teku.infrastructure.ssz.SszList;
import tech.pegasys.teku.infrastructure.ssz.SszMutableList;
import tech.pegasys.teku.infrastructure.ssz.collections.SszBitlist;
import tech.pegasys.teku.infrastructure.ssz.primitive.SszByte;
Expand All @@ -41,11 +42,14 @@
import tech.pegasys.teku.spec.config.SpecConfigElectra;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyElectra;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload;
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary;
import tech.pegasys.teku.spec.datastructures.execution.ExpectedWithdrawals;
import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ConsolidationRequest;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequest;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.WithdrawalRequest;
import tech.pegasys.teku.spec.datastructures.operations.Attestation;
import tech.pegasys.teku.spec.datastructures.operations.Deposit;
Expand All @@ -56,6 +60,7 @@
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra;
import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation;
import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingDeposit;
import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment;
import tech.pegasys.teku.spec.datastructures.type.SszPublicKey;
import tech.pegasys.teku.spec.datastructures.type.SszSignature;
import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators.ValidatorExitContext;
Expand All @@ -70,6 +75,7 @@
import tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil;
import tech.pegasys.teku.spec.logic.common.util.ValidatorsUtil;
import tech.pegasys.teku.spec.logic.versions.deneb.block.BlockProcessorDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash;
import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateAccessorsElectra;
import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateMutatorsElectra;
import tech.pegasys.teku.spec.logic.versions.electra.helpers.MiscHelpersElectra;
Expand All @@ -85,6 +91,7 @@ public class BlockProcessorElectra extends BlockProcessorDeneb {
private final BeaconStateMutatorsElectra beaconStateMutatorsElectra;
private final BeaconStateAccessorsElectra beaconStateAccessorsElectra;
private final SchemaDefinitionsElectra schemaDefinitionsElectra;
private final ExecutionRequestsDataCodec executionRequestsDataCodec;

public BlockProcessorElectra(
final SpecConfigElectra specConfig,
Expand Down Expand Up @@ -117,6 +124,29 @@ public BlockProcessorElectra(
this.beaconStateMutatorsElectra = beaconStateMutators;
this.beaconStateAccessorsElectra = beaconStateAccessors;
this.schemaDefinitionsElectra = schemaDefinitions;
this.executionRequestsDataCodec =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer adding this initialization in SpecLogicElectra for consistency.

new ExecutionRequestsDataCodec(schemaDefinitions.getExecutionRequestsSchema());
}

@Override
public NewPayloadRequest computeNewPayloadRequest(
final BeaconState state, final BeaconBlockBody beaconBlockBody)
throws BlockProcessingException {
final ExecutionPayload executionPayload = extractExecutionPayload(beaconBlockBody);
final SszList<SszKZGCommitment> blobKzgCommitments = extractBlobKzgCommitments(beaconBlockBody);
final List<VersionedHash> versionedHashes =
blobKzgCommitments.stream()
.map(SszKZGCommitment::getKZGCommitment)
.map(miscHelpers::kzgCommitmentToVersionedHash)
.toList();
final Bytes32 parentBeaconBlockRoot = state.getLatestBlockHeader().getParentRoot();
final ExecutionRequests executionRequests =
BeaconBlockBodyElectra.required(beaconBlockBody).getExecutionRequests();
return new NewPayloadRequest(
executionPayload,
versionedHashes,
parentBeaconBlockRoot,
executionRequestsDataCodec.hash(executionRequests));
}

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

import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.jupiter.api.Test;
Expand All @@ -28,22 +29,31 @@
import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.TestSpecFactory;
import tech.pegasys.teku.spec.config.SpecConfigDeneb;
import tech.pegasys.teku.spec.config.SpecConfigElectra;
import tech.pegasys.teku.spec.datastructures.blocks.Eth1Data;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody;
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.electra.BeaconBlockBodyElectra;
import tech.pegasys.teku.spec.datastructures.execution.NewPayloadRequest;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.DepositRequest;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequestsDataCodec;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.WithdrawalRequest;
import tech.pegasys.teku.spec.datastructures.operations.DepositData;
import tech.pegasys.teku.spec.datastructures.state.Validator;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra;
import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal;
import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment;
import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators.ValidatorExitContext;
import tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers;
import tech.pegasys.teku.spec.logic.common.statetransition.exceptions.BlockProcessingException;
import tech.pegasys.teku.spec.logic.versions.deneb.block.BlockProcessorDenebTest;
import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash;
import tech.pegasys.teku.spec.logic.versions.electra.util.AttestationUtilElectra;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra;

class BlockProcessorElectraTest extends BlockProcessorDenebTest {

Expand Down Expand Up @@ -524,11 +534,52 @@ void shouldUseElectraAttestationUtil() {
.isInstanceOf(AttestationUtilElectra.class);
}

@Test
public void shouldCreateNewPayloadRequestWithExecutionRequestsHash() throws Exception {
final BeaconState preState = createBeaconState();
final BeaconBlockBodyElectra blockBody =
BeaconBlockBodyElectra.required(dataStructureUtil.randomBeaconBlockBodyWithCommitments(3));
final MiscHelpers miscHelpers = spec.atSlot(UInt64.ONE).miscHelpers();
final List<VersionedHash> expectedVersionedHashes =
blockBody.getOptionalBlobKzgCommitments().orElseThrow().stream()
.map(SszKZGCommitment::getKZGCommitment)
.map(miscHelpers::kzgCommitmentToVersionedHash)
.collect(Collectors.toList());
final Bytes32 expectedExecutionRequestsHash =
getExecutionRequestsDataCodec().hash(blockBody.getExecutionRequests());

final NewPayloadRequest newPayloadRequest =
spec.getBlockProcessor(UInt64.ONE).computeNewPayloadRequest(preState, blockBody);

assertThat(newPayloadRequest.getExecutionPayload())
.isEqualTo(blockBody.getOptionalExecutionPayload().orElseThrow());
assertThat(newPayloadRequest.getVersionedHashes()).isPresent();
assertThat(newPayloadRequest.getVersionedHashes().get())
.hasSize(3)
.allSatisfy(
versionedHash ->
assertThat(versionedHash.getVersion())
.isEqualTo(SpecConfigDeneb.VERSIONED_HASH_VERSION_KZG))
.hasSameElementsAs(expectedVersionedHashes);
assertThat(newPayloadRequest.getParentBeaconBlockRoot()).isPresent();
assertThat(newPayloadRequest.getParentBeaconBlockRoot().get())
.isEqualTo(preState.getLatestBlockHeader().getParentRoot());
assertThat(newPayloadRequest.getExecutionRequestsHash())
.hasValue(expectedExecutionRequestsHash);
}

private Supplier<ValidatorExitContext> validatorExitContextSupplier(final BeaconState state) {
return spec.getGenesisSpec().beaconStateMutators().createValidatorExitContextSupplier(state);
}

private BlockProcessorElectra getBlockProcessor(final BeaconState state) {
return (BlockProcessorElectra) spec.getBlockProcessor(state.getSlot());
}

private ExecutionRequestsDataCodec getExecutionRequestsDataCodec() {
return new ExecutionRequestsDataCodec(
SchemaDefinitionsElectra.required(
spec.forMilestone(SpecMilestone.ELECTRA).getSchemaDefinitions())
.getExecutionRequestsSchema());
}
}