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

Avoid unnecessary clamp on previous_epoch by genesis_epoch #398

Closed
Closed
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
11 changes: 3 additions & 8 deletions eth2/beacon/committee_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,12 @@ def get_crosslink_committees_at_slot(
"""
Return the list of ``(committee, shard)`` tuples for the ``slot``.
"""
genesis_epoch = committee_config.GENESIS_EPOCH
shard_count = committee_config.SHARD_COUNT
slots_per_epoch = committee_config.SLOTS_PER_EPOCH

epoch = slot_to_epoch(slot, slots_per_epoch)
current_epoch = state.current_epoch(slots_per_epoch)
previous_epoch = state.previous_epoch(slots_per_epoch, genesis_epoch)
previous_epoch = state.previous_epoch(slots_per_epoch)
next_epoch = state.next_epoch(slots_per_epoch)

validate_epoch_within_previous_and_next(epoch, previous_epoch, next_epoch)
Expand Down Expand Up @@ -358,12 +357,8 @@ def get_beacon_proposer_index(state: 'BeaconState',
Return the beacon proposer index for the ``slot``.
"""
epoch = slot_to_epoch(slot, committee_config.SLOTS_PER_EPOCH)
current_epoch = state.current_epoch(committee_config.SLOTS_PER_EPOCH)
previous_epoch = state.previous_epoch(
committee_config.SLOTS_PER_EPOCH,
committee_config.GENESIS_EPOCH,
)
next_epoch = Epoch(current_epoch + 1)
previous_epoch = state.previous_epoch(committee_config.SLOTS_PER_EPOCH)
next_epoch = state.next_epoch(committee_config.SLOTS_PER_EPOCH)

validate_epoch_within_previous_and_next(epoch, previous_epoch, next_epoch)

Expand Down
73 changes: 69 additions & 4 deletions eth2/beacon/epoch_processing_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@
def get_previous_epoch_boundary_attestations(
state: 'BeaconState',
slots_per_epoch: int,
genesis_epoch: Epoch,
latest_block_roots_length: int) -> Iterable[PendingAttestationRecord]:
beacon_block_root = get_block_root(
state,
get_epoch_start_slot(
state.previous_epoch(slots_per_epoch, genesis_epoch),
state.previous_epoch(slots_per_epoch),
slots_per_epoch,
),
latest_block_roots_length,
Expand All @@ -75,7 +74,6 @@ def get_previous_epoch_boundary_attestations(
def get_previous_epoch_matching_head_attestations(
state: 'BeaconState',
slots_per_epoch: int,
genesis_epoch: Epoch,
latest_block_roots_length: int) -> Iterable[PendingAttestationRecord]:
for attestation in state.previous_epoch_attestations:
beacon_block_root = get_block_root(
Expand Down Expand Up @@ -162,12 +160,79 @@ def get_epoch_boundary_attester_indices(
)


@to_tuple
def get_attesting_indices(state: 'BeaconState',
attestations: Sequence[PendingAttestationRecord],
config: CommitteeConfig) -> Iterable[ValidatorIndex]:
output: Set[ValidatorIndex] = set()
for a in attestations:
participants = get_attestation_participants(state, a.data, a.aggregation_bitfield, config)
output = output.union(participants)
for result in sorted(output):
yield result


def get_attesting_balance(state: 'BeaconState',
attestations: Sequence[PendingAttestationRecord],
config: 'BeaconConfig') -> Gwei:
return get_total_balance(
state.validator_balances,
get_attesting_indices(state, attestations, CommitteeConfig(config)),
config.MAX_DEPOSIT_AMOUNT,
)


@to_tuple
def _get_boundary_attestations_in_epoch(
*,
state: 'BeaconState',
attestations: Sequence[PendingAttestationRecord],
epoch: Epoch,
config: 'BeaconConfig') -> Iterable[PendingAttestationRecord]:
slot = get_epoch_start_slot(epoch, config.SLOTS_PER_EPOCH)
for a in attestations:
block_root = get_block_root(
state,
slot,
config.LATEST_BLOCK_ROOTS_LENGTH
)
if a.data.epoch_boundary_root == block_root:
yield a


def _get_current_epoch_boundary_attestations(
state: 'BeaconState',
config: 'BeaconConfig') -> Tuple[PendingAttestationRecord]:
current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
current_epoch_attestations = state.current_epoch_attestations

return _get_boundary_attestations_in_epoch(
state=state,
attestations=current_epoch_attestations,
epoch=current_epoch,
config=config,
)


def _get_previous_epoch_boundary_attestations(
state: 'BeaconState',
config: 'BeaconConfig') -> Tuple[PendingAttestationRecord]:
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH)
previous_epoch_attestations = state.previous_epoch_attestations

return _get_boundary_attestations_in_epoch(
state=state,
attestations=previous_epoch_attestations,
epoch=previous_epoch,
config=config,
)


def get_epoch_boundary_attesting_balances(
current_epoch: Epoch,
previous_epoch: Epoch,
state: 'BeaconState',
config: 'BeaconConfig') -> Tuple[Gwei, Gwei]:

previous_epoch_boundary_root = get_block_root(
state,
get_epoch_start_slot(previous_epoch, config.SLOTS_PER_EPOCH),
Expand Down
15 changes: 9 additions & 6 deletions eth2/beacon/state_machines/forks/serenity/epoch_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def _get_finalized_epoch(
def process_justification(state: BeaconState, config: BeaconConfig) -> BeaconState:

current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH)

current_epoch_justifiable, previous_epoch_justifiable = _current_previous_epochs_justifiable(
state,
Expand Down Expand Up @@ -275,7 +275,7 @@ def process_crosslinks(state: BeaconState, config: BeaconConfig) -> BeaconState:
for index in range(len(state.validator_registry))
}
previous_epoch_start_slot = get_epoch_start_slot(
state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH),
state.previous_epoch(config.SLOTS_PER_EPOCH),
config.SLOTS_PER_EPOCH,
)
next_epoch_start_slot = get_epoch_start_slot(
Expand Down Expand Up @@ -523,7 +523,6 @@ def _process_rewards_and_penalties_for_finality(
previous_epoch_boundary_attestations = get_previous_epoch_boundary_attestations(
state,
config.SLOTS_PER_EPOCH,
config.GENESIS_EPOCH,
config.LATEST_BLOCK_ROOTS_LENGTH,
)
previous_epoch_boundary_attester_indices = get_attester_indices_from_attestations(
Expand All @@ -535,7 +534,6 @@ def _process_rewards_and_penalties_for_finality(
previous_epoch_head_attestations = get_previous_epoch_matching_head_attestations(
state,
config.SLOTS_PER_EPOCH,
config.GENESIS_EPOCH,
config.LATEST_BLOCK_ROOTS_LENGTH,
)
previous_epoch_head_attester_indices = get_attester_indices_from_attestations(
Expand Down Expand Up @@ -582,7 +580,7 @@ def _process_rewards_and_penalties_for_crosslinks(
effective_balances: Dict[ValidatorIndex, Gwei],
base_rewards: Dict[ValidatorIndex, Gwei]) -> Tuple[Dict[ValidatorIndex, Gwei], Dict[ValidatorIndex, Gwei]]: # noqa: E501
previous_epoch_start_slot = get_epoch_start_slot(
state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH),
state.previous_epoch(config.SLOTS_PER_EPOCH),
config.SLOTS_PER_EPOCH,
)
current_epoch_start_slot = get_epoch_start_slot(
Expand Down Expand Up @@ -637,9 +635,14 @@ def process_rewards_and_penalties(state: BeaconState, config: BeaconConfig) -> B
previous_epoch_active_validator_indices = set(
get_active_validator_indices(
state.validator_registry,
state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)
state.previous_epoch(config.SLOTS_PER_EPOCH)
)
)

# do not proceed if there are no validators in the previous epoch
if not previous_epoch_active_validator_indices:
return state

previous_total_balance: Gwei = get_total_balance(
state.validator_balances,
tuple(previous_epoch_active_validator_indices),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def process_attestations(state: BeaconState,
)

# update attestations
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH)
current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
new_previous_epoch_pending_attestations = []
new_current_epoch_pending_attestations = []
Expand Down
5 changes: 2 additions & 3 deletions eth2/beacon/tools/builder/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,9 +635,8 @@ def get_committee_assignment(
``CommitteeAssignment.is_proposer`` is a bool signalling if the validator is expected to
propose a beacon block at the assigned slot.
"""
current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)
next_epoch = Epoch(current_epoch + 1)
previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH)
next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)

validate_epoch_within_previous_and_next(epoch, previous_epoch, next_epoch)

Expand Down
4 changes: 2 additions & 2 deletions eth2/beacon/types/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ def update_validator(self,
def current_epoch(self, slots_per_epoch: int) -> Epoch:
return slot_to_epoch(self.slot, slots_per_epoch)

def previous_epoch(self, slots_per_epoch: int, genesis_epoch: int) -> Epoch:
return Epoch(max(self.current_epoch(slots_per_epoch) - 1, genesis_epoch))
def previous_epoch(self, slots_per_epoch: int) -> Epoch:
return Epoch(self.current_epoch(slots_per_epoch) - 1)

def next_epoch(self, slots_per_epoch: int) -> Epoch:
return Epoch(self.current_epoch(slots_per_epoch) + 1)
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ def mock_get_beacon_proposer_index(state,
}

prev_epoch_start_slot = get_epoch_start_slot(
state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH), slots_per_epoch,
state.previous_epoch(config.SLOTS_PER_EPOCH), slots_per_epoch,
)
prev_epoch_crosslink_committees = [
get_crosslink_committees_at_slot(
Expand Down
5 changes: 4 additions & 1 deletion tests/eth2/beacon/state_machines/test_state_transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
'genesis_slot,'
),
[
(0),
# start high enough so that we do not end up with negative numbers
(104),
]
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -54,6 +55,8 @@ def test_per_slot_transition(base_db,
config,
state_slot,
keymap):
state_slot += config.GENESIS_SLOT

chaindb = BeaconChainDB(base_db)
chaindb.persist_block(genesis_block, SerenityBeaconBlock)
chaindb.persist_state(genesis_state)
Expand Down
13 changes: 4 additions & 9 deletions tests/eth2/beacon/test_committee_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,9 @@ def mock_get_epoch_committee_count(
@pytest.mark.parametrize(
(
'genesis_slot,'
'genesis_epoch,'
),
[
(0, 0),
0,
],
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -387,7 +386,6 @@ def test_get_crosslink_committees_at_slot(
slots_per_epoch,
target_committee_size,
shard_count,
genesis_epoch,
committee_config,
registry_change,
should_reseed,
Expand Down Expand Up @@ -473,8 +471,8 @@ def mock_generate_seed(state,
#
epoch = slot_to_epoch(slot, slots_per_epoch)
current_epoch = state.current_epoch(slots_per_epoch)
previous_epoch = state.previous_epoch(slots_per_epoch, genesis_epoch)
next_epoch = current_epoch + 1
previous_epoch = state.previous_epoch(slots_per_epoch)
next_epoch = state.next_epoch(slots_per_epoch)

if epoch == current_epoch:
seed = state.current_shuffling_seed
Expand Down Expand Up @@ -507,10 +505,9 @@ def mock_generate_seed(state,
@pytest.mark.parametrize(
(
'genesis_slot,'
'genesis_epoch,'
),
[
(0, 0),
0,
],
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -547,7 +544,6 @@ def test_get_beacon_proposer_index(
registry_change,
success,
sample_state,
genesis_epoch,
target_committee_size,
shard_count,
committee_config):
Expand Down Expand Up @@ -632,7 +628,6 @@ def test_get_attestation_participants(
aggregation_bitfield,
expected,
sample_state,
genesis_epoch,
target_committee_size,
shard_count,
committee_config,
Expand Down
Loading