Search in sources :

Example 1 with SyncSubcommitteeAssignments

use of tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments in project teku by ConsenSys.

the class SyncCommitteeUtil method getSyncSubcommittees.

public Map<UInt64, SyncSubcommitteeAssignments> getSyncSubcommittees(final BeaconState state, final UInt64 epoch) {
    final UInt64 syncCommitteePeriod = computeSyncCommitteePeriod(epoch);
    final UInt64 currentEpoch = beaconStateAccessors.getCurrentEpoch(state);
    final UInt64 currentSyncCommitteePeriod = computeSyncCommitteePeriod(currentEpoch);
    checkArgument(isStateUsableForCommitteeCalculationAtEpoch(state, epoch), "State must be in the same or previous sync committee period. Cannot calculate epoch %s from state at slot %s", epoch, state.getSlot());
    final BeaconStateAltair altairState = BeaconStateAltair.required(state);
    return BeaconStateCache.getTransitionCaches(altairState).getSyncCommitteeCache().get(syncCommitteePeriod, period -> {
        final SyncCommittee syncCommittee;
        if (syncCommitteePeriod.equals(currentSyncCommitteePeriod)) {
            syncCommittee = altairState.getCurrentSyncCommittee();
        } else {
            syncCommittee = altairState.getNextSyncCommittee();
        }
        final int subcommitteeSize = getSubcommitteeSize();
        final SszVector<SszPublicKey> pubkeys = syncCommittee.getPubkeys();
        final Map<UInt64, SyncSubcommitteeAssignments.Builder> subcommitteeAssignments = new HashMap<>();
        for (int index = 0; index < pubkeys.size(); index++) {
            final BLSPublicKey pubkey = pubkeys.get(index).getBLSPublicKey();
            final UInt64 validatorIndex = UInt64.valueOf(validatorsUtil.getValidatorIndex(altairState, pubkey).orElseThrow(() -> new IllegalStateException("Unknown validator assigned to sync committee: " + pubkey)));
            final int subcommitteeIndex = index / subcommitteeSize;
            final int subcommitteeParticipationIndex = index - (subcommitteeIndex * subcommitteeSize);
            // Note we're using plain HashMap here instead of a concurrent alternative as they
            // are created once here and then never modified so safe to access from multiple
            // threads.
            subcommitteeAssignments.computeIfAbsent(validatorIndex, __ -> SyncSubcommitteeAssignments.builder()).addAssignment(subcommitteeIndex, subcommitteeParticipationIndex).addCommitteeIndex(index);
        }
        return subcommitteeAssignments.entrySet().stream().collect(toUnmodifiableMap(Map.Entry::getKey, entry -> entry.getValue().build()));
    });
}
Also used : BeaconBlockBodySchemaAltair(tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.BeaconBlockBodySchemaAltair) HashMap(java.util.HashMap) SszPublicKey(tech.pegasys.teku.spec.datastructures.type.SszPublicKey) Bytes(org.apache.tuweni.bytes.Bytes) SchemaDefinitionsAltair(tech.pegasys.teku.spec.schemas.SchemaDefinitionsAltair) ContributionAndProof(tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof) SYNC_COMMITTEE_SUBNET_COUNT(tech.pegasys.teku.spec.constants.NetworkConstants.SYNC_COMMITTEE_SUBNET_COUNT) ArrayList(java.util.ArrayList) Collectors.toUnmodifiableMap(java.util.stream.Collectors.toUnmodifiableMap) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ValidatorConstants(tech.pegasys.teku.spec.constants.ValidatorConstants) IntIterable(it.unimi.dsi.fastutil.ints.IntIterable) Map(java.util.Map) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) ForkInfo(tech.pegasys.teku.spec.datastructures.state.ForkInfo) SyncCommitteeContributionSchema(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeContributionSchema) Bytes32(org.apache.tuweni.bytes.Bytes32) SyncAggregateSchema(tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregateSchema) Domain(tech.pegasys.teku.spec.constants.Domain) SyncCommitteeContribution(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeContribution) BeaconStateAccessorsAltair(tech.pegasys.teku.spec.logic.versions.altair.helpers.BeaconStateAccessorsAltair) MiscHelpers(tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers) BLS(tech.pegasys.teku.bls.BLS) BLSSignature(tech.pegasys.teku.bls.BLSSignature) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) SyncAggregatorSelectionData(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData) SyncSubcommitteeAssignments(tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments) MutableBeaconStateAltair(tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.MutableBeaconStateAltair) SignedContributionAndProof(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof) Hash(tech.pegasys.teku.infrastructure.crypto.Hash) SyncCommittee(tech.pegasys.teku.spec.datastructures.state.SyncCommittee) MutableBeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState) List(java.util.List) IntList(it.unimi.dsi.fastutil.ints.IntList) MathHelpers.bytesToUInt64(tech.pegasys.teku.spec.logic.common.helpers.MathHelpers.bytesToUInt64) IntOpenHashSet(it.unimi.dsi.fastutil.ints.IntOpenHashSet) SszVector(tech.pegasys.teku.infrastructure.ssz.SszVector) IntSet(it.unimi.dsi.fastutil.ints.IntSet) BeaconStateCache(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache) BeaconStateAltair(tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateAltair) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList) SpecConfigAltair(tech.pegasys.teku.spec.config.SpecConfigAltair) SyncAggregate(tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) HashMap(java.util.HashMap) SyncCommittee(tech.pegasys.teku.spec.datastructures.state.SyncCommittee) SszPublicKey(tech.pegasys.teku.spec.datastructures.type.SszPublicKey) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) MathHelpers.bytesToUInt64(tech.pegasys.teku.spec.logic.common.helpers.MathHelpers.bytesToUInt64) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) HashMap(java.util.HashMap) Collectors.toUnmodifiableMap(java.util.stream.Collectors.toUnmodifiableMap) Map(java.util.Map) MutableBeaconStateAltair(tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.MutableBeaconStateAltair) BeaconStateAltair(tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateAltair)

Example 2 with SyncSubcommitteeAssignments

use of tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments in project teku by ConsenSys.

the class SyncCommitteeUtilTest method getSyncSubCommittees_shouldSupportValidatorsInTheSameSubCommitteeMultipleTimes.

@Test
void getSyncSubCommittees_shouldSupportValidatorsInTheSameSubCommitteeMultipleTimes() {
    final List<SszPublicKey> syncCommittee = new ArrayList<>(validatorPublicKeys);
    final SszPublicKey validator0 = syncCommittee.get(0);
    syncCommittee.set(2, validator0);
    syncCommittee.set(3, validator0);
    final BeaconState state = createStateWithCurrentSyncCommittee(syncCommittee);
    final Map<UInt64, SyncSubcommitteeAssignments> syncSubcommittees = syncCommitteeUtil.getSyncSubcommittees(state, spec.getCurrentEpoch(state));
    final SyncSubcommitteeAssignments assignments = syncSubcommittees.get(UInt64.ZERO);
    assertThat(assignments.getAssignedSubcommittees()).containsExactly(0);
    assertThat(assignments.getParticipationBitIndices(0)).containsExactlyInAnyOrder(0, 2, 3);
}
Also used : SyncSubcommitteeAssignments(tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments) SszPublicKey(tech.pegasys.teku.spec.datastructures.type.SszPublicKey) ArrayList(java.util.ArrayList) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) Test(org.junit.jupiter.api.Test)

Example 3 with SyncSubcommitteeAssignments

use of tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments in project teku by ConsenSys.

the class SignedContributionAndProofTestBuilder method aggregatorNotInSyncSubcommittee.

public SignedContributionAndProofTestBuilder aggregatorNotInSyncSubcommittee() {
    final Map<UInt64, SyncSubcommitteeAssignments> subcommittees = syncCommitteeUtil.getSyncSubcommittees(state, spec.computeEpochAtSlot(slot));
    for (int validatorIndex = 0; validatorIndex < 10_000; validatorIndex++) {
        final SyncSubcommitteeAssignments assignments = subcommittees.get(UInt64.valueOf(validatorIndex));
        if (assignments == null || !assignments.getAssignedSubcommittees().contains(subcommitteeIndex)) {
            this.aggregatorIndex = UInt64.valueOf(validatorIndex);
            this.aggregatorSigner = signerProvider.apply(validatorIndex);
            return this;
        } else {
            for (int candidateSubcommitteeIndex = 0; candidateSubcommitteeIndex < NetworkConstants.SYNC_COMMITTEE_SUBNET_COUNT; candidateSubcommitteeIndex++) {
                if (!assignments.getAssignedSubcommittees().contains(candidateSubcommitteeIndex)) {
                    this.aggregatorIndex = UInt64.valueOf(validatorIndex);
                    this.aggregatorSigner = signerProvider.apply(validatorIndex);
                    this.subcommitteeIndex = candidateSubcommitteeIndex;
                    return this;
                }
            }
        }
    }
    throw new IllegalStateException("Could not find validator not in the sync committee");
}
Also used : SyncSubcommitteeAssignments(tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64)

Example 4 with SyncSubcommitteeAssignments

use of tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments in project teku by ConsenSys.

the class SyncCommitteeMessageValidator method validateWithState.

private SafeFuture<InternalValidationResult> validateWithState(final ValidateableSyncCommitteeMessage validateableMessage, final SyncCommitteeMessage message, final SyncCommitteeUtil syncCommitteeUtil, final BeaconStateAltair state, final Optional<UniquenessKey> maybeUniquenessKey) {
    final UInt64 messageEpoch = spec.computeEpochAtSlot(message.getSlot());
    // Always calculate the applicable subcommittees to ensure they are cached and can be used to
    // send the gossip.
    final SyncSubcommitteeAssignments assignedSubcommittees = validateableMessage.calculateAssignments(spec, state);
    // state.current_sync_committee.pubkeys.
    if (assignedSubcommittees.isEmpty()) {
        return SafeFuture.completedFuture(reject("Rejecting sync committee message because validator is not in the sync committee"));
    }
    // For messages received via gossip, it has to be unique based on the subnet it was on
    // For locally produced messages we should accept it if it hasn't been seen on any subnet
    final List<UniquenessKey> uniquenessKeys = maybeUniquenessKey.map(List::of).orElseGet(() -> assignedSubcommittees.getAssignedSubcommittees().stream().map(subnetId -> getUniquenessKey(message, subnetId)).collect(toList()));
    // validator referenced by sync_committee_message.validator_index.
    if (seenIndices.containsAll(uniquenessKeys)) {
        return SafeFuture.completedFuture(IGNORE);
    }
    // compute_subnets_for_sync_committee(state, sync_committee_message.validator_index).
    if (validateableMessage.getReceivedSubnetId().isPresent() && !assignedSubcommittees.getAssignedSubcommittees().contains(validateableMessage.getReceivedSubnetId().getAsInt())) {
        return SafeFuture.completedFuture(reject("Rejecting sync committee message because subnet id is incorrect"));
    }
    final Optional<BLSPublicKey> maybeValidatorPublicKey = spec.getValidatorPubKey(state, message.getValidatorIndex());
    if (maybeValidatorPublicKey.isEmpty()) {
        return SafeFuture.completedFuture(reject("Rejecting sync committee message because the validator index is unknown"));
    }
    // [REJECT] The message is valid for the message beacon_block_root for the validator
    // referenced by validator_index.
    final Bytes32 signingRoot = syncCommitteeUtil.getSyncCommitteeMessageSigningRoot(message.getBeaconBlockRoot(), messageEpoch, state.getForkInfo());
    return signatureVerifier.verify(maybeValidatorPublicKey.get(), signingRoot, message.getSignature()).thenApply(signatureValid -> {
        if (!signatureValid) {
            return reject("Rejecting sync committee message because the signature is invalid");
        }
        if (!seenIndices.addAll(uniquenessKeys)) {
            return ignore("Ignoring sync committee message as a duplicate was processed during validation");
        }
        return ACCEPT;
    });
}
Also used : SyncSubcommitteeAssignments(tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) Bytes32(org.apache.tuweni.bytes.Bytes32)

Example 5 with SyncSubcommitteeAssignments

use of tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments in project teku by ConsenSys.

the class ChainBuilder method createValidSignedContributionAndProofBuilder.

public SignedContributionAndProofTestBuilder createValidSignedContributionAndProofBuilder(final UInt64 slot, final Bytes32 beaconBlockRoot) {
    final SyncCommitteeUtil syncCommitteeUtil = spec.getSyncCommitteeUtilRequired(slot);
    final SignedBlockAndState latestBlockAndState = getLatestBlockAndState();
    final UInt64 epoch = syncCommitteeUtil.getEpochForDutiesAtSlot(slot);
    final Map<UInt64, SyncSubcommitteeAssignments> subcommitteeAssignments = syncCommitteeUtil.getSyncSubcommittees(latestBlockAndState.getState(), epoch);
    for (Map.Entry<UInt64, SyncSubcommitteeAssignments> entry : subcommitteeAssignments.entrySet()) {
        final UInt64 validatorIndex = entry.getKey();
        final Signer signer = getSigner(validatorIndex.intValue());
        final SyncSubcommitteeAssignments assignments = entry.getValue();
        for (int subcommitteeIndex : assignments.getAssignedSubcommittees()) {
            final SyncAggregatorSelectionData syncAggregatorSelectionData = syncCommitteeUtil.createSyncAggregatorSelectionData(slot, UInt64.valueOf(subcommitteeIndex));
            final BLSSignature proof = signer.signSyncCommitteeSelectionProof(syncAggregatorSelectionData, latestBlockAndState.getState().getForkInfo()).join();
            if (syncCommitteeUtil.isSyncCommitteeAggregator(proof)) {
                return new SignedContributionAndProofTestBuilder().signerProvider(this::getSigner).syncCommitteeUtil(syncCommitteeUtil).spec(spec).state(latestBlockAndState.getState()).subcommitteeIndex(subcommitteeIndex).slot(slot).selectionProof(proof).beaconBlockRoot(beaconBlockRoot).aggregator(validatorIndex, signer);
            }
        }
    }
    throw new IllegalStateException("No valid sync subcommittee aggregators found");
}
Also used : SyncCommitteeUtil(tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil) SyncAggregatorSelectionData(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData) Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) SignedContributionAndProofTestBuilder(tech.pegasys.teku.core.synccomittee.SignedContributionAndProofTestBuilder) Signer(tech.pegasys.teku.core.signatures.Signer) LocalSigner(tech.pegasys.teku.core.signatures.LocalSigner) SyncSubcommitteeAssignments(tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments) SignedBlockAndState(tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Map(java.util.Map) NavigableMap(java.util.NavigableMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) BLSSignature(tech.pegasys.teku.bls.BLSSignature)

Aggregations

SyncSubcommitteeAssignments (tech.pegasys.teku.spec.datastructures.util.SyncSubcommitteeAssignments)13 UInt64 (tech.pegasys.teku.infrastructure.unsigned.UInt64)9 Test (org.junit.jupiter.api.Test)5 BeaconState (tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState)4 ArrayList (java.util.ArrayList)3 BLSSignature (tech.pegasys.teku.bls.BLSSignature)3 ValidateableSyncCommitteeMessage (tech.pegasys.teku.spec.datastructures.operations.versions.altair.ValidateableSyncCommitteeMessage)3 SszPublicKey (tech.pegasys.teku.spec.datastructures.type.SszPublicKey)3 SyncCommitteeUtil (tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil)3 IntSet (it.unimi.dsi.fastutil.ints.IntSet)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Bytes32 (org.apache.tuweni.bytes.Bytes32)2 BLSPublicKey (tech.pegasys.teku.bls.BLSPublicKey)2 SignedBlockAndState (tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState)2 SyncAggregatorSelectionData (tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncAggregatorSelectionData)2 SyncCommitteeMessage (tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeMessage)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 IntArrayList (it.unimi.dsi.fastutil.ints.IntArrayList)1 IntIterable (it.unimi.dsi.fastutil.ints.IntIterable)1