Skip to content

Conversation

jclapis
Copy link
Collaborator

@jclapis jclapis commented Sep 30, 2025

This is part of #382 and incorporates some additional user feedback. Basically, users want the PBS service to routinely query SSV or Lido when set up with muxes that use them as registries, and automatically support new pubkeys that get added to the corresponding operators. This PR adds that capability by:

  • Identifying the relevant registry muxes upon validation
  • Detecting on startup whether or not registry refreshing is required
  • Running a parallel task to the PBS service that occasionally locks the state, queries the registries, and adds any new pubkeys to the config's pubkey -> mux config HashMap.

Note this has a substantial rewrite of the SSV loader, including breaking the core structs out into a public module and a more robust mock of the SSV API server for testing.

@jclapis jclapis self-assigned this Sep 30, 2025
@jclapis jclapis added the pbs Pbs module / Builder API label Sep 30, 2025
@jclapis jclapis marked this pull request as ready for review October 7, 2025 21:03
ManuelBilbao
ManuelBilbao previously approved these changes Oct 13, 2025
Comment on lines +36 to +41
let mut is_refreshing_required = false;
if let Some(muxes) = &state.config.registry_muxes {
is_refreshing_required = muxes.iter().any(|(loader, _)| {
matches!(loader, MuxKeysLoader::Registry { enable_refreshing: true, .. })
});
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

a bit more idiomatic

Suggested change
let mut is_refreshing_required = false;
if let Some(muxes) = &state.config.registry_muxes {
is_refreshing_required = muxes.iter().any(|(loader, _)| {
matches!(loader, MuxKeysLoader::Registry { enable_refreshing: true, .. })
});
}
llet is_refreshing_required = state.config.registry_muxes.as_ref().is_some_and(|muxes| {
muxes.iter().any(|(loader, _)| {
matches!(loader, MuxKeysLoader::Registry { enable_refreshing: true, .. })
})
});

// Initialize an empty lookup if the config doesn't have one yet
let mux_lookup = match &config.mux_lookup {
Some(lookup) => lookup,
None => &HashMap::new(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we not return here?

Comment on lines +162 to +164
for (pubkey, runtime_config) in new_pubkeys.iter() {
debug!("adding new pubkey {pubkey} to mux {}", runtime_config.id);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure this adds a lot, and it iterates over the map whether debug is enabled or not

Comment on lines +169 to +171
for pubkey in removed_pubkeys.iter() {
debug!("removing old pubkey {pubkey} from mux lookup");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here

let mut state = state.write().await;
let config = state.config.as_ref();
let new_mux_lookup = if let Some(existing) = &config.mux_lookup {
let mut map = HashMap::new();
Copy link
Collaborator

Choose a reason for hiding this comment

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

instead of allocating a new map here, we can just take a mutable reference, remove all removed_pubkeys and add all new_pubkeys

Comment on lines +130 to +137
match mux_lookup.get(&pubkey) {
Some(_) => {
// Pubkey already existed
}
None => {
// New pubkey
new_pubkeys.insert(pubkey.clone(), runtime_config.clone());
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
match mux_lookup.get(&pubkey) {
Some(_) => {
// Pubkey already existed
}
None => {
// New pubkey
new_pubkeys.insert(pubkey.clone(), runtime_config.clone());
}
if mux_lookup.get(&pubkey).is_none() {
// New pubkey
new_pubkeys.insert(pubkey.clone(), runtime_config.clone());
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pbs Pbs module / Builder API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants