Skip to content

Support chain-supplied validator voluntary exits #300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
May 16, 2025

Conversation

diegomrsantos
Copy link
Contributor

@diegomrsantos diegomrsantos commented Apr 30, 2025

Issue Addressed

#259

Proposed Changes

This PR adds support for chain-supplied voluntary exits by introducing dedicated tracking and processing components for validator exit requests. Key changes include the creation of a voluntary exit tracker and processor, integration of signature collection within the validator store, and the subsequent wiring of these components into the client and event sync flows.

Additional Info

In the next PR, I'll use the tracker for duty validation.

@diegomrsantos diegomrsantos changed the base branch from stable to unstable April 30, 2025 15:51
# Conflicts:
#	anchor/eth/src/sync.rs
@diegomrsantos diegomrsantos requested a review from Copilot May 5, 2025 18:48
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces support for chain-supplied voluntary exits by adding new functionality to collect signatures, process exit requests, and update event processing accordingly.

  • Added asynchronous function to collect voluntary exit signatures in the validator store.
  • Implemented a new voluntary exit processor and integrated it into the event processor and client startup flow.
  • Updated dependency exports and adjusted operator validation and error handling in related modules.

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
anchor/validator_store/src/lib.rs Added the collect_voluntary_exit_signatures function to handle exits.
anchor/signature_collector/src/lib.rs Changed the ssv_types import to be public.
anchor/eth/src/voluntary_exit_processor.rs Introduced a new module to process voluntary exit requests asynchronously.
anchor/eth/src/util.rs Added debug logging in operator validation.
anchor/eth/src/sync.rs Integrated exit processor into syncer construction.
anchor/eth/src/lib.rs Re-exported the new voluntary exit processor module.
anchor/eth/src/event_processor.rs Updated exit handling in validator exit events and related helper functions.
anchor/eth/Cargo.toml Added dependency on anchor_validator_store.
anchor/common/ssv_types/src/share.rs Derived Eq and PartialEq for Share for equality comparisons.
anchor/client/src/lib.rs Created and passed exit channel; started the voluntary exit processor.
Comments suppressed due to low confidence (1)

anchor/eth/src/event_processor.rs:644

  • The error type in get_validator_index is nested (Result<Option, Result<(), ExecutionError>>) which is unusual and may lead to confusion. Simplify the return type to Result<Option, ExecutionError> and adjust the error return accordingly.
fn get_validator_index(&self, validator_pubkey: &PublicKeyBytes) -> Result<Option<ValidatorIndex>, Result<(), ExecutionError>> {

@diegomrsantos diegomrsantos requested a review from Copilot May 5, 2025 20:41
@diegomrsantos diegomrsantos self-assigned this May 5, 2025
@diegomrsantos diegomrsantos marked this pull request as ready for review May 5, 2025 20:41
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces support for chain-supplied validator voluntary exits by adding new functionality to collect and process voluntary exit signatures, as well as integrating these exits into the event processing and client startup flow.

  • Introduces a new async method in the validator store to collect voluntary exit signatures.
  • Adds a new voluntary exit processor component and integrates it into the event processor and client.
  • Adjusts module exports and dependencies to support voluntary exit processing.

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
anchor/validator_store/src/lib.rs Adds a new async function to collect voluntary exit signatures.
anchor/signature_collector/src/lib.rs Makes ssv_types publicly accessible.
anchor/eth/src/voluntary_exit_processor.rs Implements processing and submission of voluntary exit requests.
anchor/eth/src/util.rs Adds debug logging for operator validation.
anchor/eth/src/sync.rs Injects the exit_tx into the event syncer.
anchor/eth/src/lib.rs Exposes the voluntary exit processor module.
anchor/eth/src/event_processor.rs Integrates exit processing into validator exit events.
anchor/eth/Cargo.toml Updates dependencies to include the validator store module.
anchor/common/ssv_types/src/share.rs Derives additional traits for Share.
anchor/client/src/lib.rs Sets up the voluntary exit processor channel and startup.
Comments suppressed due to low confidence (1)

anchor/eth/src/event_processor.rs:639

  • [nitpick] If the removal of the metrics counter for validator exits was intended, please confirm that exit processing metrics are tracked elsewhere; otherwise, consider retaining or relocating this metric update for consistency.
// metrics::inc_counter_vec(&metrics::EXECUTION_EVENTS_PROCESSED, &["validator_exited"]);

@diegomrsantos diegomrsantos requested review from dknopik and jking-aus May 5, 2025 22:26
diegomrsantos and others added 3 commits May 6, 2025 13:17
# Conflicts:
#	anchor/eth/src/event_processor.rs
#	anchor/signature_collector/src/lib.rs
Copy link
Member

@dknopik dknopik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks good overall! Some first comments below, will test it out tomorrow.

@diegomrsantos diegomrsantos requested a review from Copilot May 8, 2025 16:19
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for chain-supplied voluntary exits by introducing new modules to track and process exit requests from validators. Key changes include:

  • Implementation of a voluntary exit tracker that schedules and prunes exit duties.
  • Addition of an asynchronous voluntary exit processor integrated into the event processing and client startup flows.
  • Updates to dependencies and adjustments in the validator store, event processor, and client to support voluntary exit functionality.

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
anchor/voluntary_exit/src/voluntary_exit_tracker.rs Implements tracking and scheduling of voluntary exit duties.
anchor/voluntary_exit/src/voluntary_exit_processor.rs Adds asynchronous exit request processing and scheduling logic.
anchor/voluntary_exit/src/lib.rs Exports the new voluntary exit modules.
anchor/voluntary_exit/Cargo.toml Declares the voluntary_exit crate and its dependencies.
anchor/validator_store/src/lib.rs Introduces collection of voluntary exit signatures.
anchor/signature_collector/src/lib.rs Re-exports ssv_types for external usage.
anchor/eth/src/util.rs Adds logging during operator validation.
anchor/eth/src/sync.rs Passes exit_tx to the event syncer for exit processing.
anchor/eth/src/event_processor.rs Integrates voluntary exit request handling into event processing.
anchor/eth/Cargo.toml Adds voluntary_exit dependency to the eth crate.
anchor/client/src/lib.rs Creates the voluntary exit processing channel and initiates processing.
anchor/client/Cargo.toml Adds voluntary_exit dependency to the client crate.
Cargo.toml Includes voluntary_exit in workspace members.
anchor/common/ssv_types/src/share.rs Updates Share struct with equality derivations.

@@ -346,11 +349,17 @@ impl Client {
let index_sync_tx =
start_validator_index_syncer(beacon_nodes.clone(), database.clone(), executor.clone());

// We create the channel here so that we can pass the receiver to the syncer. But we need to
// delay starting the voluntary exit processor until we have created the validator store.
let (exit_tx, exit_rx) = unbounded_channel();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know my liberal policy about unbounded_channel that have a natural boundary due to on-chain limitations ;D

Still, if you want you can estimate how many exits can be burst in a single block, add some safety margin on top and apply that as limit.

Copy link
Member

@Zacholme7 Zacholme7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nits, really good job here!

@diegomrsantos diegomrsantos requested a review from Copilot May 14, 2025 16:17
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for chain-supplied voluntary exits by introducing dedicated tracking and processing components for validator exit requests. Key changes include the creation of a voluntary exit tracker and processor, integration of signature collection within the validator store, and the subsequent wiring of these components into the client and event sync flows.

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
anchor/voluntary_exit/src/voluntary_exit_tracker.rs New tracker for scheduling and managing exit duties.
anchor/voluntary_exit/src/voluntary_exit_processor.rs New asynchronous processor for handling exit requests.
anchor/voluntary_exit/src/lib.rs Module exports for voluntary exit functionality.
anchor/voluntary_exit/Cargo.toml Cargo configuration for the new voluntary exit package.
anchor/validator_store/src/lib.rs Added function for collecting partial voluntary exit signatures.
anchor/signature_collector/src/lib.rs Exposed ssv_types with pub use to support shared usage.
anchor/eth/src/util.rs Added provider factory functions with timeout and fallback.
anchor/eth/src/sync.rs Updated event syncer to include exit_tx and utilize the new HTTP provider helper.
anchor/client/src/lib.rs Integrated voluntary exit processor into the client startup flow.
anchor/client/Cargo.toml Included voluntary exit dependency.
Cargo.toml Updated workspace members to include voluntary_exit module.

@diegomrsantos diegomrsantos requested a review from Copilot May 15, 2025 13:18
Copy link
Member

@dknopik dknopik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you! Will defer to @jking-aus for final approval due to architectural significance.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds support for chain-supplied voluntary exits by introducing a voluntary exit tracker and processor, integrating exit signature collection into the validator store, and wiring these components through the event sync and client flows.

  • New modules voluntary_exit_tracker and voluntary_exit_processor to schedule and execute exit duties.
  • Extended the validator store with collect_voluntary_exit_partial_signatures.
  • Refactored HTTP provider setup into a shared util and integrated exit handling into SsvEventSyncer and Client.

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
anchor/voluntary_exit/src/voluntary_exit_tracker.rs Tracks and manages scheduled exit duties per slot
anchor/voluntary_exit/src/voluntary_exit_processor.rs Receives exit requests, schedules, and processes them
anchor/validator_store/src/lib.rs Added collect_voluntary_exit_partial_signatures method
anchor/signature_collector/src/lib.rs Changed use ssv_types to pub use ssv_types
anchor/eth/src/util.rs Extracted HTTP provider with timeout + fallback logic
anchor/eth/src/sync.rs Wired in exit channel, removed duplicated provider code
anchor/eth/src/event_processor.rs Made process_logs async, dispatches ValidatorExited via exit queue
anchor/client/src/lib.rs Started exit processor from the client
anchor/common/ssv_types/src/share.rs Added Eq/PartialEq to Share
Comments suppressed due to low confidence (3)

anchor/voluntary_exit/src/voluntary_exit_processor.rs:83

  • Using unwrap_or_default on slot_of may silently schedule exits at slot 0 if conversion fails; consider handling the error explicitly or logging it.
let exit_slot = slot_clock.slot_of(Duration::from_secs(block_timestamp)).unwrap_or_default();

anchor/voluntary_exit/src/voluntary_exit_tracker.rs:37

  • The new tracker methods (e.g., add_duty_for_slot, get_ready_exits, prune) are untested; adding unit tests would help ensure correct behavior.
pub fn add_duty_for_slot(

anchor/eth/src/event_processor.rs:557

  • [nitpick] The metrics counter for processed ValidatorExited events is commented out; consider restoring or removing it explicitly to keep instrumentation consistent.
// metrics::inc_counter_vec(

Comment on lines +66 to +67
/// Get all exits that should be processed at or before the given slot
/// Returns the exits without removing them from the tracker
Copy link
Preview

Copilot AI May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider adding doc comments to explain the behavior of get_ready_exits, especially that it does not remove entries and that removal is handled elsewhere.

Suggested change
/// Get all exits that should be processed at or before the given slot
/// Returns the exits without removing them from the tracker
/// Get all exits that should be processed at or before the given slot.
///
/// This method retrieves a list of `ExitDuty` objects representing the exits
/// scheduled for processing at or before the specified `current_slot`. It does
/// not modify or remove any entries from the tracker. Removal of processed exits
/// is handled separately by the `remove_processed_exit` method.
///
/// # Parameters
/// - `current_slot`: The slot up to which exits should be retrieved.
///
/// # Returns
/// A `Vec<ExitDuty>` containing the exits ready for processing.

Copilot uses AI. Check for mistakes.

}

/// Remove a specific exit that has been successfully processed
pub fn remove_processed_exit(&self, exit_duty: &ExitDuty) {
Copy link
Preview

Copilot AI May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The all_duties_by_slot map is never decremented when an exit is removed, which may lead to stale counts; consider cleaning it up in remove_processed_exit or during pruning.

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good point. They don't decrement the counter in the go implementation. Any idea why? @dknopik @nkryuchkov

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diegomrsantos We remove the entire slot data after one epoch: https://github.com/ssvlabs/ssv/blob/v2.3.1/operator/duties/voluntary_exit.go#L117. Or did you mean anything else?

@@ -9,7 +9,7 @@ use dashmap::{DashMap, Entry};
use message_sender::MessageSender;
use processor::{Error, Error::Queue, Senders, work::DropOnFinish};
use slot_clock::SlotClock;
use ssv_types::{
pub use ssv_types::{
Copy link
Preview

Copilot AI May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Re-exporting the entire ssv_types public API may expose internals unintentionally; consider re-exporting only the needed types.

Copilot uses AI. Check for mistakes.

@jking-aus jking-aus merged commit 288e3d1 into sigp:unstable May 16, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants