Skip to content

Make ValidatorCache in BeaconNodeClient immutable #482

@emlautarom1-agent

Description

@emlautarom1-agent

Summary

The ValidatorCache stored in BeaconNodeClient is currently modeled as mutable, shared, optional state. It should probably be set once during construction instead of supporting later modification (and the "unset" state).

This is captured by an existing TODO in the code:

https://github.com/NethermindEth/pluto/blob/main/crates/eth2api/src/beacon_node.rs

pub struct BeaconNodeClient {
    api: EthBeaconNodeApiClient,
    // TODO: Find the concrete usages of the `validator_cache` and consider if we can make it
    // immutable, that is, set it once at construction and not have to deal with the possibility of
    // it being unset later.
    validator_cache: Arc<RwLock<Option<ValidatorCache>>>,
}

Current behavior

  • The cache is held as Arc<RwLock<Option<ValidatorCache>>>.
  • It is initialized to None in BeaconNodeClient::new.
  • It is populated later via set_validator_cache, meaning every read has to handle the "not yet set" case (BeaconNodeClientError::NoActiveValidatorCache).

This optionality leaks into callers. For example, in the scheduler (crates/core/src/scheduler.rs), reading the cache forces an expect, with a TODO noting it should always be available:

let valcache = self
    .client
    .validator_cache()
    .await
    // TODO: [`pluto_eth2api::valcache::ValidatorCache`] should always be available.
    .expect("validator cache is available");

Proposed change

  • Audit the concrete usages of validator_cache / set_validator_cache.
  • If the cache is always known at construction time, make it immutable: pass it into BeaconNodeClient::new (or a dedicated constructor) and store it as a plain ValidatorCache field.
  • This removes:
    • the Option/RwLock wrapping,
    • the set_validator_cache setter,
    • the NoActiveValidatorCache error variant,
    • and the downstream expect("validator cache is available") in the scheduler.

Open questions

  • Are there any flows where BeaconNodeClient legitimately needs to exist before the validator cache is known? If so, immutability at construction may not be feasible and we should document why the optional state is required instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rustPull requests that update rust code

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions