use of tech.pegasys.teku.spec.datastructures.state.CommitteeAssignment in project teku by ConsenSys.
the class AggregateAttestationValidatorTest method shouldRejectAggregateWhenSelectionProofDoesNotSelectAsAggregator.
@Test
public void shouldRejectAggregateWhenSelectionProofDoesNotSelectAsAggregator() {
final StateAndBlockSummary chainHead = storageSystem.getChainHead();
int aggregatorIndex = 3;
final CommitteeAssignment committeeAssignment = getCommitteeAssignment(chainHead, aggregatorIndex, ZERO);
final SignedAggregateAndProof aggregate = generator.generator().blockAndState(chainHead, committeeAssignment.getSlot()).aggregatorIndex(UInt64.valueOf(aggregatorIndex)).committeeIndex(committeeAssignment.getCommitteeIndex()).generate();
whenAttestationIsValid(aggregate);
// Sanity check
final int committeeLength = committeeAssignment.getCommittee().size();
final int aggregatorModulo = genesisSpec.getValidatorsUtil().getAggregatorModulo(committeeLength);
assertThat(aggregatorModulo).isGreaterThan(1);
assertThat(genesisSpec.getValidatorsUtil().isAggregator(aggregate.getMessage().getSelection_proof(), aggregatorModulo)).isFalse();
assertThat(validator.validate(ValidateableAttestation.aggregateFromValidator(spec, aggregate))).isCompletedWithValueMatching(InternalValidationResult::isReject);
}
use of tech.pegasys.teku.spec.datastructures.state.CommitteeAssignment in project teku by ConsenSys.
the class AggregateAttestationValidatorTest method shouldRejectIfAggregatorIndexIsNotWithinTheCommittee.
@Test
public void shouldRejectIfAggregatorIndexIsNotWithinTheCommittee() {
final StateAndBlockSummary chainHead = storageSystem.getChainHead();
final int aggregatorIndex = 60;
final SignedAggregateAndProof aggregate = generator.generator().blockAndState(chainHead).aggregatorIndex(UInt64.valueOf(aggregatorIndex)).generate();
whenAttestationIsValid(aggregate);
// Sanity check aggregator is not in the committee
final AttestationData attestationData = aggregate.getMessage().getAggregate().getData();
final CommitteeAssignment committeeAssignment = getCommitteeAssignment(chainHead, aggregatorIndex, spec.computeEpochAtSlot(chainHead.getSlot()));
if (committeeAssignment.getCommitteeIndex().equals(attestationData.getIndex()) && committeeAssignment.getSlot().equals(attestationData.getSlot())) {
fail("Aggregator was in the committee");
}
assertThat(validator.validate(ValidateableAttestation.aggregateFromValidator(spec, aggregate))).isCompletedWithValueMatching(InternalValidationResult::isReject);
}
use of tech.pegasys.teku.spec.datastructures.state.CommitteeAssignment in project teku by ConsenSys.
the class ChainDataProvider method getCommitteesFromState.
List<EpochCommitteeResponse> getCommitteesFromState(final tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState state, final Optional<UInt64> epoch, final Optional<UInt64> committeeIndex, final Optional<UInt64> slot) {
final Predicate<CommitteeAssignment> slotFilter = slot.isEmpty() ? __ -> true : (assignment) -> assignment.getSlot().equals(slot.get());
final Predicate<CommitteeAssignment> committeeFilter = committeeIndex.isEmpty() ? __ -> true : (assignment) -> assignment.getCommitteeIndex().compareTo(committeeIndex.get()) == 0;
final UInt64 stateEpoch = spec.computeEpochAtSlot(state.getSlot());
if (epoch.isPresent() && epoch.get().isGreaterThan(stateEpoch.plus(ONE))) {
throw new BadRequestException("Epoch " + epoch.get() + " is too far ahead of state epoch " + stateEpoch);
}
if (slot.isPresent()) {
final UInt64 computeEpochAtSlot = spec.computeEpochAtSlot(slot.get());
if (!computeEpochAtSlot.equals(epoch.orElse(stateEpoch))) {
throw new BadRequestException("Slot " + slot.get() + " is not in epoch " + epoch.orElse(stateEpoch));
}
}
return combinedChainDataClient.getCommitteesFromState(state, epoch.orElse(stateEpoch)).stream().filter(slotFilter).filter(committeeFilter).map(EpochCommitteeResponse::new).collect(toList());
}
use of tech.pegasys.teku.spec.datastructures.state.CommitteeAssignment in project teku by ConsenSys.
the class DebugToolsCommand method printCommittees.
@Command(name = "get-validator-assignment", description = "Gets the committee assignment for a validator at a specific epoch.", mixinStandardHelpOptions = true, showDefaultValues = true, abbreviateSynopsis = true, versionProvider = PicoCliVersionProvider.class, synopsisHeading = "%n", descriptionHeading = "%nDescription:%n%n", optionListHeading = "%nOptions:%n", footerHeading = "%n", footer = "Teku is licensed under the Apache License 2.0")
public int printCommittees(@Option(required = true, names = { "--state", "-s" }, description = "Starting state to use. Must be in or before the specified epoch.") final Path statePath, @Option(required = true, names = { "--validator", "-v" }, description = "Validator index to get assignment for") final int validatorIndex, @Option(required = true, names = { "--epoch", "-e" }, description = "Epoch to get assignment for") final long epoch, @Option(defaultValue = "mainnet", names = { "--network", "-n" }, description = "Represents which network to use.") final String network) throws Exception {
final tech.pegasys.teku.spec.Spec spec = SpecFactory.create(network);
BeaconState state = spec.deserializeBeaconState(Bytes.wrap(Files.readAllBytes(statePath)));
if (spec.getCurrentEpoch(state).isLessThan(epoch)) {
state = spec.processSlots(state, spec.computeStartSlotAtEpoch(UInt64.valueOf(epoch)));
}
final CommitteeAssignment assignment = spec.getCommitteeAssignment(state, UInt64.valueOf(epoch), validatorIndex).orElseThrow();
System.out.printf("Validator %s assigned to attest at slot %s in committee index %s, position %s%n", validatorIndex, assignment.getSlot(), assignment.getCommitteeIndex(), assignment.getCommittee().indexOf(validatorIndex));
return 0;
}
use of tech.pegasys.teku.spec.datastructures.state.CommitteeAssignment in project teku by ConsenSys.
the class ValidatorsUtil method getCommitteeAssignment.
/**
* Return the committee assignment in the ``epoch`` for ``validator_index``. ``assignment``
* returned is a tuple of the following form: ``assignment[0]`` is the list of validators in the
* committee ``assignment[1]`` is the index to which the committee is assigned ``assignment[2]``
* is the slot at which the committee is assigned Return None if no assignment.
*
* @param state the BeaconState.
* @param epoch either on or between previous or current epoch.
* @param validator_index the validator that is calling this function.
* @param committeeCountPerSlot the number of committees for the target epoch
* @return Optional.of(CommitteeAssignment).
*/
public Optional<CommitteeAssignment> getCommitteeAssignment(BeaconState state, UInt64 epoch, int validator_index, final UInt64 committeeCountPerSlot) {
UInt64 next_epoch = beaconStateAccessors.getCurrentEpoch(state).plus(UInt64.ONE);
checkArgument(epoch.compareTo(next_epoch) <= 0, "get_committee_assignment: Epoch number too high");
UInt64 start_slot = miscHelpers.computeStartSlotAtEpoch(epoch);
for (UInt64 slot = start_slot; slot.isLessThan(start_slot.plus(specConfig.getSlotsPerEpoch())); slot = slot.plus(UInt64.ONE)) {
for (UInt64 index = UInt64.ZERO; index.compareTo(committeeCountPerSlot) < 0; index = index.plus(UInt64.ONE)) {
final IntList committee = beaconStateAccessors.getBeaconCommittee(state, slot, index);
if (committee.contains(validator_index)) {
return Optional.of(new CommitteeAssignment(committee, index, slot));
}
}
}
return Optional.empty();
}
Aggregations