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

[PROTOTYPE] epbs-eip7732 #8497

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
24ca064
epbs-eip7732 boilerplate begin
tbenr Aug 2, 2024
a378731
Config/presets boilerplate
StefanBratanov Aug 12, 2024
7816cd2
Add new containers
StefanBratanov Aug 13, 2024
9d8798d
More new containers
StefanBratanov Aug 14, 2024
ffdf9f6
Mostly modified containers
StefanBratanov Aug 14, 2024
4aebb5a
small hack
StefanBratanov Aug 14, 2024
06fdf37
Last part of modified containers
StefanBratanov Aug 14, 2024
457e75d
fix assemble
StefanBratanov Aug 14, 2024
dbd76c0
fix extension
StefanBratanov Aug 14, 2024
cf41e3a
Helper functions draft
StefanBratanov Aug 15, 2024
6238c48
Implement the signature verification
StefanBratanov Aug 15, 2024
1c835d1
Modified verify_blob_sidecar_inclusion_proof
StefanBratanov Aug 19, 2024
7f4d480
gossip fork subscriptions for eip-7732
StefanBratanov Aug 19, 2024
c915b2e
add gossip managers
StefanBratanov Aug 20, 2024
3ec994d
new P2P req/resp
StefanBratanov Aug 20, 2024
1a2ee29
add MAX_REQUEST_PAYLOADS to constants
StefanBratanov Aug 20, 2024
d55c590
Add block processing
StefanBratanov Aug 27, 2024
8f71dfb
support task expiration in RepeatingTaskScheduler
tbenr Aug 27, 2024
c95741b
Modified is_merge_transition_complete
StefanBratanov Aug 28, 2024
aae2712
fix beaconstate schemas
tbenr Aug 28, 2024
9aa0d9b
Implement execution payload processing
StefanBratanov Aug 28, 2024
04fba6a
slot anatomy change: event rescheduling and related changes
tbenr Aug 28, 2024
867b382
Add ExecutionPayloadHeaderValidator
StefanBratanov Aug 30, 2024
6ca9ca1
Add Payload Attestation Duty in VC
tbenr Aug 30, 2024
962da74
Add PayloadAttestationData local signing
tbenr Sep 2, 2024
428472d
Add PayloadAttestationManager and ExecutionPayloadManager
StefanBratanov Sep 2, 2024
daccee1
Remove Slot from payloadAttestation signing.
tbenr Sep 2, 2024
b35a992
PayloadAttestationPool and ExecutionPayloadHeaderPool
StefanBratanov Sep 3, 2024
a2751cd
use bit vector for payload attestation aggregation bits
mehdi-aouadi Sep 3, 2024
fc0ccf1
Add PayloadTimeliness calculation and PayloadAttestationData creation
tbenr Sep 3, 2024
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 @@ -145,6 +145,11 @@ public boolean isRunning() {
return false;
}

@Override
public void onBlockSeen(final SignedBeaconBlock block) {
// No-op
}

@Override
public void onBlockValidated(final SignedBeaconBlock block) {
// No-op
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ public void processFetchedResult(final FetchBlockTask task, final SignedBeaconBl
removeTask(task);
}

@Override
public void onBlockSeen(final SignedBeaconBlock block) {}

@Override
public void onBlockValidated(final SignedBeaconBlock block) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@
import tech.pegasys.teku.spec.datastructures.state.Checkpoint;
import tech.pegasys.teku.statetransition.attestation.AggregatingAttestationPool;
import tech.pegasys.teku.statetransition.attestation.AttestationManager;
import tech.pegasys.teku.statetransition.attestation.PayloadAttestationManager;
import tech.pegasys.teku.statetransition.blobs.BlockBlobSidecarsTrackersPool;
import tech.pegasys.teku.statetransition.block.BlockImportChannel;
import tech.pegasys.teku.statetransition.block.ReceivedBlockEventsChannel;
import tech.pegasys.teku.statetransition.forkchoice.ForkChoiceTrigger;
import tech.pegasys.teku.statetransition.forkchoice.ProposersDataManager;
import tech.pegasys.teku.statetransition.synccommittee.SyncCommitteeContributionPool;
Expand All @@ -74,6 +76,8 @@ public class ValidatorApiHandlerIntegrationTest {
private final BlockFactory blockFactory = mock(BlockFactory.class);
private final AggregatingAttestationPool attestationPool = mock(AggregatingAttestationPool.class);
private final AttestationManager attestationManager = mock(AttestationManager.class);
private final PayloadAttestationManager payloadAttestationManager =
mock(PayloadAttestationManager.class);
private final AttestationTopicSubscriber attestationTopicSubscriber =
mock(AttestationTopicSubscriber.class);
private final ActiveValidatorTracker activeValidatorTracker = mock(ActiveValidatorTracker.class);
Expand Down Expand Up @@ -114,6 +118,7 @@ public class ValidatorApiHandlerIntegrationTest {
blobSidecarGossipChannel,
attestationPool,
attestationManager,
payloadAttestationManager,
attestationTopicSubscriber,
activeValidatorTracker,
dutyMetrics,
Expand All @@ -125,7 +130,8 @@ public class ValidatorApiHandlerIntegrationTest {
syncCommitteeContributionPool,
syncCommitteeSubscriptionManager,
new BlockProductionAndPublishingPerformanceFactory(
new SystemTimeProvider(), __ -> UInt64.ZERO, true, 0, 0, 0, 0));
new SystemTimeProvider(), __ -> UInt64.ZERO, true, 0, 0, 0, 0),
ReceivedBlockEventsChannel.NOOP);

@BeforeEach
public void setup() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import tech.pegasys.teku.ethereum.json.types.node.PeerCount;
import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuties;
import tech.pegasys.teku.ethereum.json.types.validator.BeaconCommitteeSelectionProof;
import tech.pegasys.teku.ethereum.json.types.validator.PayloadAttesterDuties;
import tech.pegasys.teku.ethereum.json.types.validator.ProposerDuties;
import tech.pegasys.teku.ethereum.json.types.validator.ProposerDuty;
import tech.pegasys.teku.ethereum.json.types.validator.SyncCommitteeDuties;
Expand All @@ -77,10 +78,12 @@
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.execution.PayloadAttestationData;
import tech.pegasys.teku.spec.datastructures.genesis.GenesisData;
import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData;
import tech.pegasys.teku.spec.datastructures.operations.Attestation;
import tech.pegasys.teku.spec.datastructures.operations.AttestationData;
import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestationMessage;
import tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof;
import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof;
import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeContribution;
Expand All @@ -93,8 +96,10 @@
import tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil;
import tech.pegasys.teku.statetransition.attestation.AggregatingAttestationPool;
import tech.pegasys.teku.statetransition.attestation.AttestationManager;
import tech.pegasys.teku.statetransition.attestation.PayloadAttestationManager;
import tech.pegasys.teku.statetransition.blobs.BlockBlobSidecarsTrackersPool;
import tech.pegasys.teku.statetransition.block.BlockImportChannel;
import tech.pegasys.teku.statetransition.block.ReceivedBlockEventsChannel;
import tech.pegasys.teku.statetransition.forkchoice.ForkChoiceTrigger;
import tech.pegasys.teku.statetransition.forkchoice.ProposersDataManager;
import tech.pegasys.teku.statetransition.synccommittee.SyncCommitteeContributionPool;
Expand Down Expand Up @@ -135,6 +140,7 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
private final BlockFactory blockFactory;
private final AggregatingAttestationPool attestationPool;
private final AttestationManager attestationManager;
private final PayloadAttestationManager payloadAttestationManager;
private final AttestationTopicSubscriber attestationTopicSubscriber;
private final ActiveValidatorTracker activeValidatorTracker;
private final DutyMetrics dutyMetrics;
Expand All @@ -145,8 +151,8 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
private final SyncCommitteeSubscriptionManager syncCommitteeSubscriptionManager;
private final SyncCommitteeContributionPool syncCommitteeContributionPool;
private final ProposersDataManager proposersDataManager;
private final ReceivedBlockEventsChannel receivedBlockEventsChannel;
private final BlockPublisher blockPublisher;

private final AttesterDutiesGenerator attesterDutiesGenerator;

public ValidatorApiHandler(
Expand All @@ -162,6 +168,7 @@ public ValidatorApiHandler(
final BlobSidecarGossipChannel blobSidecarGossipChannel,
final AggregatingAttestationPool attestationPool,
final AttestationManager attestationManager,
final PayloadAttestationManager payloadAttestationManager,
final AttestationTopicSubscriber attestationTopicSubscriber,
final ActiveValidatorTracker activeValidatorTracker,
final DutyMetrics dutyMetrics,
Expand All @@ -173,7 +180,8 @@ public ValidatorApiHandler(
final SyncCommitteeContributionPool syncCommitteeContributionPool,
final SyncCommitteeSubscriptionManager syncCommitteeSubscriptionManager,
final BlockProductionAndPublishingPerformanceFactory
blockProductionAndPublishingPerformanceFactory) {
blockProductionAndPublishingPerformanceFactory,
final ReceivedBlockEventsChannel receivedBlockEventsChannel) {
this.blockProductionAndPublishingPerformanceFactory =
blockProductionAndPublishingPerformanceFactory;
this.chainDataProvider = chainDataProvider;
Expand All @@ -184,6 +192,7 @@ public ValidatorApiHandler(
this.blockFactory = blockFactory;
this.attestationPool = attestationPool;
this.attestationManager = attestationManager;
this.payloadAttestationManager = payloadAttestationManager;
this.attestationTopicSubscriber = attestationTopicSubscriber;
this.activeValidatorTracker = activeValidatorTracker;
this.dutyMetrics = dutyMetrics;
Expand All @@ -194,6 +203,7 @@ public ValidatorApiHandler(
this.syncCommitteeContributionPool = syncCommitteeContributionPool;
this.syncCommitteeSubscriptionManager = syncCommitteeSubscriptionManager;
this.proposersDataManager = proposersDataManager;
this.receivedBlockEventsChannel = receivedBlockEventsChannel;
this.blockPublisher =
new MilestoneBasedBlockPublisher(
spec,
Expand Down Expand Up @@ -268,6 +278,41 @@ public SafeFuture<Optional<AttesterDuties>> getAttestationDuties(
combinedChainDataClient.isChainHeadOptimistic())));
}

@Override
public SafeFuture<Optional<PayloadAttesterDuties>> getPayloadAttestationDuties(
final UInt64 epoch, final IntCollection validatorIndices) {
if (isSyncActive()) {
return NodeSyncingException.failedFuture();
}
if (epoch.isGreaterThan(
combinedChainDataClient
.getCurrentEpoch()
.plus(spec.getSpecConfig(epoch).getMinSeedLookahead() + DUTY_EPOCH_TOLERANCE))) {
return SafeFuture.failedFuture(
new IllegalArgumentException(
String.format(
"Payload attestation duties were requested %s epochs ahead, only 1 epoch in future is supported.",
epoch.minus(combinedChainDataClient.getCurrentEpoch()).toString())));
}
// what state can we use? If the current or next epoch, we can use the best state,
// which would guarantee no state regeneration
final UInt64 slot = spec.getEarliestQueryableSlotForBeaconCommitteeInTargetEpoch(epoch);

LOG.trace(
"Retrieving payload attestation duties from epoch {} using state at slot {}", epoch, slot);
return combinedChainDataClient
.getStateAtSlotExact(slot)
.thenApply(
optionalState ->
optionalState.map(
state ->
attesterDutiesGenerator.getPayloadAttesterDutiesFromIndicesAndState(
state,
epoch,
validatorIndices,
combinedChainDataClient.isChainHeadOptimistic())));
}

@Override
public SafeFuture<Optional<SyncCommitteeDuties>> getSyncCommitteeDuties(
final UInt64 epoch, final IntCollection validatorIndices) {
Expand Down Expand Up @@ -477,6 +522,61 @@ public SafeFuture<Optional<AttestationData>> createAttestationData(
}
}

@Override
public SafeFuture<Optional<PayloadAttestationData>> createPayloadAttestationData(
final UInt64 slot) {
if (isSyncActive()) {
return NodeSyncingException.failedFuture();
}

return combinedChainDataClient
.getTimelyExecutionPayload(slot)
.thenApply(
executionPayloadEnvelope ->
executionPayloadEnvelope.map(
payloadStatusAndBeaconBlockRoot ->
PayloadAttestationData.SSZ_SCHEMA.create(
payloadStatusAndBeaconBlockRoot.beaconBlockRoot(),
slot,
payloadStatusAndBeaconBlockRoot.payloadStatus().getCode())));
}

@Override
public SafeFuture<List<SubmitDataError>> sendSignedPayloadAttestations(
final List<PayloadAttestationMessage> attestations) {
return SafeFuture.collectAll(attestations.stream().map(this::processPayloadAttestation))
.thenApply(this::convertAttestationProcessingResultsToErrorList);
}

private SafeFuture<InternalValidationResult> processPayloadAttestation(
final PayloadAttestationMessage attestation) {
return payloadAttestationManager
.addPayloadAttestation(attestation, Optional.empty())
.thenPeek(
result -> {
if (!result.isReject()) {
// TODO update dutyMetrics and performanceTracker
} else {
VALIDATOR_LOGGER.producedInvalidPayloadAttestation(
attestation.getData().getSlot(),
result.getDescription().orElse("Unknown reason"));
}
})
.exceptionally(
error -> {
LOG.error(
"Failed to send signed payload attestation for slot {}, block {}",
attestation.getData().getSlot(),
attestation.getData().getBeaconBlockRoot(),
error);
return InternalValidationResult.reject(
"Failed to send signed payload attestation for slot %s, block %s: %s",
attestation.getData().getSlot(),
attestation.getData().getBeaconBlockRoot(),
getMessageOrSimpleName(error));
});
}

private AttestationData createAttestationData(
final BeaconBlock block,
final BeaconState state,
Expand Down Expand Up @@ -653,6 +753,7 @@ private SafeFuture<InternalValidationResult> processAggregateAndProof(
public SafeFuture<SendSignedBlockResult> sendSignedBlock(
final SignedBlockContainer maybeBlindedBlockContainer,
final BroadcastValidationLevel broadcastValidationLevel) {
receivedBlockEventsChannel.onBlockSeen(maybeBlindedBlockContainer.getSignedBlock());
final BlockPublishingPerformance blockPublishingPerformance =
blockProductionAndPublishingPerformanceFactory.createForPublishing(
maybeBlindedBlockContainer.getSlot());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

package tech.pegasys.teku.validator.coordinator.duties;

import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.IntCollection;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -21,6 +22,8 @@
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuties;
import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuty;
import tech.pegasys.teku.ethereum.json.types.validator.PayloadAttesterDuties;
import tech.pegasys.teku.ethereum.json.types.validator.PayloadAttesterDuty;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.datastructures.state.CommitteeAssignment;
Expand All @@ -47,6 +50,20 @@ public AttesterDuties getAttesterDutiesFromIndicesAndState(
return new AttesterDuties(isChainHeadOptimistic, dependentRoot, duties);
}

public PayloadAttesterDuties getPayloadAttesterDutiesFromIndicesAndState(
final BeaconState state,
final UInt64 epoch,
final IntCollection validatorIndices,
final boolean isChainHeadOptimistic) {
final Bytes32 dependentRoot =
epoch.isGreaterThan(spec.getCurrentEpoch(state))
? spec.atEpoch(epoch).getBeaconStateUtil().getCurrentDutyDependentRoot(state)
: spec.atEpoch(epoch).getBeaconStateUtil().getPreviousDutyDependentRoot(state);
final List<PayloadAttesterDuty> duties =
createPayloadAttesterDuties(state, epoch, validatorIndices);
return new PayloadAttesterDuties(isChainHeadOptimistic, dependentRoot, duties);
}

private List<AttesterDuty> createAttesterDuties(
final BeaconState state, final UInt64 epoch, final IntCollection validatorIndices) {
final List<Optional<AttesterDuty>> maybeAttesterDutyList = new ArrayList<>();
Expand Down Expand Up @@ -84,4 +101,26 @@ private Optional<AttesterDuty> attesterDutyFromCommitteeAssignment(
committeeAssignment.getCommittee().indexOf(validatorIndex),
committeeAssignment.getSlot()));
}

private List<PayloadAttesterDuty> createPayloadAttesterDuties(
final BeaconState state, final UInt64 epoch, final IntCollection validatorIndices) {
final List<PayloadAttesterDuty> payloadAttesterDutyList = new ArrayList<>();

final Int2ObjectMap<UInt64> validatorIndexToCommitteeAssignmentMap =
spec.getValidatorIndexToPctAssignmentMap(state, epoch);
for (final int validatorIndex : validatorIndices) {
final UInt64 slot = validatorIndexToCommitteeAssignmentMap.get(validatorIndex);
if (slot != null) {
payloadAttesterDutyFromCommitteeAssignment(slot, validatorIndex, state)
.ifPresent(payloadAttesterDutyList::add);
}
}
return payloadAttesterDutyList;
}

private Optional<PayloadAttesterDuty> payloadAttesterDutyFromCommitteeAssignment(
final UInt64 slot, final int validatorIndex, final BeaconState state) {
return spec.getValidatorPubKey(state, UInt64.valueOf(validatorIndex))
.map(publicKey -> new PayloadAttesterDuty(publicKey, validatorIndex, slot));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@
import tech.pegasys.teku.spec.datastructures.execution.FallbackData;
import tech.pegasys.teku.spec.datastructures.execution.FallbackReason;
import tech.pegasys.teku.spec.datastructures.execution.GetPayloadResponse;
import tech.pegasys.teku.spec.datastructures.execution.SignedExecutionPayloadHeader;
import tech.pegasys.teku.spec.datastructures.operations.Attestation;
import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing;
import tech.pegasys.teku.spec.datastructures.operations.Deposit;
import tech.pegasys.teku.spec.datastructures.operations.PayloadAttestation;
import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing;
import tech.pegasys.teku.spec.datastructures.operations.SignedBlsToExecutionChange;
import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit;
Expand Down Expand Up @@ -1296,6 +1298,18 @@ public BeaconBlockBodyBuilder blobKzgCommitments(
return this;
}

@Override
public BeaconBlockBodyBuilder signedExecutionPayloadHeader(
final SignedExecutionPayloadHeader signedExecutionPayloadHeader) {
return this;
}

@Override
public BeaconBlockBodyBuilder payloadAttestations(
final SszList<PayloadAttestation> payloadAttestations) {
return this;
}

@Override
public BeaconBlockBody build() {
return null;
Expand Down
Loading