eth2.0-specs/specs/capella/validator.md

7.7 KiB

Capella -- Honest Validator

Notice: This document is a work-in-progress for researchers and implementers.

Table of contents

Introduction

This document represents the changes to be made in the code of an "honest validator" to implement the Capella upgrade.

Prerequisites

This document is an extension of the Bellatrix -- Honest Validator guide. All behaviors and definitions defined in this document, and documents it extends, carry over unless explicitly noted or overridden.

All terminology, constants, functions, and protocol mechanics defined in the updated Beacon Chain doc of Capella are requisite for this document and used throughout. Please see related Beacon Chain doc before continuing and use them as a reference throughout.

Helpers

Protocols

ExecutionEngine

get_payload

get_payload returns the upgraded Capella ExecutionPayload type.

Beacon chain responsibilities

All validator responsibilities remain unchanged other than those noted below.

Block proposal

Constructing the BeaconBlockBody

ExecutionPayload

ExecutionPayloads are constructed as they were in Bellatrix, except that the expected withdrawals for the slot must be gathered from the state (utilizing the helper get_expected_withdrawals) and passed into the ExecutionEngine within prepare_execution_payload.

def get_expected_withdrawals(state: BeaconState) -> Sequence[Withdrawal]:
    num_withdrawals = min(MAX_WITHDRAWALS_PER_PAYLOAD, len(state.withdrawal_queue))
    return state.withdrawal_queue[:num_withdrawals]

Note: The only change made to prepare_execution_payload is to call get_expected_withdrawals() to set the new withdrawals field of PayloadAttributes.

def prepare_execution_payload(state: BeaconState,
                              pow_chain: Dict[Hash32, PowBlock],
                              safe_block_hash: Hash32,
                              finalized_block_hash: Hash32,
                              suggested_fee_recipient: ExecutionAddress,
                              execution_engine: ExecutionEngine) -> Optional[PayloadId]:
    if not is_merge_transition_complete(state):
        is_terminal_block_hash_set = TERMINAL_BLOCK_HASH != Hash32()
        is_activation_epoch_reached = get_current_epoch(state) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
        if is_terminal_block_hash_set and not is_activation_epoch_reached:
            # Terminal block hash is set but activation epoch is not yet reached, no prepare payload call is needed
            return None

        terminal_pow_block = get_terminal_pow_block(pow_chain)
        if terminal_pow_block is None:
            # Pre-merge, no prepare payload call is needed
            return None
        # Signify merge via producing on top of the terminal PoW block
        parent_hash = terminal_pow_block.block_hash
    else:
        # Post-merge, normal payload
        parent_hash = state.latest_execution_payload_header.block_hash

    # Set the forkchoice head and initiate the payload build process
    payload_attributes = PayloadAttributes(
        timestamp=compute_timestamp_at_slot(state, state.slot),
        prev_randao=get_randao_mix(state, get_current_epoch(state)),
        suggested_fee_recipient=suggested_fee_recipient,
        withdrawals=get_expected_withdrawals(state),  # [New in Capella]
    )
    return execution_engine.notify_forkchoice_updated(
        head_block_hash=parent_hash,
        safe_block_hash=safe_block_hash,
        finalized_block_hash=finalized_block_hash,
        payload_attributes=payload_attributes,
    )
BLS to execution changes

Up to MAX_BLS_TO_EXECUTION_CHANGES, BLSToExecutionChange objects can be included in the block. The BLS to execution changes must satisfy the verification conditions found in BLS to execution change processing.

Enabling validator withdrawals

Stake belonging to validators that can safely be withdrawn from the beacon chain happens via an automatic process.

There is one prerequisite task to perform before a validator can particpate in this automatic process: ensuring the withdrawal credentials are for the execution layer, i.e. having an ETH1_ADDRESS_WITHDRAWAL_PREFIX.

If a validator has a BLS_WITHDRAWAL_PREFIX withdrawal credential prefix, Capella adds the ability for a validator to make a one-time message that changes their withdrawal credential from the version authenticated with a BLS key to the version compatible with the execution layer.

Validators who wish to enable withdrawals MUST assemble, sign, and broadcast this message so that it is accepted on the beacon chain. Validators who do not want to enable withdrawals and have the BLS_WITHDRAWAL_PREFIX version of withdrawal credentials can simply wait until they are ready to create this message and will not particpate in the automatic withdrawal process.

Changing from BLS to execution withdrawal credentials

First, the validator must construct a valid BLSToExecutionChange message. This message contains the validator_index for the validator who wishes to change their credentials, the from_bls_pubkey containing the BLS public key corresponding to the withdrawal BLS secret key used to form the BLS_WITHDRAWAL_PREFIX withdrawal credential, and the to_execution_address specifying where the validator wants stake to be withdrawn to on the execution layer.

NOTE: The withdrawal key pair used to construct the BLS_WITHDRAWAL_PREFIX withdrawal credential should be distinct from the signing key pair used to operate the validator under typical circumstances. Consult your validator deposit tooling documentation for further details if you are not aware of the difference.

The from_bls_pubkey is compared against the existing withdrawal credential on-chain for the given validator_index so it is unlikely a validator will incorrectly specify this data; however, this message can only be issued once and is currently irreversible once on-chain so take care with the to_execution_address.

Next, the validator signs the assembled BLSToExecutionChange message with the withdrawal BLS secret key and this signature is placed into a SignedBLSToExecutionChange message along with the inner BLSToExecutionChange message. Note that the SignedBLSToExecutionChange message should pass all of the validations in process_bls_to_execution_change.

The complete SignedBLSToExecutionChange message can be submitted to the consensus layer network. Once included on-chain, the withdrawal credential change takes effect. No further action is required for a validator to enter into the automated withdrawal process.