mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-01-12 03:34:20 +00:00
convert _root/_epoch tuples to Checkpoint obj in beacon spec
This commit is contained in:
parent
65bcb8884f
commit
de5b9cc823
@ -26,6 +26,7 @@
|
||||
- [Misc dependencies](#misc-dependencies)
|
||||
- [`Fork`](#fork)
|
||||
- [`Validator`](#validator)
|
||||
- [`Checkpoint`](#checkpoint)
|
||||
- [`Crosslink`](#crosslink)
|
||||
- [`AttestationData`](#attestationdata)
|
||||
- [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit)
|
||||
@ -303,6 +304,14 @@ class Fork(Container):
|
||||
epoch: Epoch # Epoch of latest fork
|
||||
```
|
||||
|
||||
#### `Checkpoint`
|
||||
|
||||
```python
|
||||
class Checkpoint(Container):
|
||||
epoch: Epoch
|
||||
root: Hash
|
||||
```
|
||||
|
||||
#### `Validator`
|
||||
|
||||
```python
|
||||
@ -337,10 +346,8 @@ class AttestationData(Container):
|
||||
# LMD GHOST vote
|
||||
beacon_block_root: Hash
|
||||
# FFG vote
|
||||
source_epoch: Epoch
|
||||
source_root: Hash
|
||||
target_epoch: Epoch
|
||||
target_root: Hash
|
||||
source_checkpoint: Checkpoint
|
||||
target_checkpoint: Checkpoint
|
||||
# Crosslink vote
|
||||
crosslink: Crosslink
|
||||
```
|
||||
@ -534,14 +541,11 @@ class BeaconState(Container):
|
||||
previous_crosslinks: Vector[Crosslink, SHARD_COUNT] # Previous epoch snapshot
|
||||
current_crosslinks: Vector[Crosslink, SHARD_COUNT]
|
||||
# Justification
|
||||
previous_justified_epoch: Epoch # Previous epoch snapshot
|
||||
previous_justified_root: Hash # Previous epoch snapshot
|
||||
current_justified_epoch: Epoch
|
||||
current_justified_root: Hash
|
||||
previous_justified_checkpoint: Checkpoint # Previous epoch snapshot
|
||||
current_justified_checkpoint: Checkpoint
|
||||
justification_bitfield: uint64 # Bit set for every recent justified epoch
|
||||
# Finality
|
||||
finalized_epoch: Epoch
|
||||
finalized_root: Hash
|
||||
finalized_checkpoint: Checkpoint
|
||||
```
|
||||
|
||||
## Helper functions
|
||||
@ -715,9 +719,10 @@ def get_epoch_start_shard(state: BeaconState, epoch: Epoch) -> Shard:
|
||||
|
||||
```python
|
||||
def get_attestation_data_slot(state: BeaconState, data: AttestationData) -> Slot:
|
||||
committee_count = get_epoch_committee_count(state, data.target_epoch)
|
||||
offset = (data.crosslink.shard + SHARD_COUNT - get_epoch_start_shard(state, data.target_epoch)) % SHARD_COUNT
|
||||
return Slot(get_epoch_start_slot(data.target_epoch) + offset // (committee_count // SLOTS_PER_EPOCH))
|
||||
target_epoch = data.target_checkpoint.epoch
|
||||
committee_count = get_epoch_committee_count(state, target_epoch)
|
||||
offset = (data.crosslink.shard + SHARD_COUNT - get_epoch_start_shard(state, target_epoch)) % SHARD_COUNT
|
||||
return Slot(get_epoch_start_slot(target_epoch) + offset // (committee_count // SLOTS_PER_EPOCH))
|
||||
```
|
||||
|
||||
### `get_block_root_at_slot`
|
||||
@ -876,12 +881,12 @@ def get_crosslink_committee(state: BeaconState, epoch: Epoch, shard: Shard) -> L
|
||||
|
||||
```python
|
||||
def get_attesting_indices(state: BeaconState,
|
||||
attestation_data: AttestationData,
|
||||
data: AttestationData,
|
||||
bitfield: bytes) -> List[ValidatorIndex]:
|
||||
"""
|
||||
Return the sorted attesting indices corresponding to ``attestation_data`` and ``bitfield``.
|
||||
Return the sorted attesting indices corresponding to ``data`` and ``bitfield``.
|
||||
"""
|
||||
committee = get_crosslink_committee(state, attestation_data.target_epoch, attestation_data.crosslink.shard)
|
||||
committee = get_crosslink_committee(state, data.target_checkpoint.epoch, data.crosslink.shard)
|
||||
assert verify_bitfield(bitfield, len(committee))
|
||||
return sorted([index for i, index in enumerate(committee) if get_bitfield_bit(bitfield, i) == 0b1])
|
||||
```
|
||||
@ -1001,7 +1006,7 @@ def validate_indexed_attestation(state: BeaconState, indexed_attestation: Indexe
|
||||
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b1)),
|
||||
],
|
||||
signature=indexed_attestation.signature,
|
||||
domain=get_domain(state, DOMAIN_ATTESTATION, indexed_attestation.data.target_epoch),
|
||||
domain=get_domain(state, DOMAIN_ATTESTATION, indexed_attestation.data.target_checkpoint.epoch),
|
||||
)
|
||||
```
|
||||
|
||||
@ -1014,9 +1019,12 @@ def is_slashable_attestation_data(data_1: AttestationData, data_2: AttestationDa
|
||||
"""
|
||||
return (
|
||||
# Double vote
|
||||
(data_1 != data_2 and data_1.target_epoch == data_2.target_epoch) or
|
||||
(data_1 != data_2 and data_1.target_checkpoint.epoch == data_2.target_checkpoint.epoch) or
|
||||
# Surround vote
|
||||
(data_1.source_epoch < data_2.source_epoch and data_2.target_epoch < data_1.target_epoch)
|
||||
(
|
||||
data_1.source_checkpoint.epoch < data_2.source_checkpoint.epoch and
|
||||
data_2.target_checkpoint.epoch < data_1.target_checkpoint.epoch
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
@ -1274,7 +1282,7 @@ def get_matching_source_attestations(state: BeaconState, epoch: Epoch) -> List[P
|
||||
def get_matching_target_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
|
||||
return [
|
||||
a for a in get_matching_source_attestations(state, epoch)
|
||||
if a.data.target_root == get_block_root(state, epoch)
|
||||
if a.data.target_checkpoint.root == get_block_root(state, epoch)
|
||||
]
|
||||
```
|
||||
|
||||
@ -1326,46 +1334,39 @@ def process_justification_and_finalization(state: BeaconState) -> None:
|
||||
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
current_epoch = get_current_epoch(state)
|
||||
old_previous_justified_epoch = state.previous_justified_epoch
|
||||
old_current_justified_epoch = state.current_justified_epoch
|
||||
old_previous_justified_checkpoint = state.previous_justified_checkpoint
|
||||
old_current_justified_checkpoint = state.current_justified_checkpoint
|
||||
|
||||
# Process justifications
|
||||
state.previous_justified_epoch = state.current_justified_epoch
|
||||
state.previous_justified_root = state.current_justified_root
|
||||
state.previous_justified_checkpoint = state.current_justified_checkpoint
|
||||
state.justification_bitfield = (state.justification_bitfield << 1) % 2**64
|
||||
previous_epoch_matching_target_balance = get_attesting_balance(
|
||||
state, get_matching_target_attestations(state, previous_epoch)
|
||||
)
|
||||
if previous_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
||||
state.current_justified_epoch = previous_epoch
|
||||
state.current_justified_root = get_block_root(state, state.current_justified_epoch)
|
||||
state.current_justified_checkpoint = Checkpoint(previous_epoch, get_block_root(state, previous_epoch))
|
||||
state.justification_bitfield |= (1 << 1)
|
||||
current_epoch_matching_target_balance = get_attesting_balance(
|
||||
state, get_matching_target_attestations(state, current_epoch)
|
||||
)
|
||||
if current_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
||||
state.current_justified_epoch = current_epoch
|
||||
state.current_justified_root = get_block_root(state, state.current_justified_epoch)
|
||||
state.current_justified_checkpoint = Checkpoint(current_epoch, get_block_root(state, current_epoch))
|
||||
state.justification_bitfield |= (1 << 0)
|
||||
|
||||
# Process finalizations
|
||||
bitfield = state.justification_bitfield
|
||||
# The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th as source
|
||||
if (bitfield >> 1) % 8 == 0b111 and old_previous_justified_epoch + 3 == current_epoch:
|
||||
state.finalized_epoch = old_previous_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint = old_previous_justified_checkpoint
|
||||
# The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as source
|
||||
if (bitfield >> 1) % 4 == 0b11 and old_previous_justified_epoch + 2 == current_epoch:
|
||||
state.finalized_epoch = old_previous_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint = old_previous_justified_checkpoint
|
||||
# The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as source
|
||||
if (bitfield >> 0) % 8 == 0b111 and old_current_justified_epoch + 2 == current_epoch:
|
||||
state.finalized_epoch = old_current_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint = old_current_justified_checkpoint
|
||||
# The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
|
||||
if (bitfield >> 0) % 4 == 0b11 and old_current_justified_epoch + 1 == current_epoch:
|
||||
state.finalized_epoch = old_current_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint = old_current_justified_checkpoint
|
||||
```
|
||||
|
||||
#### Crosslinks
|
||||
@ -1428,7 +1429,7 @@ def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
|
||||
rewards[index] += Gwei(max_attester_reward * MIN_ATTESTATION_INCLUSION_DELAY // attestation.inclusion_delay)
|
||||
|
||||
# Inactivity penalty
|
||||
finality_delay = previous_epoch - state.finalized_epoch
|
||||
finality_delay = previous_epoch - state.finalized_checkpoint.epoch
|
||||
if finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY:
|
||||
matching_target_attesting_indices = get_unslashed_attesting_indices(state, matching_target_attestations)
|
||||
for index in eligible_validator_indices:
|
||||
@ -1493,7 +1494,7 @@ def process_registry_updates(state: BeaconState) -> None:
|
||||
activation_queue = sorted([
|
||||
index for index, validator in enumerate(state.validators) if
|
||||
validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and
|
||||
validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_epoch)
|
||||
validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_checkpoint.epoch)
|
||||
], key=lambda index: state.validators[index].activation_eligibility_epoch)
|
||||
# Dequeued validators for activation up to churn limit (without resetting activation epoch)
|
||||
for index in activation_queue[:get_churn_limit(state)]:
|
||||
@ -1691,9 +1692,10 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||
Process ``Attestation`` operation.
|
||||
"""
|
||||
data = attestation.data
|
||||
target_epoch = data.target_checkpoint.epoch
|
||||
|
||||
assert data.crosslink.shard < SHARD_COUNT
|
||||
assert data.target_epoch in (get_previous_epoch(state), get_current_epoch(state))
|
||||
assert target_epoch in (get_previous_epoch(state), get_current_epoch(state))
|
||||
|
||||
attestation_slot = get_attestation_data_slot(state, data)
|
||||
assert attestation_slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= attestation_slot + SLOTS_PER_EPOCH
|
||||
@ -1705,19 +1707,19 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||
proposer_index=get_beacon_proposer_index(state),
|
||||
)
|
||||
|
||||
if data.target_epoch == get_current_epoch(state):
|
||||
ffg_data = (state.current_justified_epoch, state.current_justified_root, get_current_epoch(state))
|
||||
if target_epoch == get_current_epoch(state):
|
||||
ffg_source = state.current_justified_checkpoint
|
||||
parent_crosslink = state.current_crosslinks[data.crosslink.shard]
|
||||
state.current_epoch_attestations.append(pending_attestation)
|
||||
else:
|
||||
ffg_data = (state.previous_justified_epoch, state.previous_justified_root, get_previous_epoch(state))
|
||||
ffg_source = state.previous_justified_checkpoint
|
||||
parent_crosslink = state.previous_crosslinks[data.crosslink.shard]
|
||||
state.previous_epoch_attestations.append(pending_attestation)
|
||||
|
||||
# Check FFG data, crosslink data, and signature
|
||||
assert ffg_data == (data.source_epoch, data.source_root, data.target_epoch)
|
||||
# Check FFG source, crosslink data, and signature
|
||||
assert ffg_source == data.source_checkpoint
|
||||
assert data.crosslink.start_epoch == parent_crosslink.end_epoch
|
||||
assert data.crosslink.end_epoch == min(data.target_epoch, parent_crosslink.end_epoch + MAX_EPOCHS_PER_CROSSLINK)
|
||||
assert data.crosslink.end_epoch == min(target_epoch, parent_crosslink.end_epoch + MAX_EPOCHS_PER_CROSSLINK)
|
||||
assert data.crosslink.parent_root == hash_tree_root(parent_crosslink)
|
||||
assert data.crosslink.data_root == ZERO_HASH # [to be removed in phase 1]
|
||||
validate_indexed_attestation(state, convert_to_indexed(state, attestation))
|
||||
|
Loading…
x
Reference in New Issue
Block a user