@@ -14,6 +14,7 @@ use sc_consensus_slots::InherentDataProviderExt;
1414use sc_telemetry:: TelemetryHandle ;
1515use sp_api:: ApiExt ;
1616use sp_api:: ProvideRuntimeApi ;
17+ use sp_application_crypto:: Ss58Codec as _;
1718use sp_block_builder:: BlockBuilder as BlockBuilderApi ;
1819use sp_blockchain:: HeaderBackend ;
1920use sp_blockchain:: HeaderMetadata ;
@@ -24,7 +25,6 @@ use sp_consensus_aura::sr25519::AuthorityPair as AuraAuthorityPair;
2425use sp_consensus_babe:: AuthorityId as BabeAuthorityId ;
2526use sp_consensus_babe:: AuthorityPair as BabeAuthorityPair ;
2627use sp_consensus_babe:: BABE_ENGINE_ID ;
27- use sp_consensus_babe:: BabeApi ;
2828use sp_core:: Pair ;
2929use sp_inherents:: CreateInherentDataProviders ;
3030use sp_runtime:: Digest ;
5151 CIDP : CreateInherentDataProviders < B , ( ) > + Send + Sync ,
5252 CIDP :: InherentDataProviders : InherentDataProviderExt + Send + Sync ,
5353 C : ProvideRuntimeApi < B > + Send + Sync + sc_client_api:: backend:: AuxStore ,
54- C :: Api : BlockBuilderApi < B > + AuraApi < B , AuraAuthorityId > + ApiExt < B > + BabeApi < B > ,
54+ C :: Api : BlockBuilderApi < B > + AuraApi < B , AuraAuthorityId > + ApiExt < B > ,
5555 C : HeaderBackend < B > + HeaderMetadata < B > ,
5656{
5757 pub fn new (
@@ -86,52 +86,64 @@ where
8686 ///
8787 /// The Babe block will be verified in full after the node spins back up as a Babe service.
8888 async fn check_babe_block ( & self , block : BlockImportParams < B > ) -> Result < ( ) , String > {
89- use sp_core:: crypto:: Ss58Codec ;
90-
89+ log:: info!(
90+ "Checking Babe block {:?} is legitimate" ,
91+ block. post_header( ) . hash( )
92+ ) ;
9193 let mut header = block. header . clone ( ) ;
92-
93- let _parent_header = self
94- . client
95- . header ( * block. post_header ( ) . parent_hash ( ) )
96- . map_err ( |e| format ! ( "Failed to get parent header: {}" , e) ) ?
97- . ok_or ( "Parent header not found" . to_string ( ) ) ?;
98-
99- let _pre_digest = sc_consensus_babe:: find_pre_digest :: < B > ( & block. header ) ?
100- . ok_or ( "No predigest" . to_string ( ) ) ?;
101-
10294 let seal = header
10395 . digest_mut ( )
10496 . pop ( )
10597 . ok_or_else ( || "Header Unsealed" . to_string ( ) ) ?;
106-
10798 let sig = seal
10899 . as_babe_seal ( )
109100 . ok_or_else ( || "Header bad seal" . to_string ( ) ) ?;
110101
111- // the pre-hash of the header doesn't include the seal
112- // and that's what we sign
113- let pre_hash = header. hash ( ) ;
114-
115- // Alice pub key
116- // TODO: Make this based on last Aura authorities, not just Alice.
117- let public =
118- BabeAuthorityId :: from_ss58check ( "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" )
119- . unwrap ( ) ;
120- if !BabeAuthorityPair :: verify ( & sig, pre_hash, & public) {
121- return Ok ( ( ) ) ;
122- // TODO: Return Err
123- // return Err("Bad Sig".to_string());
102+ let authorities = self . get_last_aura_authorities ( block. header ) ?;
103+ if let Some ( a) = authorities. into_iter ( ) . find ( |a| {
104+ let babe_key = BabeAuthorityId :: from ( a. clone ( ) . into_inner ( ) ) ;
105+ BabeAuthorityPair :: verify ( & sig, header. hash ( ) , & babe_key)
106+ } ) {
107+ log:: info!(
108+ "Babe block has a valid signature by author: {}" ,
109+ a. to_ss58check( )
110+ ) ;
111+ Ok ( ( ) )
112+ } else {
113+ Err ( "Babe block has a bad signature. Rejecting." . to_string ( ) )
124114 }
115+ }
116+
117+ /// Given the hash of the first Babe block mined, get the Aura authorities that existed prior to
118+ /// the runtime upgrade.
119+ ///
120+ /// Note: We need get the Aura authorities from grandparent rather than the parent,
121+ /// because the runtime upgrade clearing the Aura authorities occurs in the parent.
122+ fn get_last_aura_authorities (
123+ & self ,
124+ first_babe_block_header : B :: Header ,
125+ ) -> Result < Vec < AuraAuthorityId > , String > {
126+ let parent_header = self
127+ . client
128+ . header ( * first_babe_block_header. parent_hash ( ) )
129+ . map_err ( |e| format ! ( "Failed to get parent header: {}" , e) ) ?
130+ . ok_or ( "Parent header not found" . to_string ( ) ) ?;
131+ let grandparent_hash = parent_header. parent_hash ( ) ;
132+
133+ let runtime_api = self . client . runtime_api ( ) ;
134+ let authorities = runtime_api
135+ . authorities ( * grandparent_hash)
136+ . map_err ( |e| format ! ( "Failed to get Aura authorities: {}" , e) ) ?;
125137
126- Ok ( ( ) )
138+ Ok ( authorities )
127139 }
128140}
129141
130142#[ async_trait:: async_trait]
131143impl < B : BlockT , C , CIDP > Verifier < B > for AuraWrappedVerifier < B , C , CIDP , NumberFor < B > >
132144where
133145 C : ProvideRuntimeApi < B > + Send + Sync + sc_client_api:: backend:: AuxStore ,
134- C :: Api : BlockBuilderApi < B > + AuraApi < B , AuraAuthorityId > + ApiExt < B > + BabeApi < B > ,
146+ C :: Api : BlockBuilderApi < B > + AuraApi < B , AuraAuthorityId > + ApiExt < B > ,
135147 C : HeaderBackend < B > + HeaderMetadata < B > ,
136148 CIDP : CreateInherentDataProviders < B , ( ) > + Send + Sync ,
137149 CIDP :: InherentDataProviders : InherentDataProviderExt + Send + Sync ,
@@ -158,7 +170,7 @@ pub fn import_queue<B, I, C, S, CIDP>(
158170) -> Result < DefaultImportQueue < B > , sp_consensus:: Error >
159171where
160172 B : BlockT ,
161- C :: Api : BlockBuilderApi < B > + AuraApi < B , AuraAuthorityId > + ApiExt < B > + BabeApi < B > ,
173+ C :: Api : BlockBuilderApi < B > + AuraApi < B , AuraAuthorityId > + ApiExt < B > ,
162174 C : ' static
163175 + ProvideRuntimeApi < B >
164176 + BlockOf
0 commit comments