Merge pull request #1895 from ethereum/hwwhww/attestation-shard
Add `shard: Shard` field to `AttestationData`
This commit is contained in:
commit
05453b786d
|
@ -54,7 +54,6 @@
|
|||
- [`get_shard_proposer_index`](#get_shard_proposer_index)
|
||||
- [`get_committee_count_delta`](#get_committee_count_delta)
|
||||
- [`get_start_shard`](#get_start_shard)
|
||||
- [`get_shard`](#get_shard)
|
||||
- [`get_latest_slot_for_shard`](#get_latest_slot_for_shard)
|
||||
- [`get_offset_slots`](#get_offset_slots)
|
||||
- [Predicates](#predicates)
|
||||
|
@ -167,6 +166,8 @@ class AttestationData(Container):
|
|||
# FFG vote
|
||||
source: Checkpoint
|
||||
target: Checkpoint
|
||||
# Shard vote
|
||||
shard: Shard
|
||||
# Current-slot shard block root
|
||||
shard_head_root: Root
|
||||
# Shard transition root
|
||||
|
@ -621,16 +622,6 @@ def get_start_shard(state: BeaconState, slot: Slot) -> Shard:
|
|||
)
|
||||
```
|
||||
|
||||
#### `get_shard`
|
||||
|
||||
```python
|
||||
def get_shard(state: BeaconState, attestation: Attestation) -> Shard:
|
||||
"""
|
||||
Return the shard that the given ``attestation`` is attesting.
|
||||
"""
|
||||
return compute_shard_from_committee_index(state, attestation.data.index, attestation.data.slot)
|
||||
```
|
||||
|
||||
#### `get_latest_slot_for_shard`
|
||||
|
||||
```python
|
||||
|
@ -775,6 +766,9 @@ def validate_attestation(state: BeaconState, attestation: Attestation) -> None:
|
|||
if is_on_time_attestation(state, attestation):
|
||||
# Correct parent block root
|
||||
assert data.beacon_block_root == get_block_root_at_slot(state, compute_previous_slot(state.slot))
|
||||
# Correct shard number
|
||||
shard = compute_shard_from_committee_index(state, attestation.data.index, attestation.data.slot)
|
||||
assert attestation.data.shard == shard
|
||||
# Type 2: no shard transition
|
||||
else:
|
||||
# Ensure delayed attestation
|
||||
|
@ -879,7 +873,6 @@ def process_crosslink_for_shard(state: BeaconState,
|
|||
on_time_attestation_slot = compute_previous_slot(state.slot)
|
||||
committee = get_beacon_committee(state, on_time_attestation_slot, committee_index)
|
||||
online_indices = get_online_validator_indices(state)
|
||||
shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot)
|
||||
|
||||
# Loop over all shard transition roots
|
||||
shard_transition_roots = set([a.data.shard_transition_root for a in attestations])
|
||||
|
@ -905,7 +898,7 @@ def process_crosslink_for_shard(state: BeaconState,
|
|||
assert shard_transition_root == hash_tree_root(shard_transition)
|
||||
|
||||
# Apply transition
|
||||
apply_shard_transition(state, shard, shard_transition)
|
||||
apply_shard_transition(state, attestation.data.shard, shard_transition)
|
||||
# Apply proposer reward and cost
|
||||
beacon_proposer_index = get_beacon_proposer_index(state)
|
||||
estimated_attester_reward = sum([get_base_reward(state, attester) for attester in transition_participants])
|
||||
|
@ -913,11 +906,11 @@ def process_crosslink_for_shard(state: BeaconState,
|
|||
increase_balance(state, beacon_proposer_index, proposer_reward)
|
||||
states_slots_lengths = zip(
|
||||
shard_transition.shard_states,
|
||||
get_offset_slots(state, shard),
|
||||
get_offset_slots(state, attestation.data.shard),
|
||||
shard_transition.shard_block_lengths
|
||||
)
|
||||
for shard_state, slot, length in states_slots_lengths:
|
||||
proposer_index = get_shard_proposer_index(state, slot, shard)
|
||||
proposer_index = get_shard_proposer_index(state, slot, attestation.data.shard)
|
||||
decrease_balance(state, proposer_index, shard_state.gasprice * length)
|
||||
|
||||
# Return winning transition root
|
||||
|
@ -938,12 +931,15 @@ def process_crosslinks(state: BeaconState,
|
|||
committee_count = get_committee_count_at_slot(state, on_time_attestation_slot)
|
||||
for committee_index in map(CommitteeIndex, range(committee_count)):
|
||||
# All attestations in the block for this committee/shard and current slot
|
||||
shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot)
|
||||
# Since the attestations are validated, all `shard_attestations` satisfy `attestation.data.shard == shard`
|
||||
shard_attestations = [
|
||||
attestation for attestation in attestations
|
||||
if is_on_time_attestation(state, attestation) and attestation.data.index == committee_index
|
||||
]
|
||||
shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot)
|
||||
winning_root = process_crosslink_for_shard(state, committee_index, shard_transitions[shard], shard_attestations)
|
||||
winning_root = process_crosslink_for_shard(
|
||||
state, committee_index, shard_transitions[shard], shard_attestations
|
||||
)
|
||||
if winning_root != Root():
|
||||
# Mark relevant pending attestations as creating a successful crosslink
|
||||
for pending_attestation in state.current_epoch_attestations:
|
||||
|
|
|
@ -39,7 +39,8 @@ class LatestMessage(object):
|
|||
def update_latest_messages(store: Store, attesting_indices: Sequence[ValidatorIndex], attestation: Attestation) -> None:
|
||||
target = attestation.data.target
|
||||
beacon_block_root = attestation.data.beacon_block_root
|
||||
shard = get_shard(store.block_states[beacon_block_root], attestation)
|
||||
# TODO: separate shard chain vote
|
||||
shard = attestation.data.shard
|
||||
for i in attesting_indices:
|
||||
if i not in store.latest_messages or target.epoch > store.latest_messages[i].epoch:
|
||||
store.latest_messages[i] = LatestMessage(
|
||||
|
|
|
@ -124,8 +124,7 @@ def is_valid_fraud_proof(beacon_state: BeaconState,
|
|||
# 2. Check if the shard state transition result is wrong between
|
||||
# `transition.shard_states[offset_index - 1]` to `transition.shard_states[offset_index]`.
|
||||
if offset_index == 0:
|
||||
shard = get_shard(beacon_state, attestation)
|
||||
shard_states = beacon_parent_block.body.shard_transitions[shard].shard_states
|
||||
shard_states = beacon_parent_block.body.shard_transitions[attestation.data.shard].shard_states
|
||||
shard_state = shard_states[len(shard_states) - 1]
|
||||
else:
|
||||
shard_state = transition.shard_states[offset_index - 1] # Not doing the actual state updates here.
|
||||
|
|
|
@ -26,7 +26,7 @@ def run_on_attestation(spec, state, store, attestation, valid=True):
|
|||
latest_message = spec.LatestMessage(
|
||||
epoch=attestation.data.target.epoch,
|
||||
root=attestation.data.beacon_block_root,
|
||||
shard=spec.get_shard(state, attestation),
|
||||
shard=attestation.data.shard,
|
||||
shard_root=attestation.data.shard_head_root,
|
||||
)
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ def apply_shard_and_beacon(spec, state, store, shard_store, shard_blocks_buffer)
|
|||
shard_transition=shard_transition,
|
||||
signed=False,
|
||||
)
|
||||
assert spec.get_shard(state, attestation) == shard
|
||||
assert attestation.data.shard == shard
|
||||
beacon_block.body.attestations = [attestation]
|
||||
beacon_block.body.shard_transitions = shard_transitions
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ def run_attestation_processing(spec, state, attestation, valid=True):
|
|||
yield 'post', state
|
||||
|
||||
|
||||
def build_attestation_data(spec, state, slot, index, shard_transition=None, on_time=True):
|
||||
def build_attestation_data(spec, state, slot, index, shard=None, shard_transition=None, on_time=True):
|
||||
assert state.slot >= slot
|
||||
|
||||
if slot == state.slot:
|
||||
|
@ -78,13 +78,15 @@ def build_attestation_data(spec, state, slot, index, shard_transition=None, on_t
|
|||
)
|
||||
|
||||
if spec.fork == PHASE1:
|
||||
if shard is None:
|
||||
shard = spec.compute_shard_from_committee_index(state, attestation_data.index, attestation_data.slot)
|
||||
attestation_data.shard = shard
|
||||
|
||||
if shard_transition is not None:
|
||||
lastest_shard_data_root_index = len(shard_transition.shard_data_roots) - 1
|
||||
attestation_data.shard_head_root = shard_transition.shard_data_roots[lastest_shard_data_root_index]
|
||||
attestation_data.shard_transition_root = shard_transition.hash_tree_root()
|
||||
else:
|
||||
# No shard transition -> no shard block
|
||||
shard = spec.get_shard(state, spec.Attestation(data=attestation_data))
|
||||
if on_time:
|
||||
shard_transition = spec.get_shard_transition(state, shard, shard_blocks=[])
|
||||
lastest_shard_data_root_index = len(shard_transition.shard_data_roots) - 1
|
||||
|
|
Loading…
Reference in New Issue