Skip to content

Commit

Permalink
curry
Browse files Browse the repository at this point in the history
  • Loading branch information
cburgdorf committed Sep 18, 2018
1 parent bfc71e1 commit ee980b5
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 82 deletions.
145 changes: 69 additions & 76 deletions eth/vm/forks/byzantium/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Any,
Callable,
)
from cytoolz import (
curry,
)
from eth.constants import (
EMPTY_UNCLE_HASH,
DIFFICULTY_ADJUSTMENT_DENOMINATOR,
Expand Down Expand Up @@ -31,89 +34,79 @@
)


def generate_difficulty_fn(
bomb_delay: int) -> Callable[[BlockHeader, int], int]:

def compute_difficulty(
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

return compute_difficulty


def generate_create_header_from_parent_fn(difficulty_fn: Callable[[BlockHeader, int], int]
) -> Callable[[BlockHeader, Any], BlockHeader]:

def create_header_from_parent(
@curry
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


@curry
def create_header_from_parent(
difficulty_fn: Callable[[BlockHeader, int], int],
parent_header: BlockHeader,
**header_params: Any) -> BlockHeader:

if 'difficulty' not in header_params:
header_params.setdefault('timestamp', parent_header.timestamp + 1)

header_params['difficulty'] = difficulty_fn(
parent_header=parent_header,
timestamp=header_params['timestamp'],
)
return create_frontier_header_from_parent(parent_header, **header_params)

return create_header_from_parent
if 'difficulty' not in header_params:
header_params.setdefault('timestamp', parent_header.timestamp + 1)

header_params['difficulty'] = difficulty_fn(
parent_header=parent_header,
timestamp=header_params['timestamp'],
)
return create_frontier_header_from_parent(parent_header, **header_params)

def generate_configure_header_fn(
difficulty_fn: Callable[[BlockHeader, int], int]) -> Callable[[BaseVM, Any], BlockHeader]:

def configure_header(vm: BaseVM, **header_params: Any) -> BlockHeader:
validate_header_params_for_configuration(header_params)

with vm.block.header.build_changeset(**header_params) as changeset:
if 'timestamp' in header_params and changeset.block_number > 0:
parent_header = get_parent_header(changeset.build_rlp(), vm.chaindb)
changeset.difficulty = difficulty_fn(
parent_header,
header_params['timestamp'],
)
@curry
def configure_header(difficulty_fn: Callable[[BlockHeader, int], int],
vm: BaseVM,
**header_params: Any) -> BlockHeader:
validate_header_params_for_configuration(header_params)

header = changeset.commit()
return header
with vm.block.header.build_changeset(**header_params) as changeset:
if 'timestamp' in header_params and changeset.block_number > 0:
parent_header = get_parent_header(changeset.build_rlp(), vm.chaindb)
changeset.difficulty = difficulty_fn(
parent_header,
header_params['timestamp'],
)

return configure_header
header = changeset.commit()
return header


compute_byzantium_difficulty = generate_difficulty_fn(3000000)
create_byzantium_header_from_parent = generate_create_header_from_parent_fn(
compute_byzantium_difficulty
)
configure_byzantium_header = generate_configure_header_fn(compute_byzantium_difficulty)
compute_byzantium_difficulty = compute_difficulty(3000000)
create_byzantium_header_from_parent = create_header_from_parent(compute_byzantium_difficulty)
configure_byzantium_header = configure_header(compute_byzantium_difficulty)
12 changes: 6 additions & 6 deletions eth/vm/forks/constantinople/headers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from eth.vm.forks.byzantium.headers import (
generate_configure_header_fn,
generate_create_header_from_parent_fn,
generate_difficulty_fn,
configure_header,
create_header_from_parent,
compute_difficulty,
)


compute_constantinople_difficulty = generate_difficulty_fn(5000000)
compute_constantinople_difficulty = compute_difficulty(5000000)

create_constantinople_header_from_parent = generate_create_header_from_parent_fn(
create_constantinople_header_from_parent = create_header_from_parent(
compute_constantinople_difficulty
)
configure_constantinople_header = generate_configure_header_fn(compute_constantinople_difficulty)
configure_constantinople_header = configure_header(compute_constantinople_difficulty)

0 comments on commit ee980b5

Please sign in to comment.