def process_deposit(state: BeaconState, deposit: Deposit,
                    config: Eth2Config) -> BeaconState:
    """
    Process a deposit from Ethereum 1.0.
    """
    validate_deposit_proof(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.set("eth1_deposit_index", state.eth1_deposit_index + 1)

    pubkey = deposit.data.pubkey
    amount = deposit.data.amount
    withdrawal_credentials = deposit.data.withdrawal_credentials
    validator_pubkeys = tuple(v.pubkey for v in state.validators)
    if pubkey not in validator_pubkeys:
        # Verify the deposit signature (proof of possession) for new validators.
        # Note: The deposit contract does not check signatures.
        # Note: Deposits are valid across forks, thus the deposit domain
        # is retrieved directly from `compute_domain`.
        deposit_message = DepositMessage.create(
            pubkey=pubkey,
            withdrawal_credentials=withdrawal_credentials,
            amount=amount)
        domain = compute_domain(SignatureDomain.DOMAIN_DEPOSIT,
                                fork_version=config.GENESIS_FORK_VERSION)
        signing_root = compute_signing_root(deposit_message, domain)

        is_valid_proof_of_possession = bls.verify(signing_root,
                                                  deposit.data.signature,
                                                  pubkey)

        if not is_valid_proof_of_possession:
            return state

        validator = Validator.create_pending_validator(pubkey,
                                                       withdrawal_credentials,
                                                       amount, config)

        return state.mset(
            "validators",
            state.validators.append(validator),
            "balances",
            state.balances.append(amount),
        )
    else:
        index = ValidatorIndex(validator_pubkeys.index(pubkey))
        return increase_balance(state, index, amount)
Beispiel #2
0
def process_block_header(state: BeaconState, block: BaseBeaconBlock,
                         config: Eth2Config) -> BeaconState:
    validate_block_slot(state, block)
    validate_block_parent_root(state, block)
    validate_proposer_is_not_slashed(state, block.hash_tree_root, config)

    return state.set(
        "latest_block_header",
        BeaconBlockHeader.create(
            slot=block.slot,
            parent_root=block.parent_root,
            # `state_root` is zeroed and overwritten in the next `process_slot` call
            body_root=block.body.hash_tree_root,
            # `signature` is zeroed
        ),
    )
def process_rewards_and_penalties(state: BeaconState,
                                  config: Eth2Config) -> BeaconState:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    if current_epoch == GENESIS_EPOCH:
        return state

    rewards_for_attestations, penalties_for_attestations = get_attestation_deltas(
        state, config)

    new_balances = (max(balance + reward - penalty, 0)
                    for balance, reward, penalty in zip(
                        state.balances, rewards_for_attestations,
                        penalties_for_attestations))

    return state.set(
        "balances",
        HashableList.from_iterable(new_balances, state.balances.sedes))
Beispiel #4
0
def process_registry_updates(state: BeaconState,
                             config: Eth2Config) -> BeaconState:
    new_validators = state.validators
    for index, validator in enumerate(state.validators):
        new_validator = _process_activation_eligibility_or_ejections(
            state, validator, config)
        new_validators = new_validators.set(index, new_validator)

    activation_exit_epoch = compute_activation_exit_epoch(
        state.finalized_checkpoint.epoch, config.MAX_SEED_LOOKAHEAD)
    activation_queue = sorted(
        (index for index, validator in enumerate(new_validators)
         if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH
         and validator.activation_epoch >= activation_exit_epoch),
        key=lambda index: new_validators[index].activation_eligibility_epoch,
    )

    for index in activation_queue[:get_validator_churn_limit(state, config)]:
        new_validators = new_validators.transform(
            (index, ), _update_validator_activation_epoch(state, config))

    return state.set("validators", new_validators)
def _increment_slot(state: BeaconState) -> BeaconState:
    return state.set("slot", state.slot + 1)