Exemple #1
0
 def run_with(
     _cls, inputs: Tuple[BeaconState, int], config: Optional[Eth2Config]
 ) -> BeaconState:
     state, offset = inputs
     target_slot = Slot(state.slot + offset)
     return process_slots(state, target_slot, config)
Exemple #2
0
    def on_attestation(self,
                       attestation: Attestation,
                       validate_signature: bool = True) -> None:
        target = attestation.data.target
        current_epoch = compute_epoch_at_slot(self.get_current_slot(),
                                              self._config.SLOTS_PER_EPOCH)
        previous_epoch = (current_epoch -
                          1 if current_epoch > self._config.GENESIS_EPOCH else
                          self._config.GENESIS_EPOCH)
        if target.epoch not in (current_epoch, previous_epoch):
            raise ValidationError(
                "Attestations must be from the current or previous epoch")

        if target.root not in self._context.blocks:
            raise ValidationError(
                "Attestation targets a block we have not seen")

        base_state = self._context.block_states[target.root]
        time_of_target_epoch = (
            base_state.genesis_time + compute_start_slot_at_epoch(
                target.epoch, self._config.SLOTS_PER_EPOCH) *
            self._config.SECONDS_PER_SLOT)
        if self._context.time < time_of_target_epoch:
            raise ValidationError("Attestation cannot be for a future epoch")

        beacon_block_root = attestation.data.beacon_block_root
        if beacon_block_root not in self._context.blocks:
            raise ValidationError("Attestations must be for a known block")

        if self._context.blocks[beacon_block_root].slot > attestation.data.slot:
            raise ValidationError(
                "Attestations must not be for a block in the future")

        if target not in self._context.checkpoint_states:
            base_state = process_slots(
                base_state,
                compute_start_slot_at_epoch(target.epoch,
                                            self._config.SLOTS_PER_EPOCH),
                self._config,
            )
            self._context.checkpoint_states[target] = base_state
        target_state = self._context.checkpoint_states[target]

        if (self._context.time <
            (attestation.data.slot + 1) * self._config.SECONDS_PER_SLOT):
            raise ValidationError(
                "Attestations can only affect the fork choice of future slots")

        # TODO: has this validation already been performed?
        indexed_attestation = get_indexed_attestation(
            target_state, attestation, CommitteeConfig(self._config))
        validate_indexed_attestation(
            target_state,
            indexed_attestation,
            self._config.MAX_VALIDATORS_PER_COMMITTEE,
            self._config.SLOTS_PER_EPOCH,
            validate_signature=validate_signature,
        )

        for i in indexed_attestation.attesting_indices:
            if (i not in self._context.latest_messages
                    or target.epoch > self._context.latest_messages[i].epoch):
                self._context.latest_messages[i] = LatestMessage(
                    epoch=target.epoch,
                    root=attestation.data.beacon_block_root)