def test_after_epoch_slots(spec, state): attestation = get_valid_attestation(spec, state, signed=True) # increment past latest inclusion slot spec.process_slots(state, state.slot + spec.SLOTS_PER_EPOCH + 1) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation, False)
def test_success_previous_epoch(spec, state): attestation = get_valid_attestation(spec, state, signed=True) state.slot = spec.SLOTS_PER_EPOCH - 1 next_epoch(spec, state) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation)
def test_success_previous_epoch(spec, state): attestation = get_valid_attestation(spec, state, signed=True, on_time=False) transition_to(spec, state, spec.SLOTS_PER_EPOCH - 1) next_epoch(spec, state) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation)
def test_finality_rule_2(spec, state): # get past first two epochs that finality does not run on next_epoch(spec, state) apply_empty_block(spec, state) next_epoch(spec, state) apply_empty_block(spec, state) yield 'pre', state blocks = [] for epoch in range(3): if epoch == 0: prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) check_finality(spec, state, prev_state, True, False, False) elif epoch == 1: prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, False) check_finality(spec, state, prev_state, False, True, False) elif epoch == 2: prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) # finalized by rule 2 check_finality(spec, state, prev_state, True, False, True) assert state.finalized_checkpoint == prev_state.previous_justified_checkpoint blocks += new_blocks yield 'blocks', blocks yield 'post', state
def test_finality_rule_1(spec, state): # get past first two epochs that finality does not run on next_epoch(spec, state) apply_empty_block(spec, state) next_epoch(spec, state) apply_empty_block(spec, state) yield 'pre', state blocks = [] for epoch in range(3): prev_state, new_blocks, state = next_epoch_with_attestations( spec, state, False, True) blocks += new_blocks if epoch == 0: check_finality(spec, state, prev_state, True, False, False) elif epoch == 1: check_finality(spec, state, prev_state, True, True, False) elif epoch == 2: # finalized by rule 1 check_finality(spec, state, prev_state, True, True, True) assert state.finalized_epoch == prev_state.previous_justified_epoch assert state.finalized_root == prev_state.previous_justified_root yield 'blocks', blocks, List[spec.BeaconBlock] yield 'post', state
def next_epoch_via_block(spec, state): """ Transition to the start slot of the next epoch via a full block transition """ apply_empty_block( spec, state, state.slot + spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH)
def transition_to_slot_via_block(spec, state, slot): """ Transition to ``slot`` via an empty block transition """ assert state.slot < slot apply_empty_block(spec, state, slot) assert state.slot == slot
def test_reveal_from_past_epoch(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) randao_key_reveal = get_valid_early_derived_secret_reveal( spec, state, spec.get_current_epoch(state) - 1) yield from run_early_derived_secret_reveal_processing( spec, state, randao_key_reveal, False)
def test_success_withdrawable(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) transfer = get_valid_transfer(spec, state, signed=True) # withdrawable_epoch in past so can transfer state.validators[ transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1 yield from run_transfer_processing(spec, state, transfer)
def test_bad_previous_crosslink(state): next_epoch(state) apply_empty_block(state) attestation = get_valid_attestation(state, signed=True) for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(state) apply_empty_block(state) state.current_crosslinks[attestation.data.shard].epoch += 10 yield from run_attestation_processing(state, attestation, False)
def test_bad_crosslink_end_epoch(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) attestation = get_valid_attestation(spec, state, signed=True) for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) attestation.data.crosslink.end_epoch += 1 yield from run_attestation_processing(spec, state, attestation, False)
def test_finality_rule_3(spec, state): """ Test scenario described here https://github.com/ethereum/eth2.0-specs/issues/611#issuecomment-463612892 """ # get past first two epochs that finality does not run on next_epoch(spec, state) apply_empty_block(spec, state) next_epoch(spec, state) apply_empty_block(spec, state) yield 'pre', state blocks = [] prev_state, new_blocks, state = next_epoch_with_attestations( spec, state, True, False) blocks += new_blocks check_finality(spec, state, prev_state, True, False, False) # In epoch N, JE is set to N, prev JE is set to N-1 prev_state, new_blocks, state = next_epoch_with_attestations( spec, state, True, False) blocks += new_blocks check_finality(spec, state, prev_state, True, True, True) # In epoch N+1, JE is N, prev JE is N-1, and not enough messages get in to do anything prev_state, new_blocks, state = next_epoch_with_attestations( spec, state, False, False) blocks += new_blocks check_finality(spec, state, prev_state, False, True, False) # In epoch N+2, JE is N, prev JE is N, and enough messages from the previous epoch get in to justify N+1. # N+1 now becomes the JE. Not enough messages from epoch N+2 itself get in to justify N+2 prev_state, new_blocks, state = next_epoch_with_attestations( spec, state, False, True) blocks += new_blocks # rule 2 check_finality(spec, state, prev_state, True, False, True) # In epoch N+3, LJE is N+1, prev LJE is N, and enough messages get in to justify epochs N+2 and N+3. prev_state, new_blocks, state = next_epoch_with_attestations( spec, state, True, True) blocks += new_blocks # rule 3 check_finality(spec, state, prev_state, True, True, True) assert state.finalized_epoch == prev_state.current_justified_epoch assert state.finalized_root == prev_state.current_justified_root yield 'blocks', blocks, List[spec.BeaconBlock] yield 'post', state
def test_bad_crosslink_start_epoch(spec, state): state.slot = spec.SLOTS_PER_EPOCH - 1 next_epoch(spec, state) apply_empty_block(spec, state) attestation = get_valid_attestation(spec, state, signed=False) for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) attestation.data.crosslink.start_epoch += 1 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)
def test_double_late_crosslink(spec, state): if spec.get_epoch_committee_count( state, spec.get_current_epoch(state)) < spec.SHARD_COUNT: print( "warning: ignoring test, test-assumptions are incompatible with configuration" ) return next_epoch(spec, state) state.slot += 4 attestation_1 = get_valid_attestation(spec, state, signed=True) fill_aggregate_attestation(spec, state, attestation_1) # add attestation_1 to next epoch next_epoch(spec, state) add_attestation_to_state(spec, state, attestation_1, state.slot + 1) for _ in range(spec.SLOTS_PER_EPOCH): attestation_2 = get_valid_attestation(spec, state) if attestation_2.data.crosslink.shard == attestation_1.data.crosslink.shard: sign_attestation(spec, state, attestation_2) break next_slot(spec, state) apply_empty_block(spec, state) fill_aggregate_attestation(spec, state, attestation_2) # add attestation_2 in the next epoch after attestation_1 has # already updated the relevant crosslink next_epoch(spec, state) add_attestation_to_state(spec, state, attestation_2, state.slot + 1) assert len(state.previous_epoch_attestations) == 1 assert len(state.current_epoch_attestations) == 0 crosslink_deltas = spec.get_crosslink_deltas(state) yield from run_process_crosslinks(spec, state) shard = attestation_2.data.crosslink.shard # ensure that the current crosslinks were not updated by the second attestation assert state.previous_crosslinks[shard] == state.current_crosslinks[shard] # ensure no reward, only penalties for the failed crosslink for index in spec.get_crosslink_committee( state, attestation_2.data.target_epoch, attestation_2.data.crosslink.shard): assert crosslink_deltas[0][index] == 0 assert crosslink_deltas[1][index] > 0
def test_success_since_max_epochs_per_crosslink(spec, state): for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2): next_epoch(spec, state) apply_empty_block(spec, state) attestation = get_valid_attestation(spec, state, signed=True) data = attestation.data # test logic sanity check: make sure the attestation only includes MAX_EPOCHS_PER_CROSSLINK epochs assert data.crosslink.end_epoch - data.crosslink.start_epoch == spec.MAX_EPOCHS_PER_CROSSLINK for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation)
def test_success_surround(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) state.current_justified_checkpoint.epoch += 1 attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attestation_1 = attester_slashing.attestation_1 attestation_2 = attester_slashing.attestation_2 # set attestion1 to surround attestation 2 attestation_1.data.source.epoch = attestation_2.data.source.epoch - 1 attestation_1.data.target.epoch = attestation_2.data.target.epoch + 1 sign_indexed_attestation(spec, state, attester_slashing.attestation_1) yield from run_attester_slashing_processing(spec, state, attester_slashing)
def test_success_since_max_epochs_per_crosslink(spec, state): # Do not run mainnet (64 epochs), that would mean the equivalent of ~7 hours chain simulation. if spec.MAX_EPOCHS_PER_CROSSLINK > 4: return for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2): next_epoch(spec, state) apply_empty_block(spec, state) attestation = get_valid_attestation(spec, state, signed=True) data = attestation.data # test logic sanity check: make sure the attestation only includes MAX_EPOCHS_PER_CROSSLINK epochs assert data.crosslink.end_epoch - data.crosslink.start_epoch == spec.MAX_EPOCHS_PER_CROSSLINK for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation)
def next_epoch_via_block(spec, state, insert_state_root=False): """ Transition to the start slot of the next epoch via a full block transition """ block = apply_empty_block( spec, state, state.slot + spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) if insert_state_root: block.state_root = state.hash_tree_root() return block
def test_max_reveal_lateness_2(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) attestation = get_valid_attestation(spec, state, signed=True) test_vector = get_custody_test_vector( spec.get_custody_chunk_count(attestation.data.crosslink) * spec.BYTES_PER_CUSTODY_CHUNK) shard_root = get_custody_merkle_root(test_vector) attestation.data.crosslink.data_root = shard_root attestation.custody_bits[0] = 0 next_epoch(spec, state) apply_empty_block(spec, state) _, _, _ = run_attestation_processing(spec, state, attestation) challenge = get_valid_bit_challenge(spec, state, attestation) responder_index = challenge.responder_index state.validators[responder_index].max_reveal_lateness = 3 for i in range(spec.get_randao_epoch_for_custody_period( spec.get_custody_period_for_validator(state, responder_index), responder_index ) + 2 * spec.EPOCHS_PER_CUSTODY_PERIOD + state.validators[responder_index].max_reveal_lateness - 1): next_epoch(spec, state) apply_empty_block(spec, state) yield from run_bit_challenge_processing(spec, state, challenge, False)
def test_finality_rule_4(spec, state): # get past first two epochs that finality does not run on next_epoch(spec, state) apply_empty_block(spec, state) next_epoch(spec, state) apply_empty_block(spec, state) yield 'pre', state blocks = [] for epoch in range(2): prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) blocks += new_blocks if epoch == 0: check_finality(spec, state, prev_state, True, False, False) elif epoch == 1: # rule 4 of finality check_finality(spec, state, prev_state, True, True, True) assert state.finalized_checkpoint == prev_state.current_justified_checkpoint yield 'blocks', blocks yield 'post', state
def test_discard_equivocations(spec, state): test_steps = [] genesis_state = state.copy() # Initialization store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state) yield 'anchor_state', state yield 'anchor_block', anchor_block anchor_root = get_anchor_root(spec, state) assert spec.get_head(store) == anchor_root test_steps.append( {'checks': { 'head': get_formatted_head_output(spec, store), }}) # Build block that serves as head before discarding equivocations state_1 = genesis_state.copy() next_slots(spec, state_1, 3) block_1 = build_empty_block_for_next_slot(spec, state_1) signed_block_1 = state_transition_and_sign_block(spec, state_1, block_1) # Build equivocating attestations to feed to store state_eqv = state_1.copy() block_eqv = apply_empty_block(spec, state_eqv, state_eqv.slot + 1) attestation_eqv = get_valid_attestation(spec, state_eqv, slot=block_eqv.slot, signed=True) next_slots(spec, state_1, 1) attestation = get_valid_attestation(spec, state_1, slot=block_eqv.slot, signed=True) assert spec.is_slashable_attestation_data(attestation.data, attestation_eqv.data) indexed_attestation = spec.get_indexed_attestation(state_1, attestation) indexed_attestation_eqv = spec.get_indexed_attestation( state_eqv, attestation_eqv) attester_slashing = spec.AttesterSlashing( attestation_1=indexed_attestation, attestation_2=indexed_attestation_eqv) # Build block that serves as head after discarding equivocations state_2 = genesis_state.copy() next_slots(spec, state_2, 2) block_2 = build_empty_block_for_next_slot(spec, state_2) signed_block_2 = state_transition_and_sign_block(spec, state_2.copy(), block_2) while spec.hash_tree_root(block_1) >= spec.hash_tree_root(block_2): block_2.body.graffiti = spec.Bytes32( hex(rng.getrandbits(8 * 32))[2:].zfill(64)) signed_block_2 = state_transition_and_sign_block( spec, state_2.copy(), block_2) assert spec.hash_tree_root(block_1) < spec.hash_tree_root(block_2) # Tick to (block_eqv.slot + 2) slot time time = store.genesis_time + (block_eqv.slot + 2) * spec.config.SECONDS_PER_SLOT on_tick_and_append_step(spec, store, time, test_steps) # Process block_2 yield from add_block(spec, store, signed_block_2, test_steps) assert store.proposer_boost_root == spec.Root() assert spec.get_head(store) == spec.hash_tree_root(block_2) # Process block_1 # The head should remain block_2 yield from add_block(spec, store, signed_block_1, test_steps) assert store.proposer_boost_root == spec.Root() assert spec.get_head(store) == spec.hash_tree_root(block_2) # Process attestation # The head should change to block_1 yield from add_attestation(spec, store, attestation, test_steps) assert spec.get_head(store) == spec.hash_tree_root(block_1) # Process attester_slashing # The head should revert to block_2 yield from add_attester_slashing(spec, store, attester_slashing, test_steps) assert spec.get_head(store) == spec.hash_tree_root(block_2) test_steps.append( {'checks': { 'head': get_formatted_head_output(spec, store), }}) yield 'steps', test_steps
def test_success_previous_epoch(spec, state): attestation = get_valid_attestation(spec, state, signed=True) next_epoch(spec, state) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation)