@@ -113,23 +113,7 @@ pub struct Inner<T, E: EthSpec> {
113113pub struct ValidatorRegistrationKey {
114114 pub fee_recipient : Address ,
115115 pub gas_limit : u64 ,
116- pub pubkey : PublicKeyBytes ,
117- }
118-
119- impl From < ValidatorRegistrationData > for ValidatorRegistrationKey {
120- fn from ( data : ValidatorRegistrationData ) -> Self {
121- let ValidatorRegistrationData {
122- fee_recipient,
123- gas_limit,
124- timestamp : _,
125- pubkey,
126- } = data;
127- Self {
128- fee_recipient,
129- gas_limit,
130- pubkey,
131- }
132- }
116+ pub signing_pubkey : PublicKeyBytes ,
133117}
134118
135119/// Attempts to produce proposer preparations for all known validators at the beginning of each epoch.
@@ -284,21 +268,31 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
284268 } )
285269 }
286270
287- fn collect_validator_registration_keys ( & self ) -> Vec < ValidatorRegistrationKey > {
288- self . collect_proposal_data ( |pubkey , proposal_data| {
271+ fn collect_validator_registration_keys ( & self ) -> Vec < ( PublicKeyBytes , ValidatorRegistrationKey ) > {
272+ self . collect_proposal_data ( |signing_pubkey , proposal_data| {
289273 // Ignore fee recipients for keys without indices, they are inactive.
290274 proposal_data. validator_index ?;
291275
292276 // We don't log for missing fee recipients here because this will be logged more
293277 // frequently in `collect_preparation_data`.
294278 proposal_data. fee_recipient . and_then ( |fee_recipient| {
295- proposal_data
296- . builder_proposals
297- . then_some ( ValidatorRegistrationKey {
298- fee_recipient,
299- gas_limit : proposal_data. gas_limit ,
300- pubkey,
301- } )
279+ proposal_data. builder_proposals . then ( || {
280+ let registration_pubkey =
281+ if let Some ( pubkey_override) = proposal_data. builder_pubkey_override {
282+ pubkey_override
283+ } else {
284+ signing_pubkey
285+ } ;
286+
287+ (
288+ registration_pubkey,
289+ ValidatorRegistrationKey {
290+ fee_recipient,
291+ gas_limit : proposal_data. gas_limit ,
292+ signing_pubkey,
293+ } ,
294+ )
295+ } )
302296 } )
303297 } )
304298 }
@@ -357,31 +351,35 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
357351 }
358352
359353 /// Register validators with builders, used in the blinded block proposal flow.
354+ /// This method re-publishes all messages if it's been `EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION`.
355+ /// Otherwise it publishes any messages that have been updated since they were last published.
360356 async fn register_validators ( & self ) -> Result < ( ) , String > {
361357 let registration_keys = self . collect_validator_registration_keys ( ) ;
362358
363- let mut changed_keys = vec ! [ ] ;
364-
365- // Need to scope this so the read lock is not held across an await point (I don't know why
366- // but the explicit `drop` is not enough).
367- {
368- let guard = self . validator_registration_cache . read ( ) ;
369- for key in registration_keys. iter ( ) {
370- if !guard. contains_key ( key) {
371- changed_keys. push ( key. clone ( ) ) ;
372- }
373- }
374- drop ( guard) ;
375- }
376-
377359 // Check if any have changed or it's been `EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION`.
378360 if let Some ( slot) = self . slot_clock . now ( ) {
379361 if slot % ( E :: slots_per_epoch ( ) * EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION ) == 0 {
380362 self . publish_validator_registration_data ( registration_keys)
381363 . await ?;
382- } else if !changed_keys. is_empty ( ) {
383- self . publish_validator_registration_data ( changed_keys)
384- . await ?;
364+ } else {
365+ let mut changed_keys = vec ! [ ] ;
366+
367+ // Need to scope this so the read lock is not held across an await point (I don't know why
368+ // but the explicit `drop` is not enough).
369+ {
370+ let guard = self . validator_registration_cache . read ( ) ;
371+ for ( registration_pubkey, key) in registration_keys. into_iter ( ) {
372+ if !guard. contains_key ( & key) {
373+ changed_keys. push ( ( registration_pubkey, key) ) ;
374+ }
375+ }
376+ drop ( guard) ;
377+ }
378+
379+ if !changed_keys. is_empty ( ) {
380+ self . publish_validator_registration_data ( changed_keys)
381+ . await ?;
382+ }
385383 }
386384 }
387385
@@ -390,14 +388,14 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
390388
391389 async fn publish_validator_registration_data (
392390 & self ,
393- registration_keys : Vec < ValidatorRegistrationKey > ,
391+ registration_keys : Vec < ( PublicKeyBytes , ValidatorRegistrationKey ) > ,
394392 ) -> Result < ( ) , String > {
395393 let log = self . context . log ( ) ;
396394
397395 let registration_data_len = registration_keys. len ( ) ;
398396 let mut signed = Vec :: with_capacity ( registration_data_len) ;
399397
400- for key in registration_keys {
398+ for ( registration_pubkey , key) in registration_keys {
401399 let cached_registration_opt =
402400 self . validator_registration_cache . read ( ) . get ( & key) . cloned ( ) ;
403401
@@ -417,22 +415,23 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
417415 let ValidatorRegistrationKey {
418416 fee_recipient,
419417 gas_limit,
420- pubkey ,
418+ signing_pubkey ,
421419 } = key. clone ( ) ;
422420
423421 let signed_data = match self
424422 . validator_store
425- . sign_validator_registration_data ( ValidatorRegistrationData {
423+ . sign_validator_registration_data ( signing_pubkey,
424+ ValidatorRegistrationData {
426425 fee_recipient,
427426 gas_limit,
428427 timestamp,
429- pubkey,
428+ pubkey : registration_pubkey ,
430429 } )
431430 . await
432431 {
433432 Ok ( data) => data,
434433 Err ( e) => {
435- error ! ( log, "Unable to sign validator registration data" ; "error" => ?e, "pubkey" => ?pubkey ) ;
434+ error ! ( log, "Unable to sign validator registration data" ; "error" => ?e, "pubkey" => ?signing_pubkey ) ;
436435 continue ;
437436 }
438437 } ;
@@ -482,4 +481,6 @@ pub struct ProposalData {
482481 pub ( crate ) fee_recipient : Option < Address > ,
483482 pub ( crate ) gas_limit : u64 ,
484483 pub ( crate ) builder_proposals : bool ,
484+ pub ( crate ) builder_pubkey_override : Option < PublicKeyBytes > ,
485+ pub ( crate ) builder_timestamp_override : Option < u64 >
485486}
0 commit comments