@@ -24,7 +24,8 @@ use types::{
2424 VoluntaryExit ,
2525} ;
2626use validator_store:: {
27- DoppelgangerStatus , Error as ValidatorStoreError , ProposalData , SignBlock , ValidatorStore ,
27+ DoppelgangerStatus , Error as ValidatorStoreError , ProposalData , SignedBlock , UnsignedBlock ,
28+ ValidatorStore ,
2829} ;
2930
3031pub type Error = ValidatorStoreError < SigningError > ;
@@ -420,6 +421,102 @@ impl<T: SlotClock + 'static, E: EthSpec> LighthouseValidatorStore<T, E> {
420421 )
421422 } )
422423 }
424+
425+ async fn sign_abstract_block < Payload : AbstractExecPayload < E > > (
426+ & self ,
427+ validator_pubkey : PublicKeyBytes ,
428+ block : BeaconBlock < E , Payload > ,
429+ current_slot : Slot ,
430+ ) -> Result < SignedBeaconBlock < E , Payload > , Error > {
431+ // Make sure the block slot is not higher than the current slot to avoid potential attacks.
432+ if block. slot ( ) > current_slot {
433+ warn ! (
434+ self . log,
435+ "Not signing block with slot greater than current slot" ;
436+ "block_slot" => block. slot( ) . as_u64( ) ,
437+ "current_slot" => current_slot. as_u64( )
438+ ) ;
439+ return Err ( Error :: GreaterThanCurrentSlot {
440+ slot : block. slot ( ) ,
441+ current_slot,
442+ } ) ;
443+ }
444+
445+ let signing_epoch = block. epoch ( ) ;
446+ let signing_context = self . signing_context ( Domain :: BeaconProposer , signing_epoch) ;
447+ let domain_hash = signing_context. domain_hash ( & self . spec ) ;
448+
449+ let signing_method = self . doppelganger_checked_signing_method ( validator_pubkey) ?;
450+
451+ // Check for slashing conditions.
452+ let slashing_status = if signing_method
453+ . requires_local_slashing_protection ( self . enable_web3signer_slashing_protection )
454+ {
455+ self . slashing_protection . check_and_insert_block_proposal (
456+ & validator_pubkey,
457+ & block. block_header ( ) ,
458+ domain_hash,
459+ )
460+ } else {
461+ Ok ( Safe :: Valid )
462+ } ;
463+
464+ match slashing_status {
465+ // We can safely sign this block without slashing.
466+ Ok ( Safe :: Valid ) => {
467+ validator_metrics:: inc_counter_vec (
468+ & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
469+ & [ validator_metrics:: SUCCESS ] ,
470+ ) ;
471+
472+ let signature = signing_method
473+ . get_signature (
474+ SignableMessage :: BeaconBlock ( & block) ,
475+ signing_context,
476+ & self . spec ,
477+ & self . task_executor ,
478+ )
479+ . await ?;
480+ Ok ( SignedBeaconBlock :: from_block ( block, signature) )
481+ }
482+ Ok ( Safe :: SameData ) => {
483+ warn ! (
484+ self . log,
485+ "Skipping signing of previously signed block" ;
486+ ) ;
487+ validator_metrics:: inc_counter_vec (
488+ & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
489+ & [ validator_metrics:: SAME_DATA ] ,
490+ ) ;
491+ Err ( Error :: SameData )
492+ }
493+ Err ( NotSafe :: UnregisteredValidator ( pk) ) => {
494+ warn ! (
495+ self . log,
496+ "Not signing block for unregistered validator" ;
497+ "msg" => "Carefully consider running with --init-slashing-protection (see --help)" ,
498+ "public_key" => format!( "{:?}" , pk)
499+ ) ;
500+ validator_metrics:: inc_counter_vec (
501+ & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
502+ & [ validator_metrics:: UNREGISTERED ] ,
503+ ) ;
504+ Err ( Error :: Slashable ( NotSafe :: UnregisteredValidator ( pk) ) )
505+ }
506+ Err ( e) => {
507+ crit ! (
508+ self . log,
509+ "Not signing slashable block" ;
510+ "error" => format!( "{:?}" , e)
511+ ) ;
512+ validator_metrics:: inc_counter_vec (
513+ & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
514+ & [ validator_metrics:: SLASHABLE ] ,
515+ ) ;
516+ Err ( Error :: Slashable ( e) )
517+ }
518+ }
519+ }
423520}
424521
425522impl < T : SlotClock + ' static , E : EthSpec > ValidatorStore for LighthouseValidatorStore < T , E > {
@@ -578,6 +675,24 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore for LighthouseValidatorS
578675 . set_index ( validator_pubkey, index) ;
579676 }
580677
678+ async fn sign_block (
679+ & self ,
680+ validator_pubkey : PublicKeyBytes ,
681+ block : UnsignedBlock < E > ,
682+ current_slot : Slot ,
683+ ) -> Result < SignedBlock < E > , Error > {
684+ match block {
685+ UnsignedBlock :: Full ( block) => self
686+ . sign_abstract_block ( validator_pubkey, block, current_slot)
687+ . await
688+ . map ( SignedBlock :: Full ) ,
689+ UnsignedBlock :: Blinded ( block) => self
690+ . sign_abstract_block ( validator_pubkey, block, current_slot)
691+ . await
692+ . map ( SignedBlock :: Blinded ) ,
693+ }
694+ }
695+
581696 async fn sign_attestation (
582697 & self ,
583698 validator_pubkey : PublicKeyBytes ,
@@ -999,103 +1114,3 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore for LighthouseValidatorS
9991114 } )
10001115 }
10011116}
1002-
1003- impl < T : SlotClock + ' static , E : EthSpec , P : AbstractExecPayload < E > >
1004- SignBlock < E , P , signing_method:: Error > for LighthouseValidatorStore < T , E >
1005- {
1006- async fn sign_block (
1007- & self ,
1008- validator_pubkey : PublicKeyBytes ,
1009- block : BeaconBlock < E , P > ,
1010- current_slot : Slot ,
1011- ) -> Result < SignedBeaconBlock < E , P > , Error > {
1012- // Make sure the block slot is not higher than the current slot to avoid potential attacks.
1013- if block. slot ( ) > current_slot {
1014- warn ! (
1015- self . log,
1016- "Not signing block with slot greater than current slot" ;
1017- "block_slot" => block. slot( ) . as_u64( ) ,
1018- "current_slot" => current_slot. as_u64( )
1019- ) ;
1020- return Err ( Error :: GreaterThanCurrentSlot {
1021- slot : block. slot ( ) ,
1022- current_slot,
1023- } ) ;
1024- }
1025-
1026- let signing_epoch = block. epoch ( ) ;
1027- let signing_context = self . signing_context ( Domain :: BeaconProposer , signing_epoch) ;
1028- let domain_hash = signing_context. domain_hash ( & self . spec ) ;
1029-
1030- let signing_method = self . doppelganger_checked_signing_method ( validator_pubkey) ?;
1031-
1032- // Check for slashing conditions.
1033- let slashing_status = if signing_method
1034- . requires_local_slashing_protection ( self . enable_web3signer_slashing_protection )
1035- {
1036- self . slashing_protection . check_and_insert_block_proposal (
1037- & validator_pubkey,
1038- & block. block_header ( ) ,
1039- domain_hash,
1040- )
1041- } else {
1042- Ok ( Safe :: Valid )
1043- } ;
1044-
1045- match slashing_status {
1046- // We can safely sign this block without slashing.
1047- Ok ( Safe :: Valid ) => {
1048- validator_metrics:: inc_counter_vec (
1049- & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
1050- & [ validator_metrics:: SUCCESS ] ,
1051- ) ;
1052-
1053- let signature = signing_method
1054- . get_signature (
1055- SignableMessage :: BeaconBlock ( & block) ,
1056- signing_context,
1057- & self . spec ,
1058- & self . task_executor ,
1059- )
1060- . await ?;
1061- Ok ( SignedBeaconBlock :: from_block ( block, signature) )
1062- }
1063- Ok ( Safe :: SameData ) => {
1064- warn ! (
1065- self . log,
1066- "Skipping signing of previously signed block" ;
1067- ) ;
1068- validator_metrics:: inc_counter_vec (
1069- & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
1070- & [ validator_metrics:: SAME_DATA ] ,
1071- ) ;
1072- Err ( Error :: SameData )
1073- }
1074- Err ( NotSafe :: UnregisteredValidator ( pk) ) => {
1075- warn ! (
1076- self . log,
1077- "Not signing block for unregistered validator" ;
1078- "msg" => "Carefully consider running with --init-slashing-protection (see --help)" ,
1079- "public_key" => format!( "{:?}" , pk)
1080- ) ;
1081- validator_metrics:: inc_counter_vec (
1082- & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
1083- & [ validator_metrics:: UNREGISTERED ] ,
1084- ) ;
1085- Err ( Error :: Slashable ( NotSafe :: UnregisteredValidator ( pk) ) )
1086- }
1087- Err ( e) => {
1088- crit ! (
1089- self . log,
1090- "Not signing slashable block" ;
1091- "error" => format!( "{:?}" , e)
1092- ) ;
1093- validator_metrics:: inc_counter_vec (
1094- & validator_metrics:: SIGNED_BLOCKS_TOTAL ,
1095- & [ validator_metrics:: SLASHABLE ] ,
1096- ) ;
1097- Err ( Error :: Slashable ( e) )
1098- }
1099- }
1100- }
1101- }
0 commit comments