Beispiel #1
0
def test_update_attestations(sample_attestation_params,
                             sample_beacon_block_params):
    block = SerenityBeaconBlock(**sample_beacon_block_params)
    attestations = block.body.attestations
    attestations = list(attestations)
    attestations.append(Attestation(**sample_attestation_params))
    body2 = block.body.copy(attestations=attestations)
    block2 = block.copy(body=body2)
    assert block2.num_attestations == 1
Beispiel #2
0
def test_process_voluntary_exits(genesis_state, sample_beacon_block_params,
                                 sample_beacon_block_body_params, config,
                                 keymap, success):
    state = genesis_state.copy(slot=get_epoch_start_slot(
        config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD,
        config.SLOTS_PER_EPOCH,
    ), )
    validator_index = 0
    validator = state.validators[validator_index].copy(
        activation_epoch=config.GENESIS_EPOCH, )
    state = state.update_validator(validator_index, validator)
    valid_voluntary_exit = create_mock_voluntary_exit(
        state,
        config,
        keymap,
        validator_index,
    )

    if success:
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(valid_voluntary_exit, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        new_state = process_voluntary_exits(
            state,
            block,
            config,
        )
        updated_validator = new_state.validators[validator_index]
        assert updated_validator.exit_epoch != FAR_FUTURE_EPOCH
        assert updated_validator.exit_epoch > state.current_epoch(
            config.SLOTS_PER_EPOCH)
        assert updated_validator.withdrawable_epoch == (
            updated_validator.exit_epoch +
            config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
    else:
        invalid_voluntary_exit = valid_voluntary_exit.copy(
            signature=b'\x12' * 96,  # Put wrong signature
        )
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(invalid_voluntary_exit, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        with pytest.raises(ValidationError):
            process_voluntary_exits(
                state,
                block,
                config,
            )
Beispiel #3
0
def test_process_attester_slashings(genesis_state, sample_beacon_block_params,
                                    sample_beacon_block_body_params, config,
                                    keymap, min_attestation_inclusion_delay,
                                    success):
    attesting_state = genesis_state.copy(
        slot=genesis_state.slot + config.SLOTS_PER_EPOCH,
        block_roots=tuple(
            i.to_bytes(32, "little")
            for i in range(config.SLOTS_PER_HISTORICAL_ROOT)))
    valid_attester_slashing = create_mock_attester_slashing_is_double_vote(
        attesting_state,
        config,
        keymap,
        attestation_epoch=0,
    )
    state = attesting_state.copy(slot=attesting_state.slot +
                                 min_attestation_inclusion_delay, )

    if success:
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            attester_slashings=(valid_attester_slashing, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        attester_index = valid_attester_slashing.attestation_1.custody_bit_0_indices[
            0]

        new_state = process_attester_slashings(
            state,
            block,
            config,
        )
        # Check if slashed
        assert not state.validators[attester_index].slashed
        assert new_state.validators[attester_index].slashed
    else:
        invalid_attester_slashing = valid_attester_slashing.copy(
            attestation_2=valid_attester_slashing.attestation_2.copy(
                data=valid_attester_slashing.attestation_1.data, ))
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            attester_slashings=(invalid_attester_slashing, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        with pytest.raises(ValidationError):
            process_attester_slashings(
                state,
                block,
                config,
            )
Beispiel #4
0
def test_process_attester_slashings(genesis_state, sample_beacon_block_params,
                                    sample_beacon_block_body_params, config,
                                    keymap, min_attestation_inclusion_delay,
                                    success):
    attesting_state = genesis_state.copy(slot=genesis_state.slot +
                                         config.SLOTS_PER_EPOCH, )
    valid_attester_slashing = create_mock_attester_slashing_is_double_vote(
        attesting_state,
        config,
        keymap,
        attestation_epoch=0,
    )
    state = attesting_state.copy(slot=attesting_state.slot +
                                 min_attestation_inclusion_delay, )

    if success:
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            attester_slashings=(valid_attester_slashing, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        attester_index = valid_attester_slashing.slashable_attestation_1.validator_indices[
            0]

        new_state = process_attester_slashings(
            state,
            block,
            config,
        )
        # Check if slashed
        assert (new_state.validator_balances[attester_index] <
                state.validator_balances[attester_index])
    else:
        invalid_attester_slashing = valid_attester_slashing.copy(
            slashable_attestation_2=valid_attester_slashing.
            slashable_attestation_2.copy(
                data=valid_attester_slashing.slashable_attestation_1.data, ))
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            attester_slashings=(invalid_attester_slashing, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        with pytest.raises(ValidationError):
            process_attester_slashings(
                state,
                block,
                config,
            )
Beispiel #5
0
def test_process_voluntary_exits(genesis_state, sample_beacon_block_params,
                                 sample_beacon_block_body_params, config,
                                 keymap, success):
    state = genesis_state.copy(slot=get_epoch_start_slot(
        config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD,
        config.SLOTS_PER_EPOCH,
    ), )
    validator_index = 0
    validator = state.validator_registry[validator_index].copy(
        activation_epoch=config.GENESIS_EPOCH, )
    state = state.update_validator_registry(validator_index, validator)
    valid_voluntary_exit = create_mock_voluntary_exit(
        state,
        config,
        keymap,
        validator_index,
    )

    if success:
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(valid_voluntary_exit, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        new_state = process_voluntary_exits(
            state,
            block,
            config,
        )
        # Check if initiated exit
        assert (new_state.validator_registry[validator_index].initiated_exit)
    else:
        invalid_voluntary_exit = valid_voluntary_exit.copy(
            signature=b'\x12' * 96,  # Put wrong signature
        )
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(invalid_voluntary_exit, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        with pytest.raises(ValidationError):
            process_voluntary_exits(
                state,
                block,
                config,
            )
Beispiel #6
0
def test_process_voluntary_exits(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    success,
):
    state = genesis_state.set(
        "slot",
        compute_start_slot_at_epoch(
            config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD,
            config.SLOTS_PER_EPOCH,
        ),
    )
    validator_index = 0
    validator = state.validators[validator_index].set("activation_epoch",
                                                      config.GENESIS_EPOCH)
    state = state.transform(["validators", validator_index], validator)
    valid_voluntary_exit = create_mock_voluntary_exit(state, config, keymap,
                                                      validator_index)

    if success:
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set("voluntary_exits",
                                                   (valid_voluntary_exit, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        new_state = process_voluntary_exits(state, block, config)
        updated_validator = new_state.validators[validator_index]
        assert updated_validator.exit_epoch != FAR_FUTURE_EPOCH
        assert updated_validator.exit_epoch > state.current_epoch(
            config.SLOTS_PER_EPOCH)
        assert updated_validator.withdrawable_epoch == (
            updated_validator.exit_epoch +
            config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
    else:
        invalid_voluntary_exit = valid_voluntary_exit.set(
            "signature",
            b"\x12" * 96  # Put wrong signature
        )
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set("voluntary_exits",
                                                   (invalid_voluntary_exit, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        with pytest.raises(ValidationError):
            process_voluntary_exits(state, block, config)
Beispiel #7
0
def test_process_attester_slashings(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    min_attestation_inclusion_delay,
    success,
):
    attesting_state = genesis_state.mset(
        "slot",
        genesis_state.slot + config.SLOTS_PER_EPOCH,
        "block_roots",
        tuple(
            i.to_bytes(32, "little")
            for i in range(config.SLOTS_PER_HISTORICAL_ROOT)),
    )
    valid_attester_slashing = create_mock_attester_slashing_is_double_vote(
        attesting_state, config, keymap, attestation_epoch=0)
    state = attesting_state.set(
        "slot", attesting_state.slot + min_attestation_inclusion_delay)

    if success:
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set("attester_slashings",
                                                   (valid_attester_slashing, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        attester_index = valid_attester_slashing.attestation_1.attesting_indices[
            0]

        new_state = process_attester_slashings(state, block, config)
        # Check if slashed
        assert not state.validators[attester_index].slashed
        assert new_state.validators[attester_index].slashed
    else:
        invalid_attester_slashing = valid_attester_slashing.transform(
            ["attestation_2", "data"],
            valid_attester_slashing.attestation_1.data)
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set(
                "attester_slashings", (invalid_attester_slashing, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        with pytest.raises(ValidationError):
            process_attester_slashings(state, block, config)
Beispiel #8
0
def test_randao_processing_validates_randao_reveal(sample_beacon_block_params,
                                                   sample_beacon_state_params,
                                                   sample_fork_params, keymap,
                                                   config):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator_record(proposer_pubkey)
            for _ in range(config.TARGET_COMMITTEE_SIZE)),
        validator_balances=(config.MAX_DEPOSIT_AMOUNT, ) *
        config.TARGET_COMMITTEE_SIZE,
        latest_randao_mixes=tuple(
            ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)),
    )

    epoch = state.current_epoch(config.EPOCH_LENGTH)
    slot = epoch * config.EPOCH_LENGTH
    message = (epoch + 1).to_bytes(32, byteorder="big")
    fork = Fork(**sample_fork_params)
    domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO)
    randao_reveal = bls.sign(message, proposer_privkey, domain)

    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        randao_reveal=randao_reveal, )

    with pytest.raises(ValidationError):
        process_randao(state, block, config)
def test_randao_processing_validates_randao_reveal(
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    sample_beacon_state_params,
    sample_fork_params,
    keymap,
    config,
):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState.create(**sample_beacon_state_params).mset(
        "validators",
        tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(config.TARGET_COMMITTEE_SIZE)),
        "balances",
        (config.MAX_EFFECTIVE_BALANCE, ) * config.TARGET_COMMITTEE_SIZE,
        "randao_mixes",
        tuple(ZERO_HASH32 for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR)),
    )

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    message_hash = (epoch + 1).to_bytes(32, byteorder="little")
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO,
                        config.SLOTS_PER_EPOCH)
    randao_reveal = bls.sign(message_hash, proposer_privkey, domain)

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "randao_reveal", randao_reveal)

    block = SerenityBeaconBlock.create(**sample_beacon_block_params).set(
        "body", block_body)

    with pytest.raises(ValidationError):
        process_randao(state, block, config)
Beispiel #10
0
def test_randao_processing(sample_beacon_block_params,
                           sample_beacon_state_params, sample_fork_params,
                           keymap, config):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator_record(proposer_pubkey)
            for _ in range(config.TARGET_COMMITTEE_SIZE)),
        validator_balances=(config.MAX_DEPOSIT_AMOUNT, ) *
        config.TARGET_COMMITTEE_SIZE,
        latest_randao_mixes=tuple(
            ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)),
    )

    epoch = state.current_epoch(config.EPOCH_LENGTH)
    slot = epoch * config.EPOCH_LENGTH
    message = epoch.to_bytes(32, byteorder="big")
    fork = Fork(**sample_fork_params)
    domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO)
    randao_reveal = bls.sign(message, proposer_privkey, domain)

    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        randao_reveal=randao_reveal, )

    new_state = process_randao(state, block, config)

    updated_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH
    original_mixes = state.latest_randao_mixes
    updated_mixes = new_state.latest_randao_mixes

    assert all(
        updated == original if index != updated_index else updated != original
        for index, (updated,
                    original) in enumerate(zip(updated_mixes, original_mixes)))
Beispiel #11
0
def test_process_max_attestations(genesis_state, genesis_block,
                                  sample_beacon_block_params,
                                  sample_beacon_block_body_params, config,
                                  keymap):
    attestation_slot = config.GENESIS_SLOT
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.copy(slot=current_slot, )

    attestations = create_mock_signed_attestations_at_slot(
        state=state,
        config=config,
        attestation_slot=attestation_slot,
        beacon_block_root=genesis_block.root,
        keymap=keymap,
        voted_attesters_ratio=1.0,
    )

    attestations_count = len(attestations)
    assert attestations_count > 0

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        attestations=attestations *
        (attestations_count // config.MAX_ATTESTATIONS + 1), )
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=current_slot,
        body=block_body,
    )

    with pytest.raises(ValidationError):
        process_attestations(
            state,
            block,
            config,
        )
Beispiel #12
0
def test_process_attestations(genesis_state, genesis_block,
                              sample_beacon_block_params,
                              sample_beacon_block_body_params, config, keymap,
                              fixture_sm_class, chaindb,
                              empty_attestation_pool, success):

    attestation_slot = 0
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.copy(slot=current_slot, )

    attestations = create_mock_signed_attestations_at_slot(
        state=state,
        config=config,
        state_machine=fixture_sm_class(
            chaindb,
            empty_attestation_pool,
            genesis_block.slot,
        ),
        attestation_slot=attestation_slot,
        beacon_block_root=genesis_block.signing_root,
        keymap=keymap,
        voted_attesters_ratio=1.0,
    )

    assert len(attestations) > 0

    if not success:
        # create invalid attestation by shard
        # i.e. wrong parent
        invalid_attestation_data = attestations[-1].data.copy(
            crosslink=attestations[-1].data.crosslink.copy(
                parent_root=Crosslink(shard=333, ).root, ))
        invalid_attestation = attestations[-1].copy(
            data=invalid_attestation_data, )
        attestations = attestations[:-1] + (invalid_attestation, )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        attestations=attestations, )
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=current_slot,
        body=block_body,
    )

    if success:
        new_state = process_attestations(
            state,
            block,
            config,
        )

        assert len(new_state.current_epoch_attestations) == len(attestations)
    else:
        with pytest.raises(ValidationError):
            process_attestations(
                state,
                block,
                config,
            )
Beispiel #13
0
def test_process_voluntary_exits(genesis_state, sample_beacon_block_params,
                                 sample_beacon_block_body_params, config,
                                 keymap, min_attestation_inclusion_delay,
                                 success):
    state = genesis_state
    validator_index = 0
    valid_voluntary_exit = create_mock_voluntary_exit(
        state,
        config,
        keymap,
        validator_index,
    )

    if success:
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(valid_voluntary_exit, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        new_state = process_voluntary_exits(
            state,
            block,
            config,
        )
        # Check if initiated exit
        assert (new_state.validator_registry[validator_index].initiated_exit)
    else:
        invalid_voluntary_exit = valid_voluntary_exit.copy(
            signature=b'\x12' * 96,  # Put wrong signature
        )
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(invalid_voluntary_exit, ), )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot,
            body=block_body,
        )

        with pytest.raises(ValidationError):
            process_voluntary_exits(
                state,
                block,
                config,
            )
Beispiel #14
0
def test_process_attestations(genesis_state, genesis_block,
                              sample_beacon_block_params,
                              sample_beacon_block_body_params, config, keymap,
                              fixture_sm_class, base_db, success):

    attestation_slot = 0
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.copy(slot=current_slot, )

    attestations = create_mock_signed_attestations_at_slot(
        state=state,
        config=config,
        state_machine=fixture_sm_class(
            BeaconChainDB(base_db),
            genesis_block,
        ),
        attestation_slot=attestation_slot,
        beacon_block_root=genesis_block.signed_root,
        keymap=keymap,
        voted_attesters_ratio=1.0,
    )

    assert len(attestations) > 0

    if not success:
        # create invalid attestation in the future
        invalid_attestation_data = attestations[-1].data.copy(slot=state.slot +
                                                              10, )
        invalid_attestation = attestations[-1].copy(
            data=invalid_attestation_data, )
        attestations = attestations[:-1] + (invalid_attestation, )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        attestations=attestations, )
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=current_slot,
        body=block_body,
    )

    if success:
        new_state = process_attestations(
            state,
            block,
            config,
        )

        assert len(new_state.current_epoch_attestations) == len(attestations)
    else:
        with pytest.raises(ValidationError):
            process_attestations(
                state,
                block,
                config,
            )
Beispiel #15
0
def test_demo(base_db, sample_beacon_block_params, genesis_state,
              fixture_sm_class, config, privkeys, pubkeys):
    chaindb = BeaconChainDB(base_db)
    state = genesis_state
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=state.slot + 2,
        state_root=state.root,
    )

    # Sign block
    beacon_proposer_index = get_beacon_proposer_index(
        state,
        block.slot,
        config.EPOCH_LENGTH,
    )
    index_in_privkeys = pubkeys.index(
        state.validator_registry[beacon_proposer_index].pubkey)
    beacon_proposer_privkey = privkeys[index_in_privkeys]
    empty_signature_block_root = block.block_without_signature_root
    proposal_root = ProposalSignedData(
        block.slot,
        config.BEACON_CHAIN_SHARD_NUMBER,
        empty_signature_block_root,
    ).root
    block = block.copy(signature=bls.sign(
        message=proposal_root,
        privkey=beacon_proposer_privkey,
        domain=SignatureDomain.DOMAIN_PROPOSAL,
    ), )

    # Store in chaindb
    chaindb.persist_block(block, SerenityBeaconBlock)
    chaindb.persist_state(state)

    # Get state machine instance
    sm = fixture_sm_class(chaindb, block.root, SerenityBeaconBlock)
    result_state, _ = sm.import_block(block)

    assert state.slot == 0
    assert result_state.slot == block.slot
    assert isinstance(sm.block, SerenityBeaconBlock)
Beispiel #16
0
def test_process_proposer_slashings(genesis_state,
                                    sample_beacon_block_params,
                                    sample_beacon_block_body_params,
                                    config,
                                    keymap,
                                    block_root_1,
                                    block_root_2,
                                    success):
    current_slot = config.GENESIS_SLOT + 1
    state = genesis_state.copy(
        slot=current_slot,
    )
    whistleblower_index = get_beacon_proposer_index(
        state,
        CommitteeConfig(config),
    )
    slashing_proposer_index = (whistleblower_index + 1) % len(state.validators)
    proposer_slashing = create_mock_proposer_slashing_at_block(
        state,
        config,
        keymap,
        block_root_1=block_root_1,
        block_root_2=block_root_2,
        proposer_index=slashing_proposer_index,
    )
    proposer_slashings = (proposer_slashing,)

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        proposer_slashings=proposer_slashings,
    )
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=current_slot,
        body=block_body,
    )

    if success:
        new_state = process_proposer_slashings(
            state,
            block,
            config,
        )
        # Check if slashed
        assert (
            new_state.balances[slashing_proposer_index] <
            state.balances[slashing_proposer_index]
        )
    else:
        with pytest.raises(ValidationError):
            process_proposer_slashings(
                state,
                block,
                config,
            )
Beispiel #17
0
def test_process_attestations(
    genesis_state,
    genesis_block,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    fixture_sm_class,
    chaindb,
    genesis_fork_choice_context,
    success,
):

    attestation_slot = 0
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.set("slot", current_slot)

    attestations = create_mock_signed_attestations_at_slot(
        state=state,
        config=config,
        state_machine=fixture_sm_class(chaindb, genesis_fork_choice_context),
        attestation_slot=attestation_slot,
        beacon_block_root=genesis_block.message.hash_tree_root,
        keymap=keymap,
        voted_attesters_ratio=1.0,
    )

    assert len(attestations) > 0

    if not success:
        # create invalid attestation
        # i.e. wrong slot
        invalid_attestation_data = attestations[-1].data.set(
            "slot", state.slot + 1)
        invalid_attestation = attestations[-1].set("data",
                                                   invalid_attestation_data)
        attestations = attestations[:-1] + (invalid_attestation, )

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "attestations", attestations)
    block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
        "slot", current_slot, "body", block_body)

    if success:
        new_state = process_attestations(state, block, config)

        assert len(new_state.current_epoch_attestations) == len(attestations)
    else:
        with pytest.raises(ValidationError):
            process_attestations(state, block, config)
def test_process_attestations(genesis_state, sample_beacon_block_params,
                              sample_beacon_block_body_params, config, keymap,
                              success):

    attestation_slot = 0
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.copy(slot=current_slot, )

    attestations = create_mock_signed_attestations_at_slot(
        state,
        config,
        attestation_slot,
        keymap,
        1.0,
    )

    assert len(attestations) > 0

    if not success:
        # create invalid attestation in the future
        invalid_attestation_data = attestations[-1].data.copy(slot=state.slot +
                                                              10, )
        invalid_attestation = attestations[-1].copy(
            data=invalid_attestation_data, )
        attestations = attestations[:-1] + (invalid_attestation, )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        attestations=attestations, )
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=current_slot,
        body=block_body,
    )

    if success:
        new_state = process_attestations(
            state,
            block,
            config,
        )

        assert len(new_state.latest_attestations) == len(attestations)
    else:
        with pytest.raises(ValidationError):
            process_attestations(
                state,
                block,
                config,
            )
Beispiel #19
0
def test_randao_processing(sample_beacon_block_params,
                           sample_beacon_block_body_params,
                           sample_beacon_state_params,
                           keymap,
                           config):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator_record(proposer_pubkey, config)
            for _ in range(config.TARGET_COMMITTEE_SIZE)
        ),
        validator_balances=(config.MAX_DEPOSIT_AMOUNT,) * config.TARGET_COMMITTEE_SIZE,

        latest_randao_mixes=tuple(
            ZERO_HASH32
            for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)
        ),
    )

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    slot = get_epoch_start_slot(epoch, config.SLOTS_PER_EPOCH)

    randao_reveal = _generate_randao_reveal(
        privkey=proposer_privkey,
        slot=slot,
        fork=state.fork,
        config=config,
    )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        randao_reveal=randao_reveal,
    )

    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        body=block_body,
    )

    new_state = process_randao(state, block, config)

    updated_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH
    original_mixes = state.latest_randao_mixes
    updated_mixes = new_state.latest_randao_mixes

    assert all(
        updated == original if index != updated_index else updated != original
        for index, (updated, original) in enumerate(zip(updated_mixes, original_mixes))
    )
Beispiel #20
0
def test_randao_processing(sample_beacon_block_params,
                           sample_beacon_block_body_params,
                           sample_beacon_state_params,
                           keymap,
                           config):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState(**sample_beacon_state_params).copy(
        validators=tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(config.TARGET_COMMITTEE_SIZE)
        ),
        balances=(config.MAX_EFFECTIVE_BALANCE,) * config.TARGET_COMMITTEE_SIZE,

        randao_mixes=tuple(
            ZERO_HASH32
            for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR)
        ),
    )

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    slot = get_epoch_start_slot(epoch, config.SLOTS_PER_EPOCH)

    randao_reveal = _generate_randao_reveal(
        privkey=proposer_privkey,
        slot=slot,
        state=state,
        config=config,
    )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        randao_reveal=randao_reveal,
    )

    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        body=block_body,
    )

    new_state = process_randao(state, block, config)

    updated_index = epoch % config.EPOCHS_PER_HISTORICAL_VECTOR
    original_mixes = state.randao_mixes
    updated_mixes = new_state.randao_mixes

    assert all(
        updated == original if index != updated_index else updated != original
        for index, (updated, original) in enumerate(zip(updated_mixes, original_mixes))
    )
Beispiel #21
0
def test_process_proposer_slashings(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    block_root_1,
    block_root_2,
    success,
):
    current_slot = config.GENESIS_SLOT + 1
    state = genesis_state.set("slot", current_slot)
    whistleblower_index = get_beacon_proposer_index(state, config)
    slashing_proposer_index = (whistleblower_index + 1) % len(state.validators)
    proposer_slashing = create_mock_proposer_slashing_at_block(
        state,
        config,
        keymap,
        block_root_1=block_root_1,
        block_root_2=block_root_2,
        proposer_index=slashing_proposer_index,
    )
    proposer_slashings = (proposer_slashing, )

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "proposer_slashings", proposer_slashings)
    block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
        "slot", current_slot, "body", block_body)

    if success:
        new_state = process_proposer_slashings(state, block, config)
        # Check if slashed
        assert (new_state.balances[slashing_proposer_index] <
                state.balances[slashing_proposer_index])
    else:
        with pytest.raises(ValidationError):
            process_proposer_slashings(state, block, config)
def test_process_max_attestations(
    genesis_state,
    genesis_block,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    fixture_sm_class,
    chaindb,
    genesis_fork_choice_context,
):
    attestation_slot = config.GENESIS_SLOT
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.copy(slot=current_slot)

    attestations = create_mock_signed_attestations_at_slot(
        state=state,
        config=config,
        state_machine=fixture_sm_class(chaindb, genesis_fork_choice_context),
        attestation_slot=attestation_slot,
        beacon_block_root=genesis_block.signing_root,
        keymap=keymap,
        voted_attesters_ratio=1.0,
    )

    attestations_count = len(attestations)
    assert attestations_count > 0

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        attestations=attestations * (config.MAX_ATTESTATIONS // attestations_count + 1)
    )
    block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
        slot=current_slot, body=block_body
    )

    with pytest.raises(ValidationError):
        process_attestations(state, block, config)
Beispiel #23
0
def sample_block(sample_beacon_block_params):
    return SerenityBeaconBlock(**sample_beacon_block_params)
Beispiel #24
0
def test_defaults(sample_beacon_block_params):
    block = SerenityBeaconBlock(**sample_beacon_block_params)
    assert block.slot == sample_beacon_block_params['slot']
    assert len(block.body.custody_challenges) == 0