Example #1
0
 def get_next_difficulty(self, header_hash: bytes32, new_slot: bool) -> uint64:
     assert self.contains_sub_block(header_hash)
     curr = self.sub_block_record(header_hash)
     if curr.height <= 2:
         return self.constants.DIFFICULTY_STARTING
     return get_next_difficulty(
         self.constants,
         self,
         header_hash,
         curr.height,
         uint64(curr.weight - self.sub_block_record(curr.prev_hash).weight),
         curr.deficit,
         new_slot,
         curr.sp_total_iters(self.constants),
     )
 def get_next_difficulty(self, header_hash: bytes32,
                         new_slot: bool) -> uint64:
     assert header_hash in self.sub_blocks
     curr = self.sub_blocks[header_hash]
     if curr.sub_block_height <= 2:
         return self.constants.DIFFICULTY_STARTING
     return get_next_difficulty(
         self.constants,
         self.sub_blocks,
         self.sub_height_to_hash,
         header_hash,
         curr.sub_block_height,
         uint64(curr.weight - self.sub_blocks[curr.prev_hash].weight),
         curr.deficit,
         new_slot,
         curr.sp_total_iters(self.constants),
     )
Example #3
0
def next_sub_epoch_summary(
    constants: ConsensusConstants,
    blocks: BlockchainInterface,
    required_iters: uint64,
    block: Union[UnfinishedBlock, FullBlock],
    can_finish_soon: bool = False,
) -> Optional[SubEpochSummary]:
    """
    Returns the sub-epoch summary that can be included in the block after block. If it should include one. Block
    must be eligible to be the last block in the epoch. If not, returns None. Assumes that there is a new slot
    ending after block.

    Args:
        constants: consensus constants being used for this chain
        blocks: interface to cached SBR
        required_iters: required iters of the proof of space in block
        block: the (potentially) last block in the new epoch
        can_finish_soon: this is useful when sending SES to timelords. We might not be able to finish it, but we will
            soon (within MAX_SUB_SLOT_BLOCKS)

    Returns:
        object: the new sub-epoch summary
    """
    signage_point_index = block.reward_chain_block.signage_point_index
    prev_b: Optional[BlockRecord] = blocks.try_block_record(
        block.prev_header_hash)
    if prev_b is None or prev_b.height == 0:
        return None

    if len(block.finished_sub_slots) > 0 and block.finished_sub_slots[
            0].challenge_chain.new_difficulty is not None:
        # We just included a sub-epoch summary
        return None

    assert prev_b is not None
    # This is the ssi of the current block
    sub_slot_iters = get_next_sub_slot_iters(
        constants,
        blocks,
        prev_b.prev_hash,
        prev_b.height,
        prev_b.sub_slot_iters,
        prev_b.deficit,
        len(block.finished_sub_slots) > 0,
        prev_b.sp_total_iters(constants),
    )
    overflow = is_overflow_block(constants, signage_point_index)
    deficit = calculate_deficit(
        constants,
        uint32(prev_b.height + 1),
        prev_b,
        overflow,
        len(block.finished_sub_slots),
    )
    can_finish_se, can_finish_epoch = can_finish_sub_and_full_epoch(
        constants,
        uint32(prev_b.height + 1),
        deficit,
        blocks,
        prev_b.header_hash if prev_b is not None else None,
        can_finish_soon,
    )

    # can't finish se, no summary
    if not can_finish_se:
        return None

    next_difficulty = None
    next_sub_slot_iters = None

    # if can finish epoch, new difficulty and ssi
    if can_finish_epoch:
        sp_iters = calculate_sp_iters(constants, sub_slot_iters,
                                      signage_point_index)
        ip_iters = calculate_ip_iters(constants, sub_slot_iters,
                                      signage_point_index, required_iters)
        next_difficulty = get_next_difficulty(
            constants,
            blocks,
            block.prev_header_hash,
            uint32(prev_b.height + 1),
            uint64(prev_b.weight -
                   blocks.block_record(prev_b.prev_hash).weight),
            deficit,
            True,
            uint128(block.total_iters - ip_iters + sp_iters -
                    (sub_slot_iters if overflow else 0)),
            True,
        )
        next_sub_slot_iters = get_next_sub_slot_iters(
            constants,
            blocks,
            block.prev_header_hash,
            uint32(prev_b.height + 1),
            sub_slot_iters,
            deficit,
            True,
            uint128(block.total_iters - ip_iters + sp_iters -
                    (sub_slot_iters if overflow else 0)),
            True,
        )

    return make_sub_epoch_summary(
        constants,
        blocks,
        uint32(prev_b.height + 2),
        prev_b,
        next_difficulty,
        next_sub_slot_iters,
    )