WIP test case

This commit is contained in:
Hsiao-Wei Wang 2020-06-04 05:33:01 +08:00
parent 26aae40941
commit c9a53b8039
No known key found for this signature in database
GPG Key ID: 95B070122902DEA4
2 changed files with 78 additions and 39 deletions

View File

@ -5,6 +5,7 @@ from eth2spec.test.helpers.shard_block import (
build_attestation_with_shard_transition,
build_shard_block,
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.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
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
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
# Create SignedShardBlock
body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
target_len_offset_slot = 1
shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
shard_blocks = [shard_block]
# Check offsets
temp_state = state.copy()
next_slot(spec, temp_state)
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`
if has_shard_committee and len(shard_blocks_buffer) > 0:
# Use temporary next state to get ShardTransition of shard block
shard_transitions = build_shard_transitions_till_slot(
spec,
state,
shard_blocks={shard: shard_blocks},
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(
spec,
state,
index=committee_index,
on_time_slot=state.slot + target_len_offset_slot,
on_time_slot=state.slot + 1,
shard_transition=shard_transition,
)
# Propose beacon block at slot
beacon_block = build_empty_block(spec, state, slot=state.slot + 1)
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
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)
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])
@ -69,16 +91,19 @@ def run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index)
def test_basic(spec, state):
spec.PHASE_1_GENESIS_SLOT = 0 # FIXME: remove mocking
state = spec.upgrade_to_phase1(state)
next_slot(spec, state)
# Initialization
store = spec.get_forkchoice_store(state)
anchor_root = get_anchor_root(spec, state)
assert spec.get_head(store) == anchor_root
committee_index = spec.CommitteeIndex(0)
shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
shard = spec.Shard(1)
shard_store = spec.get_forkchoice_shard_store(state, shard)
run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index)
run_apply_shard_and_beacon(spec, state, store, shard_store, committee_index)
shard_block_count = 2
shard_blocks_buffer = []
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

View File

@ -23,19 +23,24 @@ def build_shard_block(spec,
shard,
slot=None,
body=None,
shard_parent_state=None,
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:
slot = shard_state.slot + 1
slot = shard_parent_state.slot + 1
if body is None:
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)
assert beacon_state == temp_state
proposer_index = spec.get_shard_proposer_index(temp_state, slot, shard)
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,
slot=slot,
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():
offset_slots = spec.get_offset_slots(temp_state, shard)
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)
if len(blocks) > 0:
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:
assert attestation.data.shard_transition_root == shard_transition.hash_tree_root()
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