1818//!
1919//! Contains message send between collators and logic to process them.
2020
21+ #[ cfg( test) ]
22+ mod tests;
23+
2124use sp_api:: ProvideRuntimeApi ;
22- use sp_blockchain:: Error as ClientError ;
25+ use sp_blockchain:: { Error as ClientError , HeaderBackend } ;
2326use sp_consensus:: block_validation:: { BlockAnnounceValidator , Validation } ;
2427use sp_runtime:: { generic:: BlockId , traits:: Block as BlockT } ;
2528
2629use polkadot_collator:: Network as CollatorNetwork ;
2730use polkadot_network:: legacy:: gossip:: { GossipMessage , GossipStatement } ;
2831use polkadot_primitives:: {
29- parachain:: { ParachainHost , ValidatorId } ,
32+ parachain:: ParachainHost ,
3033 Block as PBlock , Hash as PHash ,
3134} ;
3235use polkadot_statement_table:: { SignedStatement , Statement } ;
@@ -49,15 +52,13 @@ use parking_lot::Mutex;
4952///
5053/// Note: if no justification is provided the annouce is considered valid.
5154pub struct JustifiedBlockAnnounceValidator < B , P > {
52- authorities : Vec < ValidatorId > ,
5355 phantom : PhantomData < B > ,
5456 polkadot_client : Arc < P > ,
5557}
5658
5759impl < B , P > JustifiedBlockAnnounceValidator < B , P > {
58- pub fn new ( authorities : Vec < ValidatorId > , polkadot_client : Arc < P > ) -> Self {
60+ pub fn new ( polkadot_client : Arc < P > ) -> Self {
5961 Self {
60- authorities,
6162 phantom : Default :: default ( ) ,
6263 polkadot_client,
6364 }
@@ -66,7 +67,7 @@ impl<B, P> JustifiedBlockAnnounceValidator<B, P> {
6667
6768impl < B : BlockT , P > BlockAnnounceValidator < B > for JustifiedBlockAnnounceValidator < B , P >
6869where
69- P : ProvideRuntimeApi < PBlock > ,
70+ P : ProvideRuntimeApi < PBlock > + HeaderBackend < PBlock > ,
7071 P :: Api : ParachainHost < PBlock > ,
7172{
7273 fn validate (
@@ -106,14 +107,42 @@ where
106107 } ,
107108 } = gossip_statement;
108109
109- let signing_context = self
110- . polkadot_client
111- . runtime_api ( )
112- . signing_context ( & BlockId :: Hash ( relay_chain_leaf) )
110+ // Check that the relay chain parent of the block is the relay chain head
111+ let best_number = self . polkadot_client . info ( ) . best_number ;
112+
113+ match self . polkadot_client . number ( relay_chain_leaf) {
114+ Err ( err) => {
115+ return Err ( Box :: new ( ClientError :: Backend ( format ! (
116+ "could not find block number for {}: {}" ,
117+ relay_chain_leaf, err,
118+ ) ) ) ) ;
119+ } ,
120+ Ok ( Some ( x) ) if x == best_number => { } ,
121+ Ok ( None ) => {
122+ return Err ( Box :: new ( ClientError :: UnknownBlock ( relay_chain_leaf. to_string ( ) ) ) ) ;
123+ } ,
124+ Ok ( Some ( _) ) => {
125+ trace ! (
126+ target: "cumulus-network" ,
127+ "validation failed because the relay chain parent ({}) is not the relay chain \
128+ head ({})",
129+ relay_chain_leaf, best_number,
130+ ) ;
131+
132+ return Ok ( Validation :: Failure ) ;
133+ } ,
134+ }
135+
136+ let runtime_api = self . polkadot_client . runtime_api ( ) ;
137+ let runtime_api_block_id = BlockId :: Hash ( relay_chain_leaf) ;
138+ let signing_context = runtime_api
139+ . signing_context ( & runtime_api_block_id)
113140 . map_err ( |e| Box :: new ( ClientError :: Msg ( format ! ( "{:?}" , e) ) ) as Box < _ > ) ?;
114141
115142 // Check that the signer is a legit validator.
116- let signer = self . authorities . get ( sender as usize ) . ok_or_else ( || {
143+ let authorities = runtime_api. validators ( & runtime_api_block_id)
144+ . map_err ( |e| Box :: new ( ClientError :: Msg ( format ! ( "{:?}" , e) ) ) as Box < _ > ) ?;
145+ let signer = authorities. get ( sender as usize ) . ok_or_else ( || {
117146 Box :: new ( ClientError :: BadJustification (
118147 "block accounced justification signer is a validator index out of bound"
119148 . to_string ( ) ,
0 commit comments