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_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`
|
||||
# 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_transition = shard_transitions[shard]
|
||||
attestation = build_attestation_with_shard_transition(
|
||||
spec,
|
||||
state,
|
||||
index=committee_index,
|
||||
on_time_slot=state.slot + target_len_offset_slot,
|
||||
shard_transition=shard_transition,
|
||||
)
|
||||
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_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 + 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)
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue