def compute_byzantium_difficulty(parent_header, timestamp): """ 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 - 3000000, ) // BOMB_EXPONENTIAL_PERIOD) - BOMB_EXPONENTIAL_FREE_PERIODS if num_bomb_periods >= 0: return max(difficulty + 2**num_bomb_periods, DIFFICULTY_MINIMUM) else: return difficulty
def compute_byzantium_difficulty(parent_header, timestamp): """ 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 - 3000000, ) // BOMB_EXPONENTIAL_PERIOD ) - BOMB_EXPONENTIAL_FREE_PERIODS if num_bomb_periods >= 0: return max(difficulty + 2**num_bomb_periods, DIFFICULTY_MINIMUM) else: return difficulty
def compute_homestead_difficulty(parent_header, timestamp): """ Computes the difficulty for a homestead block based on the parent block. """ parent_tstamp = parent_header.timestamp validate_gt(timestamp, parent_tstamp) offset = parent_header.difficulty // DIFFICULTY_ADJUSTMENT_DENOMINATOR sign = max( 1 - (timestamp - parent_tstamp) // HOMESTEAD_DIFF_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
def compute_homestead_difficulty(parent_header, timestamp): """ 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
def compute_frontier_difficulty(parent_header, timestamp): """ Computes the difficulty for a frontier block based on the parent block. """ validate_gt(timestamp, parent_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
def compute_frontier_difficulty(parent_header, timestamp): """ 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
def test_validate_gt(value, minimum, is_valid): if is_valid: validate_gt(value, minimum) else: with pytest.raises(ValidationError): validate_gt(value, minimum)