use of tech.pegasys.teku.spec.datastructures.type.SszPublicKey in project teku by ConsenSys.
the class SyncCommittee method asInternalSyncCommittee.
public tech.pegasys.teku.spec.datastructures.state.SyncCommittee asInternalSyncCommittee(final tech.pegasys.teku.spec.datastructures.state.SyncCommittee.SyncCommitteeSchema schema) {
SszPublicKey aggregate = new SszPublicKey(aggregatePubkey.asBLSPublicKey());
List<SszPublicKey> committee = pubkeys.stream().map(key -> new SszPublicKey(key.asBLSPublicKey())).collect(Collectors.toList());
return schema.create(committee, aggregate);
}
use of tech.pegasys.teku.spec.datastructures.type.SszPublicKey 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()));
});
}
use of tech.pegasys.teku.spec.datastructures.type.SszPublicKey in project teku by ConsenSys.
the class BeaconStateAccessorsAltair method getNextSyncCommittee.
/**
* Return the *next* sync committee for a given state.
*
* <p>SyncCommittee contains an aggregate pubkey that enables resource-constrained clients to save
* some computation when verifying the sync committee's signature.
*
* <p>SyncCommittee can also contain duplicate pubkeys, when {@link
* #getNextSyncCommitteeIndices(BeaconState)} returns duplicate indices. Implementations must take
* care when handling optimizations relating to aggregation and verification in the presence of
* duplicates.
*
* <p>Note: This function should only be called at sync committee period boundaries by {@link
* tech.pegasys.teku.spec.logic.common.statetransition.epoch.EpochProcessor#processSyncCommitteeUpdates(MutableBeaconState)}
* as {@link #getNextSyncCommitteeIndices(BeaconState)} is not stable within a given period.
*
* @param state the state to get the sync committee for
* @return the SyncCommittee
*/
public SyncCommittee getNextSyncCommittee(final BeaconState state) {
final IntList indices = getNextSyncCommitteeIndices(state);
final List<BLSPublicKey> pubkeys = indices.intStream().mapToObj(index -> getValidatorPubKey(state, UInt64.valueOf(index)).orElseThrow()).collect(toList());
final BLSPublicKey aggregatePubkey = BLSPublicKey.aggregate(pubkeys);
return state.getBeaconStateSchema().getNextSyncCommitteeSchemaOrThrow().create(pubkeys.stream().map(SszPublicKey::new).collect(toList()), new SszPublicKey(aggregatePubkey));
}
use of tech.pegasys.teku.spec.datastructures.type.SszPublicKey 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);
}
use of tech.pegasys.teku.spec.datastructures.type.SszPublicKey in project teku by ConsenSys.
the class SyncCommitteeUtilTest method getSyncSubCommittees_shouldSupportValidatorsInMultipleSubCommittees.
@Test
void getSyncSubCommittees_shouldSupportValidatorsInMultipleSubCommittees() {
final List<SszPublicKey> singleSubcommittee = validatorPublicKeys.subList(0, subcommitteeSize);
final List<SszPublicKey> syncCommittee = new ArrayList<>();
for (int i = 0; i < SYNC_COMMITTEE_SUBNET_COUNT; i++) {
syncCommittee.addAll(singleSubcommittee);
}
final List<UInt64> expectedValidatorIndices = IntStream.range(0, subcommitteeSize).mapToObj(UInt64::valueOf).collect(toList());
final BeaconState state = createStateWithCurrentSyncCommittee(syncCommittee);
final Map<UInt64, SyncSubcommitteeAssignments> syncSubcommittees = syncCommitteeUtil.getSyncSubcommittees(state, spec.getCurrentEpoch(state));
assertThat(syncSubcommittees).containsOnlyKeys(expectedValidatorIndices);
expectedValidatorIndices.forEach(index -> {
final SyncSubcommitteeAssignments assignments = syncSubcommittees.get(index);
assertThat(assignments.getAssignedSubcommittees()).containsExactlyInAnyOrderElementsOf(IntStream.range(0, SYNC_COMMITTEE_SUBNET_COUNT).boxed().collect(toList()));
IntStream.range(0, SYNC_COMMITTEE_SUBNET_COUNT).forEach(subcommitteeIndex -> assertThat(assignments.getParticipationBitIndices(subcommitteeIndex)).containsExactly(index.intValue()));
});
}
Aggregations