@@ -645,7 +645,8 @@ pub(crate) fn ancestry<Block: BlockT, Client>(
645645 client : & Arc < Client > ,
646646 base : Block :: Hash ,
647647 block : Block :: Hash ,
648- ) -> Result < Vec < Block :: Hash > , GrandpaError > where
648+ ) -> Result < Vec < Block :: Hash > , GrandpaError >
649+ where
649650 Client : HeaderMetadata < Block , Error = sp_blockchain:: Error > ,
650651{
651652 if base == block { return Err ( GrandpaError :: NotDescendent ) }
@@ -671,15 +672,14 @@ pub(crate) fn ancestry<Block: BlockT, Client>(
671672 Ok ( tree_route. retracted ( ) . iter ( ) . skip ( 1 ) . map ( |e| e. hash ) . collect ( ) )
672673}
673674
674- impl < B , Block : BlockT , C , N , SC , VR >
675- voter:: Environment < Block :: Hash , NumberFor < Block > >
676- for Environment < B , Block , C , N , SC , VR >
675+ impl < B , Block : BlockT , C , N , SC , VR > voter:: Environment < Block :: Hash , NumberFor < Block > >
676+ for Environment < B , Block , C , N , SC , VR >
677677where
678678 Block : ' static ,
679679 B : Backend < Block > ,
680680 C : crate :: ClientForGrandpa < Block , B > + ' static ,
681681 C :: Api : GrandpaApi < Block , Error = sp_blockchain:: Error > ,
682- N : NetworkT < Block > + ' static + Send + Sync ,
682+ N : NetworkT < Block > + ' static + Send + Sync ,
683683 SC : SelectChain < Block > + ' static ,
684684 VR : VotingRule < Block , C > ,
685685 NumberFor < Block > : BlockNumberOps ,
@@ -1023,7 +1023,7 @@ where
10231023 number,
10241024 ( round, commit) . into ( ) ,
10251025 false ,
1026- & self . justification_sender ,
1026+ self . justification_sender . as_ref ( ) ,
10271027 )
10281028 }
10291029
@@ -1088,9 +1088,10 @@ pub(crate) fn finalize_block<BE, Block, Client>(
10881088 number : NumberFor < Block > ,
10891089 justification_or_commit : JustificationOrCommit < Block > ,
10901090 initial_sync : bool ,
1091- justification_sender : & Option < GrandpaJustificationSender < Block > > ,
1092- ) -> Result < ( ) , CommandOrError < Block :: Hash , NumberFor < Block > > > where
1093- Block : BlockT ,
1091+ justification_sender : Option < & GrandpaJustificationSender < Block > > ,
1092+ ) -> Result < ( ) , CommandOrError < Block :: Hash , NumberFor < Block > > >
1093+ where
1094+ Block : BlockT ,
10941095 BE : Backend < Block > ,
10951096 Client : crate :: ClientForGrandpa < Block , BE > ,
10961097{
@@ -1154,14 +1155,29 @@ pub(crate) fn finalize_block<BE, Block, Client>(
11541155 }
11551156 }
11561157
1158+ // send a justification notification if a sender exists and in case of error log it.
1159+ fn notify_justification < Block : BlockT > (
1160+ justification_sender : Option < & GrandpaJustificationSender < Block > > ,
1161+ justification : impl FnOnce ( ) -> Result < GrandpaJustification < Block > , Error > ,
1162+ ) {
1163+ if let Some ( sender) = justification_sender {
1164+ if let Err ( err) = sender. notify ( justification) {
1165+ warn ! ( target: "afg" , "Error creating justification for subscriber: {:?}" , err) ;
1166+ }
1167+ }
1168+ }
1169+
11571170 // NOTE: this code assumes that honest voters will never vote past a
11581171 // transition block, thus we don't have to worry about the case where
11591172 // we have a transition with `effective_block = N`, but we finalize
11601173 // `N+1`. this assumption is required to make sure we store
11611174 // justifications for transition blocks which will be requested by
11621175 // syncing clients.
11631176 let justification = match justification_or_commit {
1164- JustificationOrCommit :: Justification ( justification) => Some ( justification) ,
1177+ JustificationOrCommit :: Justification ( justification) => {
1178+ notify_justification ( justification_sender, || Ok ( justification. clone ( ) ) ) ;
1179+ Some ( justification. encode ( ) )
1180+ } ,
11651181 JustificationOrCommit :: Commit ( ( round_number, commit) ) => {
11661182 let mut justification_required =
11671183 // justification is always required when block that enacts new authorities
@@ -1181,29 +1197,31 @@ pub(crate) fn finalize_block<BE, Block, Client>(
11811197 }
11821198 }
11831199
1200+ // NOTE: the code below is a bit more verbose because we
1201+ // really want to avoid creating a justification if it isn't
1202+ // needed (e.g. if there's no subscribers), and also to avoid
1203+ // creating it twice. depending on the vote tree for the round,
1204+ // creating a justification might require multiple fetches of
1205+ // headers from the database.
1206+ let justification = || GrandpaJustification :: from_commit (
1207+ & client,
1208+ round_number,
1209+ commit,
1210+ ) ;
1211+
11841212 if justification_required {
1185- let justification = GrandpaJustification :: from_commit (
1186- & client,
1187- round_number,
1188- commit,
1189- ) ?;
1213+ let justification = justification ( ) ?;
1214+ notify_justification ( justification_sender, || Ok ( justification. clone ( ) ) ) ;
11901215
1191- Some ( justification)
1216+ Some ( justification. encode ( ) )
11921217 } else {
1218+ notify_justification ( justification_sender, justification) ;
1219+
11931220 None
11941221 }
11951222 } ,
11961223 } ;
11971224
1198- // Notify any registered listeners in case we have a justification
1199- if let Some ( sender) = justification_sender {
1200- if let Some ( ref justification) = justification {
1201- let _ = sender. notify ( justification. clone ( ) ) ;
1202- }
1203- }
1204-
1205- let justification = justification. map ( |j| j. encode ( ) ) ;
1206-
12071225 debug ! ( target: "afg" , "Finalizing blocks up to ({:?}, {})" , number, hash) ;
12081226
12091227 // ideally some handle to a synchronization oracle would be used
0 commit comments