@@ -60,7 +60,7 @@ use sp_runtime::{
6060 codec:: Encode ,
6161 generic:: BlockId ,
6262 traits:: { Header as HeaderT , NumberFor } ,
63- BuildStorage , DigestItem , Justifications , Storage ,
63+ BuildStorage , DigestItem , EncodedJustification , Justifications , Storage ,
6464} ;
6565use std:: { collections:: HashMap , marker:: PhantomData , sync:: Arc , task:: Poll } ;
6666use substrate_test_runtime_client:: { runtime:: Header , ClientExt } ;
@@ -107,11 +107,13 @@ pub(crate) struct PeerData {
107107#[ derive( Default ) ]
108108pub ( crate ) struct BeefyTestNet {
109109 peers : Vec < BeefyPeer > ,
110+ pub beefy_genesis : NumberFor < Block > ,
110111}
111112
112113impl BeefyTestNet {
113114 pub ( crate ) fn new ( n_authority : usize ) -> Self {
114- let mut net = BeefyTestNet { peers : Vec :: with_capacity ( n_authority) } ;
115+ let beefy_genesis = 1 ;
116+ let mut net = BeefyTestNet { peers : Vec :: with_capacity ( n_authority) , beefy_genesis } ;
115117
116118 for i in 0 ..n_authority {
117119 let ( rx, cfg) = on_demand_justifications_protocol_config ( GENESIS_HASH , None ) ;
@@ -202,7 +204,7 @@ impl TestNetFactory for BeefyTestNet {
202204 ) {
203205 let keys = & [ BeefyKeyring :: Alice , BeefyKeyring :: Bob ] ;
204206 let validator_set = ValidatorSet :: new ( make_beefy_ids ( keys) , 0 ) . unwrap ( ) ;
205- let api = Arc :: new ( TestApi :: with_validator_set ( & validator_set) ) ;
207+ let api = Arc :: new ( TestApi :: new ( self . beefy_genesis , & validator_set, GOOD_MMR_ROOT ) ) ;
206208 let inner = BlockImportAdapter :: new ( client. clone ( ) ) ;
207209 let ( block_import, voter_links, rpc_links) =
208210 beefy_block_import_and_links ( inner, client. as_backend ( ) , api, None ) ;
@@ -716,7 +718,7 @@ async fn correct_beefy_payload() {
716718}
717719
718720#[ tokio:: test]
719- async fn beefy_importing_blocks ( ) {
721+ async fn beefy_importing_justifications ( ) {
720722 use futures:: { future:: poll_fn, task:: Poll } ;
721723 use sc_block_builder:: BlockBuilderProvider ;
722724 use sc_client_api:: BlockBackend ;
@@ -726,11 +728,15 @@ async fn beefy_importing_blocks() {
726728 let mut net = BeefyTestNet :: new ( 2 ) ;
727729 let keys = & [ BeefyKeyring :: Alice , BeefyKeyring :: Bob ] ;
728730 let good_set = ValidatorSet :: new ( make_beefy_ids ( keys) , 0 ) . unwrap ( ) ;
731+ // Set BEEFY genesis to block 3.
732+ net. beefy_genesis = 3 ;
729733
730734 let client = net. peer ( 0 ) . client ( ) . clone ( ) ;
735+ let full_client = client. as_client ( ) ;
731736 let ( mut block_import, _, peer_data) = net. make_block_import ( client. clone ( ) ) ;
732737 let PeerData { beefy_voter_links, .. } = peer_data;
733738 let justif_stream = beefy_voter_links. lock ( ) . take ( ) . unwrap ( ) . from_block_import_justif_stream ;
739+ let mut justif_recv = justif_stream. subscribe ( 100_000 ) ;
734740
735741 let params = |block : Block , justifications : Option < Justifications > | {
736742 let mut import = BlockImportParams :: new ( BlockOrigin :: File , block. header ) ;
@@ -740,15 +746,19 @@ async fn beefy_importing_blocks() {
740746 import. fork_choice = Some ( ForkChoiceStrategy :: LongestChain ) ;
741747 import
742748 } ;
749+ let backend_justif_for = |block_hash : H256 | -> Option < EncodedJustification > {
750+ full_client
751+ . justifications ( block_hash)
752+ . unwrap ( )
753+ . and_then ( |j| j. get ( BEEFY_ENGINE_ID ) . cloned ( ) )
754+ } ;
743755
744- let full_client = client. as_client ( ) ;
745756 let parent_id = BlockId :: Number ( 0 ) ;
746757 let builder = full_client. new_block_at ( & parent_id, Default :: default ( ) , false ) . unwrap ( ) ;
747758 let block = builder. build ( ) . unwrap ( ) . block ;
748759 let hashof1 = block. header . hash ( ) ;
749760
750- // Import without justifications.
751- let mut justif_recv = justif_stream. subscribe ( 100_000 ) ;
761+ // Import block 1 without justifications.
752762 assert_eq ! (
753763 block_import
754764 . import_block( params( block. clone( ) , None ) , HashMap :: new( ) )
@@ -760,16 +770,32 @@ async fn beefy_importing_blocks() {
760770 block_import. import_block( params( block, None ) , HashMap :: new( ) ) . await . unwrap( ) ,
761771 ImportResult :: AlreadyInChain ,
762772 ) ;
763- // Verify no BEEFY justifications present:
773+
774+ // Import block 2 with "valid" justification (beefy pallet genesis block not yet reached).
775+ let parent_id = BlockId :: Number ( 1 ) ;
776+ let block_num = 2 ;
777+ let builder = full_client. new_block_at ( & parent_id, Default :: default ( ) , false ) . unwrap ( ) ;
778+ let block = builder. build ( ) . unwrap ( ) . block ;
779+ let hashof2 = block. header . hash ( ) ;
780+
781+ let proof = crate :: justification:: tests:: new_finality_proof ( block_num, & good_set, keys) ;
782+ let versioned_proof: VersionedFinalityProof < NumberFor < Block > , Signature > = proof. into ( ) ;
783+ let encoded = versioned_proof. encode ( ) ;
784+ let justif = Some ( Justifications :: from ( ( BEEFY_ENGINE_ID , encoded) ) ) ;
785+ assert_eq ! (
786+ block_import. import_block( params( block, justif) , HashMap :: new( ) ) . await . unwrap( ) ,
787+ ImportResult :: Imported ( ImportedAux {
788+ bad_justification: false ,
789+ is_new_best: true ,
790+ ..Default :: default ( )
791+ } ) ,
792+ ) ;
793+
794+ // Verify no BEEFY justifications present (for either block 1 or 2):
764795 {
765796 // none in backend,
766- assert_eq ! (
767- full_client
768- . justifications( hashof1)
769- . unwrap( )
770- . and_then( |j| j. get( BEEFY_ENGINE_ID ) . cloned( ) ) ,
771- None
772- ) ;
797+ assert_eq ! ( backend_justif_for( hashof1) , None ) ;
798+ assert_eq ! ( backend_justif_for( hashof2) , None ) ;
773799 // and none sent to BEEFY worker.
774800 poll_fn ( move |cx| {
775801 assert_eq ! ( justif_recv. poll_next_unpin( cx) , Poll :: Pending ) ;
@@ -778,17 +804,16 @@ async fn beefy_importing_blocks() {
778804 . await ;
779805 }
780806
781- // Import with valid justification.
782- let parent_id = BlockId :: Number ( 1 ) ;
783- let block_num = 2 ;
807+ // Import block 3 with valid justification.
808+ let parent_id = BlockId :: Number ( 2 ) ;
809+ let block_num = 3 ;
810+ let builder = full_client. new_block_at ( & parent_id, Default :: default ( ) , false ) . unwrap ( ) ;
811+ let block = builder. build ( ) . unwrap ( ) . block ;
812+ let hashof3 = block. header . hash ( ) ;
784813 let proof = crate :: justification:: tests:: new_finality_proof ( block_num, & good_set, keys) ;
785814 let versioned_proof: VersionedFinalityProof < NumberFor < Block > , Signature > = proof. into ( ) ;
786815 let encoded = versioned_proof. encode ( ) ;
787816 let justif = Some ( Justifications :: from ( ( BEEFY_ENGINE_ID , encoded) ) ) ;
788-
789- let builder = full_client. new_block_at ( & parent_id, Default :: default ( ) , false ) . unwrap ( ) ;
790- let block = builder. build ( ) . unwrap ( ) . block ;
791- let hashof2 = block. header . hash ( ) ;
792817 let mut justif_recv = justif_stream. subscribe ( 100_000 ) ;
793818 assert_eq ! (
794819 block_import. import_block( params( block, justif) , HashMap :: new( ) ) . await . unwrap( ) ,
@@ -801,13 +826,7 @@ async fn beefy_importing_blocks() {
801826 // Verify BEEFY justification successfully imported:
802827 {
803828 // still not in backend (worker is responsible for appending to backend),
804- assert_eq ! (
805- full_client
806- . justifications( hashof2)
807- . unwrap( )
808- . and_then( |j| j. get( BEEFY_ENGINE_ID ) . cloned( ) ) ,
809- None
810- ) ;
829+ assert_eq ! ( backend_justif_for( hashof3) , None ) ;
811830 // but sent to BEEFY worker
812831 // (worker will append it to backend when all previous mandatory justifs are there as well).
813832 poll_fn ( move |cx| {
@@ -820,19 +839,18 @@ async fn beefy_importing_blocks() {
820839 . await ;
821840 }
822841
823- // Import with invalid justification (incorrect validator set).
824- let parent_id = BlockId :: Number ( 2 ) ;
825- let block_num = 3 ;
842+ // Import block 4 with invalid justification (incorrect validator set).
843+ let parent_id = BlockId :: Number ( 3 ) ;
844+ let block_num = 4 ;
845+ let builder = full_client. new_block_at ( & parent_id, Default :: default ( ) , false ) . unwrap ( ) ;
846+ let block = builder. build ( ) . unwrap ( ) . block ;
847+ let hashof4 = block. header . hash ( ) ;
826848 let keys = & [ BeefyKeyring :: Alice ] ;
827849 let bad_set = ValidatorSet :: new ( make_beefy_ids ( keys) , 1 ) . unwrap ( ) ;
828850 let proof = crate :: justification:: tests:: new_finality_proof ( block_num, & bad_set, keys) ;
829851 let versioned_proof: VersionedFinalityProof < NumberFor < Block > , Signature > = proof. into ( ) ;
830852 let encoded = versioned_proof. encode ( ) ;
831853 let justif = Some ( Justifications :: from ( ( BEEFY_ENGINE_ID , encoded) ) ) ;
832-
833- let builder = full_client. new_block_at ( & parent_id, Default :: default ( ) , false ) . unwrap ( ) ;
834- let block = builder. build ( ) . unwrap ( ) . block ;
835- let hashof3 = block. header . hash ( ) ;
836854 let mut justif_recv = justif_stream. subscribe ( 100_000 ) ;
837855 assert_eq ! (
838856 block_import. import_block( params( block, justif) , HashMap :: new( ) ) . await . unwrap( ) ,
@@ -846,13 +864,7 @@ async fn beefy_importing_blocks() {
846864 // Verify bad BEEFY justifications was not imported:
847865 {
848866 // none in backend,
849- assert_eq ! (
850- full_client
851- . justifications( hashof3)
852- . unwrap( )
853- . and_then( |j| j. get( BEEFY_ENGINE_ID ) . cloned( ) ) ,
854- None
855- ) ;
867+ assert_eq ! ( backend_justif_for( hashof4) , None ) ;
856868 // and none sent to BEEFY worker.
857869 poll_fn ( move |cx| {
858870 assert_eq ! ( justif_recv. poll_next_unpin( cx) , Poll :: Pending ) ;
0 commit comments