@@ -44,9 +44,12 @@ use bp_header_chain::{
44
44
} ;
45
45
use bp_runtime:: { BlockNumberOf , Chain , HashOf , HasherOf , HeaderId , HeaderOf , OwnedBridgeModule } ;
46
46
use finality_grandpa:: voter_set:: VoterSet ;
47
- use frame_support:: { ensure, fail} ;
47
+ use frame_support:: { dispatch :: PostDispatchInfo , ensure, fail} ;
48
48
use 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
+ } ;
50
53
use sp_std:: { boxed:: Box , convert:: TryInto } ;
51
54
52
55
mod extension;
@@ -152,8 +155,8 @@ pub mod pallet {
152
155
/// pallet.
153
156
#[ pallet:: call_index( 0 ) ]
154
157
#[ 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 ( ) ,
157
160
) ) ]
158
161
pub fn submit_finality_proof (
159
162
_origin : OriginFor < T > ,
@@ -189,6 +192,7 @@ pub mod pallet {
189
192
ensure ! ( best_finalized_number < * number, <Error <T , I >>:: OldHeader ) ;
190
193
191
194
let authority_set = <CurrentAuthoritySet < T , I > >:: get ( ) ;
195
+ let unused_proof_size = authority_set. unused_proof_size ( ) ;
192
196
let set_id = authority_set. set_id ;
193
197
verify_justification :: < T , I > ( & justification, hash, * number, authority_set. into ( ) ) ?;
194
198
@@ -210,7 +214,18 @@ pub mod pallet {
210
214
let is_mandatory_header = is_authorities_change_enacted;
211
215
let pays_fee = if is_mandatory_header { Pays :: No } else { Pays :: Yes } ;
212
216
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 } )
214
229
}
215
230
216
231
/// Bootstrap the bridge pallet with an initial header and authority set from which to sync.
@@ -819,9 +834,27 @@ mod tests {
819
834
fn succesfully_imports_header_with_valid_finality ( ) {
820
835
run_test ( || {
821
836
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) ;
823
848
assert_ok ! ( result) ;
824
849
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
+ ) ;
825
858
826
859
let header = test_header ( 1 ) ;
827
860
assert_eq ! ( <BestFinalized <TestRuntime >>:: get( ) . unwrap( ) . 1 , header. hash( ) ) ;
0 commit comments