@@ -9,8 +9,9 @@ use crate::beacon_node_health::{
99use crate :: check_synced:: check_node_health;
1010use crate :: http_metrics:: metrics:: { inc_counter_vec, ENDPOINT_ERRORS , ENDPOINT_REQUESTS } ;
1111use environment:: RuntimeContext ;
12- use eth2:: BeaconNodeHttpClient ;
12+ use eth2:: { BeaconNodeHttpClient , Timeouts } ;
1313use futures:: future;
14+ use sensitive_url:: SensitiveUrl ;
1415use serde:: { ser:: SerializeStruct , Deserialize , Serialize , Serializer } ;
1516use slog:: { debug, error, warn, Logger } ;
1617use slot_clock:: SlotClock ;
@@ -461,6 +462,42 @@ impl<T: SlotClock, E: EthSpec> BeaconNodeFallback<T, E> {
461462 ( candidate_info, num_available, num_synced)
462463 }
463464
465+ /// Update the list of candidates with a new list.
466+ /// Returns `Ok(new_list)` if the update was successful.
467+ /// Returns `Err(some_err)` if the list is empty.
468+ pub async fn replace_candidates (
469+ & self ,
470+ new_list : Vec < SensitiveUrl > ,
471+ use_long_timeouts : bool ,
472+ ) -> Result < Vec < SensitiveUrl > , String > {
473+ if new_list. is_empty ( ) {
474+ return Err ( "Beacon Node list cannot be empty" . to_string ( ) ) ;
475+ }
476+
477+ let timeouts: Timeouts = if new_list. len ( ) == 1 || use_long_timeouts {
478+ Timeouts :: set_all ( Duration :: from_secs ( self . spec . seconds_per_slot ) )
479+ } else {
480+ Timeouts :: use_optimized_timeouts ( Duration :: from_secs ( self . spec . seconds_per_slot ) )
481+ } ;
482+
483+ let new_candidates: Vec < CandidateBeaconNode < E > > = new_list
484+ . clone ( )
485+ . into_iter ( )
486+ . enumerate ( )
487+ . map ( |( index, url) | {
488+ CandidateBeaconNode :: < E > :: new (
489+ BeaconNodeHttpClient :: new ( url, timeouts. clone ( ) ) ,
490+ index,
491+ )
492+ } )
493+ . collect ( ) ;
494+
495+ let mut candidates = self . candidates . write ( ) . await ;
496+ * candidates = new_candidates;
497+
498+ Ok ( new_list)
499+ }
500+
464501 /// Loop through ALL candidates in `self.candidates` and update their sync status.
465502 ///
466503 /// It is possible for a node to return an unsynced status while continuing to serve
0 commit comments