Exemplo n.º 1
0
def test_deposit_in_block(spec, state):
    initial_registry_len = len(state.validators)
    initial_balances_len = len(state.balances)

    validator_index = len(state.validators)
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(spec,
                                        state,
                                        validator_index,
                                        amount,
                                        signed=True)

    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    block.body.deposits.append(deposit)
    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    assert len(state.validators) == initial_registry_len + 1
    assert len(state.balances) == initial_balances_len + 1
    assert get_balance(state, validator_index) == spec.MAX_EFFECTIVE_BALANCE
    assert state.validators[validator_index].pubkey == pubkeys[validator_index]
Exemplo n.º 2
0
def test_check_if_validator_active(spec, state):
    active_validator_index = len(state.validators) - 1
    assert spec.check_if_validator_active(state, active_validator_index)
    new_validator_index = len(state.validators)
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(spec, state, new_validator_index, amount, signed=True)
    spec.process_deposit(state, deposit)
    assert not spec.check_if_validator_active(state, new_validator_index)
def test_success_top_up(state):
    validator_index = 0
    amount = spec.MAX_EFFECTIVE_BALANCE // 4
    deposit = prepare_state_and_deposit(state,
                                        validator_index,
                                        amount,
                                        signed=True)

    yield from run_deposit_processing(state, deposit, validator_index)
def test_invalid_sig_new_deposit(state):
    # fresh deposit = next validator index = validator appended to registry
    validator_index = len(state.validator_registry)
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(state, validator_index, amount)
    yield from run_deposit_processing(state,
                                      deposit,
                                      validator_index,
                                      valid=True,
                                      effective=False)
def test_invalid_sig_top_up(state):
    validator_index = 0
    amount = spec.MAX_EFFECTIVE_BALANCE // 4
    deposit = prepare_state_and_deposit(state, validator_index, amount)

    # invalid signatures, in top-ups, are allowed!
    yield from run_deposit_processing(state,
                                      deposit,
                                      validator_index,
                                      valid=True,
                                      effective=True)
Exemplo n.º 6
0
def test_new_deposit_under_max(spec, state):
    # fresh deposit = next validator index = validator appended to registry
    validator_index = len(state.validators)
    # effective balance will be 1 EFFECTIVE_BALANCE_INCREMENT smaller because of this small decrement.
    amount = spec.MAX_EFFECTIVE_BALANCE - 1
    deposit = prepare_state_and_deposit(spec,
                                        state,
                                        validator_index,
                                        amount,
                                        signed=True)

    yield from run_deposit_processing(spec, state, deposit, validator_index)
Exemplo n.º 7
0
def test_new_deposit_over_max(spec, state):
    # fresh deposit = next validator index = validator appended to registry
    validator_index = len(state.validators)
    # just 1 over the limit, effective balance should be set MAX_EFFECTIVE_BALANCE during processing
    amount = spec.MAX_EFFECTIVE_BALANCE + 1
    deposit = prepare_state_and_deposit(spec,
                                        state,
                                        validator_index,
                                        amount,
                                        signed=True)

    yield from run_deposit_processing(spec, state, deposit, validator_index)
Exemplo n.º 8
0
def test_new_deposit_max(spec, state):
    # fresh deposit = next validator index = validator appended to registry
    validator_index = len(state.validators)
    # effective balance will be exactly the same as balance.
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(spec,
                                        state,
                                        validator_index,
                                        amount,
                                        signed=True)

    yield from run_deposit_processing(spec, state, deposit, validator_index)
def test_bad_merkle_proof(state):
    validator_index = len(state.validator_registry)
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(state, validator_index, amount)

    # mess up merkle branch
    deposit.proof[-1] = spec.ZERO_HASH

    sign_deposit_data(state, deposit.data, privkeys[validator_index])

    yield from run_deposit_processing(state,
                                      deposit,
                                      validator_index,
                                      valid=False)
def test_wrong_index(state):
    validator_index = len(state.validator_registry)
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(state, validator_index, amount)

    # mess up deposit_index
    deposit.index = state.deposit_index + 1

    sign_deposit_data(state, deposit.data, privkeys[validator_index])

    yield from run_deposit_processing(state,
                                      deposit,
                                      validator_index,
                                      valid=False)
Exemplo n.º 11
0
def test_valid_sig_but_forked_state(spec, state):
    validator_index = len(state.validators)
    amount = spec.MAX_EFFECTIVE_BALANCE
    # deposits will always be valid, regardless of the current fork
    state.fork.current_version = spec.Version('0x1234abcd')
    deposit = prepare_state_and_deposit(spec,
                                        state,
                                        validator_index,
                                        amount,
                                        signed=True)
    yield from run_deposit_processing(spec,
                                      state,
                                      deposit,
                                      validator_index,
                                      valid=True,
                                      effective=True)
Exemplo n.º 12
0
def test_bad_merkle_proof(spec, state):
    validator_index = len(state.validators)
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(spec, state, validator_index, amount)

    # mess up merkle branch
    deposit.proof[5] = spec.Bytes32()

    sign_deposit_data(spec,
                      deposit.data,
                      privkeys[validator_index],
                      state=state)

    yield from run_deposit_processing(spec,
                                      state,
                                      deposit,
                                      validator_index,
                                      valid=False)
Exemplo n.º 13
0
def test_new_deposit_non_versioned_withdrawal_credentials(spec, state):
    # fresh deposit = next validator index = validator appended to registry
    validator_index = len(state.validators)
    withdrawal_credentials = (
        b'\xFF'  # Non specified withdrawal credentials version
        + b'\x02' * 31  # Garabage bytes
    )
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(
        spec,
        state,
        validator_index,
        amount,
        withdrawal_credentials=withdrawal_credentials,
        signed=True,
    )

    yield from run_deposit_processing(spec, state, deposit, validator_index)
Exemplo n.º 14
0
def test_invalid_withdrawal_credentials_top_up(state):
    validator_index = 0
    amount = spec.MAX_EFFECTIVE_BALANCE // 4
    withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(
        b"junk")[1:]
    deposit = prepare_state_and_deposit(
        state,
        validator_index,
        amount,
        withdrawal_credentials=withdrawal_credentials,
    )

    # inconsistent withdrawal credentials, in top-ups, are allowed!
    yield from run_deposit_processing(state,
                                      deposit,
                                      validator_index,
                                      valid=True,
                                      effective=True)
Exemplo n.º 15
0
def test_new_deposit_eth1_withdrawal_credentials(spec, state):
    # fresh deposit = next validator index = validator appended to registry
    validator_index = len(state.validators)
    withdrawal_credentials = (
        spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + b'\x00' * 11  # specified 0s
        + b'\x59' * 20  # a 20-byte eth1 address
    )
    amount = spec.MAX_EFFECTIVE_BALANCE
    deposit = prepare_state_and_deposit(
        spec,
        state,
        validator_index,
        amount,
        withdrawal_credentials=withdrawal_credentials,
        signed=True,
    )

    yield from run_deposit_processing(spec, state, deposit, validator_index)
Exemplo n.º 16
0
def test_deposit_top_up(spec, state):
    validator_index = 0
    amount = spec.MAX_EFFECTIVE_BALANCE // 4
    deposit = prepare_state_and_deposit(spec, state, validator_index, amount)

    initial_registry_len = len(state.validators)
    initial_balances_len = len(state.balances)
    validator_pre_balance = get_balance(state, validator_index)

    pre_state = state.copy()
    yield 'pre', pre_state

    block = build_empty_block_for_next_slot(spec, state)
    block.body.deposits.append(deposit)

    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    assert len(state.validators) == initial_registry_len
    assert len(state.balances) == initial_balances_len

    # Altair introduces sync committee (sm) reward and penalty
    sync_committee_reward = sync_committee_penalty = 0
    if is_post_altair(spec):
        committee_indices = compute_committee_indices(
            spec, state, state.current_sync_committee)
        committee_bits = block.body.sync_aggregate.sync_committee_bits
        sync_committee_reward, sync_committee_penalty = compute_sync_committee_participant_reward_and_penalty(
            spec,
            pre_state,
            validator_index,
            committee_indices,
            committee_bits,
        )

    assert get_balance(state,
                       validator_index) == (validator_pre_balance + amount +
                                            sync_committee_reward -
                                            sync_committee_penalty)
Exemplo n.º 17
0
def test_deposit_top_up(spec, state):
    validator_index = 0
    amount = spec.MAX_EFFECTIVE_BALANCE // 4
    deposit = prepare_state_and_deposit(spec, state, validator_index, amount)

    initial_registry_len = len(state.validators)
    initial_balances_len = len(state.balances)
    validator_pre_balance = get_balance(state, validator_index)

    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    block.body.deposits.append(deposit)

    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    assert len(state.validators) == initial_registry_len
    assert len(state.balances) == initial_balances_len
    assert get_balance(state, validator_index) == validator_pre_balance + amount
Exemplo n.º 18
0
def run_transition_with_operation(state, fork_epoch, spec, post_spec, pre_tag,
                                  post_tag, operation_type, operation_at_slot):
    """
    Generate `operation_type` operation with the spec before fork.
    The operation would be included into the block at `operation_at_slot`.
    """
    is_at_fork = operation_at_slot == fork_epoch * spec.SLOTS_PER_EPOCH
    is_right_before_fork = operation_at_slot == fork_epoch * spec.SLOTS_PER_EPOCH - 1
    assert is_at_fork or is_right_before_fork

    if is_at_fork:
        transition_until_fork(spec, state, fork_epoch)
    elif is_right_before_fork:
        _transition_until_fork_minus_one(spec, state, fork_epoch)

    is_slashing_operation = operation_type in (OperationType.PROPOSER_SLASHING,
                                               OperationType.ATTESTER_SLASHING)
    # prepare operation
    selected_validator_index = None
    if is_slashing_operation:
        # avoid slashing the next proposer
        future_state = state.copy()
        next_slot(spec, future_state)
        proposer_index = spec.get_beacon_proposer_index(future_state)
        selected_validator_index = (proposer_index + 1) % len(state.validators)
        if operation_type == OperationType.PROPOSER_SLASHING:
            proposer_slashing = get_valid_proposer_slashing(
                spec,
                state,
                slashed_index=selected_validator_index,
                signed_1=True,
                signed_2=True)
            operation_dict = {'proposer_slashings': [proposer_slashing]}
        else:
            # operation_type == OperationType.ATTESTER_SLASHING:
            attester_slashing = get_valid_attester_slashing_by_indices(
                spec,
                state,
                [selected_validator_index],
                signed_1=True,
                signed_2=True,
            )
            operation_dict = {'attester_slashings': [attester_slashing]}
    elif operation_type == OperationType.DEPOSIT:
        # create a new deposit
        selected_validator_index = len(state.validators)
        amount = spec.MAX_EFFECTIVE_BALANCE
        deposit = prepare_state_and_deposit(spec,
                                            state,
                                            selected_validator_index,
                                            amount,
                                            signed=True)
        operation_dict = {'deposits': [deposit]}
    elif operation_type == OperationType.VOLUNTARY_EXIT:
        selected_validator_index = 0
        signed_exits = prepare_signed_exits(spec, state,
                                            [selected_validator_index])
        operation_dict = {'voluntary_exits': signed_exits}

    def _check_state():
        if operation_type == OperationType.PROPOSER_SLASHING:
            slashed_proposer = state.validators[
                proposer_slashing.signed_header_1.message.proposer_index]
            assert slashed_proposer.slashed
        elif operation_type == OperationType.ATTESTER_SLASHING:
            indices = set(
                attester_slashing.attestation_1.attesting_indices
            ).intersection(attester_slashing.attestation_2.attesting_indices)
            assert selected_validator_index in indices
            assert len(indices) > 0
            for validator_index in indices:
                assert state.validators[validator_index].slashed
        elif operation_type == OperationType.DEPOSIT:
            assert not post_spec.is_active_validator(
                state.validators[selected_validator_index],
                post_spec.get_current_epoch(state))
        elif operation_type == OperationType.VOLUNTARY_EXIT:
            validator = state.validators[selected_validator_index]
            assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH

    yield "pre", state

    blocks = []

    if is_right_before_fork:
        # add a block with operation.
        block = build_empty_block_for_next_slot(spec, state)
        _set_operations_by_dict(block, operation_dict)
        signed_block = state_transition_and_sign_block(spec, state, block)
        blocks.append(pre_tag(signed_block))

        _check_state()

    # irregular state transition to handle fork:
    _operation_at_slot = operation_dict if is_at_fork else None
    state, block = do_fork(state,
                           spec,
                           post_spec,
                           fork_epoch,
                           operation_dict=_operation_at_slot)
    blocks.append(post_tag(block))

    if is_at_fork:
        _check_state()

    # after the fork
    if operation_type == OperationType.DEPOSIT:
        state = _transition_until_active(post_spec, state, post_tag, blocks,
                                         selected_validator_index)
    else:
        # avoid using the slashed validators as block proposers
        ignoring_proposers = [selected_validator_index
                              ] if is_slashing_operation else None

        # continue regular state transition with new spec into next epoch
        transition_to_next_epoch_and_append_blocks(
            post_spec,
            state,
            post_tag,
            blocks,
            only_last_block=True,
            ignoring_proposers=ignoring_proposers,
        )

    yield "blocks", blocks
    yield "post", state