Skip to content
This repository has been archived by the owner on Jul 1, 2021. It is now read-only.

Implement light client friendliness changes #234

Merged
merged 3 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions eth2/beacon/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ class ValidatorStatusFlags(IntEnum):
WITHDRAWABLE = 2


class ValidatorRegistryDeltaFlag(IntEnum):
ACTIVATION = 0
EXIT = 1


class SignatureDomain(IntEnum):
DOMAIN_DEPOSIT = 0
DOMAIN_ATTESTATION = 1
Expand Down
63 changes: 58 additions & 5 deletions eth2/beacon/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
from eth2._utils.numeric import (
bitwise_xor,
)
from eth2.beacon._utils.hash import (
hash_eth2,
)
from eth2.beacon._utils.random import (
shuffle,
split,
Expand All @@ -43,6 +46,7 @@
ValidatorIndex,
)
from eth2.beacon.validation import (
validate_epoch_for_active_index_root,
validate_slot_for_state_slot,
)

Expand Down Expand Up @@ -108,6 +112,7 @@ def get_randao_mix(state: 'BeaconState',
"""
Return the randao mix at a recent ``slot``.
"""
# TODO: update to epoch version
assert state.slot < slot + latest_randao_mixes_length
assert slot <= state.slot
return state.latest_randao_mixes[slot % latest_randao_mixes_length]
Expand Down Expand Up @@ -243,7 +248,7 @@ def get_crosslink_committees_at_slot(
target_committee_size=target_committee_size,
)

seed = state.previous_epoch_randao_mix
seed = state.previous_epoch_seed
shuffling_slot = state.previous_epoch_calculation_slot
shuffling_start_shard = state.previous_epoch_start_shard
else:
Expand All @@ -253,7 +258,7 @@ def get_crosslink_committees_at_slot(
epoch_length=epoch_length,
target_committee_size=target_committee_size,
)
seed = state.current_epoch_randao_mix
seed = state.current_epoch_seed
shuffling_slot = state.current_epoch_calculation_slot
shuffling_start_shard = state.current_epoch_start_shard

Expand All @@ -279,9 +284,46 @@ def get_crosslink_committees_at_slot(
)


#
# Get proposer position
#
def get_active_index_root(state: 'BeaconState',
slot: SlotNumber,
epoch_length: int,
latest_index_roots_length: int) -> Hash32:
"""
Return the index root at a recent ``slot``.
"""
state_epoch = state.slot // epoch_length
given_epoch = slot // epoch_length

validate_epoch_for_active_index_root(state_epoch, given_epoch, latest_index_roots_length)

return state.latest_index_roots[given_epoch % latest_index_roots_length]


def generate_seed(state: 'BeaconState',
slot: SlotNumber,
epoch_length: int,
seed_lookahead: int,
latest_index_roots_length: int,
latest_randao_mixes_length: int) -> Hash32:
"""
Generate a seed for the given ``slot``.

TODO: it's slot version, will be changed to epoch version.
"""
randao_mix = get_randao_mix(
state,
SlotNumber(slot - seed_lookahead),
latest_randao_mixes_length=latest_randao_mixes_length,
)
active_index_root = get_active_index_root(
state,
slot,
epoch_length=epoch_length,
latest_index_roots_length=latest_index_roots_length,
)

return hash_eth2(randao_mix + active_index_root)


def get_beacon_proposer_index(state: 'BeaconState',
slot: SlotNumber,
Expand Down Expand Up @@ -506,3 +548,14 @@ def is_surround_vote(attestation_data_1: 'AttestationData',
(attestation_data_2.justified_slot + 1 == attestation_data_2.slot) and
(attestation_data_2.slot < attestation_data_1.slot)
)


def get_entry_exit_effect_slot(slot: SlotNumber,
epoch_length: int,
entry_exit_delay: int) -> SlotNumber:
"""
An entry or exit triggered in the slot given by the input takes effect at
the slot given by the output.
"""
# TODO: update to epoch version
return SlotNumber((slot - slot % epoch_length) + epoch_length + entry_exit_delay)
11 changes: 6 additions & 5 deletions eth2/beacon/on_startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ def get_initial_beacon_state(*,
genesis_start_shard: ShardNumber,
shard_count: int,
latest_block_roots_length: int,
latest_index_roots_length: int,
epoch_length: int,
target_committee_size: int,
max_deposit: Ether,
latest_penalized_exit_length: int,
latest_randao_mixes_length: int,
Expand All @@ -87,7 +87,6 @@ def get_initial_beacon_state(*,
validator_balances=(),
validator_registry_update_slot=genesis_slot,
validator_registry_exit_count=0,
validator_registry_delta_chain_tip=ZERO_HASH32,

# Randomness and committees
latest_randao_mixes=tuple(ZERO_HASH32 for _ in range(latest_randao_mixes_length)),
Expand All @@ -101,8 +100,8 @@ def get_initial_beacon_state(*,
current_epoch_start_shard=genesis_start_shard,
previous_epoch_calculation_slot=genesis_slot,
current_epoch_calculation_slot=genesis_slot,
previous_epoch_randao_mix=ZERO_HASH32,
current_epoch_randao_mix=ZERO_HASH32,
previous_epoch_seed=ZERO_HASH32,
current_epoch_seed=ZERO_HASH32,

# Custody challenges
custody_challenges=(),
Expand All @@ -119,6 +118,7 @@ def get_initial_beacon_state(*,
for _ in range(shard_count)
]),
latest_block_roots=tuple(ZERO_HASH32 for _ in range(latest_block_roots_length)),
latest_index_roots=tuple(ZERO_HASH32 for _ in range(latest_index_roots_length)),
latest_penalized_balances=tuple(
Gwei(0)
for _ in range(latest_penalized_exit_length)
Expand Down Expand Up @@ -154,8 +154,9 @@ def get_initial_beacon_state(*,
state = activate_validator(
state,
validator_index,
genesis=True,
is_genesis=True,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

genesis_slot=genesis_slot,
epoch_length=epoch_length,
entry_exit_delay=entry_exit_delay,
)

Expand Down
1 change: 1 addition & 0 deletions eth2/beacon/state_machines/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
('BEACON_CHAIN_SHARD_NUMBER', ShardNumber),
('MAX_CASPER_VOTES', int),
('LATEST_BLOCK_ROOTS_LENGTH', int),
('LATEST_INDEX_ROOTS_LENGTH', int),
('LATEST_RANDAO_MIXES_LENGTH', int),
('LATEST_PENALIZED_EXIT_LENGTH', int),
# EMPTY_SIGNATURE is defined in constants.py
Expand Down
1 change: 1 addition & 0 deletions eth2/beacon/state_machines/forks/serenity/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
BEACON_CHAIN_SHARD_NUMBER=ShardNumber(2**64 - 1),
MAX_CASPER_VOTES=2**10, # (= 1,024) votes
LATEST_BLOCK_ROOTS_LENGTH=2**13, # (= 8,192) block roots
LATEST_INDEX_ROOTS_LENGTH=2**13, # (= 8,192) index roots
LATEST_RANDAO_MIXES_LENGTH=2**13, # (= 8,192) randao mixes
LATEST_PENALIZED_EXIT_LENGTH=2**13, # (= 8,192) randao mixes
# Deposit contract
Expand Down
80 changes: 67 additions & 13 deletions eth2/beacon/state_machines/forks/serenity/epoch_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@
from eth2._utils.tuple import (
update_tuple_item,
)
from eth2.beacon._utils.hash import (
hash_eth2,
)
from eth2.beacon import helpers
from eth2.beacon.helpers import (
get_active_validator_indices,
get_current_epoch_committee_count_per_slot,
get_randao_mix,
)
from eth2.beacon.types.states import BeaconState
from eth2.beacon.state_machines.configs import BeaconConfig


#
# Validator Registry
# Validator registry and shuffling seed data
#
def _check_if_update_validator_registry(state: BeaconState,
config: BeaconConfig) -> Tuple[bool, int]:
Expand Down Expand Up @@ -48,13 +52,47 @@ def update_validator_registry(state: BeaconState) -> BeaconState:
return state


def _update_latest_index_roots(state: BeaconState,
config: BeaconConfig) -> BeaconState:
"""
Return the BeaconState with updated `latest_index_roots`.
"""
next_epoch = state.next_epoch(config.EPOCH_LENGTH)

# TODO: chanege to hash_tree_root
active_validator_indices = get_active_validator_indices(
state.validator_registry,
# TODO: change to `per-epoch` version
state.slot,
)
index_root = hash_eth2(
b''.join(
[
index.to_bytes(32, 'big')
for index in active_validator_indices
]
)
)

latest_index_roots = update_tuple_item(
state.latest_index_roots,
next_epoch % config.LATEST_INDEX_ROOTS_LENGTH,
index_root,
)

return state.copy(
latest_index_roots=latest_index_roots,
)


def process_validator_registry(state: BeaconState,
config: BeaconConfig) -> BeaconState:
state = state.copy(
previous_epoch_calculation_slot=state.current_epoch_calculation_slot,
previous_epoch_start_shard=state.current_epoch_start_shard,
previous_epoch_randao_mix=state.current_epoch_randao_mix,
previous_epoch_seed=state.current_epoch_seed,
)
state = _update_latest_index_roots(state, config)

need_to_update, num_shards_in_committees = _check_if_update_validator_registry(state, config)

Expand All @@ -71,12 +109,19 @@ def process_validator_registry(state: BeaconState,
state.current_epoch_start_shard + num_shards_in_committees
) % config.SHARD_COUNT,
)

# The `helpers.generate_seed` function is only present to provide an entry point
# for mocking this out in tests.
current_epoch_seed = helpers.generate_seed(
state=state,
slot=state.current_epoch_calculation_slot,
epoch_length=config.EPOCH_LENGTH,
seed_lookahead=config.SEED_LOOKAHEAD,
latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH,
latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
)
state = state.copy(
current_epoch_randao_mix=get_randao_mix(
state,
state.current_epoch_calculation_slot - config.SEED_LOOKAHEAD,
config.LATEST_RANDAO_MIXES_LENGTH,
),
current_epoch_seed=current_epoch_seed,
)
else:
epochs_since_last_registry_change = (
Expand All @@ -88,13 +133,22 @@ def process_validator_registry(state: BeaconState,
state = state.copy(
current_epoch_calculation_slot=state.slot,
)

# The `helpers.generate_seed` function is only present to provide an entry point
# for mocking this out in tests.
current_epoch_seed = helpers.generate_seed(
state=state,
slot=state.current_epoch_calculation_slot,
epoch_length=config.EPOCH_LENGTH,
seed_lookahead=config.SEED_LOOKAHEAD,
latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH,
latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
)
state = state.copy(
current_epoch_randao_mix=get_randao_mix(
state,
state.current_epoch_calculation_slot - config.SEED_LOOKAHEAD,
config.LATEST_RANDAO_MIXES_LENGTH,
),
current_epoch_seed=current_epoch_seed,
)
else:
pass

return state

Expand Down
2 changes: 1 addition & 1 deletion eth2/beacon/tools/builder/initializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ def create_mock_genesis(
genesis_start_shard=config.GENESIS_START_SHARD,
shard_count=config.SHARD_COUNT,
latest_block_roots_length=config.LATEST_BLOCK_ROOTS_LENGTH,
latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH,
epoch_length=config.EPOCH_LENGTH,
target_committee_size=config.TARGET_COMMITTEE_SIZE,
max_deposit=config.MAX_DEPOSIT,
latest_penalized_exit_length=config.LATEST_PENALIZED_EXIT_LENGTH,
latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
Expand Down
Loading