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