convert finality vars to epochs and do some more epohh cleaning
This commit is contained in:
parent
c9494dbf88
commit
ae5dfab217
|
@ -333,8 +333,8 @@ Code snippets appearing in `this style` are to be interpreted as Python code. Be
|
||||||
'shard_block_root': 'bytes32',
|
'shard_block_root': 'bytes32',
|
||||||
# Last crosslink's hash of root
|
# Last crosslink's hash of root
|
||||||
'latest_crosslink_root': 'bytes32',
|
'latest_crosslink_root': 'bytes32',
|
||||||
# Slot of the last justified beacon block
|
# Last justified epoch in the beacon state
|
||||||
'justified_slot': 'uint64',
|
'justified_epoch': 'uint64',
|
||||||
# Hash of the last justified beacon block
|
# Hash of the last justified beacon block
|
||||||
'justified_block_root': 'bytes32',
|
'justified_block_root': 'bytes32',
|
||||||
}
|
}
|
||||||
|
@ -487,10 +487,10 @@ Code snippets appearing in `this style` are to be interpreted as Python code. Be
|
||||||
'custody_challenges': [CustodyChallenge],
|
'custody_challenges': [CustodyChallenge],
|
||||||
|
|
||||||
# Finality
|
# Finality
|
||||||
'previous_justified_slot': 'uint64',
|
'previous_justified_epoch': 'uint64',
|
||||||
'justified_slot': 'uint64',
|
'justified_epoch': 'uint64',
|
||||||
'justification_bitfield': 'uint64',
|
'justification_bitfield': 'uint64',
|
||||||
'finalized_slot': 'uint64',
|
'finalized_epoch': 'uint64',
|
||||||
|
|
||||||
# Recent state
|
# Recent state
|
||||||
'latest_crosslinks': [Crosslink],
|
'latest_crosslinks': [Crosslink],
|
||||||
|
@ -726,7 +726,7 @@ The beacon chain fork choice rule is a hybrid that combines justification and fi
|
||||||
def lmd_ghost(store, start):
|
def lmd_ghost(store, start):
|
||||||
validators = start.state.validator_registry
|
validators = start.state.validator_registry
|
||||||
active_validators = [validators[i] for i in
|
active_validators = [validators[i] for i in
|
||||||
get_active_validator_indices(validators, start.state.slot)]
|
get_active_validator_indices(validators, current_epoch(start.state))]
|
||||||
attestation_targets = [get_latest_attestation_target(store, validator)
|
attestation_targets = [get_latest_attestation_target(store, validator)
|
||||||
for validator in active_validators]
|
for validator in active_validators]
|
||||||
def get_vote_count(block):
|
def get_vote_count(block):
|
||||||
|
@ -781,21 +781,21 @@ def current_epoch(state: BeaconState) -> int:
|
||||||
|
|
||||||
#### `is_active_validator`
|
#### `is_active_validator`
|
||||||
```python
|
```python
|
||||||
def is_active_validator(validator: Validator, slot: int) -> bool:
|
def is_active_validator(validator: Validator, epoch: int) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if ``validator`` is active.
|
Checks if ``validator`` is active.
|
||||||
"""
|
"""
|
||||||
return validator.activation_epoch <= slot_to_epoch(slot) < validator.exit_epoch
|
return validator.activation_epoch <= epoch < validator.exit_epoch
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_active_validator_indices`
|
#### `get_active_validator_indices`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_active_validator_indices(validators: [Validator], slot: int) -> List[int]:
|
def get_active_validator_indices(validators: [Validator], epoch: int) -> List[int]:
|
||||||
"""
|
"""
|
||||||
Gets indices of active validators from ``validators``.
|
Gets indices of active validators from ``validators``.
|
||||||
"""
|
"""
|
||||||
return [i for i, v in enumerate(validators) if is_active_validator(v, slot)]
|
return [i for i, v in enumerate(validators) if is_active_validator(v, epoch)]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `shuffle`
|
#### `shuffle`
|
||||||
|
@ -890,7 +890,7 @@ def get_shuffling(seed: Bytes32,
|
||||||
committee is itself a list of validator indices.
|
committee is itself a list of validator indices.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
active_validator_indices = get_active_validator_indices(validators, slot)
|
active_validator_indices = get_active_validator_indices(validators, epoch)
|
||||||
|
|
||||||
committees_per_slot = get_committee_count_per_slot(len(active_validator_indices))
|
committees_per_slot = get_committee_count_per_slot(len(active_validator_indices))
|
||||||
|
|
||||||
|
@ -936,11 +936,11 @@ def get_crosslink_committees_at_slot(state: BeaconState,
|
||||||
"""
|
"""
|
||||||
Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
||||||
"""
|
"""
|
||||||
state_epoch_slot = state.slot - (state.slot % EPOCH_LENGTH)
|
current_epoch_slot = current_epoch(state) * EPOCH_LENGTH
|
||||||
assert state_epoch_slot <= slot + EPOCH_LENGTH
|
assert current_epoch_slot <= slot + EPOCH_LENGTH
|
||||||
assert slot < state_epoch_slot + EPOCH_LENGTH
|
assert slot < current_epoch_slot + EPOCH_LENGTH
|
||||||
|
|
||||||
if slot < state_epoch_slot:
|
if slot < current_epoch_slot:
|
||||||
committees_per_slot = get_previous_epoch_committee_count_per_slot(state)
|
committees_per_slot = get_previous_epoch_committee_count_per_slot(state)
|
||||||
seed = state.previous_epoch_seed
|
seed = state.previous_epoch_seed
|
||||||
shuffling_epoch = state.previous_calculation_epoch
|
shuffling_epoch = state.previous_calculation_epoch
|
||||||
|
@ -1171,8 +1171,8 @@ def is_surround_vote(attestation_data_1: AttestationData,
|
||||||
Note: parameter order matters as this function only checks
|
Note: parameter order matters as this function only checks
|
||||||
that ``attestation_data_1`` surrounds ``attestation_data_2``.
|
that ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||||
"""
|
"""
|
||||||
source_epoch_1 = slot_to_epoch(attestation_data_1.justified_slot)
|
source_epoch_1 = attestation_data_1.justified_epoch
|
||||||
source_epoch_2 = slot_to_epoch(attestation_data_2.justified_slot)
|
source_epoch_2 = attestation_data_2.justified_epoch
|
||||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||||
return (
|
return (
|
||||||
|
@ -1201,12 +1201,12 @@ def integer_squareroot(n: int) -> int:
|
||||||
#### `entry_exit_effect_epoch`
|
#### `entry_exit_effect_epoch`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def entry_exit_effect_epoch(slot: int) -> int:
|
def entry_exit_effect_epoch(epoch: int) -> int:
|
||||||
"""
|
"""
|
||||||
An entry or exit triggered in the slot given by the input takes effect at
|
An entry or exit triggered in the ``epoch`` given by the input takes effect at
|
||||||
the epoch given by the output.
|
the epoch given by the output.
|
||||||
"""
|
"""
|
||||||
return slot_to_epoch(slot) + 1 + ENTRY_EXIT_DELAY
|
return epoch + 1 + ENTRY_EXIT_DELAY
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `bls_verify`
|
#### `bls_verify`
|
||||||
|
@ -1255,6 +1255,7 @@ A valid block with slot `GENESIS_SLOT` (a "genesis block") has the following val
|
||||||
def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
genesis_time: int,
|
genesis_time: int,
|
||||||
latest_eth1_data: Eth1Data) -> BeaconState:
|
latest_eth1_data: Eth1Data) -> BeaconState:
|
||||||
|
genesis_epoch = slot_to_epoch(GENESIS_SLOT)
|
||||||
state = BeaconState(
|
state = BeaconState(
|
||||||
# Misc
|
# Misc
|
||||||
slot=GENESIS_SLOT,
|
slot=GENESIS_SLOT,
|
||||||
|
@ -1268,7 +1269,7 @@ def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
# Validator registry
|
# Validator registry
|
||||||
validator_registry=[],
|
validator_registry=[],
|
||||||
validator_balances=[],
|
validator_balances=[],
|
||||||
validator_registry_update_epoch=slot_to_epoch(GENESIS_SLOT),
|
validator_registry_update_epoch=genesis_epoch,
|
||||||
validator_registry_exit_count=0,
|
validator_registry_exit_count=0,
|
||||||
|
|
||||||
# Randomness and committees
|
# Randomness and committees
|
||||||
|
@ -1276,8 +1277,8 @@ def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
latest_vdf_outputs=[ZERO_HASH for _ in range(LATEST_RANDAO_MIXES_LENGTH // EPOCH_LENGTH)],
|
latest_vdf_outputs=[ZERO_HASH for _ in range(LATEST_RANDAO_MIXES_LENGTH // EPOCH_LENGTH)],
|
||||||
previous_epoch_start_shard=GENESIS_START_SHARD,
|
previous_epoch_start_shard=GENESIS_START_SHARD,
|
||||||
current_epoch_start_shard=GENESIS_START_SHARD,
|
current_epoch_start_shard=GENESIS_START_SHARD,
|
||||||
previous_calculation_epoch=slot_to_epoch(GENESIS_SLOT),
|
previous_calculation_epoch=genesis_epoch,
|
||||||
current_calculation_epoch=slot_to_epoch(GENESIS_SLOT),
|
current_calculation_epoch=genesis_epoch,
|
||||||
previous_epoch_seed=ZERO_HASH,
|
previous_epoch_seed=ZERO_HASH,
|
||||||
current_epoch_seed=ZERO_HASH,
|
current_epoch_seed=ZERO_HASH,
|
||||||
|
|
||||||
|
@ -1285,13 +1286,13 @@ def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
custody_challenges=[],
|
custody_challenges=[],
|
||||||
|
|
||||||
# Finality
|
# Finality
|
||||||
previous_justified_slot=GENESIS_SLOT,
|
previous_justified_epoch=genesis_epoch,
|
||||||
justified_slot=GENESIS_SLOT,
|
justified_epoch=genesis_epoch,
|
||||||
justification_bitfield=0,
|
justification_bitfield=0,
|
||||||
finalized_slot=GENESIS_SLOT,
|
finalized_epoch=genesis_epoch,
|
||||||
|
|
||||||
# Recent state
|
# Recent state
|
||||||
latest_crosslinks=[Crosslink(epoch=slot_to_epoch(GENESIS_SLOT), shard_block_root=ZERO_HASH) for _ in range(SHARD_COUNT)],
|
latest_crosslinks=[Crosslink(epoch=genesis_epoch, shard_block_root=ZERO_HASH) for _ in range(SHARD_COUNT)],
|
||||||
latest_block_roots=[ZERO_HASH for _ in range(LATEST_BLOCK_ROOTS_LENGTH)],
|
latest_block_roots=[ZERO_HASH for _ in range(LATEST_BLOCK_ROOTS_LENGTH)],
|
||||||
latest_index_roots=[ZERO_HASH for _ in range(LATEST_INDEX_ROOTS_LENGTH)],
|
latest_index_roots=[ZERO_HASH for _ in range(LATEST_INDEX_ROOTS_LENGTH)],
|
||||||
latest_penalized_balances=[0 for _ in range(LATEST_PENALIZED_EXIT_LENGTH)],
|
latest_penalized_balances=[0 for _ in range(LATEST_PENALIZED_EXIT_LENGTH)],
|
||||||
|
@ -1318,7 +1319,6 @@ def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
if get_effective_balance(state, validator_index) >= MAX_DEPOSIT_AMOUNT:
|
if get_effective_balance(state, validator_index) >= MAX_DEPOSIT_AMOUNT:
|
||||||
activate_validator(state, validator_index, True)
|
activate_validator(state, validator_index, True)
|
||||||
|
|
||||||
genesis_epoch = current_epoch(state)
|
|
||||||
state.latest_index_roots[genesis_epoch % LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state, genesis_epoch))
|
state.latest_index_roots[genesis_epoch % LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state, genesis_epoch))
|
||||||
state.current_epoch_seed = generate_seed(state, genesis_epoch)
|
state.current_epoch_seed = generate_seed(state, genesis_epoch)
|
||||||
|
|
||||||
|
@ -1409,7 +1409,7 @@ Note: All functions in this section mutate `state`.
|
||||||
def activate_validator(state: BeaconState, index: int, genesis: bool) -> None:
|
def activate_validator(state: BeaconState, index: int, genesis: bool) -> None:
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
|
|
||||||
validator.activation_epoch = slot_to_epoch(GENESIS_SLOT) if genesis else entry_exit_effect_epoch(state.slot)
|
validator.activation_epoch = slot_to_epoch(GENESIS_SLOT) if genesis else entry_exit_effect_epoch(current_epoch(state))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -1423,10 +1423,10 @@ def exit_validator(state: BeaconState, index: int) -> None:
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
|
|
||||||
# The following updates only occur if not previous exited
|
# The following updates only occur if not previous exited
|
||||||
if validator.exit_epoch <= entry_exit_effect_epoch(state.slot):
|
if validator.exit_epoch <= entry_exit_effect_epoch(current_epoch(state)):
|
||||||
return
|
return
|
||||||
|
|
||||||
validator.exit_epoch = entry_exit_effect_epoch(state.slot)
|
validator.exit_epoch = entry_exit_effect_epoch(current_epoch(state))
|
||||||
|
|
||||||
state.validator_registry_exit_count += 1
|
state.validator_registry_exit_count += 1
|
||||||
validator.exit_count = state.validator_registry_exit_count
|
validator.exit_count = state.validator_registry_exit_count
|
||||||
|
@ -1504,7 +1504,7 @@ For each `proposer_slashing` in `block.body.proposer_slashings`:
|
||||||
* Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`.
|
* Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`.
|
||||||
* Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`.
|
* Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`.
|
||||||
* Verify that `proposer_slashing.proposal_data_1.block_root != proposer_slashing.proposal_data_2.block_root`.
|
* Verify that `proposer_slashing.proposal_data_1.block_root != proposer_slashing.proposal_data_2.block_root`.
|
||||||
* Verify that `proposer.penalized_slot > state.slot`.
|
* Verify that `proposer.penalized_epoch > current_epoch(state)`.
|
||||||
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_1), signature=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`.
|
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_1), signature=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`.
|
||||||
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_2), signature=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`.
|
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_2), signature=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`.
|
||||||
* Run `penalize_validator(state, proposer_slashing.proposer_index)`.
|
* Run `penalize_validator(state, proposer_slashing.proposer_index)`.
|
||||||
|
@ -1524,7 +1524,7 @@ For each `casper_slashing` in `block.body.casper_slashings`:
|
||||||
* Verify that `is_double_vote(slashable_vote_data_1.data, slashable_vote_data_2.data)` or `is_surround_vote(slashable_vote_data_1.data, slashable_vote_data_2.data)`.
|
* Verify that `is_double_vote(slashable_vote_data_1.data, slashable_vote_data_2.data)` or `is_surround_vote(slashable_vote_data_1.data, slashable_vote_data_2.data)`.
|
||||||
* Verify that `verify_slashable_vote_data(state, slashable_vote_data_1)`.
|
* Verify that `verify_slashable_vote_data(state, slashable_vote_data_1)`.
|
||||||
* Verify that `verify_slashable_vote_data(state, slashable_vote_data_2)`.
|
* Verify that `verify_slashable_vote_data(state, slashable_vote_data_2)`.
|
||||||
* For each [validator](#dfn-validator) index `i` in `intersection` run `penalize_validator(state, i)` if `state.validator_registry[i].penalized_slot > state.slot`.
|
* For each [validator](#dfn-validator) index `i` in `intersection` run `penalize_validator(state, i)` if `state.validator_registry[i].penalized_epoch > current_epoch(state)`.
|
||||||
|
|
||||||
#### Attestations
|
#### Attestations
|
||||||
|
|
||||||
|
@ -1534,8 +1534,8 @@ For each `attestation` in `block.body.attestations`:
|
||||||
|
|
||||||
* Verify that `attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot`.
|
* Verify that `attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot`.
|
||||||
* Verify that `attestation.data.slot + EPOCH_LENGTH >= state.slot`.
|
* Verify that `attestation.data.slot + EPOCH_LENGTH >= state.slot`.
|
||||||
* Verify that `attestation.data.justified_slot` is equal to `state.justified_slot if attestation.data.slot >= state.slot - (state.slot % EPOCH_LENGTH) else state.previous_justified_slot`.
|
* Verify that `attestation.data.justified_epoch` is equal to `state.justified_epoch if attestation.data.slot >= state.slot - (state.slot % EPOCH_LENGTH) else state.previous_justified_epoch`.
|
||||||
* Verify that `attestation.data.justified_block_root` is equal to `get_block_root(state, attestation.data.justified_slot)`.
|
* Verify that `attestation.data.justified_block_root` is equal to `get_block_root(state, attestation.data.justified_epoch * EPOCH_LENGTH)`.
|
||||||
* Verify that either `attestation.data.latest_crosslink_root` or `attestation.data.shard_block_root` equals `state.latest_crosslinks[shard].shard_block_root`.
|
* Verify that either `attestation.data.latest_crosslink_root` or `attestation.data.shard_block_root` equals `state.latest_crosslinks[shard].shard_block_root`.
|
||||||
* `aggregate_signature` verification:
|
* `aggregate_signature` verification:
|
||||||
* Let `participants = get_attestation_participants(state, attestation.data, attestation.aggregation_bitfield)`.
|
* Let `participants = get_attestation_participants(state, attestation.data, attestation.aggregation_bitfield)`.
|
||||||
|
@ -1586,7 +1586,7 @@ Verify that `len(block.body.exits) <= MAX_EXITS`.
|
||||||
For each `exit` in `block.body.exits`:
|
For each `exit` in `block.body.exits`:
|
||||||
|
|
||||||
* Let `validator = state.validator_registry[exit.validator_index]`.
|
* Let `validator = state.validator_registry[exit.validator_index]`.
|
||||||
* Verify that `validator.exit_epoch > entry_exit_effect_epoch(state.slot)`.
|
* Verify that `validator.exit_epoch > entry_exit_effect_epoch(current_epoch(state))`.
|
||||||
* Verify that `state.slot >= exit.slot`.
|
* Verify that `state.slot >= exit.slot`.
|
||||||
* Let `exit_message = hash_tree_root(Exit(slot=exit.slot, validator_index=exit.validator_index, signature=EMPTY_SIGNATURE))`.
|
* Let `exit_message = hash_tree_root(Exit(slot=exit.slot, validator_index=exit.validator_index, signature=EMPTY_SIGNATURE))`.
|
||||||
* Verify that `bls_verify(pubkey=validator.pubkey, message=exit_message, signature=exit.signature, domain=get_domain(state.fork, exit.slot, DOMAIN_EXIT))`.
|
* Verify that `bls_verify(pubkey=validator.pubkey, message=exit_message, signature=exit.signature, domain=get_domain(state.fork, exit.slot, DOMAIN_EXIT))`.
|
||||||
|
@ -1617,7 +1617,7 @@ All [validators](#dfn-validator):
|
||||||
|
|
||||||
* Let `current_epoch_attestations = [a for a in state.latest_attestations if current_epoch_start_slot <= a.data.slot < next_epoch_start_slot]`. (Note: this is the set of attestations of slots in the epoch `current_epoch_start_slot...next_epoch_start_slot`, _not_ attestations that got included in the chain during the epoch `current_epoch_start_slot...next_epoch_start_slot`.)
|
* Let `current_epoch_attestations = [a for a in state.latest_attestations if current_epoch_start_slot <= a.data.slot < next_epoch_start_slot]`. (Note: this is the set of attestations of slots in the epoch `current_epoch_start_slot...next_epoch_start_slot`, _not_ attestations that got included in the chain during the epoch `current_epoch_start_slot...next_epoch_start_slot`.)
|
||||||
* Validators justifying the epoch boundary block at the start of the current epoch:
|
* Validators justifying the epoch boundary block at the start of the current epoch:
|
||||||
* Let `current_epoch_boundary_attestations = [a for a in current_epoch_attestations if a.data.epoch_boundary_root == get_block_root(state, current_epoch_start_slot) and a.data.justified_slot == state.justified_slot]`.
|
* Let `current_epoch_boundary_attestations = [a for a in current_epoch_attestations if a.data.epoch_boundary_root == get_block_root(state, current_epoch_start_slot) and a.data.justified_epoch == state.justified_epoch]`.
|
||||||
* Let `current_epoch_boundary_attester_indices` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.aggregation_bitfield) for a in current_epoch_boundary_attestations]`.
|
* Let `current_epoch_boundary_attester_indices` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.aggregation_bitfield) for a in current_epoch_boundary_attestations]`.
|
||||||
* Let `current_epoch_boundary_attesting_balance = sum([get_effective_balance(state, i) for i in current_epoch_boundary_attester_indices])`.
|
* Let `current_epoch_boundary_attesting_balance = sum([get_effective_balance(state, i) for i in current_epoch_boundary_attester_indices])`.
|
||||||
|
|
||||||
|
@ -1627,7 +1627,7 @@ All [validators](#dfn-validator):
|
||||||
* Let `previous_epoch_attestations = [a for a in state.latest_attestations if previous_epoch_start_slot <= a.data.slot < current_epoch_start_slot]`.
|
* Let `previous_epoch_attestations = [a for a in state.latest_attestations if previous_epoch_start_slot <= a.data.slot < current_epoch_start_slot]`.
|
||||||
* Let `previous_epoch_attester_indices` be the union of the validator index sets given by `[get_attestation_participants(state, a.data, a.aggregation_bitfield) for a in previous_epoch_attestations]`.
|
* Let `previous_epoch_attester_indices` be the union of the validator index sets given by `[get_attestation_participants(state, a.data, a.aggregation_bitfield) for a in previous_epoch_attestations]`.
|
||||||
* Validators targeting the previous justified slot:
|
* Validators targeting the previous justified slot:
|
||||||
* Let `previous_epoch_justified_attestations = [a for a in current_epoch_attestations + previous_epoch_attestations if a.data.justified_slot == state.previous_justified_slot]`.
|
* Let `previous_epoch_justified_attestations = [a for a in current_epoch_attestations + previous_epoch_attestations if a.data.justified_epoch == state.previous_justified_epoch]`.
|
||||||
* Let `previous_epoch_justified_attester_indices` be the union of the validator index sets given by `[get_attestation_participants(state, a.data, a.aggregation_bitfield) for a in previous_epoch_justified_attestations]`.
|
* Let `previous_epoch_justified_attester_indices` be the union of the validator index sets given by `[get_attestation_participants(state, a.data, a.aggregation_bitfield) for a in previous_epoch_justified_attestations]`.
|
||||||
* Let `previous_epoch_justified_attesting_balance = sum([get_effective_balance(state, i) for i in previous_epoch_justified_attester_indices])`.
|
* Let `previous_epoch_justified_attesting_balance = sum([get_effective_balance(state, i) for i in previous_epoch_justified_attester_indices])`.
|
||||||
* Validators justifying the epoch boundary block at the start of the previous epoch:
|
* Validators justifying the epoch boundary block at the start of the previous epoch:
|
||||||
|
@ -1666,22 +1666,22 @@ If `current_epoch(state) % ETH1_DATA_VOTING_PERIOD == 0`:
|
||||||
|
|
||||||
First, update the justification bitfield:
|
First, update the justification bitfield:
|
||||||
|
|
||||||
* Let `new_justified_slot = state.justified_slot`.
|
* Let `new_justified_epoch = state.justified_epoch`.
|
||||||
* Set `state.justification_bitfield = (state.justification_bitfield * 2) % 2**64`.
|
* Set `state.justification_bitfield = (state.justification_bitfield * 2) % 2**64`.
|
||||||
* Set `state.justification_bitfield |= 2` and `new_justified_slot = previous_epoch_start_slot` if `3 * previous_epoch_boundary_attesting_balance >= 2 * total_balance`.
|
* Set `state.justification_bitfield |= 2` and `new_justified_epoch = previous_epoch` if `3 * previous_epoch_boundary_attesting_balance >= 2 * total_balance`.
|
||||||
* Set `state.justification_bitfield |= 1` and `new_justified_slot = current_epoch_start_slot` if `3 * current_epoch_boundary_attesting_balance >= 2 * total_balance`.
|
* Set `state.justification_bitfield |= 1` and `new_justified_epoch = current_epoch(state)` if `3 * current_epoch_boundary_attesting_balance >= 2 * total_balance`.
|
||||||
|
|
||||||
Next, update last finalized slot if possible:
|
Next, update last finalized slot if possible:
|
||||||
|
|
||||||
* Set `state.finalized_slot = state.previous_justified_slot` if `(state.justification_bitfield >> 1) % 8 == 0b111 and state.previous_justified_slot == previous_epoch_start_slot - 2 * EPOCH_LENGTH`.
|
* Set `state.finalized_epoch = state.previous_justified_epoch` if `(state.justification_bitfield >> 1) % 8 == 0b111 and state.previous_justified_epoch == previous_epoch - 2`.
|
||||||
* Set `state.finalized_slot = state.previous_justified_slot` if `(state.justification_bitfield >> 1) % 4 == 0b11 and state.previous_justified_slot == previous_epoch_start_slot - EPOCH_LENGTH`.
|
* Set `state.finalized_epoch = state.previous_justified_epoch` if `(state.justification_bitfield >> 1) % 4 == 0b11 and state.previous_justified_epoch == previous_epoch - 1`.
|
||||||
* Set `state.finalized_slot = state.justified_slot` if `(state.justification_bitfield >> 0) % 8 == 0b111 and state.justified_slot == previous_epoch_start_slot - EPOCH_LENGTH`.
|
* Set `state.finalized_epoch = state.justified_epoch` if `(state.justification_bitfield >> 0) % 8 == 0b111 and state.justified_epoch == previous_epoch - 1`.
|
||||||
* Set `state.finalized_slot = state.justified_slot` if `(state.justification_bitfield >> 0) % 4 == 0b11 and state.justified_slot == previous_epoch_start_slot`.
|
* Set `state.finalized_epoch = state.justified_epoch` if `(state.justification_bitfield >> 0) % 4 == 0b11 and state.justified_epoch == previous_epoch`.
|
||||||
|
|
||||||
Finally, update the following:
|
Finally, update the following:
|
||||||
|
|
||||||
* Set `state.previous_justified_slot = state.justified_slot`.
|
* Set `state.previous_justified_epoch = state.justified_epoch`.
|
||||||
* Set `state.justified_slot = justified_slot`.
|
* Set `state.justified_epoch = new_justified_epoch`.
|
||||||
|
|
||||||
### Crosslinks
|
### Crosslinks
|
||||||
|
|
||||||
|
@ -1701,7 +1701,7 @@ First, we define some additional helpers:
|
||||||
|
|
||||||
Note: When applying penalties in the following balance recalculations implementers should make sure the `uint64` does not underflow.
|
Note: When applying penalties in the following balance recalculations implementers should make sure the `uint64` does not underflow.
|
||||||
|
|
||||||
* Let `epochs_since_finality = next_epoch - slot_to_epoch(state.finalized_slot)`.
|
* Let `epochs_since_finality = next_epoch - state.finalized_epoch`.
|
||||||
|
|
||||||
Case 1: `epochs_since_finality <= 4`:
|
Case 1: `epochs_since_finality <= 4`:
|
||||||
|
|
||||||
|
@ -1758,11 +1758,11 @@ First, update the following:
|
||||||
* Set `state.previous_calculation_epoch = state.current_calculation_epoch`.
|
* Set `state.previous_calculation_epoch = state.current_calculation_epoch`.
|
||||||
* Set `state.previous_epoch_start_shard = state.current_epoch_start_shard`.
|
* Set `state.previous_epoch_start_shard = state.current_epoch_start_shard`.
|
||||||
* Set `state.previous_epoch_seed = state.current_epoch_seed`.
|
* Set `state.previous_epoch_seed = state.current_epoch_seed`.
|
||||||
* Set `state.latest_index_roots[next_epoch % LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state, next_epoch_start_slot))`.
|
* Set `state.latest_index_roots[next_epoch % LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state, next_epoch))`.
|
||||||
|
|
||||||
If the following are satisfied:
|
If the following are satisfied:
|
||||||
|
|
||||||
* `slot_to_epoch(state.finalized_slot) > state.validator_registry_update_epoch`
|
* `state.finalized_epoch > state.validator_registry_update_epoch`
|
||||||
* `state.latest_crosslinks[shard].epoch > state.validator_registry_update_epoch` for every shard number `shard` in `[(state.current_epoch_start_shard + i) % SHARD_COUNT for i in range(get_current_epoch_committee_count_per_slot(state) * EPOCH_LENGTH)]` (that is, for every shard in the current committees)
|
* `state.latest_crosslinks[shard].epoch > state.validator_registry_update_epoch` for every shard number `shard` in `[(state.current_epoch_start_shard + i) % SHARD_COUNT for i in range(get_current_epoch_committee_count_per_slot(state) * EPOCH_LENGTH)]` (that is, for every shard in the current committees)
|
||||||
|
|
||||||
update the validator registry and associated fields by running
|
update the validator registry and associated fields by running
|
||||||
|
@ -1787,7 +1787,7 @@ def update_validator_registry(state: BeaconState) -> None:
|
||||||
# Activate validators within the allowable balance churn
|
# Activate validators within the allowable balance churn
|
||||||
balance_churn = 0
|
balance_churn = 0
|
||||||
for index, validator in enumerate(state.validator_registry):
|
for index, validator in enumerate(state.validator_registry):
|
||||||
if validator.activation_epoch > entry_exit_effect_epoch(state.slot) and state.validator_balances[index] >= MAX_DEPOSIT_AMOUNT:
|
if validator.activation_epoch > entry_exit_effect_epoch(current_epoch(state)) and state.validator_balances[index] >= MAX_DEPOSIT_AMOUNT:
|
||||||
# Check the balance churn would be within the allowance
|
# Check the balance churn would be within the allowance
|
||||||
balance_churn += get_effective_balance(state, index)
|
balance_churn += get_effective_balance(state, index)
|
||||||
if balance_churn > max_balance_churn:
|
if balance_churn > max_balance_churn:
|
||||||
|
@ -1799,7 +1799,7 @@ def update_validator_registry(state: BeaconState) -> None:
|
||||||
# Exit validators within the allowable balance churn
|
# Exit validators within the allowable balance churn
|
||||||
balance_churn = 0
|
balance_churn = 0
|
||||||
for index, validator in enumerate(state.validator_registry):
|
for index, validator in enumerate(state.validator_registry):
|
||||||
if validator.exit_epoch > entry_exit_effect_epoch(state.slot) and validator.status_flags & INITIATED_EXIT:
|
if validator.exit_epoch > entry_exit_effect_epoch(current_epoch(state)) and validator.status_flags & INITIATED_EXIT:
|
||||||
# Check the balance churn would be within the allowance
|
# Check the balance churn would be within the allowance
|
||||||
balance_churn += get_effective_balance(state, index)
|
balance_churn += get_effective_balance(state, index)
|
||||||
if balance_churn > max_balance_churn:
|
if balance_churn > max_balance_churn:
|
||||||
|
@ -1832,7 +1832,7 @@ Regardless of whether or not a validator set change happens, run the following:
|
||||||
```python
|
```python
|
||||||
def process_penalties_and_exits(state: BeaconState) -> None:
|
def process_penalties_and_exits(state: BeaconState) -> None:
|
||||||
# The active validators
|
# The active validators
|
||||||
active_validator_indices = get_active_validator_indices(state.validator_registry, state.slot)
|
active_validator_indices = get_active_validator_indices(state.validator_registry, current_epoch(state))
|
||||||
# The total effective balance of active validators
|
# The total effective balance of active validators
|
||||||
total_balance = sum([get_effective_balance(state, i) for i in active_validator_indices])
|
total_balance = sum([get_effective_balance(state, i) for i in active_validator_indices])
|
||||||
|
|
||||||
|
@ -1867,7 +1867,7 @@ def process_penalties_and_exits(state: BeaconState) -> None:
|
||||||
### Final updates
|
### Final updates
|
||||||
|
|
||||||
* Set `state.latest_penalized_balances[(next_epoch) % LATEST_PENALIZED_EXIT_LENGTH] = state.latest_penalized_balances[current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH]`.
|
* Set `state.latest_penalized_balances[(next_epoch) % LATEST_PENALIZED_EXIT_LENGTH] = state.latest_penalized_balances[current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH]`.
|
||||||
* Remove any `attestation` in `state.latest_attestations` such that `attestation.data.slot < current_epoch_start_slot`.
|
* Remove any `attestation` in `state.latest_attestations` such that `slot_to_epoch(attestation.data.slot) < current_epoch(state)`.
|
||||||
|
|
||||||
## State root processing
|
## State root processing
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue