Пример #1
0
def compute_difficulty(bomb_delay: int, parent_header: BlockHeader,
                       timestamp: int) -> int:
    """
    https://github.com/ethereum/EIPs/issues/100
    """
    parent_timestamp = parent_header.timestamp
    validate_gt(timestamp, parent_timestamp, title="Header.timestamp")

    parent_difficulty = parent_header.difficulty
    offset = parent_difficulty // DIFFICULTY_ADJUSTMENT_DENOMINATOR

    has_uncles = parent_header.uncles_hash != EMPTY_UNCLE_HASH
    adj_factor = max(
        ((2 if has_uncles else 1) - ((timestamp - parent_timestamp) //
                                     BYZANTIUM_DIFFICULTY_ADJUSTMENT_CUTOFF)),
        -99,
    )
    difficulty = max(parent_difficulty + offset * adj_factor,
                     min(parent_header.difficulty, DIFFICULTY_MINIMUM))
    num_bomb_periods = (max(
        0,
        parent_header.block_number + 1 - bomb_delay,
    ) // BOMB_EXPONENTIAL_PERIOD) - BOMB_EXPONENTIAL_FREE_PERIODS

    if num_bomb_periods >= 0:
        return max(difficulty + 2**num_bomb_periods, DIFFICULTY_MINIMUM)
    else:
        return difficulty
Пример #2
0
def compute_homestead_difficulty(parent_header: BlockHeader, timestamp: int) -> int:
    """
    Computes the difficulty for a homestead block based on the parent block.
    """
    parent_tstamp = parent_header.timestamp
    validate_gt(timestamp, parent_tstamp, title="Header.timestamp")
    offset = parent_header.difficulty // DIFFICULTY_ADJUSTMENT_DENOMINATOR
    sign = max(
        1 - (timestamp - parent_tstamp) // HOMESTEAD_DIFFICULTY_ADJUSTMENT_CUTOFF,
        -99)
    difficulty = int(max(
        parent_header.difficulty + offset * sign,
        min(parent_header.difficulty, DIFFICULTY_MINIMUM)))
    num_bomb_periods = (
        (parent_header.block_number + 1) // BOMB_EXPONENTIAL_PERIOD
    ) - BOMB_EXPONENTIAL_FREE_PERIODS
    if num_bomb_periods >= 0:
        return max(difficulty + 2**num_bomb_periods, DIFFICULTY_MINIMUM)
    else:
        return difficulty
Пример #3
0
def compute_frontier_difficulty(parent_header: BlockHeader,
                                timestamp: int) -> int:
    """
    Computes the difficulty for a frontier block based on the parent block.
    """
    validate_gt(timestamp, parent_header.timestamp, title="Header timestamp")

    offset = parent_header.difficulty // DIFFICULTY_ADJUSTMENT_DENOMINATOR

    # We set the minimum to the lowest of the protocol minimum and the parent
    # minimum to allow for the initial frontier *warming* period during which
    # the difficulty begins lower than the protocol minimum.
    difficulty_minimum = min(parent_header.difficulty, DIFFICULTY_MINIMUM)

    if timestamp - parent_header.timestamp < FRONTIER_DIFFICULTY_ADJUSTMENT_CUTOFF:
        base_difficulty = max(
            parent_header.difficulty + offset,
            difficulty_minimum,
        )
    else:
        base_difficulty = max(
            parent_header.difficulty - offset,
            difficulty_minimum,
        )

    # Adjust for difficulty bomb.
    num_bomb_periods = (
        (parent_header.block_number + 1) //
        BOMB_EXPONENTIAL_PERIOD) - BOMB_EXPONENTIAL_FREE_PERIODS

    if num_bomb_periods >= 0:
        difficulty = max(
            base_difficulty + 2**num_bomb_periods,
            DIFFICULTY_MINIMUM,
        )
    else:
        difficulty = base_difficulty

    return difficulty
Пример #4
0
def test_validate_gt(value, minimum, is_valid):
    if is_valid:
        validate_gt(value, minimum)
    else:
        with pytest.raises(ValidationError):
            validate_gt(value, minimum)