Пример #1
0
def test_aggregator_selection(validator_count, privkeys, genesis_state,
                              config):
    state = genesis_state
    epoch = compute_epoch_at_slot(state.slot, config.SLOTS_PER_EPOCH)

    sum_aggregator_count = 0
    for committee, committee_index, slot in iterate_committees_at_epoch(
            state, epoch, config):
        assert config.TARGET_COMMITTEE_SIZE == len(committee)
        aggregator_count = 0
        for index in range(validator_count):
            if index in committee:
                signature = get_slot_signature(genesis_state, slot,
                                               privkeys[index], config)
                attester_is_aggregator = is_aggregator(state, slot,
                                                       committee_index,
                                                       signature, config)
                if attester_is_aggregator:
                    aggregator_count += 1
        assert aggregator_count > 0
        sum_aggregator_count += aggregator_count
    # The average aggregator count per slot should be around
    # `TARGET_AGGREGATORS_PER_COMMITTEE`.
    average_aggregator_count = sum_aggregator_count / config.SLOTS_PER_EPOCH
    assert (TARGET_AGGREGATORS_PER_COMMITTEE - 3 < average_aggregator_count <
            TARGET_AGGREGATORS_PER_COMMITTEE + 3)
Пример #2
0
    async def aggregate(self, slot: Slot) -> Tuple[AggregateAndProof, ...]:
        """
        Aggregate the attestations at ``slot`` and broadcast them.
        """
        # Check the aggregators selection
        aggregate_and_proofs: Tuple[AggregateAndProof, ...] = ()
        state_machine = self.chain.get_state_machine()
        state = self.chain.get_head_state()
        config = state_machine.config

        attesting_committee_assignments_at_slot = self._get_attesting_assignments_at_slot(
            slot)
        # 1. For each committee_assignment at the given slot
        for committee_assignment in attesting_committee_assignments_at_slot:
            committee_index = committee_assignment.committee_index

            local_attesters = self._get_local_attesters_at_assignment(
                committee_assignment)
            # Get the validator_index -> privkey map of the attesting validators
            attesting_validator_privkeys = {
                index: self.validator_privkeys[index]
                for index in local_attesters
            }

            selected_proofs: Dict[ValidatorIndex, BLSSignature] = {}
            # 2. For each attester
            for validator_index, privkey in attesting_validator_privkeys.items(
            ):
                # Check if the vallidator is one of the aggregators
                signature = get_slot_signature(state, slot, privkey,
                                               CommitteeConfig(config))
                is_aggregator_result = is_aggregator(state, slot,
                                                     committee_index,
                                                     signature,
                                                     CommitteeConfig(config))
                if is_aggregator_result:
                    self.logger.debug(
                        f"validator ({validator_index}) is aggregator of"
                        f" committee_index={committee_index} at slot={slot}")
                    selected_proofs[validator_index] = signature
                else:
                    continue

                aggregates = self._get_aggregates(slot, committee_index,
                                                  config)
                # 3. For each aggregate
                # (it's possible with same CommitteeIndex and different AttesatationData)
                for aggregate in aggregates:
                    aggregate_and_proof = AggregateAndProof.create(
                        aggregator_index=validator_index,
                        aggregate=aggregate,
                        selection_proof=selected_proofs[validator_index],
                    )
                    self.import_attestation(aggregate_and_proof.aggregate,
                                            True)
                    await self.p2p_node.broadcast_beacon_aggregate_and_proof(
                        aggregate_and_proof)
                    aggregate_and_proofs += (aggregate_and_proof, )

        return aggregate_and_proofs