Merge pull request #756 from ethereum/store-justified-root
cache justified roots in state/rename attestation fields
This commit is contained in:
commit
9ee7ed061e
|
@ -335,22 +335,19 @@ The types are defined topologically to aid in facilitating an executable version
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{
|
{
|
||||||
# Slot number
|
# LMD GHOST vote
|
||||||
'slot': 'uint64',
|
'slot': 'uint64',
|
||||||
# Shard number
|
|
||||||
'shard': 'uint64',
|
|
||||||
# Root of the signed beacon block
|
|
||||||
'beacon_block_root': 'bytes32',
|
'beacon_block_root': 'bytes32',
|
||||||
# Root of the ancestor at the epoch boundary
|
|
||||||
'epoch_boundary_root': 'bytes32',
|
# FFG vote
|
||||||
# Data from the shard since the last attestation
|
'source_epoch': 'uint64',
|
||||||
|
'source_root': 'bytes32',
|
||||||
|
'target_root': 'bytes32',
|
||||||
|
|
||||||
|
# Crosslink vote
|
||||||
|
'shard': 'uint64',
|
||||||
|
'previous_crosslink': Crosslink,
|
||||||
'crosslink_data_root': 'bytes32',
|
'crosslink_data_root': 'bytes32',
|
||||||
# Last crosslink
|
|
||||||
'latest_crosslink': Crosslink,
|
|
||||||
# Last justified epoch in the beacon state
|
|
||||||
'justified_epoch': 'uint64',
|
|
||||||
# Hash of the last justified beacon block
|
|
||||||
'justified_block_root': 'bytes32',
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -612,9 +609,12 @@ The types are defined topologically to aid in facilitating an executable version
|
||||||
'previous_epoch_attestations': [PendingAttestation],
|
'previous_epoch_attestations': [PendingAttestation],
|
||||||
'current_epoch_attestations': [PendingAttestation],
|
'current_epoch_attestations': [PendingAttestation],
|
||||||
'previous_justified_epoch': 'uint64',
|
'previous_justified_epoch': 'uint64',
|
||||||
'justified_epoch': 'uint64',
|
'current_justified_epoch': 'uint64',
|
||||||
|
'previous_justified_root': 'bytes32',
|
||||||
|
'current_justified_root': 'bytes32',
|
||||||
'justification_bitfield': 'uint64',
|
'justification_bitfield': 'uint64',
|
||||||
'finalized_epoch': 'uint64',
|
'finalized_epoch': 'uint64',
|
||||||
|
'finalized_root': 'bytes32',
|
||||||
|
|
||||||
# Recent state
|
# Recent state
|
||||||
'latest_crosslinks': [Crosslink, SHARD_COUNT],
|
'latest_crosslinks': [Crosslink, SHARD_COUNT],
|
||||||
|
@ -1222,8 +1222,8 @@ def is_surround_vote(attestation_data_1: AttestationData,
|
||||||
"""
|
"""
|
||||||
Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||||
"""
|
"""
|
||||||
source_epoch_1 = attestation_data_1.justified_epoch
|
source_epoch_1 = attestation_data_1.source_epoch
|
||||||
source_epoch_2 = attestation_data_2.justified_epoch
|
source_epoch_2 = attestation_data_2.source_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)
|
||||||
|
|
||||||
|
@ -1540,9 +1540,12 @@ def get_genesis_beacon_state(genesis_validator_deposits: List[Deposit],
|
||||||
previous_epoch_attestations=[],
|
previous_epoch_attestations=[],
|
||||||
current_epoch_attestations=[],
|
current_epoch_attestations=[],
|
||||||
previous_justified_epoch=GENESIS_EPOCH,
|
previous_justified_epoch=GENESIS_EPOCH,
|
||||||
justified_epoch=GENESIS_EPOCH,
|
current_justified_epoch=GENESIS_EPOCH,
|
||||||
|
previous_justified_root=ZERO_HASH,
|
||||||
|
current_justified_root=ZERO_HASH,
|
||||||
justification_bitfield=0,
|
justification_bitfield=0,
|
||||||
finalized_epoch=GENESIS_EPOCH,
|
finalized_epoch=GENESIS_EPOCH,
|
||||||
|
finalized_root=ZERO_HASH,
|
||||||
|
|
||||||
# Recent state
|
# Recent state
|
||||||
latest_crosslinks=[Crosslink(epoch=GENESIS_EPOCH, crosslink_data_root=ZERO_HASH) for _ in range(SHARD_COUNT)],
|
latest_crosslinks=[Crosslink(epoch=GENESIS_EPOCH, crosslink_data_root=ZERO_HASH) for _ in range(SHARD_COUNT)],
|
||||||
|
@ -1724,7 +1727,7 @@ def get_attesting_balance(state: BeaconState, attestations: List[PendingAttestat
|
||||||
def get_current_epoch_boundary_attestations(state: BeaconState) -> List[PendingAttestation]:
|
def get_current_epoch_boundary_attestations(state: BeaconState) -> List[PendingAttestation]:
|
||||||
return [
|
return [
|
||||||
a for a in state.current_epoch_attestations
|
a for a in state.current_epoch_attestations
|
||||||
if a.data.epoch_boundary_root == get_block_root(state, get_epoch_start_slot(get_current_epoch(state)))
|
if a.data.target_root == get_block_root(state, get_epoch_start_slot(get_current_epoch(state)))
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1732,7 +1735,7 @@ def get_current_epoch_boundary_attestations(state: BeaconState) -> List[PendingA
|
||||||
def get_previous_epoch_boundary_attestations(state: BeaconState) -> List[PendingAttestation]:
|
def get_previous_epoch_boundary_attestations(state: BeaconState) -> List[PendingAttestation]:
|
||||||
return [
|
return [
|
||||||
a for a in state.previous_epoch_attestations
|
a for a in state.previous_epoch_attestations
|
||||||
if a.data.epoch_boundary_root == get_block_root(state, get_epoch_start_slot(get_previous_epoch(state)))
|
if a.data.target_root == get_block_root(state, get_epoch_start_slot(get_previous_epoch(state)))
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1750,7 +1753,7 @@ def get_previous_epoch_matching_head_attestations(state: BeaconState) -> List[Pe
|
||||||
def get_winning_root_and_participants(state: BeaconState, shard: Shard) -> Tuple[Bytes32, List[ValidatorIndex]]:
|
def get_winning_root_and_participants(state: BeaconState, shard: Shard) -> Tuple[Bytes32, List[ValidatorIndex]]:
|
||||||
all_attestations = state.current_epoch_attestations + state.previous_epoch_attestations
|
all_attestations = state.current_epoch_attestations + state.previous_epoch_attestations
|
||||||
valid_attestations = [
|
valid_attestations = [
|
||||||
a for a in all_attestations if a.data.latest_crosslink == state.latest_crosslinks[shard]
|
a for a in all_attestations if a.data.previous_crosslink == state.latest_crosslinks[shard]
|
||||||
]
|
]
|
||||||
all_roots = [a.data.crosslink_data_root for a in valid_attestations]
|
all_roots = [a.data.crosslink_data_root for a in valid_attestations]
|
||||||
|
|
||||||
|
@ -1793,7 +1796,9 @@ Run the following function:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def update_justification_and_finalization(state: BeaconState) -> None:
|
def update_justification_and_finalization(state: BeaconState) -> None:
|
||||||
new_justified_epoch = state.justified_epoch
|
new_justified_epoch = state.current_justified_epoch
|
||||||
|
new_finalized_epoch = state.finalized_epoch
|
||||||
|
|
||||||
# Rotate the justification bitfield up one epoch to make room for the current epoch
|
# Rotate the justification bitfield up one epoch to make room for the current epoch
|
||||||
state.justification_bitfield <<= 1
|
state.justification_bitfield <<= 1
|
||||||
# If the previous epoch gets justified, fill the second last bit
|
# If the previous epoch gets justified, fill the second last bit
|
||||||
|
@ -1812,20 +1817,26 @@ def update_justification_and_finalization(state: BeaconState) -> None:
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
# The 2nd/3rd/4th most recent epochs are all justified, the 2nd using the 4th as source
|
# The 2nd/3rd/4th most recent epochs are all justified, the 2nd using the 4th as source
|
||||||
if (bitfield >> 1) % 8 == 0b111 and state.previous_justified_epoch == current_epoch - 3:
|
if (bitfield >> 1) % 8 == 0b111 and state.previous_justified_epoch == current_epoch - 3:
|
||||||
state.finalized_epoch = state.previous_justified_epoch
|
new_finalized_epoch = state.previous_justified_epoch
|
||||||
# The 2nd/3rd most recent epochs are both justified, the 2nd using the 3rd as source
|
# The 2nd/3rd most recent epochs are both justified, the 2nd using the 3rd as source
|
||||||
if (bitfield >> 1) % 4 == 0b11 and state.previous_justified_epoch == current_epoch - 2:
|
if (bitfield >> 1) % 4 == 0b11 and state.previous_justified_epoch == current_epoch - 2:
|
||||||
state.finalized_epoch = state.previous_justified_epoch
|
new_finalized_epoch = state.previous_justified_epoch
|
||||||
# The 1st/2nd/3rd most recent epochs are all justified, the 1st using the 3rd as source
|
# The 1st/2nd/3rd most recent epochs are all justified, the 1st using the 3rd as source
|
||||||
if (bitfield >> 0) % 8 == 0b111 and state.justified_epoch == current_epoch - 2:
|
if (bitfield >> 0) % 8 == 0b111 and state.current_justified_epoch == current_epoch - 2:
|
||||||
state.finalized_epoch = state.justified_epoch
|
new_finalized_epoch = state.current_justified_epoch
|
||||||
# The 1st/2nd most recent epochs are both justified, the 1st using the 2nd as source
|
# The 1st/2nd most recent epochs are both justified, the 1st using the 2nd as source
|
||||||
if (bitfield >> 0) % 4 == 0b11 and state.justified_epoch == current_epoch - 1:
|
if (bitfield >> 0) % 4 == 0b11 and state.current_justified_epoch == current_epoch - 1:
|
||||||
state.finalized_epoch = state.justified_epoch
|
new_finalized_epoch = state.current_justified_epoch
|
||||||
|
|
||||||
# Rotate justified epochs
|
# Update state jusification/finality fields
|
||||||
state.previous_justified_epoch = state.justified_epoch
|
state.previous_justified_epoch = state.current_justified_epoch
|
||||||
state.justified_epoch = new_justified_epoch
|
state.previous_justified_root = state.current_justified_root
|
||||||
|
if new_justified_epoch != state.current_justified_epoch:
|
||||||
|
state.current_justified_epoch = new_justified_epoch
|
||||||
|
state.current_justified_root = get_block_root(state, get_epoch_start_slot(new_justified_epoch))
|
||||||
|
if new_finalized_epoch != state.finalized_epoch:
|
||||||
|
state.finalized_epoch = new_finalized_epoch
|
||||||
|
state.finalized_root = get_block_root(state, get_epoch_start_slot(new_finalized_epoch))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Crosslinks
|
#### Crosslinks
|
||||||
|
@ -2369,20 +2380,19 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||||
assert state.slot <= attestation.data.slot + SLOTS_PER_EPOCH
|
assert state.slot <= attestation.data.slot + SLOTS_PER_EPOCH
|
||||||
# Can't submit attestations too quickly
|
# Can't submit attestations too quickly
|
||||||
assert attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot
|
assert attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot
|
||||||
# Verify that the justified epoch is correct, case 1: current epoch attestations
|
# Verify that the justified epoch and root is correct
|
||||||
if slot_to_epoch(attestation.data.slot) >= get_current_epoch(state):
|
if slot_to_epoch(attestation.data.slot) >= get_current_epoch(state):
|
||||||
assert attestation.data.justified_epoch == state.justified_epoch
|
# Case 1: current epoch attestations
|
||||||
# Case 2: previous epoch attestations
|
assert attestation.data.source_epoch == state.current_justified_epoch
|
||||||
|
assert attestation.data.source_root == state.current_justified_root
|
||||||
else:
|
else:
|
||||||
assert attestation.data.justified_epoch == state.previous_justified_epoch
|
# Case 2: previous epoch attestations
|
||||||
# Check that the justified block root is correct
|
assert attestation.data.source_epoch == state.previous_justified_epoch
|
||||||
assert attestation.data.justified_block_root == get_block_root(
|
assert attestation.data.source_root == state.previous_justified_root
|
||||||
state, get_epoch_start_slot(attestation.data.justified_epoch)
|
|
||||||
)
|
|
||||||
# Check that the crosslink data is valid
|
# Check that the crosslink data is valid
|
||||||
acceptable_crosslink_data = {
|
acceptable_crosslink_data = {
|
||||||
# Case 1: Latest crosslink matches the one in the state
|
# Case 1: Latest crosslink matches the one in the state
|
||||||
attestation.data.latest_crosslink,
|
attestation.data.previous_crosslink,
|
||||||
# Case 2: State has already been updated, state's latest crosslink matches the crosslink
|
# Case 2: State has already been updated, state's latest crosslink matches the crosslink
|
||||||
# the attestation is trying to create
|
# the attestation is trying to create
|
||||||
Crosslink(
|
Crosslink(
|
||||||
|
|
Loading…
Reference in New Issue