@@ -44,9 +44,12 @@ use bp_header_chain::{
4444} ;
4545use bp_runtime:: { BlockNumberOf , Chain , HashOf , HasherOf , HeaderId , HeaderOf , OwnedBridgeModule } ;
4646use finality_grandpa:: voter_set:: VoterSet ;
47- use frame_support:: { ensure, fail} ;
47+ use frame_support:: { dispatch :: PostDispatchInfo , ensure, fail} ;
4848use sp_finality_grandpa:: { ConsensusLog , GRANDPA_ENGINE_ID } ;
49- use sp_runtime:: traits:: { Header as HeaderT , Zero } ;
49+ use sp_runtime:: {
50+ traits:: { Header as HeaderT , Zero } ,
51+ SaturatedConversion ,
52+ } ;
5053use sp_std:: { boxed:: Box , convert:: TryInto } ;
5154
5255mod extension;
@@ -152,8 +155,8 @@ pub mod pallet {
152155 /// pallet.
153156 #[ pallet:: call_index( 0 ) ]
154157 #[ pallet:: weight( T :: WeightInfo :: submit_finality_proof(
155- justification. commit. precommits. len( ) . try_into ( ) . unwrap_or ( u32 :: MAX ) ,
156- justification. votes_ancestries. len( ) . try_into ( ) . unwrap_or ( u32 :: MAX ) ,
158+ justification. commit. precommits. len( ) . saturated_into ( ) ,
159+ justification. votes_ancestries. len( ) . saturated_into ( ) ,
157160 ) ) ]
158161 pub fn submit_finality_proof (
159162 _origin : OriginFor < T > ,
@@ -189,6 +192,7 @@ pub mod pallet {
189192 ensure ! ( best_finalized_number < * number, <Error <T , I >>:: OldHeader ) ;
190193
191194 let authority_set = <CurrentAuthoritySet < T , I > >:: get ( ) ;
195+ let unused_proof_size = authority_set. unused_proof_size ( ) ;
192196 let set_id = authority_set. set_id ;
193197 verify_justification :: < T , I > ( & justification, hash, * number, authority_set. into ( ) ) ?;
194198
@@ -210,7 +214,18 @@ pub mod pallet {
210214 let is_mandatory_header = is_authorities_change_enacted;
211215 let pays_fee = if is_mandatory_header { Pays :: No } else { Pays :: Yes } ;
212216
213- Ok ( pays_fee. into ( ) )
217+ // the proof size component of the call weight assumes that there are
218+ // `MaxBridgedAuthorities` in the `CurrentAuthoritySet` (we use `MaxEncodedLen`
219+ // estimation). But if their number is lower, then we may "refund" some `proof_size`,
220+ // making proof smaller and leaving block space to other useful transactions
221+ let pre_dispatch_weight = T :: WeightInfo :: submit_finality_proof (
222+ justification. commit . precommits . len ( ) . saturated_into ( ) ,
223+ justification. votes_ancestries . len ( ) . saturated_into ( ) ,
224+ ) ;
225+ let actual_weight = pre_dispatch_weight
226+ . set_proof_size ( pre_dispatch_weight. proof_size ( ) . saturating_sub ( unused_proof_size) ) ;
227+
228+ Ok ( PostDispatchInfo { actual_weight : Some ( actual_weight) , pays_fee } )
214229 }
215230
216231 /// Bootstrap the bridge pallet with an initial header and authority set from which to sync.
@@ -819,9 +834,27 @@ mod tests {
819834 fn succesfully_imports_header_with_valid_finality ( ) {
820835 run_test ( || {
821836 initialize_substrate_bridge ( ) ;
822- let result = submit_finality_proof ( 1 ) ;
837+
838+ let header_number = 1 ;
839+ let header = test_header ( header_number. into ( ) ) ;
840+ let justification = make_default_justification ( & header) ;
841+
842+ let pre_dispatch_weight = <TestRuntime as Config >:: WeightInfo :: submit_finality_proof (
843+ justification. commit . precommits . len ( ) . try_into ( ) . unwrap_or ( u32:: MAX ) ,
844+ justification. votes_ancestries . len ( ) . try_into ( ) . unwrap_or ( u32:: MAX ) ,
845+ ) ;
846+
847+ let result = submit_finality_proof ( header_number) ;
823848 assert_ok ! ( result) ;
824849 assert_eq ! ( result. unwrap( ) . pays_fee, frame_support:: dispatch:: Pays :: Yes ) ;
850+ // our test config assumes 2048 max authorities and we are just using couple
851+ let pre_dispatch_proof_size = pre_dispatch_weight. proof_size ( ) ;
852+ let actual_proof_size = result. unwrap ( ) . actual_weight . unwrap ( ) . proof_size ( ) ;
853+ assert ! ( actual_proof_size > 0 ) ;
854+ assert ! (
855+ actual_proof_size < pre_dispatch_proof_size,
856+ "Actual proof size {actual_proof_size} must be less than the pre-dispatch {pre_dispatch_proof_size}" ,
857+ ) ;
825858
826859 let header = test_header ( 1 ) ;
827860 assert_eq ! ( <BestFinalized <TestRuntime >>:: get( ) . unwrap( ) . 1 , header. hash( ) ) ;
0 commit comments