@@ -66,7 +66,7 @@ use consensus_common::ImportResult;
6666use consensus_common:: import_queue:: {
6767 BoxJustificationImport , BoxFinalityProofImport ,
6868} ;
69- use sr_primitives:: { generic:: { BlockId , OpaqueDigestItemId } , Justification } ;
69+ use sr_primitives:: { generic:: { BlockId , OpaqueDigestItemId } , Justification , RuntimeString } ;
7070use sr_primitives:: traits:: {
7171 Block as BlockT , Header , DigestItemFor , ProvideRuntimeApi ,
7272 Zero ,
@@ -102,6 +102,7 @@ use log::{warn, debug, info, trace};
102102use slots:: { SlotWorker , SlotData , SlotInfo , SlotCompatible } ;
103103use epoch_changes:: descendent_query;
104104use header_metadata:: HeaderMetadata ;
105+ use schnorrkel:: SignatureError ;
105106
106107mod aux_schema;
107108mod verification;
@@ -114,13 +115,71 @@ pub use babe_primitives::{
114115} ;
115116pub use epoch_changes:: { EpochChanges , EpochChangesFor , SharedEpochChanges } ;
116117
117- macro_rules! babe_err {
118- ( $( $i: expr) ,+) => {
119- {
120- debug!( target: "babe" , $( $i) ,+) ;
121- format!( $( $i) ,+)
122- }
123- } ;
118+
119+ #[ derive( derive_more:: Display , Debug ) ]
120+ enum Error < B : BlockT > {
121+ #[ display( fmt = "Multiple BABE pre-runtime digests, rejecting!" ) ]
122+ MultiplePreRuntimeDigests ,
123+ #[ display( fmt = "No BABE pre-runtime digest found" ) ]
124+ NoPreRuntimeDigest ,
125+ #[ display( fmt = "Multiple BABE epoch change digests, rejecting!" ) ]
126+ MultipleEpochChangeDigests ,
127+ #[ display( fmt = "Could not extract timestamp and slot: {:?}" , _0) ]
128+ Extraction ( consensus_common:: Error ) ,
129+ #[ display( fmt = "Could not fetch epoch at {:?}" , _0) ]
130+ FetchEpoch ( B :: Hash ) ,
131+ #[ display( fmt = "Header {:?} rejected: too far in the future" , _0) ]
132+ TooFarInFuture ( B :: Hash ) ,
133+ #[ display( fmt = "Parent ({}) of {} unavailable. Cannot import" , _0, _1) ]
134+ ParentUnavailable ( B :: Hash , B :: Hash ) ,
135+ #[ display( fmt = "Slot number must increase: parent slot: {}, this slot: {}" , _0, _1) ]
136+ SlotNumberMustIncrease ( u64 , u64 ) ,
137+ #[ display( fmt = "Header {:?} has a bad seal" , _0) ]
138+ HeaderBadSeal ( B :: Hash ) ,
139+ #[ display( fmt = "Header {:?} is unsealed" , _0) ]
140+ HeaderUnsealed ( B :: Hash ) ,
141+ #[ display( fmt = "Slot author not found" ) ]
142+ SlotAuthorNotFound ,
143+ #[ display( fmt = "Secondary slot assignments are disabled for the current epoch." ) ]
144+ SecondarySlotAssignmentsDisabled ,
145+ #[ display( fmt = "Bad signature on {:?}" , _0) ]
146+ BadSignature ( B :: Hash ) ,
147+ #[ display( fmt = "Invalid author: Expected secondary author: {:?}, got: {:?}." , _0, _1) ]
148+ InvalidAuthor ( AuthorityId , AuthorityId ) ,
149+ #[ display( fmt = "No secondary author expected." ) ]
150+ NoSecondaryAuthorExpected ,
151+ #[ display( fmt = "VRF verification of block by author {:?} failed: threshold {} exceeded" , _0, _1) ]
152+ VRFVerificationOfBlockFailed ( AuthorityId , u128 ) ,
153+ #[ display( fmt = "VRF verification failed: {:?}" , _0) ]
154+ VRFVerificationFailed ( SignatureError ) ,
155+ #[ display( fmt = "Could not fetch parent header: {:?}" , _0) ]
156+ FetchParentHeader ( client:: error:: Error ) ,
157+ #[ display( fmt = "Expected epoch change to happen at {:?}, s{}" , _0, _1) ]
158+ ExpectedEpochChange ( B :: Hash , u64 ) ,
159+ #[ display( fmt = "Could not look up epoch: {:?}" , _0) ]
160+ CouldNotLookUpEpoch ( Box < fork_tree:: Error < client:: error:: Error > > ) ,
161+ #[ display( fmt = "Block {} is not valid under any epoch." , _0) ]
162+ BlockNotValid ( B :: Hash ) ,
163+ #[ display( fmt = "Unexpected epoch change" ) ]
164+ UnexpectedEpochChange ,
165+ #[ display( fmt = "Parent block of {} has no associated weight" , _0) ]
166+ ParentBlockNoAssociatedWeight ( B :: Hash ) ,
167+ #[ display( fmt = "Checking inherents failed: {}" , _0) ]
168+ CheckInherents ( String ) ,
169+ Client ( client:: error:: Error ) ,
170+ Runtime ( RuntimeString ) ,
171+ ForkTree ( Box < fork_tree:: Error < client:: error:: Error > > ) ,
172+ }
173+
174+ impl < B : BlockT > std:: convert:: From < Error < B > > for String {
175+ fn from ( error : Error < B > ) -> String {
176+ error. to_string ( )
177+ }
178+ }
179+
180+ fn babe_err < B : BlockT > ( error : Error < B > ) -> Error < B > {
181+ debug ! ( target: "babe" , "{}" , error) ;
182+ error
124183}
125184
126185macro_rules! babe_info {
@@ -385,7 +444,7 @@ impl<B, C, E, I, Error, SO> slots::SimpleSlotWorker<B> for BabeWorker<B, C, E, I
385444
386445 fn proposer ( & mut self , block : & B :: Header ) -> Result < Self :: Proposer , consensus_common:: Error > {
387446 self . env . init ( block) . map_err ( |e| {
388- consensus_common:: Error :: ClientImport ( format ! ( "{:?}" , e) ) . into ( )
447+ consensus_common:: Error :: ClientImport ( format ! ( "{:?}" , e) )
389448 } )
390449 }
391450}
@@ -410,7 +469,7 @@ impl<B, C, E, I, Error, SO> SlotWorker<B> for BabeWorker<B, C, E, I, SO> where
410469
411470/// Extract the BABE pre digest from the given header. Pre-runtime digests are
412471/// mandatory, the function will return `Err` if none is found.
413- fn find_pre_digest < H : Header > ( header : & H ) -> Result < BabePreDigest , String >
472+ fn find_pre_digest < B : BlockT > ( header : & B :: Header ) -> Result < BabePreDigest , Error < B > >
414473{
415474 // genesis block doesn't contain a pre digest so let's generate a
416475 // dummy one to not break any invariants in the rest of the code
@@ -425,25 +484,25 @@ fn find_pre_digest<H: Header>(header: &H) -> Result<BabePreDigest, String>
425484 for log in header. digest ( ) . logs ( ) {
426485 trace ! ( target: "babe" , "Checking log {:?}, looking for pre runtime digest" , log) ;
427486 match ( log. as_babe_pre_digest ( ) , pre_digest. is_some ( ) ) {
428- ( Some ( _) , true ) => Err ( babe_err ! ( "Multiple BABE pre-runtime digests, rejecting!" ) ) ? ,
487+ ( Some ( _) , true ) => return Err ( babe_err ( Error :: MultiplePreRuntimeDigests ) ) ,
429488 ( None , _) => trace ! ( target: "babe" , "Ignoring digest not meant for us" ) ,
430489 ( s, false ) => pre_digest = s,
431490 }
432491 }
433- pre_digest. ok_or_else ( || babe_err ! ( "No BABE pre-runtime digest found" ) )
492+ pre_digest. ok_or_else ( || babe_err ( Error :: NoPreRuntimeDigest ) )
434493}
435494
436495/// Extract the BABE epoch change digest from the given header, if it exists.
437496fn find_next_epoch_digest < B : BlockT > ( header : & B :: Header )
438- -> Result < Option < NextEpochDescriptor > , String >
497+ -> Result < Option < NextEpochDescriptor > , Error < B > >
439498 where DigestItemFor < B > : CompatibleDigestItem ,
440499{
441500 let mut epoch_digest: Option < _ > = None ;
442501 for log in header. digest ( ) . logs ( ) {
443502 trace ! ( target: "babe" , "Checking log {:?}, looking for epoch change digest." , log) ;
444503 let log = log. try_to :: < ConsensusLog > ( OpaqueDigestItemId :: Consensus ( & BABE_ENGINE_ID ) ) ;
445504 match ( log, epoch_digest. is_some ( ) ) {
446- ( Some ( ConsensusLog :: NextEpochData ( _) ) , true ) => Err ( babe_err ! ( "Multiple BABE epoch change digests, rejecting!" ) ) ? ,
505+ ( Some ( ConsensusLog :: NextEpochData ( _) ) , true ) => return Err ( babe_err ( Error :: MultipleEpochChangeDigests ) ) ,
447506 ( Some ( ConsensusLog :: NextEpochData ( epoch) ) , false ) => epoch_digest = Some ( epoch) ,
448507 _ => trace ! ( target: "babe" , "Ignoring digest not meant for us" ) ,
449508 }
@@ -493,20 +552,20 @@ impl<B, E, Block: BlockT, RA, PRA> BabeVerifier<B, E, Block, RA, PRA> {
493552 block : Block ,
494553 block_id : BlockId < Block > ,
495554 inherent_data : InherentData ,
496- ) -> Result < ( ) , String >
555+ ) -> Result < ( ) , Error < Block > >
497556 where PRA : ProvideRuntimeApi , PRA :: Api : BlockBuilderApi < Block >
498557 {
499558 let inherent_res = self . api . runtime_api ( ) . check_inherents (
500559 & block_id,
501560 block,
502561 inherent_data,
503- ) . map_err ( |e| format ! ( "{:?}" , e ) ) ?;
562+ ) . map_err ( Error :: Client ) ?;
504563
505564 if !inherent_res. ok ( ) {
506565 inherent_res
507566 . into_errors ( )
508567 . try_for_each ( |( i, e) | {
509- Err ( self . inherent_data_providers . error_to_string ( & i, & e) )
568+ Err ( Error :: CheckInherents ( self . inherent_data_providers . error_to_string ( & i, & e) ) )
510569 } )
511570 } else {
512571 Ok ( ( ) )
@@ -585,18 +644,18 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
585644 let mut inherent_data = self
586645 . inherent_data_providers
587646 . create_inherent_data ( )
588- . map_err ( String :: from ) ?;
647+ . map_err ( Error :: < Block > :: Runtime ) ?;
589648
590649 let ( _, slot_now, _) = self . time_source . extract_timestamp_and_slot ( & inherent_data)
591- . map_err ( |e| format ! ( "Could not extract timestamp and slot: {:?}" , e ) ) ?;
650+ . map_err ( Error :: < Block > :: Extraction ) ?;
592651
593652 let hash = header. hash ( ) ;
594653 let parent_hash = * header. parent_hash ( ) ;
595654
596655 let parent_header_metadata = self . client . header_metadata ( parent_hash)
597- . map_err ( |e| format ! ( "Could not fetch parent header: {:?}" , e ) ) ?;
656+ . map_err ( Error :: < Block > :: FetchParentHeader ) ?;
598657
599- let pre_digest = find_pre_digest :: < Block :: Header > ( & header) ?;
658+ let pre_digest = find_pre_digest :: < Block > ( & header) ?;
600659 let epoch = {
601660 let epoch_changes = self . epoch_changes . lock ( ) ;
602661 epoch_changes. epoch_for_child_of (
@@ -606,8 +665,8 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
606665 pre_digest. slot_number ( ) ,
607666 |slot| self . config . genesis_epoch ( slot) ,
608667 )
609- . map_err ( |e| format ! ( "{:?}" , e ) ) ?
610- . ok_or_else ( || format ! ( "Could not fetch epoch at {:?}" , parent_hash) ) ?
668+ . map_err ( |e| Error :: < Block > :: ForkTree ( Box :: new ( e ) ) ) ?
669+ . ok_or_else ( || Error :: < Block > :: FetchEpoch ( parent_hash) ) ?
611670 } ;
612671
613672 // We add one to the current slot to allow for some small drift.
@@ -691,7 +750,7 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
691750 telemetry ! ( CONSENSUS_DEBUG ; "babe.header_too_far_in_future" ;
692751 "hash" => ?hash, "a" => ?a, "b" => ?b
693752 ) ;
694- Err ( format ! ( "Header {:?} rejected: too far in the future" , hash) )
753+ Err ( Error :: < Block > :: TooFarInFuture ( hash) . into ( ) )
695754 }
696755 }
697756 }
@@ -787,36 +846,32 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
787846 match self . client . status ( BlockId :: Hash ( hash) ) {
788847 Ok ( blockchain:: BlockStatus :: InChain ) => return Ok ( ImportResult :: AlreadyInChain ) ,
789848 Ok ( blockchain:: BlockStatus :: Unknown ) => { } ,
790- Err ( e) => return Err ( ConsensusError :: ClientImport ( e. to_string ( ) ) . into ( ) ) ,
849+ Err ( e) => return Err ( ConsensusError :: ClientImport ( e. to_string ( ) ) ) ,
791850 }
792851
793- let pre_digest = find_pre_digest :: < Block :: Header > ( & block. header )
852+ let pre_digest = find_pre_digest :: < Block > ( & block. header )
794853 . expect ( "valid babe headers must contain a predigest; \
795854 header has been already verified; qed") ;
796855 let slot_number = pre_digest. slot_number ( ) ;
797856
798857 let parent_hash = * block. header . parent_hash ( ) ;
799858 let parent_header = self . client . header ( & BlockId :: Hash ( parent_hash) )
800859 . map_err ( |e| ConsensusError :: ChainLookup ( e. to_string ( ) ) ) ?
801- . ok_or_else ( || ConsensusError :: ChainLookup ( babe_err ! (
802- "Parent ({}) of {} unavailable. Cannot import" ,
803- parent_hash,
804- hash
805- ) ) ) ?;
860+ . ok_or_else ( || ConsensusError :: ChainLookup ( babe_err (
861+ Error :: < Block > :: ParentUnavailable ( parent_hash, hash)
862+ ) . into ( ) ) ) ?;
806863
807- let parent_slot = find_pre_digest :: < Block :: Header > ( & parent_header)
864+ let parent_slot = find_pre_digest :: < Block > ( & parent_header)
808865 . map ( |d| d. slot_number ( ) )
809866 . expect ( "parent is non-genesis; valid BABE headers contain a pre-digest; \
810867 header has already been verified; qed") ;
811868
812869 // make sure that slot number is strictly increasing
813870 if slot_number <= parent_slot {
814871 return Err (
815- ConsensusError :: ClientImport ( babe_err ! (
816- "Slot number must increase: parent slot: {}, this slot: {}" ,
817- parent_slot,
818- slot_number
819- ) )
872+ ConsensusError :: ClientImport ( babe_err (
873+ Error :: < Block > :: SlotNumberMustIncrease ( parent_slot, slot_number)
874+ ) . into ( ) )
820875 ) ;
821876 }
822877
@@ -834,7 +889,7 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
834889 aux_schema:: load_block_weight ( & * self . client , parent_hash)
835890 . map_err ( |e| ConsensusError :: ClientImport ( e. to_string ( ) ) ) ?
836891 . ok_or_else ( || ConsensusError :: ClientImport (
837- babe_err ! ( "Parent block of {} has no associated weight" , hash)
892+ babe_err ( Error :: < Block > :: ParentBlockNoAssociatedWeight ( hash) ) . into ( )
838893 ) ) ?
839894 } ;
840895
@@ -846,10 +901,10 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
846901 |slot| self . config . genesis_epoch ( slot) ,
847902 )
848903 . map_err ( |e : fork_tree:: Error < client:: error:: Error > | ConsensusError :: ChainLookup (
849- babe_err ! ( "Could not look up epoch: {:?}" , e )
904+ babe_err ( Error :: < Block > :: CouldNotLookUpEpoch ( Box :: new ( e ) ) ) . into ( )
850905 ) ) ?
851906 . ok_or_else ( || ConsensusError :: ClientImport (
852- babe_err ! ( " Block {} is not valid under any epoch." , hash)
907+ babe_err ( Error :: < Block > :: BlockNotValid ( hash) ) . into ( )
853908 ) ) ?;
854909
855910 let first_in_epoch = parent_slot < epoch. as_ref ( ) . start_slot ;
@@ -860,20 +915,20 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
860915
861916 // search for this all the time so we can reject unexpected announcements.
862917 let next_epoch_digest = find_next_epoch_digest :: < Block > ( & block. header )
863- . map_err ( |e| ConsensusError :: from ( ConsensusError :: ClientImport ( e. to_string ( ) ) ) ) ?;
918+ . map_err ( |e| ConsensusError :: ClientImport ( e. to_string ( ) ) ) ?;
864919
865920 match ( first_in_epoch, next_epoch_digest. is_some ( ) ) {
866921 ( true , true ) => { } ,
867922 ( false , false ) => { } ,
868923 ( true , false ) => {
869924 return Err (
870925 ConsensusError :: ClientImport (
871- babe_err ! ( "Expected epoch change to happen at {:?}, s{}" , hash, slot_number) ,
926+ babe_err ( Error :: < Block > :: ExpectedEpochChange ( hash, slot_number) ) . into ( ) ,
872927 )
873928 ) ;
874929 } ,
875930 ( false , true ) => {
876- return Err ( ConsensusError :: ClientImport ( "Unexpected epoch change" . into ( ) ) ) ;
931+ return Err ( ConsensusError :: ClientImport ( Error :: < Block > :: UnexpectedEpochChange . into ( ) ) ) ;
877932 } ,
878933 }
879934
@@ -917,7 +972,7 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
917972 } ;
918973
919974 if let Err ( e) = prune_and_import ( ) {
920- babe_err ! ( "Failed to launch next epoch: {:?}" , e) ;
975+ debug ! ( target : "babe" , "Failed to launch next epoch: {:?}" , e) ;
921976 * epoch_changes = old_epoch_changes. expect ( "set `Some` above and not taken; qed" ) ;
922977 return Err ( e) ;
923978 }
@@ -1004,7 +1059,7 @@ fn prune_finalized<B, E, Block, RA>(
10041059 . expect ( "best finalized hash was given by client; \
10051060 finalized headers must exist in db; qed") ;
10061061
1007- find_pre_digest :: < Block :: Header > ( & finalized_header)
1062+ find_pre_digest :: < Block > ( & finalized_header)
10081063 . expect ( "finalized header must be valid; \
10091064 valid blocks have a pre-digest; qed")
10101065 . slot_number ( )
0 commit comments