def state_transition_and_sign_block(spec, state, block, expect_fail=False): """ State transition via the provided ``block`` then package the block with the correct state root and signature. """ if expect_fail: expect_assertion_error(lambda: transition_unsigned_block(spec, state, block)) else: transition_unsigned_block(spec, state, block) block.state_root = state.hash_tree_root() return sign_block(spec, state, block)
def test_on_block_bad_parent_root(spec, state): # Initialization store = get_genesis_forkchoice_store(spec, state) time = 100 spec.on_tick(store, time) # Fail receiving block of `GENESIS_SLOT + 1` slot block = build_empty_block_for_next_slot(spec, state) transition_unsigned_block(spec, state, block) block.state_root = state.hash_tree_root() block.parent_root = b'\x45' * 32 signed_block = sign_block(spec, state, block) run_on_block(spec, store, signed_block, False)
def test_on_block_finalized_skip_slots_not_in_skip_chain(spec, state): # Initialization transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH - 1) block = build_empty_block_for_next_slot(spec, state) transition_unsigned_block(spec, state, block) block.state_root = state.hash_tree_root() store = spec.get_forkchoice_store(state, block) store.finalized_checkpoint = spec.Checkpoint( epoch=store.finalized_checkpoint.epoch + 2, root=store.finalized_checkpoint.root ) # First transition through the epoch to ensure no skipped slots state, store, _ = apply_next_epoch_with_attestations(spec, state, store) # Now build a block at later slot than finalized epoch # Includes finalized block in chain, but not at appropriate skip slot block = build_empty_block(spec, state, spec.compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) + 2) signed_block = state_transition_and_sign_block(spec, state, block) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) run_on_block(spec, store, signed_block, False)
def test_on_block_bad_parent_root(spec, state): test_steps = [] # Initialization store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state) yield 'anchor_state', state yield 'anchor_block', anchor_block current_time = state.slot * spec.config.SECONDS_PER_SLOT + store.genesis_time on_tick_and_append_step(spec, store, current_time, test_steps) assert store.time == current_time # Fail receiving block of `GENESIS_SLOT + 1` slot block = build_empty_block_for_next_slot(spec, state) transition_unsigned_block(spec, state, block) block.state_root = state.hash_tree_root() block.parent_root = b'\x45' * 32 signed_block = sign_block(spec, state, block) yield from add_block(spec, store, signed_block, test_steps, valid=False) yield 'steps', test_steps
def test_prev_slot_block_transition(spec, state): # Go to clean slot spec.process_slots(state, state.slot + 1) # Make a block for it block = build_empty_block(spec, state, slot=state.slot) proposer_index = spec.get_beacon_proposer_index(state) # Transition to next slot, above block will not be invalid on top of new state. spec.process_slots(state, state.slot + 1) yield 'pre', state # State is beyond block slot, but the block can still be realistic when invalid. # Try the transition, and update the state root to where it is halted. Then sign with the supposed proposer. expect_assertion_error(lambda: transition_unsigned_block(spec, state, block)) block.state_root = state.hash_tree_root() signed_block = sign_block(spec, state, block, proposer_index=proposer_index) yield 'blocks', [signed_block] yield 'post', None
def test_invalid_signature_past_block(spec, state): committee = spec.get_sync_committee_indices(state, spec.get_current_epoch(state)) yield 'pre', state blocks = [] for _ in range(2): # NOTE: need to transition twice to move beyond the degenerate case at genesis block = build_empty_block_for_next_slot(spec, state) # Valid sync committee signature here... block.body.sync_committee_bits = [True] * len(committee) block.body.sync_committee_signature = compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee, ) signed_block = state_transition_and_sign_block(spec, state, block) blocks.append(signed_block) invalid_block = build_empty_block_for_next_slot(spec, state) # Invalid signature from a slot other than the previous invalid_block.body.sync_committee_bits = [True] * len(committee) invalid_block.body.sync_committee_signature = compute_aggregate_sync_committee_signature( spec, state, invalid_block.slot - 2, committee, ) blocks.append(invalid_block) expect_assertion_error(lambda: transition_unsigned_block(spec, state, invalid_block)) yield 'blocks', blocks yield 'post', None
def add_attestations_to_state(spec, state, attestations, slot): block = build_empty_block(spec, state, slot) for attestation in attestations: block.body.attestations.append(attestation) spec.process_slots(state, block.slot) transition_unsigned_block(spec, state, block)