Skip to content

Weber -- Honest Validator

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

Table of contents

Introduction

This document represents the behaviors and responsibilities of an "honest validator" in the Weber protocol. Validators in Weber have additional responsibilities related to the reputation system, quick finality protocol, and rotation mechanisms introduced in this upgrade.

Prerequisites

This document is an extension of the previous validator guides and assumes familiarity with prior specifications. All behaviors and definitions from previous versions carry over unless explicitly modified or overridden by the Weber specification.

All terminology, constants, functions, and protocol mechanics defined in the Weber Beacon Chain documentation are requisite for this document and used throughout. Please review the Weber Beacon Chain documentation before continuing.

Validator Responsibilities

In addition to all previous validator responsibilities, validators in Weber have the following new or modified responsibilities:

Attestation Production

Attestations include reputation data and follow the same timing requirements as before.

Block Proposal

Block proposal now includes reputation updates and quick finality aggregates.

Quick Finality Votes

Validators must participate in the quick finality protocol when assigned.

Reputation Management

Validators must monitor and maintain their reputation scores.

Protocols

Modified get_payload

The get_payload function includes Weber-specific parameters:

1
2
3
4
5
6
7
8
9
def get_payload(payload_id: PayloadId,
                execution_engine: ExecutionEngine) -> Optional[GetPayloadResponse]:
    """
    Returns a response containing:
    1. An execution payload with the payload ID obtained from notify_forkchoice_updated
    2. The block value in wei
    3. Weber-specific execution metrics (new in Weber)
    """
    return execution_engine.get_payload(payload_id)

Quick Finality Protocol

def produce_quick_finality_vote(state: BeaconState,
                               validator_index: ValidatorIndex,
                               private_key: int,
                               target_epoch: Epoch,
                               target_root: Root) -> SignedQuickFinalityVote:
    """
    Produces a signed quick finality vote for the specified target.
    """
    # Create unsigned quick finality vote
    quick_finality_vote = QuickFinalityVote(
        validator_index=validator_index,
        epoch=target_epoch,
        target_root=target_root
    )

    # Get signing domain
    domain = get_domain(state, DOMAIN_QUICK_FINALITY, compute_epoch_at_slot(state.slot))
    signing_root = compute_signing_root(quick_finality_vote, domain)

    # Sign and create signed vote
    signature = bls.Sign(private_key, signing_root)
    return SignedQuickFinalityVote(message=quick_finality_vote, signature=signature)

Attestation Responsibilities

Producing Attestations

def get_weber_attestation_data(state: BeaconState, 
                              committee_index: CommitteeIndex, 
                              slot: Slot) -> AttestationData:
    """
    Returns attestation data with Weber-specific components.
    """
    # Get attestation data as before
    data = get_attestation_data(state, committee_index, slot)

    # Add Weber-specific reputation components
    data.reputation_updates = get_reputation_updates_for_attestation(state)

    return data

Aggregating Attestations

When serving as an aggregator, validators must also properly aggregate reputation updates.

Block Proposal

Constructing the BeaconBlockBody

When constructing a block body, the validator now needs to include quick finality aggregates and reputation updates:

def construct_weber_block_body(state: BeaconState,
                              execution_payload: Optional[ExecutionPayload],
                              eth1_data: Eth1Data,
                              graffiti: Bytes32,
                              proposer_slashings: Sequence[ProposerSlashing],
                              attester_slashings: Sequence[AttesterSlashing],
                              attestations: Sequence[Attestation],
                              deposits: Sequence[Deposit],
                              voluntary_exits: Sequence[SignedVoluntaryExit],
                              sync_aggregate: SyncAggregate,
                              reputation_updates: Sequence[ReputationUpdate],
                              quick_finality_aggregate: QuickFinalityAggregate) -> BeaconBlockBody:
    """
    Construct a BeaconBlockBody for a Weber block proposal.
    """
    if execution_payload is None:
        execution_payload = ExecutionPayload()

    return BeaconBlockBody(
        randao_reveal=get_epoch_signature(state, state.slot, private_key),
        eth1_data=eth1_data,
        graffiti=graffiti,
        proposer_slashings=proposer_slashings,
        attester_slashings=attester_slashings,
        attestations=attestations,
        deposits=deposits,
        voluntary_exits=voluntary_exits,
        sync_aggregate=sync_aggregate,
        execution_payload=execution_payload,
        reputation_updates=reputation_updates,  # Weber-specific
        quick_finality_aggregate=quick_finality_aggregate,  # Weber-specific
    )

Including Reputation Updates

A block proposer should include reputation updates following these rules:

def get_reputation_updates_for_block(state: BeaconState, 
                                    attestations: Sequence[Attestation]) -> Sequence[ReputationUpdate]:
    """
    Extract reputation updates to include in a block.
    """
    updates = []

    # Extract reputation data from attestations
    for attestation in attestations:
        updates.extend(extract_reputation_updates(attestation))

    # Add proposer's own reputation updates
    updates.append(create_self_reputation_update(state))

    # Deduplicate and sort by priority
    return deduplicate_and_prioritize_updates(updates)

Quick Finality Aggregation

Block proposers are responsible for aggregating quick finality votes:

def get_quick_finality_aggregate(state: BeaconState,
                                quick_finality_votes: Sequence[SignedQuickFinalityVote]) -> QuickFinalityAggregate:
    """
    Aggregate quick finality votes to include in a block.
    """
    # Filter valid votes for current target
    valid_votes = filter_valid_quick_finality_votes(state, quick_finality_votes)

    # Create aggregated signature
    aggregate_signature = aggregate_signatures([vote.signature for vote in valid_votes])

    # Create bitfield of participating validators
    participation_bitfield = create_participation_bitfield(state, valid_votes)

    return QuickFinalityAggregate(
        target_epoch=compute_epoch_at_slot(state.slot),
        target_root=get_block_root_at_slot(state, compute_start_slot_at_epoch(compute_epoch_at_slot(state.slot))),
        participation_bitfield=participation_bitfield,
        aggregate_signature=aggregate_signature
    )

Sync Committee Responsibilities

Sync committee duties remain similar to previous versions but include additional reputation-based weights.

Validator Rotation

Preparation for Rotation

def prepare_for_rotation(state: BeaconState,
                        validator_index: ValidatorIndex,
                        current_epoch: Epoch) -> None:
    """
    Prepare validator for upcoming rotation.
    """
    # Check if validator is scheduled for rotation
    rotation_epoch = get_next_rotation_epoch(state, validator_index)

    if current_epoch >= rotation_epoch - ROTATION_PREPARATION_EPOCHS:
        # Begin transition to standby mode
        signal_rotation_preparation(state, validator_index)

        # Prepare state data for smooth handover
        backup_validator_state(validator_index)

Post-Rotation Duties

After rotation, validators have specific responsibilities:

def post_rotation_duties(state: BeaconState,
                        validator_index: ValidatorIndex) -> None:
    """
    Handle validator duties after rotation.
    """
    # Reset reputation metrics
    reset_reputation_score(validator_index)

    # Initialize new consensus responsibilities
    initialize_post_rotation_duties(state, validator_index)

    # Signal readiness for new duties
    signal_rotation_complete(state, validator_index)

Optional Validator Behaviors

Reputation Score Optimization

def optimize_reputation_score(state: BeaconState,
                             validator_index: ValidatorIndex) -> None:
    """
    Optimize validator behavior to improve reputation score.
    """
    # Analyze current reputation factors
    current_score = get_validator_reputation_score(state, validator_index)
    reputation_factors = analyze_reputation_factors(state, validator_index)

    # Adjust behavior based on weak factors
    if reputation_factors.attestation_timeliness < REPUTATION_THRESHOLD:
        adjust_attestation_timing(validator_index)

    if reputation_factors.proposal_quality < REPUTATION_THRESHOLD:
        adjust_proposal_strategy(validator_index)

Performance Monitoring

Validators should monitor their performance metrics:

def monitor_validator_performance(state: BeaconState,
                                 validator_index: ValidatorIndex) -> PerformanceMetrics:
    """
    Monitor validator performance metrics.
    """
    # Collect attestation performance
    attestation_metrics = track_attestation_performance(state, validator_index)

    # Collect proposal performance
    proposal_metrics = track_proposal_performance(state, validator_index)

    # Collect quick finality participation
    finality_metrics = track_quick_finality_performance(state, validator_index)

    # Calculate reputation impact
    reputation_impact = calculate_reputation_impact(
        attestation_metrics,
        proposal_metrics,
        finality_metrics
    )

    return PerformanceMetrics(
        attestation_metrics=attestation_metrics,
        proposal_metrics=proposal_metrics,
        finality_metrics=finality_metrics,
        reputation_impact=reputation_impact,
        expected_rewards=calculate_expected_rewards(state, validator_index)
    )