示例#1
0
def process_deposit(state: BeaconState, deposit: Deposit, slots_per_epoch: int,
                    deposit_contract_tree_depth: int) -> BeaconState:
    """
    Process a deposit from Ethereum 1.0.
    """
    validate_deposit(state, deposit, deposit_contract_tree_depth)

    # Increment the next deposit index we are expecting. Note that this
    # needs to be done here because while the deposit contract will never
    # create an invalid Merkle branch, it may admit an invalid deposit
    # object, and we need to be able to skip over it
    state = state.copy(deposit_index=state.deposit_index + 1, )

    validator_pubkeys = tuple(v.pubkey for v in state.validator_registry)
    deposit_input = deposit.deposit_data.deposit_input
    pubkey = deposit_input.pubkey
    amount = deposit.deposit_data.amount
    withdrawal_credentials = deposit_input.withdrawal_credentials

    if pubkey not in validator_pubkeys:
        # Verify the proof of possession
        proof_is_valid = bls.verify(
            pubkey=pubkey,
            message_hash=deposit_input.signed_root,
            signature=deposit_input.proof_of_possession,
            domain=get_domain(
                state.fork,
                state.current_epoch(slots_per_epoch),
                SignatureDomain.DOMAIN_DEPOSIT,
            ),
        )
        if not proof_is_valid:
            return state

        validator = ValidatorRecord.create_pending_validator(
            pubkey=pubkey,
            withdrawal_credentials=withdrawal_credentials,
        )

        # Note: In phase 2 registry indices that has been withdrawn for a long time
        # will be recycled.
        state = add_pending_validator(
            state,
            validator,
            amount,
        )
    else:
        # Top-up - increase balance by deposit
        index = ValidatorIndex(validator_pubkeys.index(pubkey))
        validator = state.validator_registry[index]

        # Update validator's balance and state
        state = state.update_validator_balance(
            validator_index=index,
            balance=state.validator_balances[index] + amount,
        )

    return state
示例#2
0
def process_deposit(*, state: BeaconState, pubkey: BLSPubkey, amount: Gwei,
                    proof_of_possession: BLSSignature,
                    withdrawal_credentials: Hash32, randao_commitment: Hash32,
                    custody_commitment: Hash32,
                    epoch_length: int) -> BeaconState:
    """
    Process a deposit from Ethereum 1.0.
    """
    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,
        epoch_length=epoch_length,
    )

    validator_pubkeys = tuple(v.pubkey for v in state.validator_registry)
    if pubkey not in validator_pubkeys:
        validator = ValidatorRecord.create_pending_validator(
            pubkey=pubkey,
            withdrawal_credentials=withdrawal_credentials,
            randao_commitment=randao_commitment,
            custody_commitment=custody_commitment,
        )

        # Note: In phase 2 registry indices that has been withdrawn for a long time
        # will be recycled.
        state = add_pending_validator(
            state,
            validator,
            amount,
        )
    else:
        # Top-up - increase balance by deposit
        index = ValidatorIndex(validator_pubkeys.index(pubkey))
        validator = state.validator_registry[index]

        if validator.withdrawal_credentials != withdrawal_credentials:
            raise ValidationError("`withdrawal_credentials` are incorrect:\n"
                                  "\texpected: %s, found: %s" % (
                                      validator.withdrawal_credentials,
                                      validator.withdrawal_credentials,
                                  ))

        # Update validator's balance and state
        state = state.update_validator_balance(
            validator_index=index,
            balance=state.validator_balances[index] + amount,
        )

    return state
示例#3
0
def test_create_pending_validator():
    pubkey = 123
    withdrawal_credentials = b'\x11' * 32

    validator = ValidatorRecord.create_pending_validator(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
    )

    assert validator.pubkey == pubkey
    assert validator.withdrawal_credentials == withdrawal_credentials
    assert validator.activation_epoch == FAR_FUTURE_EPOCH
    assert validator.exit_epoch == FAR_FUTURE_EPOCH
    assert validator.initiated_exit is False
    assert validator.slashed is False
示例#4
0
def test_create_pending_validator():
    pubkey = 123
    withdrawal_credentials = b'\x11' * 32
    randao_commitment = b'\x22' * 32

    validator = ValidatorRecord.create_pending_validator(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
    )

    assert validator.pubkey == pubkey
    assert validator.withdrawal_credentials == withdrawal_credentials
    assert validator.randao_commitment == randao_commitment
    assert validator.randao_layers == 0
    assert validator.activation_epoch == FAR_FUTURE_EPOCH
    assert validator.exit_epoch == FAR_FUTURE_EPOCH
    assert validator.withdrawal_epoch == FAR_FUTURE_EPOCH
    assert validator.penalized_epoch == FAR_FUTURE_EPOCH
示例#5
0
def test_create_pending_validator():
    pubkey = 123
    withdrawal_credentials = b'\x11' * 32
    randao_commitment = b'\x22' * 32
    custody_commitment = b'\x33' * 32

    validator = ValidatorRecord.create_pending_validator(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
    )

    assert validator.pubkey == pubkey
    assert validator.withdrawal_credentials == withdrawal_credentials
    assert validator.randao_commitment == randao_commitment
    assert validator.randao_layers == 0
    assert validator.activation_slot == FAR_FUTURE_SLOT
    assert validator.exit_slot == FAR_FUTURE_SLOT
    assert validator.withdrawal_slot == FAR_FUTURE_SLOT
    assert validator.penalized_slot == FAR_FUTURE_SLOT
    assert validator.exit_count == 0
def test_update_validator_registry(n,
                                   n_validators_state,
                                   config,
                                   slots_per_epoch):
    validator_registry = list(n_validators_state.validator_registry)
    activating_index = n
    exiting_index = 0

    activating_validator = ValidatorRecord.create_pending_validator(
        pubkey=b'\x10' * 48,
        withdrawal_credentials=b'\x11' * 32,
    )

    exiting_validator = n_validators_state.validator_registry[exiting_index].copy(
        exit_epoch=FAR_FUTURE_EPOCH,
        initiated_exit=True,
    )

    validator_registry[exiting_index] = exiting_validator
    validator_registry.append(activating_validator)
    state = n_validators_state.copy(
        validator_registry=validator_registry,
        validator_balances=n_validators_state.validator_balances + (config.MAX_DEPOSIT_AMOUNT,),
    )

    state = update_validator_registry(state, config)

    entry_exit_effect_epoch = get_delayed_activation_exit_epoch(
        state.current_epoch(slots_per_epoch),
        config.ACTIVATION_EXIT_DELAY,
    )

    # Check if the activating_validator is activated
    assert state.validator_registry[activating_index].activation_epoch == entry_exit_effect_epoch
    # Check if the activating_validator is exited
    assert state.validator_registry[exiting_index].exit_epoch == entry_exit_effect_epoch