def test_wrong_shard_transition_root(spec, state): if not is_full_crosslink(spec, state): # Skip this test return state, shard, target_shard_slot = get_initial_env(spec, state, target_len_offset_slot=1) init_slot = state.slot # Create SignedShardBlock at init_slot shard_block = build_shard_block(spec, state, shard, slot=init_slot, body=get_sample_shard_block_body( spec, is_max=True), signed=True) # Transition state to target shard slot transition_to(spec, state, target_shard_slot) # Create a shard_transitions that would be included at beacon block `target_shard_slot + 1` shard_transitions = get_shard_transitions(spec, state, {shard: [shard_block]}) shard_transition = shard_transitions[shard] wrong_shard_transition = shard_transition.copy() wrong_shard_transition.shard_states[ shard].gasprice = shard_transition.shard_states[shard].gasprice + 1 committee_index = get_committee_index_of_shard(spec, state, state.slot, shard) attestation = get_valid_attestation( spec, state, index=committee_index, shard_transition=wrong_shard_transition, signed=True, on_time=True, ) attestations = [attestation] next_slot(spec, state) run_attestation_processing(spec, state, attestation) # Check if winning root != shard_transition.hash_tree_root() _, winning_roots = spec.get_shard_winning_roots(state, attestations) assert len(winning_roots) == 1 shard_transition = shard_transitions[shard] assert winning_roots[0] != shard_transition.hash_tree_root() yield from run_shard_transitions_processing(spec, state, shard_transitions, attestations, valid=False)
def test_empty_participants_zeroes_sig(spec, state): attestation = get_valid_attestation( spec, state, filter_participant_set=lambda comm: []) # 0 participants attestation.signature = spec.BLSSignature(b'\x00' * 96) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) yield from run_attestation_processing(spec, state, attestation, False)
def test_after_epoch_slots(spec, state): attestation = get_valid_attestation(spec, state, signed=True, on_time=False) # increment past latest inclusion slot transition_to_slot_via_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH + 1) yield from run_attestation_processing(spec, state, attestation, False)
def test_empty_participants_seemingly_valid_sig(spec, state): attestation = get_valid_attestation(spec, state, filter_participant_set=lambda comm: []) # 0 participants # Special BLS value, valid for zero pubkeys on some (but not all) BLS implementations. attestation.signature = spec.BLSSignature(b'\xc0' + b'\x00' * 95) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) yield from run_attestation_processing(spec, state, attestation, False)
def test_correct_after_epoch_delay(spec, state): attestation = get_valid_attestation(spec, state, signed=True) # increment past latest inclusion slot next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1) yield from run_attestation_processing(spec, state, attestation, False)
def test_invalid_current_source_root(spec, state): next_slots(spec, state, spec.SLOTS_PER_EPOCH * 5) state.finalized_checkpoint.epoch = 2 state.previous_justified_checkpoint = spec.Checkpoint(epoch=3, root=b'\x01' * 32) state.current_justified_checkpoint = spec.Checkpoint(epoch=4, root=b'\x32' * 32) attestation = get_valid_attestation(spec, state, slot=(spec.SLOTS_PER_EPOCH * 3) + 1, on_time=False) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) # Test logic sanity checks: assert state.current_justified_checkpoint.root != state.previous_justified_checkpoint.root assert attestation.data.source.root == state.previous_justified_checkpoint.root # Make attestation source root invalid: should be previous justified, not current one attestation.data.source.root = state.current_justified_checkpoint.root sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)
def test_wrong_index_for_committee_signature(spec, state): attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) attestation.data.index += 1 yield from run_attestation_processing(spec, state, attestation, False)
def test_late_success(spec, state): attestation = get_valid_late_attestation(spec, state, signed=True) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY + 1) 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_too_many_aggregation_bits(spec, state): attestation = get_valid_attestation(spec, state, signed=True) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) # one too many bits attestation.aggregation_bits.append(0b0) yield from run_attestation_processing(spec, state, attestation, False)
def test_invalid_index(spec, state): attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) # Invalid index: off by one (with respect to valid range) on purpose attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT yield from run_attestation_processing(spec, state, attestation, False)
def test_correct_epoch_delay(spec, state): attestation = get_valid_attestation(spec, state, signed=True, on_time=False) next_slots(spec, state, spec.SLOTS_PER_EPOCH) 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) next_epoch_via_block(spec, state) yield from run_attestation_processing(spec, state, attestation)
def test_old_target_epoch(spec, state): assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2 attestation = get_valid_attestation(spec, state, signed=True, on_time=False) next_slots(spec, state, spec.SLOTS_PER_EPOCH * 2) # target epoch will be too old to handle yield from run_attestation_processing(spec, state, attestation, False)
def test_incorrect_target_epoch_delay(spec, state): attestation = get_valid_attestation(spec, state, signed=False) next_slots(spec, state, spec.SLOTS_PER_EPOCH) attestation.data.target.root = b'\x42' * 32 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation)
def test_incorrect_head_sqrt_epoch_delay(spec, state): attestation = get_valid_attestation(spec, state, signed=False) next_slots(spec, state, spec.integer_squareroot(spec.SLOTS_PER_EPOCH)) attestation.data.beacon_block_root = b'\x42' * 32 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation)
def test_on_time_empty_custody_bits_blocks(spec, state): attestation = get_valid_late_attestation(spec, state, signed=True) assert not any(attestation.custody_bits_blocks) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) yield from run_attestation_processing(spec, state, attestation, False)
def test_incorrect_target_min_inclusion_delay(spec, state): attestation = get_valid_attestation(spec, state, signed=False) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) attestation.data.target.root = b'\x42' * 32 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation)
def test_new_source_epoch(spec, state): attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) attestation.data.source.epoch += 1 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)
def test_incorrect_target_after_epoch_delay(spec, state): attestation = get_valid_attestation(spec, state, signed=False) # increment past latest inclusion slot next_slots(spec, state, spec.SLOTS_PER_EPOCH + 1) attestation.data.target.root = b'\x42' * 32 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)
def test_bad_source_root(spec, state): attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) attestation.data.source.root = b'\x42' * 32 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)
def test_empty_aggregation_bits(spec, state): next_slot(spec, state) attestation = get_valid_attestation(spec, state, empty=True) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) assert attestation.aggregation_bits == Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE]( *([0b0] * len(attestation.aggregation_bits))) yield from run_attestation_processing(spec, state, attestation)
def test_no_winning_root(spec, state): if not is_full_crosslink(spec, state): # Skip this test return state, shard, target_shard_slot = get_initial_env(spec, state, target_len_offset_slot=1) init_slot = state.slot # Create SignedShardBlock at init_slot shard_block = build_shard_block(spec, state, shard, slot=init_slot, body=get_sample_shard_block_body( spec, is_max=True), signed=True) # Transition state to target shard slot transition_to(spec, state, target_shard_slot) # Create a shard_transitions that would be included at beacon block `target_shard_slot + 1` shard_transitions = get_shard_transitions(spec, state, {shard: [shard_block]}) shard_transition = shard_transitions[shard] committee_index = get_committee_index_of_shard(spec, state, state.slot, shard) attestation = get_valid_attestation( spec, state, index=committee_index, shard_transition=shard_transition, # Decrease attested participants to 1/3 committee filter_participant_set=lambda committee: set( list(committee)[:len(committee) // 3]), signed=True, on_time=True, ) next_slot(spec, state) _, _, _ = run_attestation_processing(spec, state, attestation) _, winning_roots = spec.get_shard_winning_roots(state, [attestation]) assert len(winning_roots) == 0 # No winning root, shard_transitions[shard] is empty shard_transitions = [spec.ShardTransition()] * spec.MAX_SHARDS pre_shard_states = state.shard_states.copy() yield from run_shard_transitions_processing(spec, state, shard_transitions, [attestation]) for pending_attestation in state.current_epoch_attestations: assert bool(pending_attestation.crosslink_success) is False assert state.shard_states == pre_shard_states
def test_wrong_index_for_slot_0(spec, state): reduce_state_committee_count_from_max(spec, state) attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) # Invalid index: current committees per slot is less than the max attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT - 1 yield from run_attestation_processing(spec, state, attestation, False)
def test_mismatched_target_and_slot(spec, state): next_epoch_via_block(spec, state) next_epoch_via_block(spec, state) attestation = get_valid_attestation(spec, state, on_time=False) attestation.data.slot = attestation.data.slot - spec.SLOTS_PER_EPOCH sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)
def test_wrong_index_for_slot(spec, state): while spec.get_committee_count_at_slot(state, state.slot) >= spec.MAX_COMMITTEES_PER_SLOT: state.validators = state.validators[:len(state.validators) // 2] state.balances = state.balances[:len(state.balances) // 2] index = spec.MAX_COMMITTEES_PER_SLOT - 1 attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) attestation.data.index = index yield from run_attestation_processing(spec, state, attestation, False)
def test_wrong_index_for_slot_1(spec, state): reduce_state_committee_count_from_max(spec, state) current_epoch = spec.get_current_epoch(state) committee_count = spec.get_committee_count_per_slot(state, current_epoch) attestation = get_valid_attestation(spec, state, index=0) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) # Invalid index: off by one attestation.data.index = committee_count yield from run_attestation_processing(spec, state, attestation, False)
def test_too_few_aggregation_bits(spec, state): attestation = get_valid_attestation(spec, state) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) attestation.aggregation_bits = Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE]( *([0b1] + [0b0] * (len(attestation.aggregation_bits) - 1))) sign_attestation(spec, state, attestation) # one too few bits attestation.aggregation_bits = attestation.aggregation_bits[:-1] yield from run_attestation_processing(spec, state, attestation, False)
def run_successful_crosslink_tests(spec, state, target_len_offset_slot): state, shard, target_shard_slot = get_initial_env(spec, state, target_len_offset_slot) init_slot = state.slot # Create SignedShardBlock at init_slot shard_block = build_shard_block(spec, state, shard, slot=init_slot, body=get_sample_shard_block_body( spec, is_max=True), signed=True) # Transition state to target shard slot transition_to(spec, state, target_shard_slot) # Create a shard_transitions that would be included at beacon block `target_shard_slot + 1` shard_block_dict = {shard: [shard_block]} attestations, shard_transitions = get_attestations_and_shard_transitions( spec, state, shard_block_dict) next_slot(spec, state) for attestation in attestations: _, _, _ = run_attestation_processing(spec, state, attestation) _, winning_roots = spec.get_shard_winning_roots(state, attestations) assert len(winning_roots) == 1 shard_transition = shard_transitions[shard] assert winning_roots[0] == shard_transition.hash_tree_root() pre_gasprice = state.shard_states[shard].gasprice pre_shard_states = state.shard_states.copy() yield from run_shard_transitions_processing(spec, state, shard_transitions, attestations) for index, shard_state in enumerate(state.shard_states): if index == shard: assert shard_state != pre_shard_states[index] assert shard_state == shard_transition.shard_states[ len(shard_transition.shard_states) - 1] assert shard_state.latest_block_root == shard_block.message.hash_tree_root( ) if target_len_offset_slot == 1: assert shard_state.gasprice > pre_gasprice else: assert shard_state == pre_shard_states[index] for pending_attestation in state.current_epoch_attestations: assert bool(pending_attestation.crosslink_success) is True
def test_old_source_epoch(spec, state): next_slots(spec, state, spec.SLOTS_PER_EPOCH * 5) state.finalized_checkpoint.epoch = 2 state.previous_justified_checkpoint.epoch = 3 state.current_justified_checkpoint.epoch = 4 attestation = get_valid_attestation(spec, state, slot=(spec.SLOTS_PER_EPOCH * 3) + 1) # test logic sanity check: make sure the attestation is pointing to oldest known source epoch assert attestation.data.source.epoch == state.previous_justified_checkpoint.epoch # Now go beyond that, it will be invalid attestation.data.source.epoch -= 1 sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False)