WIP test case
This commit is contained in:
parent
26aae40941
commit
c9a53b8039
|
@ -5,6 +5,7 @@ from eth2spec.test.helpers.shard_block import (
|
||||||
build_attestation_with_shard_transition,
|
build_attestation_with_shard_transition,
|
||||||
build_shard_block,
|
build_shard_block,
|
||||||
build_shard_transitions_till_slot,
|
build_shard_transitions_till_slot,
|
||||||
|
get_committee_index_of_shard,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.fork_choice import add_block_to_store, get_anchor_root
|
from eth2spec.test.helpers.fork_choice import add_block_to_store, get_anchor_root
|
||||||
from eth2spec.test.helpers.state import next_slot, state_transition_and_sign_block
|
from eth2spec.test.helpers.state import next_slot, state_transition_and_sign_block
|
||||||
|
@ -24,44 +25,65 @@ def run_on_shard_block(spec, store, shard_store, signed_block, valid=True):
|
||||||
assert shard_store.blocks[hash_tree_root(signed_block.message)] == signed_block.message
|
assert shard_store.blocks[hash_tree_root(signed_block.message)] == signed_block.message
|
||||||
|
|
||||||
|
|
||||||
def run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index):
|
def run_apply_shard_and_beacon(spec, state, store, shard_store, shard_blocks_buffer):
|
||||||
shard = shard_store.shard
|
shard = shard_store.shard
|
||||||
|
committee_index = get_committee_index_of_shard(spec, state, state.slot, shard)
|
||||||
|
has_shard_committee = committee_index is not None
|
||||||
store.time = store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
store.time = store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
||||||
|
|
||||||
# Create SignedShardBlock
|
# Create SignedShardBlock
|
||||||
body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
|
# Check offsets
|
||||||
target_len_offset_slot = 1
|
temp_state = state.copy()
|
||||||
shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
|
next_slot(spec, temp_state)
|
||||||
shard_blocks = [shard_block]
|
offset_slots = spec.get_offset_slots(temp_state, shard)
|
||||||
|
if state.slot in offset_slots:
|
||||||
|
# Build block
|
||||||
|
body = b'\x56' * 4
|
||||||
|
shard_head_root = spec.get_shard_head(store, shard_store)
|
||||||
|
shard_parent_state = shard_store.block_states[shard_head_root]
|
||||||
|
assert shard_parent_state.slot != state.slot
|
||||||
|
shard_block = build_shard_block(
|
||||||
|
spec, state, shard,
|
||||||
|
shard_parent_state=shard_parent_state, slot=state.slot, body=body, signed=True
|
||||||
|
)
|
||||||
|
shard_blocks_buffer.append(shard_block)
|
||||||
|
run_on_shard_block(spec, store, shard_store, shard_block)
|
||||||
|
assert spec.get_shard_head(store, shard_store) == shard_block.message.hash_tree_root()
|
||||||
|
|
||||||
|
beacon_block = build_empty_block(spec, state, slot=state.slot + 1)
|
||||||
|
|
||||||
# Attester creates `attestation`
|
# Attester creates `attestation`
|
||||||
# Use temporary next state to get ShardTransition of shard block
|
if has_shard_committee and len(shard_blocks_buffer) > 0:
|
||||||
shard_transitions = build_shard_transitions_till_slot(
|
# Use temporary next state to get ShardTransition of shard block
|
||||||
spec,
|
shard_transitions = build_shard_transitions_till_slot(
|
||||||
state,
|
spec,
|
||||||
shard_blocks={shard: shard_blocks},
|
state,
|
||||||
on_time_slot=state.slot + target_len_offset_slot,
|
shard_blocks={shard: shard_blocks_buffer},
|
||||||
)
|
on_time_slot=state.slot + 1,
|
||||||
shard_transition = shard_transitions[shard]
|
)
|
||||||
attestation = build_attestation_with_shard_transition(
|
shard_transition = shard_transitions[shard]
|
||||||
spec,
|
|
||||||
state,
|
attestation = build_attestation_with_shard_transition(
|
||||||
index=committee_index,
|
spec,
|
||||||
on_time_slot=state.slot + target_len_offset_slot,
|
state,
|
||||||
shard_transition=shard_transition,
|
index=committee_index,
|
||||||
)
|
on_time_slot=state.slot + 1,
|
||||||
|
shard_transition=shard_transition,
|
||||||
|
)
|
||||||
|
assert attestation.data.slot == state.slot
|
||||||
|
assert spec.get_shard(state, attestation) == shard
|
||||||
|
beacon_block.body.attestations = [attestation]
|
||||||
|
beacon_block.body.shard_transitions = shard_transitions
|
||||||
|
|
||||||
# Propose beacon block at slot
|
|
||||||
beacon_block = build_empty_block(spec, state, slot=state.slot + 1)
|
|
||||||
beacon_block.body.attestations = [attestation]
|
|
||||||
beacon_block.body.shard_transitions = shard_transitions
|
|
||||||
signed_beacon_block = state_transition_and_sign_block(spec, state, beacon_block)
|
signed_beacon_block = state_transition_and_sign_block(spec, state, beacon_block)
|
||||||
|
|
||||||
run_on_shard_block(spec, store, shard_store, shard_block)
|
|
||||||
add_block_to_store(spec, store, signed_beacon_block)
|
add_block_to_store(spec, store, signed_beacon_block)
|
||||||
|
|
||||||
assert spec.get_head(store) == beacon_block.hash_tree_root()
|
assert spec.get_head(store) == beacon_block.hash_tree_root()
|
||||||
assert spec.get_shard_head(store, shard_store) == shard_block.message.hash_tree_root()
|
|
||||||
|
if has_shard_committee:
|
||||||
|
shard_blocks_buffer = [] # clear buffer
|
||||||
|
|
||||||
|
return has_shard_committee, shard_blocks_buffer
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases_except([PHASE0])
|
@with_all_phases_except([PHASE0])
|
||||||
|
@ -69,16 +91,19 @@ def run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index)
|
||||||
def test_basic(spec, state):
|
def test_basic(spec, state):
|
||||||
spec.PHASE_1_GENESIS_SLOT = 0 # FIXME: remove mocking
|
spec.PHASE_1_GENESIS_SLOT = 0 # FIXME: remove mocking
|
||||||
state = spec.upgrade_to_phase1(state)
|
state = spec.upgrade_to_phase1(state)
|
||||||
next_slot(spec, state)
|
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
store = spec.get_forkchoice_store(state)
|
store = spec.get_forkchoice_store(state)
|
||||||
anchor_root = get_anchor_root(spec, state)
|
anchor_root = get_anchor_root(spec, state)
|
||||||
assert spec.get_head(store) == anchor_root
|
assert spec.get_head(store) == anchor_root
|
||||||
|
|
||||||
committee_index = spec.CommitteeIndex(0)
|
shard = spec.Shard(1)
|
||||||
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
|
|
||||||
shard_store = spec.get_forkchoice_shard_store(state, shard)
|
shard_store = spec.get_forkchoice_shard_store(state, shard)
|
||||||
|
shard_block_count = 2
|
||||||
run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index)
|
shard_blocks_buffer = []
|
||||||
run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index)
|
while shard_block_count > 0:
|
||||||
|
has_shard_committee, shard_blocks_buffer = run_apply_shard_and_beacon(
|
||||||
|
spec, state, store, shard_store, shard_blocks_buffer
|
||||||
|
)
|
||||||
|
if has_shard_committee:
|
||||||
|
shard_block_count -= 1
|
||||||
|
|
|
@ -23,19 +23,24 @@ def build_shard_block(spec,
|
||||||
shard,
|
shard,
|
||||||
slot=None,
|
slot=None,
|
||||||
body=None,
|
body=None,
|
||||||
|
shard_parent_state=None,
|
||||||
signed=False):
|
signed=False):
|
||||||
shard_state = beacon_state.shard_states[shard]
|
if shard_parent_state is None:
|
||||||
|
shard_parent_state = beacon_state.shard_states[shard]
|
||||||
|
|
||||||
if slot is None:
|
if slot is None:
|
||||||
slot = shard_state.slot + 1
|
slot = shard_parent_state.slot + 1
|
||||||
|
|
||||||
if body is None:
|
if body is None:
|
||||||
body = b'\x56' * 128
|
body = b'\x56' * 128
|
||||||
|
|
||||||
proposer_index = spec.get_shard_proposer_index(beacon_state, slot, shard)
|
temp_state = beacon_state.copy()
|
||||||
|
transition_to(spec, temp_state, slot)
|
||||||
beacon_state, beacon_parent_root = get_state_and_beacon_parent_root_at_slot(spec, beacon_state, slot)
|
beacon_state, beacon_parent_root = get_state_and_beacon_parent_root_at_slot(spec, beacon_state, slot)
|
||||||
|
assert beacon_state == temp_state
|
||||||
|
proposer_index = spec.get_shard_proposer_index(temp_state, slot, shard)
|
||||||
block = spec.ShardBlock(
|
block = spec.ShardBlock(
|
||||||
shard_parent_root=shard_state.latest_block_root,
|
shard_parent_root=shard_parent_state.latest_block_root,
|
||||||
beacon_parent_root=beacon_parent_root,
|
beacon_parent_root=beacon_parent_root,
|
||||||
slot=slot,
|
slot=slot,
|
||||||
shard=shard,
|
shard=shard,
|
||||||
|
@ -59,7 +64,6 @@ def build_shard_transitions_till_slot(spec, state, shard_blocks, on_time_slot):
|
||||||
for shard, blocks in shard_blocks.items():
|
for shard, blocks in shard_blocks.items():
|
||||||
offset_slots = spec.get_offset_slots(temp_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 == on_time_slot - state.shard_states[shard].slot - 1
|
|
||||||
shard_transition = spec.get_shard_transition(temp_state, shard, blocks)
|
shard_transition = spec.get_shard_transition(temp_state, shard, blocks)
|
||||||
if len(blocks) > 0:
|
if len(blocks) > 0:
|
||||||
shard_block_root = blocks[-1].message.hash_tree_root()
|
shard_block_root = blocks[-1].message.hash_tree_root()
|
||||||
|
@ -84,3 +88,13 @@ def build_attestation_with_shard_transition(spec, state, index, on_time_slot, sh
|
||||||
if shard_transition is not None:
|
if shard_transition is not None:
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
def get_committee_index_of_shard(spec, state, slot, shard): # Optional[CommitteeIndex]
|
||||||
|
active_shard_count = spec.get_active_shard_count(state)
|
||||||
|
committee_count = spec.get_committee_count_at_slot(state, slot)
|
||||||
|
start_shard = spec.get_start_shard(state, slot)
|
||||||
|
for committee_index in range(committee_count):
|
||||||
|
if (start_shard + committee_index) % active_shard_count == shard:
|
||||||
|
return committee_index
|
||||||
|
return None
|
||||||
|
|
Loading…
Reference in New Issue