Refactor the tests
This commit is contained in:
parent
ff85025113
commit
977cd73379
|
@ -1,6 +1,6 @@
|
||||||
from eth2spec.test.helpers.attestations import get_valid_on_time_attestation
|
from eth2spec.test.helpers.attestations import get_valid_on_time_attestation
|
||||||
from eth2spec.test.helpers.block import get_state_and_beacon_parent_root_at_slot
|
from eth2spec.test.helpers.block import get_state_and_beacon_parent_root_at_slot
|
||||||
from eth2spec.test.helpers.state import next_slots
|
from eth2spec.test.helpers.state import transition_to
|
||||||
from eth2spec.test.helpers.keys import privkeys
|
from eth2spec.test.helpers.keys import privkeys
|
||||||
from eth2spec.utils import bls
|
from eth2spec.utils import bls
|
||||||
from eth2spec.utils.bls import only_with_bls
|
from eth2spec.utils.bls import only_with_bls
|
||||||
|
@ -51,18 +51,17 @@ def build_shard_block(spec,
|
||||||
return signed_block
|
return signed_block
|
||||||
|
|
||||||
|
|
||||||
def build_shard_transitions_till_slot(spec, state, shards, shard_blocks, target_len_offset_slot):
|
def build_shard_transitions_till_slot(spec, state, shard_blocks, on_time_slot):
|
||||||
state = state.copy()
|
temp_state = state.copy()
|
||||||
next_slots(spec, state, target_len_offset_slot)
|
transition_to(spec, temp_state, on_time_slot)
|
||||||
shard_transitions = [spec.ShardTransition()] * spec.MAX_SHARDS
|
shard_transitions = [spec.ShardTransition()] * spec.MAX_SHARDS
|
||||||
for shard in shards:
|
for shard, blocks in shard_blocks.items():
|
||||||
offset_slots = spec.get_offset_slots(state, shard)
|
offset_slots = spec.get_offset_slots(temp_state, shard)
|
||||||
len_offset_slots = len(offset_slots)
|
len_offset_slots = len(offset_slots)
|
||||||
assert len_offset_slots == target_len_offset_slot
|
assert len_offset_slots == on_time_slot - state.shard_states[shard].slot - 1
|
||||||
shard_blocks_of_shard = shard_blocks[shard]
|
shard_transition = spec.get_shard_transition(temp_state, shard, blocks)
|
||||||
shard_transition = spec.get_shard_transition(state, shard, shard_blocks_of_shard)
|
if len(blocks) > 0:
|
||||||
if len(shard_blocks_of_shard) > 0:
|
shard_block_root = blocks[-1].message.hash_tree_root()
|
||||||
shard_block_root = shard_blocks_of_shard[-1].message.hash_tree_root()
|
|
||||||
assert shard_transition.shard_states[len_offset_slots - 1].latest_block_root == shard_block_root
|
assert shard_transition.shard_states[len_offset_slots - 1].latest_block_root == shard_block_root
|
||||||
assert shard_transition.shard_states[len_offset_slots - 1].slot == offset_slots[-1]
|
assert shard_transition.shard_states[len_offset_slots - 1].slot == offset_slots[-1]
|
||||||
shard_transitions[shard] = shard_transition
|
shard_transitions[shard] = shard_transition
|
||||||
|
@ -70,19 +69,17 @@ def build_shard_transitions_till_slot(spec, state, shards, shard_blocks, target_
|
||||||
return shard_transitions
|
return shard_transitions
|
||||||
|
|
||||||
|
|
||||||
def build_attestation_with_shard_transition(spec, state, slot, index, target_len_offset_slot, shard_transition=None):
|
def build_attestation_with_shard_transition(spec, state, index, on_time_slot, shard_transition=None):
|
||||||
state = state.copy()
|
temp_state = state.copy()
|
||||||
next_slots(spec, state, target_len_offset_slot)
|
transition_to(spec, temp_state, on_time_slot - 1)
|
||||||
attestation = get_valid_on_time_attestation(
|
attestation = get_valid_on_time_attestation(
|
||||||
spec,
|
spec,
|
||||||
state,
|
temp_state,
|
||||||
slot=slot,
|
|
||||||
index=index,
|
index=index,
|
||||||
shard_transition=shard_transition,
|
shard_transition=shard_transition,
|
||||||
signed=True,
|
signed=True,
|
||||||
)
|
)
|
||||||
assert attestation.data.slot == slot
|
assert attestation.data.slot == temp_state.slot
|
||||||
if shard_transition is not None:
|
if shard_transition is not None:
|
||||||
assert target_len_offset_slot == len(shard_transition.shard_states)
|
|
||||||
assert attestation.data.shard_transition_root == shard_transition.hash_tree_root()
|
assert attestation.data.shard_transition_root == shard_transition.hash_tree_root()
|
||||||
return attestation
|
return attestation
|
||||||
|
|
|
@ -30,6 +30,16 @@ def transition_to(spec, state, slot):
|
||||||
assert state.slot == slot
|
assert state.slot == slot
|
||||||
|
|
||||||
|
|
||||||
|
def transition_to_valid_shard_slot(spec, state):
|
||||||
|
"""
|
||||||
|
Transition to slot `spec.PHASE_1_GENESIS_SLOT + 1` and fork at `spec.PHASE_1_GENESIS_SLOT`.
|
||||||
|
"""
|
||||||
|
transition_to(spec, state, spec.PHASE_1_GENESIS_SLOT)
|
||||||
|
state = spec.upgrade_to_phase1(state) # `upgrade_to_phase1` is a pure function
|
||||||
|
next_slot(spec, state)
|
||||||
|
return state
|
||||||
|
|
||||||
|
|
||||||
def next_epoch(spec, state):
|
def next_epoch(spec, state):
|
||||||
"""
|
"""
|
||||||
Transition to the start slot of the next epoch
|
Transition to the start slot of the next epoch
|
||||||
|
|
|
@ -10,50 +10,45 @@ from eth2spec.test.helpers.shard_block import (
|
||||||
build_shard_block,
|
build_shard_block,
|
||||||
build_shard_transitions_till_slot,
|
build_shard_transitions_till_slot,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.state import next_epoch, next_slot, transition_to
|
from eth2spec.test.helpers.state import transition_to, transition_to_valid_shard_slot
|
||||||
|
|
||||||
|
|
||||||
def run_basic_crosslink_tests(spec, state, target_len_offset_slot):
|
def run_basic_crosslink_tests(spec, state, target_len_offset_slot, valid=True):
|
||||||
next_epoch(spec, state)
|
state = transition_to_valid_shard_slot(spec, state)
|
||||||
next_epoch(spec, state)
|
|
||||||
state = spec.upgrade_to_phase1(state)
|
|
||||||
next_slot(spec, state)
|
|
||||||
|
|
||||||
# At the beginning, let `x = state.slot`, `state.shard_states[shard].slot == x - 1`
|
# At the beginning, let `x = state.slot`, `state.shard_states[shard].slot == x - 1`
|
||||||
slot_x = state.slot
|
slot_x = state.slot
|
||||||
committee_index = spec.CommitteeIndex(0)
|
committee_index = spec.CommitteeIndex(0)
|
||||||
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
||||||
assert state.shard_states[shard].slot == slot_x - 1
|
assert state.shard_states[shard].slot == slot_x - 1
|
||||||
|
|
||||||
# Create SignedShardBlock at slot `shard_state.slot + 1` -> x
|
# Create SignedShardBlock
|
||||||
body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
|
body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
|
||||||
shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
|
shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
|
||||||
shard_blocks = [shard_block]
|
shard_blocks = [shard_block]
|
||||||
|
# Create a shard_transitions that would be included at beacon block `state.slot + target_len_offset_slot`
|
||||||
# Attester creates `attestation` at slot x
|
|
||||||
# Use temporary next state to get ShardTransition of shard block
|
|
||||||
shard_transitions = build_shard_transitions_till_slot(
|
shard_transitions = build_shard_transitions_till_slot(
|
||||||
spec,
|
spec,
|
||||||
state,
|
state,
|
||||||
shards=[shard, ],
|
|
||||||
shard_blocks={shard: shard_blocks},
|
shard_blocks={shard: shard_blocks},
|
||||||
target_len_offset_slot=target_len_offset_slot,
|
on_time_slot=state.slot + target_len_offset_slot,
|
||||||
)
|
)
|
||||||
shard_transition = shard_transitions[shard]
|
shard_transition = shard_transitions[shard]
|
||||||
|
# Create an attestation that would be included at beacon block `state.slot + target_len_offset_slot`
|
||||||
attestation = build_attestation_with_shard_transition(
|
attestation = build_attestation_with_shard_transition(
|
||||||
spec,
|
spec,
|
||||||
state,
|
state,
|
||||||
slot=slot_x + target_len_offset_slot - 1,
|
|
||||||
index=committee_index,
|
index=committee_index,
|
||||||
target_len_offset_slot=target_len_offset_slot,
|
on_time_slot=state.slot + target_len_offset_slot,
|
||||||
shard_transition=shard_transition,
|
shard_transition=shard_transition,
|
||||||
)
|
)
|
||||||
pre_gasprice = state.shard_states[shard].gasprice
|
pre_gasprice = state.shard_states[shard].gasprice
|
||||||
|
|
||||||
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
|
transition_to(spec, state, state.slot + target_len_offset_slot)
|
||||||
pre_shard_state = state.shard_states[shard]
|
pre_shard_state = state.shard_states[shard]
|
||||||
yield from run_crosslinks_processing(spec, state, shard_transitions, [attestation])
|
|
||||||
|
|
||||||
|
yield from run_crosslinks_processing(spec, state, shard_transitions, [attestation], valid=valid)
|
||||||
|
|
||||||
|
if valid:
|
||||||
# After state transition,
|
# After state transition,
|
||||||
assert state.slot == slot_x + target_len_offset_slot
|
assert state.slot == slot_x + target_len_offset_slot
|
||||||
shard_state = state.shard_states[shard]
|
shard_state = state.shard_states[shard]
|
||||||
|
@ -68,11 +63,11 @@ def run_basic_crosslink_tests(spec, state, target_len_offset_slot):
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
def test_basic_crosslinks(spec, state):
|
def test_basic_crosslinks(spec, state):
|
||||||
run_basic_crosslink_tests(spec, state, target_len_offset_slot=1)
|
yield from run_basic_crosslink_tests(spec, state, target_len_offset_slot=1, valid=True)
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases_except([PHASE0])
|
@with_all_phases_except([PHASE0])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
def test_multiple_offset_slots(spec, state):
|
def test_multiple_offset_slots(spec, state):
|
||||||
run_basic_crosslink_tests(spec, state, target_len_offset_slot=3)
|
yield from run_basic_crosslink_tests(spec, state, target_len_offset_slot=3, valid=True)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from typing import Dict, Sequence
|
||||||
|
|
||||||
from eth2spec.test.context import (
|
from eth2spec.test.context import (
|
||||||
PHASE0,
|
PHASE0,
|
||||||
with_all_phases_except,
|
with_all_phases_except,
|
||||||
|
@ -10,69 +12,74 @@ from eth2spec.test.helpers.shard_block import (
|
||||||
build_shard_block,
|
build_shard_block,
|
||||||
build_shard_transitions_till_slot,
|
build_shard_transitions_till_slot,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.state import next_epoch, next_slot, state_transition_and_sign_block
|
from eth2spec.test.helpers.state import state_transition_and_sign_block, transition_to_valid_shard_slot
|
||||||
|
|
||||||
|
|
||||||
|
def run_beacon_block_with_shard_blocks(spec, state, shard_blocks, target_len_offset_slot, committee_index, valid=True):
|
||||||
|
shard_transitions = build_shard_transitions_till_slot(
|
||||||
|
spec, state, shard_blocks, on_time_slot=state.slot + target_len_offset_slot
|
||||||
|
)
|
||||||
|
attestations = [
|
||||||
|
build_attestation_with_shard_transition(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
on_time_slot=state.slot + target_len_offset_slot,
|
||||||
|
index=committee_index,
|
||||||
|
shard_transition=shard_transitions[shard],
|
||||||
|
)
|
||||||
|
for shard in shard_blocks.keys()
|
||||||
|
]
|
||||||
|
|
||||||
|
# Propose beacon block at slot `x + 1`
|
||||||
|
beacon_block = build_empty_block(spec, state, slot=state.slot + target_len_offset_slot)
|
||||||
|
beacon_block.body.attestations = attestations
|
||||||
|
beacon_block.body.shard_transitions = shard_transitions
|
||||||
|
|
||||||
|
pre_shard_states = state.shard_states.copy()
|
||||||
|
yield 'pre', state.copy()
|
||||||
|
yield 'block', beacon_block
|
||||||
|
state_transition_and_sign_block(spec, state, beacon_block)
|
||||||
|
if valid:
|
||||||
|
yield 'post', state
|
||||||
|
else:
|
||||||
|
yield 'post', None
|
||||||
|
return
|
||||||
|
|
||||||
|
for shard in range(spec.get_active_shard_count(state)):
|
||||||
|
post_shard_state = state.shard_states[shard]
|
||||||
|
if shard in shard_blocks:
|
||||||
|
# Shard state has been changed to state_transition result
|
||||||
|
assert post_shard_state == shard_transitions[shard].shard_states[
|
||||||
|
len(shard_transitions[shard].shard_states) - 1
|
||||||
|
]
|
||||||
|
assert beacon_block.slot == shard_transitions[shard].shard_states[0].slot + target_len_offset_slot
|
||||||
|
assert post_shard_state.slot == state.slot - 1
|
||||||
|
if len(shard_blocks[shard]) == 0:
|
||||||
|
# `latest_block_root` is the same
|
||||||
|
assert post_shard_state.latest_block_root == pre_shard_states[shard].latest_block_root
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases_except([PHASE0])
|
@with_all_phases_except([PHASE0])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
def test_process_beacon_block_with_normal_shard_transition(spec, state):
|
def test_process_beacon_block_with_normal_shard_transition(spec, state):
|
||||||
next_epoch(spec, state)
|
state = transition_to_valid_shard_slot(spec, state)
|
||||||
next_epoch(spec, state)
|
|
||||||
state = spec.upgrade_to_phase1(state)
|
|
||||||
next_slot(spec, state)
|
|
||||||
|
|
||||||
target_len_offset_slot = 1
|
target_len_offset_slot = 1
|
||||||
|
|
||||||
# At the beginning, let `x = state.slot`, `state.shard_states[shard].slot == x - 1`
|
|
||||||
slot_x = state.slot
|
|
||||||
committee_index = spec.CommitteeIndex(0)
|
committee_index = spec.CommitteeIndex(0)
|
||||||
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
||||||
assert state.shard_states[shard].slot == slot_x - 1
|
assert state.shard_states[shard].slot == state.slot - 1
|
||||||
|
|
||||||
# Create SignedShardBlock at slot `shard_state.slot + 1` -> x
|
|
||||||
body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
|
|
||||||
shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
|
|
||||||
shard_blocks = [shard_block]
|
|
||||||
|
|
||||||
# Attester creates `attestation` at slot x
|
|
||||||
# Use temporary next state to get ShardTransition of shard block
|
|
||||||
shard_transitions = build_shard_transitions_till_slot(
|
|
||||||
spec,
|
|
||||||
state,
|
|
||||||
shards=[shard, ],
|
|
||||||
shard_blocks={shard: shard_blocks},
|
|
||||||
target_len_offset_slot=target_len_offset_slot,
|
|
||||||
)
|
|
||||||
shard_transition = shard_transitions[shard]
|
|
||||||
attestation = build_attestation_with_shard_transition(
|
|
||||||
spec,
|
|
||||||
state,
|
|
||||||
slot=slot_x + target_len_offset_slot - 1,
|
|
||||||
index=committee_index,
|
|
||||||
target_len_offset_slot=target_len_offset_slot,
|
|
||||||
shard_transition=shard_transition,
|
|
||||||
)
|
|
||||||
pre_gasprice = state.shard_states[shard].gasprice
|
pre_gasprice = state.shard_states[shard].gasprice
|
||||||
|
|
||||||
# Propose beacon block at slot `x + 1`
|
# Create SignedShardBlock at slot `shard_state.slot + 1`
|
||||||
pre_shard_state = state.shard_states[shard]
|
body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
|
||||||
beacon_block_1 = build_empty_block(spec, state, slot=slot_x + target_len_offset_slot)
|
shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
|
||||||
beacon_block_1.body.attestations = [attestation]
|
shard_blocks: Dict[spec.Shard, Sequence[spec.SignedShardBlock]] = {shard: [shard_block]}
|
||||||
beacon_block_1.body.shard_transitions = shard_transitions
|
|
||||||
assert (
|
yield from run_beacon_block_with_shard_blocks(spec, state, shard_blocks, target_len_offset_slot, committee_index)
|
||||||
beacon_block_1.slot == slot_x + target_len_offset_slot
|
|
||||||
== shard_transition.shard_states[0].slot + target_len_offset_slot
|
|
||||||
)
|
|
||||||
state_transition_and_sign_block(spec, state, beacon_block_1)
|
|
||||||
|
|
||||||
# After state transition
|
|
||||||
assert state.slot == slot_x + target_len_offset_slot
|
|
||||||
shard_state = state.shard_states[shard]
|
shard_state = state.shard_states[shard]
|
||||||
# latest_block_root has changed
|
|
||||||
assert shard_state.latest_block_root == shard_block.message.hash_tree_root()
|
|
||||||
assert shard_state != pre_shard_state
|
|
||||||
assert shard_state == shard_transition.shard_states[len(shard_transition.shard_states) - 1]
|
|
||||||
|
|
||||||
if target_len_offset_slot == 1 and len(shard_blocks) > 0:
|
if target_len_offset_slot == 1 and len(shard_blocks) > 0:
|
||||||
assert shard_state.gasprice > pre_gasprice
|
assert shard_state.gasprice > pre_gasprice
|
||||||
|
@ -82,60 +89,19 @@ def test_process_beacon_block_with_normal_shard_transition(spec, state):
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
def test_process_beacon_block_with_empty_proposal_transition(spec, state):
|
def test_process_beacon_block_with_empty_proposal_transition(spec, state):
|
||||||
next_epoch(spec, state)
|
state = transition_to_valid_shard_slot(spec, state)
|
||||||
next_epoch(spec, state)
|
|
||||||
state = spec.upgrade_to_phase1(state)
|
|
||||||
next_slot(spec, state)
|
|
||||||
|
|
||||||
target_len_offset_slot = 1
|
target_len_offset_slot = 1
|
||||||
|
|
||||||
# At the beginning, let `x = state.slot`, `state.shard_states[shard].slot == x - 1`
|
|
||||||
slot_x = state.slot
|
|
||||||
committee_index = spec.CommitteeIndex(0)
|
committee_index = spec.CommitteeIndex(0)
|
||||||
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
||||||
assert state.shard_states[shard].slot == slot_x - 1
|
assert state.shard_states[shard].slot == state.slot - 1
|
||||||
|
|
||||||
# No new shard block
|
# No new shard block
|
||||||
shard_blocks = []
|
shard_blocks = {}
|
||||||
|
|
||||||
# Attester creates `attestation` at slot x
|
|
||||||
# Use temporary next state to get ShardTransition of shard block
|
|
||||||
shard_transitions = build_shard_transitions_till_slot(
|
|
||||||
spec,
|
|
||||||
state,
|
|
||||||
shards=[shard, ],
|
|
||||||
shard_blocks={shard: shard_blocks},
|
|
||||||
target_len_offset_slot=target_len_offset_slot,
|
|
||||||
)
|
|
||||||
shard_transition = shard_transitions[shard]
|
|
||||||
attestation = build_attestation_with_shard_transition(
|
|
||||||
spec,
|
|
||||||
state,
|
|
||||||
slot=slot_x + target_len_offset_slot - 1,
|
|
||||||
index=committee_index,
|
|
||||||
target_len_offset_slot=target_len_offset_slot,
|
|
||||||
shard_transition=shard_transition,
|
|
||||||
)
|
|
||||||
pre_gasprice = state.shard_states[shard].gasprice
|
pre_gasprice = state.shard_states[shard].gasprice
|
||||||
|
|
||||||
# Propose beacon block at slot `x + 1`
|
yield from run_beacon_block_with_shard_blocks(spec, state, shard_blocks, target_len_offset_slot, committee_index)
|
||||||
pre_shard_state = state.shard_states[shard]
|
|
||||||
beacon_block_1 = build_empty_block(spec, state, slot=slot_x + target_len_offset_slot)
|
|
||||||
beacon_block_1.body.attestations = [attestation]
|
|
||||||
beacon_block_1.body.shard_transitions = shard_transitions
|
|
||||||
assert (
|
|
||||||
beacon_block_1.slot == slot_x + target_len_offset_slot
|
|
||||||
== shard_transition.shard_states[0].slot + target_len_offset_slot
|
|
||||||
)
|
|
||||||
state_transition_and_sign_block(spec, state, beacon_block_1)
|
|
||||||
|
|
||||||
# After state transition
|
|
||||||
assert state.slot == slot_x + target_len_offset_slot
|
|
||||||
shard_state = state.shard_states[shard]
|
|
||||||
# latest_block_root hasn't changed
|
|
||||||
assert shard_state.latest_block_root == pre_shard_state.latest_block_root
|
|
||||||
assert shard_state != pre_shard_state
|
|
||||||
assert shard_state == shard_transition.shard_states[len(shard_transition.shard_states) - 1]
|
|
||||||
|
|
||||||
if target_len_offset_slot == 1 and len(shard_blocks) > 0:
|
if target_len_offset_slot == 1 and len(shard_blocks) > 0:
|
||||||
assert shard_state.gasprice > pre_gasprice
|
assert state.shard_states[shard].gasprice > pre_gasprice
|
||||||
|
|
Loading…
Reference in New Issue