Example #1
0
    def get_prev_blocks(cls, last_block_hash: Hash32,
                        chaindb: BaseBeaconChainDB, max_search_depth: int,
                        min_slot_number: int) -> Iterable[BaseBeaconBlock]:
        """
        Return the previous blocks.

        Slot numbers are not guaranteed to be contiguous since it is possible for there
        to be no block at a given slot.  The search is bounded by two parameters.

        - `max_search_depth` - The maximum number of slots below the slot of the block denoted by
            `last_block_hash` that we should search.
        - `min_slot_number` - The slot number for which we should NOT include any deeper if reached.
        """
        if last_block_hash == GENESIS_PARENT_HASH:
            return

        block = chaindb.get_block_by_hash(last_block_hash)

        for _ in range(max_search_depth):
            yield block
            try:
                block = chaindb.get_block_by_hash(block.parent_hash)
            except (IndexError, BlockNotFound):
                break
            # Only include the blocks that are greater than or equal to min_slot_number.
            if block.slot_number < min_slot_number:
                break
Example #2
0
    def attest_proposed_block(cls, post_crystallized_state: CrystallizedState,
                              post_active_state: ActiveState,
                              block_proposal: 'BlockProposal',
                              chaindb: BaseBeaconChainDB,
                              private_key: int) -> 'AttestationRecord':
        """
        Return the initial attestation by the block proposer.

        The proposer broadcasts their attestation with the proposed block.
        """
        block_committees_info = get_block_committees_info(
            block_proposal.block,
            post_crystallized_state,
            cls.config.CYCLE_LENGTH,
        )
        # Vote
        attester_bitfield = set_voted(
            get_empty_bitfield(block_committees_info.proposer_committee_size),
            block_committees_info.proposer_index_in_committee,
        )

        # Get justified_slot and justified_block_hash
        justified_slot = post_crystallized_state.last_justified_slot
        justified_block_hash = chaindb.get_canonical_block_hash_by_slot(
            justified_slot)

        # Get signing message and sign it
        parent_hashes = get_hashes_to_sign(
            post_active_state.recent_block_hashes,
            block_proposal.block,
            cls.config.CYCLE_LENGTH,
        )

        message = create_signing_message(
            block_proposal.block.slot_number,
            parent_hashes,
            block_proposal.shard_id,
            block_proposal.shard_block_hash,
            justified_slot,
        )
        sig = bls.sign(
            message,
            private_key,
        )

        return cls.get_attestation_record_class()(
            slot=block_proposal.block.slot_number,
            shard_id=block_proposal.shard_id,
            oblique_parent_hashes=(),
            shard_block_hash=block_proposal.shard_block_hash,
            attester_bitfield=attester_bitfield,
            justified_slot=justified_slot,
            justified_block_hash=justified_block_hash,
            aggregate_sig=sig,
        )
Example #3
0
    def compute_per_block_transition(
            cls,
            crystallized_state: CrystallizedState,
            active_state: ActiveState,
            block: BaseBeaconBlock,
            chaindb: BaseBeaconChainDB,
            cycle_length: int,
            is_validating_signatures: bool = True) -> ActiveState:
        """
        Process ``block`` and return the new ActiveState.


        TODO: It doesn't match the latest spec.
        There will be more fields need to be updated in ActiveState.
        """
        parent_block = chaindb.get_block_by_hash(block.parent_hash)
        recent_block_hashes = get_new_recent_block_hashes(
            active_state.recent_block_hashes, parent_block.slot_number,
            block.slot_number, block.parent_hash)

        if parent_block.parent_hash != GENESIS_PARENT_HASH:
            validate_parent_block_proposer(
                crystallized_state,
                block,
                parent_block,
                cycle_length,
            )

        # TODO: to implement the RANDAO reveal validation.
        cls.validate_randao_reveal()
        for attestation in block.attestations:
            validate_attestation(
                block,
                parent_block,
                crystallized_state,
                recent_block_hashes,
                attestation,
                chaindb,
                cycle_length,
                is_validating_signatures=is_validating_signatures,
            )

        return active_state.copy(
            recent_block_hashes=recent_block_hashes,
            pending_attestations=(active_state.pending_attestations +
                                  block.attestations),
        )