ensure no reward for crosslinks taht can't form a chain
This commit is contained in:
parent
0a5a5b77d5
commit
a6b3b11356
|
@ -1917,6 +1917,13 @@ def get_crosslink_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
|
||||||
for slot in range(previous_epoch_start_slot, current_epoch_start_slot):
|
for slot in range(previous_epoch_start_slot, current_epoch_start_slot):
|
||||||
for crosslink_committee, shard in get_crosslink_committees_at_slot(state, slot):
|
for crosslink_committee, shard in get_crosslink_committees_at_slot(state, slot):
|
||||||
winning_root, previous_crosslink_root, participants = get_winning_root_and_participants(state, slot, shard)
|
winning_root, previous_crosslink_root, participants = get_winning_root_and_participants(state, slot, shard)
|
||||||
|
|
||||||
|
# do not count as success if winning_root did not or cannot form a chain
|
||||||
|
attempted_crosslink = Crosslink(epoch=slot_to_epoch(slot), crosslink_data_root=winning_root, previous_crosslink_root=previous_crosslink_root)
|
||||||
|
current_crosslink_root = hash_tree_root(state.current_crosslinks[shard])
|
||||||
|
if not current_crosslink_root in {previous_crosslink_root, hash_tree_root(attempted_crosslink) }:
|
||||||
|
participants = []
|
||||||
|
|
||||||
participating_balance = get_total_balance(state, participants)
|
participating_balance = get_total_balance(state, participants)
|
||||||
total_balance = get_total_balance(state, crosslink_committee)
|
total_balance = get_total_balance(state, crosslink_committee)
|
||||||
for index in crosslink_committee:
|
for index in crosslink_committee:
|
||||||
|
|
|
@ -7,12 +7,9 @@ from build.phase0.state_transition import (
|
||||||
state_transition,
|
state_transition,
|
||||||
)
|
)
|
||||||
from build.phase0.spec import (
|
from build.phase0.spec import (
|
||||||
ZERO_HASH,
|
|
||||||
cache_state,
|
cache_state,
|
||||||
get_crosslink_committee_for_attestation,
|
get_crosslink_deltas,
|
||||||
get_current_epoch,
|
|
||||||
process_crosslinks,
|
process_crosslinks,
|
||||||
slot_to_epoch,
|
|
||||||
)
|
)
|
||||||
from tests.phase0.helpers import (
|
from tests.phase0.helpers import (
|
||||||
add_attestation_to_state,
|
add_attestation_to_state,
|
||||||
|
@ -20,6 +17,7 @@ from tests.phase0.helpers import (
|
||||||
fill_aggregate_attestation,
|
fill_aggregate_attestation,
|
||||||
get_valid_attestation,
|
get_valid_attestation,
|
||||||
next_epoch,
|
next_epoch,
|
||||||
|
next_slot,
|
||||||
set_bitfield_bit,
|
set_bitfield_bit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -102,8 +100,11 @@ def test_double_late_crosslink(state):
|
||||||
next_epoch(state)
|
next_epoch(state)
|
||||||
add_attestation_to_state(state, attestation_1, state.slot + 1)
|
add_attestation_to_state(state, attestation_1, state.slot + 1)
|
||||||
|
|
||||||
state.slot = attestation_1.data.slot + spec.SLOTS_PER_EPOCH
|
for slot in range(spec.SLOTS_PER_EPOCH):
|
||||||
attestation_2 = get_valid_attestation(state)
|
attestation_2 = get_valid_attestation(state)
|
||||||
|
if attestation_2.data.shard == attestation_1.data.shard:
|
||||||
|
break
|
||||||
|
next_slot(state)
|
||||||
fill_aggregate_attestation(state, attestation_2)
|
fill_aggregate_attestation(state, attestation_2)
|
||||||
|
|
||||||
# add attestation_2 in the next epoch after attestation_1 has
|
# add attestation_2 in the next epoch after attestation_1 has
|
||||||
|
@ -115,13 +116,15 @@ def test_double_late_crosslink(state):
|
||||||
assert len(state.current_epoch_attestations) == 0
|
assert len(state.current_epoch_attestations) == 0
|
||||||
|
|
||||||
pre_state, post_state = run_process_crosslinks(state)
|
pre_state, post_state = run_process_crosslinks(state)
|
||||||
|
crosslink_deltas = get_crosslink_deltas(state)
|
||||||
|
|
||||||
shard_1 = attestation_1.data.shard
|
shard = attestation_2.data.shard
|
||||||
shard_2 = attestation_2.data.shard
|
slot = attestation_2.data.slot
|
||||||
assert shard_1 == shard_2
|
|
||||||
shard = shard_1
|
|
||||||
|
|
||||||
# ensure that the current crosslinks were not updated by the second attestation
|
# ensure that the current crosslinks were not updated by the second attestation
|
||||||
assert post_state.previous_crosslinks[shard] == post_state.current_crosslinks[shard]
|
assert post_state.previous_crosslinks[shard] == post_state.current_crosslinks[shard]
|
||||||
|
# ensure no reward, only penalties for the failed crosslink
|
||||||
|
assert crosslink_deltas[0][slot % spec.SLOTS_PER_EPOCH] == 0
|
||||||
|
assert crosslink_deltas[1][slot % spec.SLOTS_PER_EPOCH] > 0
|
||||||
|
|
||||||
return pre_state, post_state
|
return pre_state, post_state
|
||||||
|
|
|
@ -274,7 +274,7 @@ def get_valid_attester_slashing(state):
|
||||||
def get_valid_attestation(state, slot=None):
|
def get_valid_attestation(state, slot=None):
|
||||||
if slot is None:
|
if slot is None:
|
||||||
slot = state.slot
|
slot = state.slot
|
||||||
shard = state.latest_start_shard + slot % spec.SLOTS_PER_EPOCH
|
shard = (state.latest_start_shard + slot) % spec.SLOTS_PER_EPOCH
|
||||||
attestation_data = build_attestation_data(state, slot, shard)
|
attestation_data = build_attestation_data(state, slot, shard)
|
||||||
|
|
||||||
crosslink_committee = get_crosslink_committee_for_attestation(state, attestation_data)
|
crosslink_committee = get_crosslink_committee_for_attestation(state, attestation_data)
|
||||||
|
@ -341,6 +341,11 @@ def add_attestation_to_state(state, attestation, slot):
|
||||||
state_transition(state, block)
|
state_transition(state, block)
|
||||||
|
|
||||||
|
|
||||||
|
def next_slot(state):
|
||||||
|
block = build_empty_block_for_next_slot(state)
|
||||||
|
state_transition(state, block)
|
||||||
|
|
||||||
|
|
||||||
def next_epoch(state):
|
def next_epoch(state):
|
||||||
block = build_empty_block_for_next_slot(state)
|
block = build_empty_block_for_next_slot(state)
|
||||||
block.slot += spec.SLOTS_PER_EPOCH - (state.slot % spec.SLOTS_PER_EPOCH)
|
block.slot += spec.SLOTS_PER_EPOCH - (state.slot % spec.SLOTS_PER_EPOCH)
|
||||||
|
|
Loading…
Reference in New Issue