use of tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil in project teku by ConsenSys.
the class ValidatorApiHandlerTest method getSyncCommitteeDuties_shouldFailForEpochTooFarAhead.
@Test
void getSyncCommitteeDuties_shouldFailForEpochTooFarAhead() {
final BeaconState state = dataStructureUtil.stateBuilderAltair().slot(EPOCH_START_SLOT).build();
when(chainDataClient.getCurrentEpoch()).thenReturn(EPOCH);
when(chainDataClient.getBestState()).thenReturn(Optional.of(SafeFuture.completedFuture(state)));
final int epochsPerSyncCommitteePeriod = SpecConfigAltair.required(spec.getSpecConfig(EPOCH)).getEpochsPerSyncCommitteePeriod();
final SyncCommitteeUtil syncCommitteeUtil = spec.getSyncCommitteeUtilRequired(EPOCH_START_SLOT);
final UInt64 firstSlotAfterNextSyncCommitteePeriod = syncCommitteeUtil.computeFirstEpochOfCurrentSyncCommitteePeriod(EPOCH).plus(epochsPerSyncCommitteePeriod * 2L);
assertThatSafeFuture(validatorApiHandler.getSyncCommitteeDuties(firstSlotAfterNextSyncCommitteePeriod, IntList.of(1))).isCompletedExceptionallyWith(IllegalArgumentException.class).hasMessageContaining("not within the current or next sync committee periods");
}
use of tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil in project teku by ConsenSys.
the class SyncCommitteeContributionPoolTest method withParticipationBits.
private SignedContributionAndProof withParticipationBits(final SignedContributionAndProof proof, final int... participationBits) {
final SyncCommitteeContribution contribution = proof.getMessage().getContribution();
final SyncCommitteeUtil syncCommitteeUtil = spec.getSyncCommitteeUtilRequired(altairSlot);
final SyncCommitteeContribution newContribution = syncCommitteeUtil.createSyncCommitteeContribution(contribution.getSlot(), contribution.getBeaconBlockRoot(), contribution.getSubcommitteeIndex(), IntList.of(participationBits), contribution.getSignature());
return syncCommitteeUtil.createSignedContributionAndProof(syncCommitteeUtil.createContributionAndProof(proof.getMessage().getAggregatorIndex(), newContribution, proof.getMessage().getSelectionProof()), proof.getSignature());
}
use of tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil in project teku by ConsenSys.
the class SignedContributionAndProofValidatorTest method shouldAcceptWhenValidInSlotLastSlotOfSyncCommitteePeriod.
@Test
void shouldAcceptWhenValidInSlotLastSlotOfSyncCommitteePeriod() {
final SyncCommitteeUtil syncCommitteeUtil = spec.getSyncCommitteeUtilRequired(UInt64.ZERO);
final UInt64 period2StartEpoch = syncCommitteeUtil.computeFirstEpochOfNextSyncCommitteePeriod(UInt64.ZERO);
final UInt64 period3StartEpoch = syncCommitteeUtil.computeFirstEpochOfNextSyncCommitteePeriod(period2StartEpoch);
final UInt64 period2StartSlot = spec.computeStartSlotAtEpoch(period2StartEpoch);
final UInt64 period3StartSlot = spec.computeStartSlotAtEpoch(period3StartEpoch);
final UInt64 lastSlotOfPeriod = period3StartSlot.minus(1);
final UInt64 slotSeconds = lastSlotOfPeriod.times(spec.getSecondsPerSlot(lastSlotOfPeriod));
timeProvider.advanceTimeBy(Duration.ofSeconds(slotSeconds.longValue()));
// The first two sync committees are the same so advance the chain into the second period
// so we can test going into the third period which is actually different
final SignedBlockAndState chainHead = storageSystem.chainUpdater().advanceChainUntil(period2StartSlot);
storageSystem.chainUpdater().setCurrentSlot(lastSlotOfPeriod);
storageSystem.chainUpdater().updateBestBlock(chainHead);
// Contributions from the last slot of the sync committee period should be valid according to
// the next sync committee since that's when they'll be included in blocks
final SignedContributionAndProof message = chainBuilder.createValidSignedContributionAndProofBuilder(lastSlotOfPeriod).build();
final SafeFuture<InternalValidationResult> result = validator.validate(message);
assertThat(result).isCompletedWithValue(ACCEPT);
}
use of tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil in project teku by ConsenSys.
the class SignedContributionAndProofValidator method validate.
public SafeFuture<InternalValidationResult> validate(final SignedContributionAndProof proof) {
final ContributionAndProof contributionAndProof = proof.getMessage();
final SyncCommitteeContribution contribution = contributionAndProof.getContribution();
// [IGNORE] The sync committee contribution is the first valid contribution received for the
// aggregator with index contribution_and_proof.aggregator_index for the slot contribution.slot.
// (this requires maintaining a cache of size `SYNC_COMMITTEE_SIZE` for this topic that can be
// flushed after each slot).
final UniquenessKey uniquenessKey = getUniquenessKey(contributionAndProof, contribution);
if (seenIndices.contains(uniquenessKey)) {
return SafeFuture.completedFuture(IGNORE);
}
final Optional<SyncCommitteeUtil> maybeSyncCommitteeUtil = spec.getSyncCommitteeUtil(contribution.getSlot());
if (maybeSyncCommitteeUtil.isEmpty()) {
return futureFailureResult("Rejecting proof because the fork active at slot %s does not support sync committees", contribution.getSlot());
}
final SyncCommitteeUtil syncCommitteeUtil = maybeSyncCommitteeUtil.get();
if (proof.getMessage().getContribution().getAggregationBits().getBitCount() == 0) {
return SafeFuture.completedFuture(failureResult("Rejecting proof because participant set is empty"));
}
// `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e. `contribution.slot == current_slot`.
if (!slotUtil.isForCurrentSlot(contribution.getSlot())) {
LOG.trace("Ignoring proof because it is not from the current slot");
return SafeFuture.completedFuture(IGNORE);
}
// i.e. contribution.subcommittee_index < SYNC_COMMITTEE_SUBNET_COUNT.
if (contribution.getSubcommitteeIndex().isGreaterThanOrEqualTo(SYNC_COMMITTEE_SUBNET_COUNT)) {
return futureFailureResult("Rejecting proof because subcommittee index %s is too big", contribution.getSubcommitteeIndex());
}
return syncCommitteeStateUtils.getStateForSyncCommittee(contribution.getSlot()).thenCompose(maybeState -> {
if (maybeState.isEmpty()) {
LOG.trace("Ignoring proof because state is not available or not from Altair fork");
return SafeFuture.completedFuture(IGNORE);
}
return validateWithState(proof, contributionAndProof, contribution, syncCommitteeUtil, uniquenessKey, maybeState.get());
});
}
use of tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil in project teku by ConsenSys.
the class SyncCommitteeAggregationDuty method produceAggregates.
public SafeFuture<DutyResult> produceAggregates(final UInt64 slot, final Bytes32 beaconBlockRoot) {
final Optional<SyncCommitteeUtil> maybeSyncCommitteeUtils = spec.getSyncCommitteeUtil(slot);
if (assignments.isEmpty() || maybeSyncCommitteeUtils.isEmpty()) {
return SafeFuture.completedFuture(DutyResult.NO_OP);
}
final SyncCommitteeUtil syncCommitteeUtil = maybeSyncCommitteeUtils.get();
return forkProvider.getForkInfo(slot).thenCompose(forkInfo -> SafeFuture.collectAll(assignments.stream().flatMap(assignment -> performAggregationsForValidator(slot, beaconBlockRoot, syncCommitteeUtil, forkInfo, assignment)))).thenCompose(this::sendAggregates).exceptionally(error -> DutyResult.forError(assignments.stream().map(assignment -> assignment.getValidator().getPublicKey()).collect(Collectors.toSet()), error));
}
Aggregations