use of tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate in project teku by ConsenSys.
the class BlockProcessorAltair method processSyncAggregate.
@Override
public void processSyncAggregate(final MutableBeaconState baseState, final SyncAggregate aggregate, final BLSSignatureVerifier signatureVerifier) throws BlockProcessingException {
final MutableBeaconStateAltair state = MutableBeaconStateAltair.required(baseState);
final List<BLSPublicKey> participantPubkeys = new ArrayList<>();
final List<BLSPublicKey> idlePubkeys = new ArrayList<>();
for (int i = 0; i < specConfigAltair.getSyncCommitteeSize(); i++) {
final BLSPublicKey publicKey = syncCommitteeUtil.getCurrentSyncCommitteeParticipantPubKey(state, i);
if (aggregate.getSyncCommitteeBits().getBit(i)) {
participantPubkeys.add(publicKey);
} else {
idlePubkeys.add(publicKey);
}
}
final UInt64 previousSlot = state.getSlot().minusMinZero(1);
final Bytes32 domain = beaconStateAccessors.getDomain(state.getForkInfo(), Domain.SYNC_COMMITTEE, miscHelpers.computeEpochAtSlot(previousSlot));
final Bytes32 signingRoot = miscHelpersAltair.computeSigningRoot(beaconStateAccessors.getBlockRootAtSlot(state, previousSlot), domain);
if (!eth2FastAggregateVerify(signatureVerifier, participantPubkeys, signingRoot, aggregate.getSyncCommitteeSignature().getSignature())) {
throw new BlockProcessingException("Invalid sync committee signature in " + aggregate);
}
// Compute participant and proposer rewards
final UInt64 totalActiveIncrements = beaconStateAccessors.getTotalActiveBalance(state).dividedBy(specConfig.getEffectiveBalanceIncrement());
final UInt64 totalBaseRewards = beaconStateAccessorsAltair.getBaseRewardPerIncrement(state).times(totalActiveIncrements);
final UInt64 maxParticipantRewards = totalBaseRewards.times(SYNC_REWARD_WEIGHT).dividedBy(WEIGHT_DENOMINATOR).dividedBy(specConfig.getSlotsPerEpoch());
final UInt64 participantReward = maxParticipantRewards.dividedBy(specConfigAltair.getSyncCommitteeSize());
final UInt64 proposerReward = participantReward.times(PROPOSER_WEIGHT).dividedBy(WEIGHT_DENOMINATOR.minus(PROPOSER_WEIGHT));
// Apply participant and proposer rewards
participantPubkeys.stream().map(pubkey -> validatorsUtil.getValidatorIndex(state, pubkey).orElseThrow()).forEach(participantIndex -> beaconStateMutators.increaseBalance(state, participantIndex, participantReward));
UInt64 totalProposerReward = proposerReward.times(participantPubkeys.size());
beaconStateMutators.increaseBalance(state, beaconStateAccessors.getBeaconProposerIndex(state), totalProposerReward);
// impose penalties for any idle validators
idlePubkeys.stream().map(pubkey -> validatorsUtil.getValidatorIndex(state, pubkey).orElseThrow()).forEach(participantIndex -> beaconStateMutators.decreaseBalance(state, participantIndex, participantReward));
}
use of tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate in project teku by ConsenSys.
the class SyncCommitteeContributionPoolTest method shouldSelectBestContribution.
@Test
void shouldSelectBestContribution() {
final SignedContributionAndProof proof = dataStructureUtil.randomSignedContributionAndProof(25);
final SignedContributionAndProof bestProof = withParticipationBits(proof, 1, 2, 3);
addValid(withParticipationBits(proof, 1, 3));
addValid(bestProof);
addValid(withParticipationBits(proof, 2));
final SyncCommitteeContribution contribution = bestProof.getMessage().getContribution();
final SyncAggregate result = pool.createSyncAggregateForBlock(contribution.getSlot().plus(1), contribution.getBeaconBlockRoot());
assertSyncAggregateFromContribution(contribution, result);
}
use of tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate in project teku by ConsenSys.
the class SyncCommitteeContributionPoolTest method assertSyncAggregateFromContribution.
private void assertSyncAggregateFromContribution(final SyncCommitteeContribution contribution, final SyncAggregate result) {
final int subcommitteeIndexOffset = config.getSyncCommitteeSize() / SYNC_COMMITTEE_SUBNET_COUNT * contribution.getSubcommitteeIndex().intValue();
final IntList expectedParticipants = IntArrayList.toList(contribution.getAggregationBits().getAllSetBits().intStream().map(index -> subcommitteeIndexOffset + index));
assertThatSyncAggregate(result).hasSyncCommitteeBits(expectedParticipants).hasSignature(contribution.getSignature());
}
use of tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate in project teku by ConsenSys.
the class SyncCommitteePerformanceTracker method calculateSyncCommitteePerformance.
private SafeFuture<SyncCommitteePerformance> calculateSyncCommitteePerformance(final UInt64 epoch, final Map<UInt64, IntSet> assignedSubcommitteeIndicesByValidatorIndex, final Map<UInt64, Map<Bytes32, Set<UInt64>>> producingValidatorsBySlotAndBlock, final Optional<StateAndBlockSummary> chainHead) {
final int numberOfExpectedMessages = assignedSubcommitteeIndicesByValidatorIndex.values().stream().mapToInt(Set::size).sum() * spec.atEpoch(epoch).getSlotsPerEpoch();
int producedMessageCount = 0;
int correctMessageCount = 0;
final List<SafeFuture<Integer>> includedMessageCountFutures = new ArrayList<>();
for (Map.Entry<UInt64, Map<Bytes32, Set<UInt64>>> entry : producingValidatorsBySlotAndBlock.entrySet()) {
final UInt64 slot = entry.getKey();
final Map<Bytes32, Set<UInt64>> producingValidatorsByBlock = entry.getValue();
final Optional<Bytes32> correctBlockRoot = chainHead.map(head -> {
if (slot.isGreaterThanOrEqualTo(head.getSlot())) {
return head.getRoot();
} else {
return spec.getBlockRootAtSlot(head.getState(), slot);
}
});
for (Entry<Bytes32, Set<UInt64>> blockEntry : producingValidatorsByBlock.entrySet()) {
final Bytes32 blockRoot = blockEntry.getKey();
final Set<UInt64> producingValidators = blockEntry.getValue();
final int producedMessageCountForBlock = countProducedMessages(assignedSubcommitteeIndicesByValidatorIndex, slot, producingValidators);
if (correctBlockRoot.isPresent() && correctBlockRoot.get().equals(blockRoot)) {
correctMessageCount += producedMessageCountForBlock;
}
producedMessageCount += producedMessageCountForBlock;
final UInt64 inclusionSlot = slot.plus(1);
includedMessageCountFutures.add(getSyncAggregateAtSlot(inclusionSlot).thenApply(maybeSyncAggregate -> maybeSyncAggregate.map(syncAggregate -> countIncludedMessages(assignedSubcommitteeIndicesByValidatorIndex, slot, producingValidators, syncAggregate)).orElse(0)));
}
}
final int numberOfProducedMessages = producedMessageCount;
final int numberOfCorrectMessages = correctMessageCount;
return SafeFuture.collectAll(includedMessageCountFutures.stream()).thenApply(includedMessageCounts -> includedMessageCounts.stream().mapToInt(a -> a).sum()).thenApply(numberOfIncludedMessages -> new SyncCommitteePerformance(epoch, numberOfExpectedMessages, numberOfProducedMessages, numberOfCorrectMessages, numberOfIncludedMessages));
}
use of tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.altair.SyncAggregate in project teku by ConsenSys.
the class BlockFactoryTest method shouldIncludeSyncAggregateWhenAltairIsActive.
@Test
void shouldIncludeSyncAggregateWhenAltairIsActive() throws Exception {
final BeaconBlock block = assertBlockCreated(1, TestSpecFactory.createMinimalAltair());
final SyncAggregate result = getSyncAggregate(block);
assertThatSyncAggregate(result).isNotNull();
verify(syncCommitteeContributionPool).createSyncAggregateForBlock(UInt64.ONE, block.getParentRoot());
}
Aggregations