@@ -22,6 +22,7 @@ use account_utils::{
2222} ;
2323pub use api_secret:: ApiSecret ;
2424use beacon_node_fallback:: CandidateInfo ;
25+ use core:: convert:: Infallible ;
2526use create_validator:: {
2627 create_validators_mnemonic, create_validators_web3signer, get_voting_password_storage,
2728} ;
@@ -30,14 +31,15 @@ use eth2::lighthouse_vc::{
3031 std_types:: { AuthResponse , GetFeeRecipientResponse , GetGasLimitResponse } ,
3132 types:: {
3233 self as api_types, GenericResponse , GetGraffitiResponse , Graffiti , PublicKey ,
33- PublicKeyBytes , SetGraffitiRequest ,
34+ PublicKeyBytes , SetGraffitiRequest , UpdateCandidatesRequest , UpdateCandidatesResponse ,
3435 } ,
3536} ;
3637use health_metrics:: observe:: Observe ;
3738use lighthouse_version:: version_with_platform;
3839use logging:: crit;
3940use logging:: SSELoggingComponents ;
4041use parking_lot:: RwLock ;
42+ use sensitive_url:: SensitiveUrl ;
4143use serde:: { Deserialize , Serialize } ;
4244use slot_clock:: SlotClock ;
4345use std:: collections:: HashMap ;
@@ -53,7 +55,8 @@ use tracing::{info, warn};
5355use types:: { ChainSpec , ConfigAndPreset , EthSpec } ;
5456use validator_dir:: Builder as ValidatorDirBuilder ;
5557use validator_services:: block_service:: BlockService ;
56- use warp:: { sse:: Event , Filter } ;
58+ use warp:: { reply:: Response , sse:: Event , Filter } ;
59+ use warp_utils:: reject:: convert_rejection;
5760use warp_utils:: task:: blocking_json_task;
5861
5962#[ derive( Debug ) ]
@@ -102,6 +105,7 @@ pub struct Config {
102105 pub allow_keystore_export : bool ,
103106 pub store_passwords_in_secrets_dir : bool ,
104107 pub http_token_path : PathBuf ,
108+ pub bn_long_timeouts : bool ,
105109}
106110
107111impl Default for Config {
@@ -121,6 +125,7 @@ impl Default for Config {
121125 allow_keystore_export : false ,
122126 store_passwords_in_secrets_dir : false ,
123127 http_token_path,
128+ bn_long_timeouts : false ,
124129 }
125130 }
126131}
@@ -147,6 +152,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
147152 let config = & ctx. config ;
148153 let allow_keystore_export = config. allow_keystore_export ;
149154 let store_passwords_in_secrets_dir = config. store_passwords_in_secrets_dir ;
155+ let use_long_timeouts = config. bn_long_timeouts ;
150156
151157 // Configure CORS.
152158 let cors_builder = {
@@ -839,6 +845,59 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
839845 } )
840846 } ) ;
841847
848+ // POST /lighthouse/beacon/update
849+ let post_lighthouse_beacon_update = warp:: path ( "lighthouse" )
850+ . and ( warp:: path ( "beacon" ) )
851+ . and ( warp:: path ( "update" ) )
852+ . and ( warp:: path:: end ( ) )
853+ . and ( warp:: body:: json ( ) )
854+ . and ( block_service_filter. clone ( ) )
855+ . then (
856+ move |request : UpdateCandidatesRequest ,
857+ block_service : BlockService < LighthouseValidatorStore < T , E > , T > | async move {
858+ async fn parse_urls ( urls : & [ String ] ) -> Result < Vec < SensitiveUrl > , Response > {
859+ match urls
860+ . iter ( )
861+ . map ( |url| SensitiveUrl :: parse ( url) . map_err ( |e| e. to_string ( ) ) )
862+ . collect ( )
863+ {
864+ Ok ( sensitive_urls) => Ok ( sensitive_urls) ,
865+ Err ( _) => Err ( convert_rejection :: < Infallible > ( Err (
866+ warp_utils:: reject:: custom_bad_request (
867+ "one or more urls could not be parsed" . to_string ( ) ,
868+ ) ,
869+ ) )
870+ . await ) ,
871+ }
872+ }
873+
874+ let beacons: Vec < SensitiveUrl > = match parse_urls ( & request. beacon_nodes ) . await {
875+ Ok ( new_beacons) => {
876+ match block_service
877+ . beacon_nodes
878+ . update_candidates_list ( new_beacons, use_long_timeouts)
879+ . await
880+ {
881+ Ok ( beacons) => beacons,
882+ Err ( e) => {
883+ return convert_rejection :: < Infallible > ( Err (
884+ warp_utils:: reject:: custom_bad_request ( e. to_string ( ) ) ,
885+ ) )
886+ . await
887+ }
888+ }
889+ }
890+ Err ( e) => return e,
891+ } ;
892+
893+ let response: UpdateCandidatesResponse = UpdateCandidatesResponse {
894+ new_beacon_nodes_list : beacons. iter ( ) . map ( |surl| surl. to_string ( ) ) . collect ( ) ,
895+ } ;
896+
897+ blocking_json_task ( move || Ok ( api_types:: GenericResponse :: from ( response) ) ) . await
898+ } ,
899+ ) ;
900+
842901 // Standard key-manager endpoints.
843902 let eth_v1 = warp:: path ( "eth" ) . and ( warp:: path ( "v1" ) ) ;
844903 let std_keystores = eth_v1. and ( warp:: path ( "keystores" ) ) . and ( warp:: path:: end ( ) ) ;
@@ -1316,6 +1375,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
13161375 . or ( post_std_keystores)
13171376 . or ( post_std_remotekeys)
13181377 . or ( post_graffiti)
1378+ . or ( post_lighthouse_beacon_update)
13191379 . recover ( warp_utils:: reject:: handle_rejection) ,
13201380 ) )
13211381 . or ( warp:: patch ( )
0 commit comments