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)
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)