2020extern crate alloc;
2121
2222use super :: * ;
23- use crate :: Pallet ;
2423use frame_benchmarking:: v2:: * ;
2524use frame_support:: dispatch:: { DispatchInfo , PostDispatchInfo } ;
2625use frame_system:: { EventRecord , RawOrigin } ;
2726use sp_runtime:: traits:: { AsTransactionAuthorizedOrigin , DispatchTransaction , Dispatchable } ;
2827
29- fn assert_last_event < T : Config > ( generic_event : <T as Config >:: RuntimeEvent ) {
28+ /// Re-export the pallet for benchmarking with custom Config trait.
29+ pub struct Pallet < T : Config > ( crate :: Pallet < T > ) ;
30+
31+ /// Benchmark configuration trait.
32+ ///
33+ /// This extends the pallet's Config trait to allow runtimes to set up any
34+ /// required state before running benchmarks. For example, runtimes that
35+ /// distribute fees to block authors may need to set the author before
36+ /// the benchmark runs.
37+ pub trait Config : crate :: Config {
38+ /// Called at the start of each benchmark to set up any required state.
39+ ///
40+ /// The default implementation is a no-op. Runtimes can override this
41+ /// to perform setup like setting the block author for fee distribution.
42+ fn setup_benchmark_environment ( ) { }
43+ }
44+
45+ fn assert_last_event < T : crate :: Config > ( generic_event : <T as crate :: Config >:: RuntimeEvent ) {
3046 let events = frame_system:: Pallet :: < T > :: events ( ) ;
3147 let system_event: <T as frame_system:: Config >:: RuntimeEvent = generic_event. into ( ) ;
3248 // compare to the last event record
@@ -44,19 +60,17 @@ mod benchmarks {
4460
4561 #[ benchmark]
4662 fn charge_transaction_payment ( ) {
63+ T :: setup_benchmark_environment ( ) ;
64+
4765 let caller: T :: AccountId = account ( "caller" , 0 , 0 ) ;
4866 let existential_deposit =
4967 <T :: OnChargeTransaction as OnChargeTransaction < T > >:: minimum_balance ( ) ;
5068
51- let ( amount_to_endow, tip) = if existential_deposit. is_zero ( ) {
52- let min_tip: <<T as pallet:: Config >:: OnChargeTransaction as payment:: OnChargeTransaction < T > >:: Balance = 1_000_000_000u32 . into ( ) ;
53- ( min_tip * 1000u32 . into ( ) , min_tip)
54- } else {
55- ( existential_deposit * 1000u32 . into ( ) , existential_deposit)
56- } ;
57-
58- <T :: OnChargeTransaction as OnChargeTransaction < T > >:: endow_account ( & caller, amount_to_endow) ;
69+ // Use a reasonable minimum tip that works for most runtimes
70+ let min_tip: BalanceOf < T > = 1_000_000_000u32 . into ( ) ;
71+ let tip = if existential_deposit. is_zero ( ) { min_tip } else { existential_deposit } ;
5972
73+ // Build the call and dispatch info first so we can compute the actual fee
6074 let ext: ChargeTransactionPayment < T > = ChargeTransactionPayment :: from ( tip) ;
6175 let inner = frame_system:: Call :: remark { remark : alloc:: vec![ ] } ;
6276 let call = T :: RuntimeCall :: from ( inner) ;
@@ -72,18 +86,29 @@ mod benchmarks {
7286 pays_fee : Pays :: Yes ,
7387 } ;
7488
89+ // Calculate the actual fee that will be charged, then endow enough to cover it
90+ // with a 10x buffer to account for any fee multiplier variations.
91+ // Ensure we endow at least the existential deposit so the account can exist.
92+ let len: u32 = 10 ;
93+ let expected_fee = crate :: Pallet :: < T > :: compute_fee ( len, & info, tip) ;
94+ let amount_to_endow = expected_fee
95+ . saturating_mul ( 10u32 . into ( ) )
96+ . max ( existential_deposit) ;
97+
98+ <T :: OnChargeTransaction as OnChargeTransaction < T > >:: endow_account ( & caller, amount_to_endow) ;
99+
75100 #[ block]
76101 {
77102 assert ! ( ext
78- . test_run( RawOrigin :: Signed ( caller. clone( ) ) . into( ) , & call, & info, 10 , 0 , |_| Ok (
103+ . test_run( RawOrigin :: Signed ( caller. clone( ) ) . into( ) , & call, & info, len as usize , 0 , |_| Ok (
79104 post_info
80105 ) )
81106 . unwrap( )
82107 . is_ok( ) ) ;
83108 }
84109
85110 post_info. actual_weight . as_mut ( ) . map ( |w| w. saturating_accrue ( extension_weight) ) ;
86- let actual_fee = Pallet :: < T > :: compute_actual_fee ( 10 , & info, & post_info, tip) ;
111+ let actual_fee = crate :: Pallet :: < T > :: compute_actual_fee ( len , & info, & post_info, tip) ;
87112 assert_last_event :: < T > (
88113 Event :: < T > :: TransactionFeePaid { who : caller, actual_fee, tip } . into ( ) ,
89114 ) ;
0 commit comments