示例#1
0
def test_update_validator(sample_beacon_state_params, sample_validator_record_params, max_deposit):
    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=[
            mock_validator_record(
                pubkey,
            )
            for pubkey in range(10)
        ],
        validator_balances=(
            max_deposit
            for _ in range(10)
        )
    )

    new_pubkey = 100
    validator_index = 5
    balance = 5566
    validator = state.validator_registry[validator_index].copy(
        pubkey=new_pubkey,
    )
    result_state = state.update_validator(
        validator_index=validator_index,
        validator=validator,
        balance=balance,
    )
    assert result_state.validator_balances[validator_index] == balance
    assert result_state.validator_registry[validator_index].pubkey == new_pubkey
    assert state.validator_registry[validator_index].pubkey != new_pubkey
示例#2
0
def test_verify_slashable_vote_data_signature(
        num_validators, privkeys, sample_beacon_state_params,
        activated_genesis_validators, genesis_balances,
        sample_slashable_vote_data_params, sample_fork_data_params):
    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=activated_genesis_validators,
        validator_balances=genesis_balances,
        fork_data=ForkData(**sample_fork_data_params),
    )

    # NOTE: we can do this before "correcting" the params as they
    # touch disjoint subsets of the provided params
    messages = _create_slashable_vote_data_messages(
        sample_slashable_vote_data_params)

    valid_params = _correct_slashable_vote_data_params(
        num_validators,
        sample_slashable_vote_data_params,
        messages,
        privkeys,
        state.fork_data,
    )
    valid_votes = SlashableVoteData(**valid_params)
    assert verify_slashable_vote_data_signature(state, valid_votes)

    invalid_params = _corrupt_signature(valid_params, state.fork_data)
    invalid_votes = SlashableVoteData(**invalid_params)
    assert not verify_slashable_vote_data_signature(state, invalid_votes)
示例#3
0
def test_verify_slashable_vote_data(
        num_validators, param_mapper, should_succeed, needs_fork_data,
        privkeys, sample_beacon_state_params, activated_genesis_validators,
        genesis_balances, sample_slashable_vote_data_params,
        sample_fork_data_params, max_casper_votes):
    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=activated_genesis_validators,
        validator_balances=genesis_balances,
        fork_data=ForkData(**sample_fork_data_params),
    )

    # NOTE: we can do this before "correcting" the params as they
    # touch disjoint subsets of the provided params
    messages = _create_slashable_vote_data_messages(
        sample_slashable_vote_data_params)

    params = _correct_slashable_vote_data_params(
        num_validators,
        sample_slashable_vote_data_params,
        messages,
        privkeys,
        state.fork_data,
    )
    if needs_fork_data:
        params = param_mapper(params, state.fork_data)
    else:
        params = param_mapper(params)
    _run_verify_slashable_vote(params, state, max_casper_votes, should_succeed)
def test_add_pending_validator(monkeypatch, sample_beacon_state_params,
                               sample_validator_record_params,
                               validator_registry_len,
                               min_empty_validator_index_result,
                               expected_index):
    from eth.beacon import deposit_helpers

    def mock_get_min_empty_validator_index(validators, validator_balances,
                                           current_slot,
                                           zero_balance_validator_ttl):
        if min_empty_validator_index_result is None:
            raise MinEmptyValidatorIndexNotFound()
        else:
            return min_empty_validator_index_result

    monkeypatch.setattr(deposit_helpers, 'get_min_empty_validator_index',
                        mock_get_min_empty_validator_index)

    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=[
            ValidatorRecord(**sample_validator_record_params)
            for _ in range(validator_registry_len)
        ],
        validator_balances=[100 for _ in range(validator_registry_len)],
    )
    validator = ValidatorRecord(**sample_validator_record_params)
    deposit = 5566
    state, index = add_pending_validator(
        state,
        validator,
        deposit,
        zero_balance_validator_ttl=0,  # it's for `get_min_empty_validator_index`
    )
    assert index == expected_index
    assert state.validator_registry[index] == validator
示例#5
0
def empty_beacon_state():
    return BeaconState(
        slot=0,
        genesis_time=0,
        fork_data=ForkData(
            pre_fork_version=0,
            post_fork_version=0,
            fork_slot=0,
        ),
        validator_registry=(),
        validator_registry_latest_change_slot=10,
        validator_registry_exit_count=10,
        validator_registry_delta_chain_tip=b'\x55' * 32,
        latest_randao_mixes=(),
        latest_vdf_outputs=(),
        shard_committees_at_slots=(),
        persistent_committees=(),
        persistent_committee_reassignments=(),
        previous_justified_slot=0,
        justified_slot=0,
        justification_bitfield=0,
        finalized_slot=0,
        latest_crosslinks=(),
        latest_block_roots=(),
        latest_penalized_exit_balances=(),
        latest_attestations=(),
        batched_block_roots=(),
        processed_pow_receipt_root=b'\x55' * 32,
        candidate_pow_receipt_roots=(),
    )
示例#6
0
def test_demo(base_db, sample_beacon_block_params, sample_beacon_state_params,
              fixture_sm_class):
    chaindb = BeaconChainDB(base_db)
    block = BaseBeaconBlock(**sample_beacon_block_params)
    state = BeaconState(**sample_beacon_state_params)

    sm = fixture_sm_class(chaindb, block, state)
    result_state, result_block = sm.import_block(block)

    assert state.slot == 0
    assert result_state.slot == sm.config.ZERO_BALANCE_VALIDATOR_TTL
示例#7
0
def test_validate_proposer_signature(
        proposer_privkey,
        proposer_pubkey,
        is_valid_signature,
        sample_beacon_block_params,
        sample_beacon_state_params,
        sample_shard_committee_params,
        beacon_chain_shard_number,
        epoch_length):

    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=[
            mock_validator_record(proposer_pubkey)
            for _ in range(10)
        ],
        shard_committees_at_slots=get_sample_shard_committees_at_slots(
            num_slot=128,
            num_shard_committee_per_slot=10,
            sample_shard_committee_params=sample_shard_committee_params,
        ),
    )

    default_block = BaseBeaconBlock(**sample_beacon_block_params)
    empty_signature_block_root = default_block.block_without_signature_root

    proposal_root = ProposalSignedData(
        state.slot,
        beacon_chain_shard_number,
        empty_signature_block_root,
    ).root

    proposed_block = BaseBeaconBlock(**sample_beacon_block_params).copy(
        signature=bls.sign(
            message=proposal_root,
            privkey=proposer_privkey,
            domain=SignatureDomain.DOMAIN_PROPOSAL,
        ),
    )

    if is_valid_signature:
        validate_proposer_signature(
            state,
            proposed_block,
            beacon_chain_shard_number,
            epoch_length,
        )
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(
                state,
                proposed_block,
                beacon_chain_shard_number,
                epoch_length,
            )
示例#8
0
def test_update_validator(sample_beacon_state_params,
                          sample_validator_record_params, max_deposit):
    state = BeaconState(**sample_beacon_state_params).copy(validator_registry=[
        mock_validator_record(
            pubkey,
            max_deposit,
        ) for pubkey in range(10)
    ])

    new_pubkey = 100
    validator_index = 5
    validator = state.validator_registry[validator_index].copy(
        pubkey=new_pubkey, )
    result_state = state.update_validator(validator_index=validator_index,
                                          validator=validator)
    assert result_state.validator_registry[
        validator_index].pubkey == new_pubkey
    assert state.validator_registry[validator_index].pubkey != new_pubkey
def test_validate_proof_of_possession(sample_beacon_state_params, pubkeys,
                                      privkeys, expected):
    state = BeaconState(**sample_beacon_state_params)

    privkey = privkeys[0]
    pubkey = pubkeys[0]
    withdrawal_credentials = b'\x34' * 32
    custody_commitment = b'\x12' * 32
    randao_commitment = b'\x56' * 32
    domain = get_domain(
        state.fork_data,
        state.slot,
        SignatureDomain.DOMAIN_DEPOSIT,
    )

    deposit_input = make_deposit_input(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    if expected is True:
        proof_of_possession = sign_proof_of_possession(deposit_input, privkey,
                                                       domain)

        validate_proof_of_possession(
            state=state,
            pubkey=pubkey,
            proof_of_possession=proof_of_possession,
            withdrawal_credentials=withdrawal_credentials,
            randao_commitment=randao_commitment,
            custody_commitment=custody_commitment,
        )
    else:
        proof_of_possession = b'\x11' * 32
        with pytest.raises(ValidationError):
            validate_proof_of_possession(
                state=state,
                pubkey=pubkey,
                proof_of_possession=proof_of_possession,
                withdrawal_credentials=withdrawal_credentials,
                randao_commitment=randao_commitment,
                custody_commitment=custody_commitment,
            )
示例#10
0
def test_add_pending_validator(sample_beacon_state_params,
                               sample_validator_record_params):

    validator_registry_len = 2
    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=[
            ValidatorRecord(**sample_validator_record_params)
            for _ in range(validator_registry_len)
        ],
        validator_balances=(100, ) * validator_registry_len,
    )
    validator = ValidatorRecord(**sample_validator_record_params)
    amount = 5566
    state = add_pending_validator(
        state,
        validator,
        amount,
    )

    assert state.validator_registry[-1] == validator
示例#11
0
def test_verify_slashable_vote_data(param_mapper, should_succeed, privkeys,
                                    sample_beacon_state_params,
                                    genesis_validators,
                                    sample_slashable_vote_data_params,
                                    max_casper_votes):
    sample_beacon_state_params["validator_registry"] = genesis_validators
    state = BeaconState(**sample_beacon_state_params)

    # NOTE: we can do this before "correcting" the params as they
    # touch disjoint subsets of the provided params
    messages = _create_slashable_vote_data_messages(
        sample_slashable_vote_data_params)

    params = _correct_slashable_vote_data_params(
        sample_slashable_vote_data_params,
        genesis_validators,
        messages,
        privkeys,
    )
    params = param_mapper(params)
    _run_verify_slashable_vote(params, state, max_casper_votes, should_succeed)
示例#12
0
def genesis_state(sample_beacon_state_params, genesis_validators, epoch_length,
                  target_committee_size, initial_slot_number, shard_count,
                  latest_block_roots_length):
    initial_shuffling = get_new_shuffling(
        seed=ZERO_HASH32,
        validators=genesis_validators,
        crosslinking_start_shard=0,
        epoch_length=epoch_length,
        target_committee_size=target_committee_size,
        shard_count=shard_count)

    return BeaconState(**sample_beacon_state_params).copy(
        validator_registry=genesis_validators,
        shard_committees_at_slots=initial_shuffling + initial_shuffling,
        latest_block_roots=tuple(ZERO_HASH32
                                 for _ in range(latest_block_roots_length)),
        latest_crosslinks=tuple(
            CrosslinkRecord(
                slot=initial_slot_number,
                shard_block_root=ZERO_HASH32,
            ) for _ in range(shard_count)))
示例#13
0
def test_verify_slashable_vote_data_signature(
        privkeys, sample_beacon_state_params, genesis_validators,
        sample_slashable_vote_data_params):
    sample_beacon_state_params["validator_registry"] = genesis_validators
    state = BeaconState(**sample_beacon_state_params)

    # NOTE: we can do this before "correcting" the params as they
    # touch disjoint subsets of the provided params
    messages = _create_slashable_vote_data_messages(
        sample_slashable_vote_data_params)

    valid_params = _correct_slashable_vote_data_params(
        sample_slashable_vote_data_params,
        genesis_validators,
        messages,
        privkeys,
    )
    valid_votes = SlashableVoteData(**valid_params)
    assert verify_slashable_vote_data_signature(state, valid_votes)

    invalid_params = _corrupt_signature(valid_params)
    invalid_votes = SlashableVoteData(**invalid_params)
    assert not verify_slashable_vote_data_signature(state, invalid_votes)
示例#14
0
def test_validator_registry_and_balances_length(sample_beacon_state_params):
    # When len(BeaconState.validator_registry) != len(BeaconState.validtor_balances)
    with pytest.raises(ValueError):
        BeaconState(**sample_beacon_state_params).copy(
            validator_registry=tuple(
                mock_validator_record(pubkey) for pubkey in range(10)), )
示例#15
0
def test_hash(sample_beacon_state_params):
    state = BeaconState(**sample_beacon_state_params)
    assert state.hash == blake(rlp.encode(state))
示例#16
0
def test_process_deposit(sample_beacon_state_params,
                         zero_balance_validator_ttl, privkeys, pubkeys):
    state = BeaconState(**sample_beacon_state_params).copy(
        slot=zero_balance_validator_ttl + 1,
        validator_registry=(),
    )

    privkey_1 = privkeys[0]
    pubkey_1 = pubkeys[0]
    deposit = 32 * denoms.gwei
    withdrawal_credentials = b'\x34' * 32
    custody_commitment = b'\x11' * 32
    randao_commitment = b'\x56' * 32
    domain = get_domain(
        state.fork_data,
        state.slot,
        SignatureDomain.DOMAIN_DEPOSIT,
    )

    deposit_input = make_deposit_input(
        pubkey=pubkey_1,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    proof_of_possession = sign_proof_of_possession(deposit_input, privkey_1,
                                                   domain)
    # Add the first validator
    result_state, index = process_deposit(
        state=state,
        pubkey=pubkey_1,
        deposit=deposit,
        proof_of_possession=proof_of_possession,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
        zero_balance_validator_ttl=zero_balance_validator_ttl,
    )

    assert len(result_state.validator_registry) == 1
    index = 0
    assert result_state.validator_registry[0].pubkey == pubkey_1
    assert result_state.validator_registry[
        index].withdrawal_credentials == withdrawal_credentials
    assert result_state.validator_registry[
        index].randao_commitment == randao_commitment
    assert result_state.validator_balances[index] == deposit
    # test immutable
    assert len(state.validator_registry) == 0

    # Add the second validator
    privkey_2 = privkeys[1]
    pubkey_2 = pubkeys[1]
    deposit_input = make_deposit_input(
        pubkey=pubkey_2,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    proof_of_possession = sign_proof_of_possession(deposit_input, privkey_2,
                                                   domain)
    result_state, index = process_deposit(
        state=result_state,
        pubkey=pubkey_2,
        deposit=deposit,
        proof_of_possession=proof_of_possession,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
        zero_balance_validator_ttl=zero_balance_validator_ttl,
    )
    assert len(result_state.validator_registry) == 2
    assert result_state.validator_registry[1].pubkey == pubkey_2

    # Force the first validator exited -> a empty slot in state.validator_registry.
    result_state = result_state.copy(validator_registry=(
        result_state.validator_registry[0].copy(latest_status_change_slot=0, ),
        result_state.validator_registry[1],
    ),
                                     validator_balances=(0, ) +
                                     result_state.validator_balances[1:])

    # Add the third validator.
    # Should overwrite previously exited validator.
    privkey_3 = privkeys[2]
    pubkey_3 = pubkeys[2]
    deposit_input = make_deposit_input(
        pubkey=pubkey_3,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    proof_of_possession = sign_proof_of_possession(deposit_input, privkey_3,
                                                   domain)
    result_state, index = process_deposit(
        state=result_state,
        pubkey=pubkey_3,
        deposit=deposit,
        proof_of_possession=proof_of_possession,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
        zero_balance_validator_ttl=zero_balance_validator_ttl,
    )
    # Overwrite the second validator.
    assert len(result_state.validator_registry) == 2
    assert result_state.validator_registry[0].pubkey == pubkey_3
示例#17
0
def sample_state(sample_beacon_state_params):
    return BeaconState(**sample_beacon_state_params)
示例#18
0
def test_defaults(sample_beacon_state_params):
    state = BeaconState(**sample_beacon_state_params)
    assert state.validator_registry == sample_beacon_state_params['validator_registry']
    assert state.validator_registry_latest_change_slot == sample_beacon_state_params['validator_registry_latest_change_slot']  # noqa: E501
示例#19
0
def test_hash(sample_beacon_state_params):
    state = BeaconState(**sample_beacon_state_params)
    assert state.root == hash_eth2(rlp.encode(state))
示例#20
0
def test_process_deposit(sample_beacon_state_params, privkeys, pubkeys,
                         max_deposit):
    state = BeaconState(**sample_beacon_state_params).copy(
        slot=1,
        validator_registry=(),
    )

    privkey_1 = privkeys[0]
    pubkey_1 = pubkeys[0]
    amount = max_deposit * GWEI_PER_ETH
    withdrawal_credentials = b'\x34' * 32
    custody_commitment = b'\x11' * 32
    randao_commitment = b'\x56' * 32

    deposit_input = make_deposit_input(
        pubkey=pubkey_1,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    proof_of_possession = sign_proof_of_possession(
        deposit_input,
        privkey_1,
        state.fork_data,
        state.slot,
    )

    # Add the first validator
    result_state = process_deposit(
        state=state,
        pubkey=pubkey_1,
        amount=amount,
        proof_of_possession=proof_of_possession,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )

    assert len(result_state.validator_registry) == 1
    index = 0
    assert result_state.validator_registry[0].pubkey == pubkey_1
    assert result_state.validator_registry[
        index].withdrawal_credentials == withdrawal_credentials
    assert result_state.validator_registry[
        index].randao_commitment == randao_commitment
    assert result_state.validator_balances[index] == amount
    # test immutable
    assert len(state.validator_registry) == 0

    # Add the second validator
    privkey_2 = privkeys[1]
    pubkey_2 = pubkeys[1]
    deposit_input = make_deposit_input(
        pubkey=pubkey_2,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    proof_of_possession = sign_proof_of_possession(
        deposit_input,
        privkey_2,
        state.fork_data,
        state.slot,
    )
    result_state = process_deposit(
        state=result_state,
        pubkey=pubkey_2,
        amount=amount,
        proof_of_possession=proof_of_possession,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )
    assert len(result_state.validator_registry) == 2
    assert result_state.validator_registry[1].pubkey == pubkey_2