@@ -29,6 +29,9 @@ mod keyword {
2929 syn:: custom_keyword!( storage_prefix) ;
3030 syn:: custom_keyword!( unbounded) ;
3131 syn:: custom_keyword!( whitelist_storage) ;
32+ syn:: custom_keyword!( proof_size) ;
33+ syn:: custom_keyword!( MaxEncodedLen ) ;
34+ syn:: custom_keyword!( Measured ) ;
3235 syn:: custom_keyword!( OptionQuery ) ;
3336 syn:: custom_keyword!( ResultQuery ) ;
3437 syn:: custom_keyword!( ValueQuery ) ;
@@ -39,11 +42,19 @@ mod keyword {
3942/// * `#[pallet::storage_prefix = "CustomName"]`
4043/// * `#[pallet::unbounded]`
4144/// * `#[pallet::whitelist_storage]
45+ /// * `#[pallet::proof_size = MaxEncodedLen]
4246pub enum PalletStorageAttr {
4347 Getter ( syn:: Ident , proc_macro2:: Span ) ,
4448 StorageName ( syn:: LitStr , proc_macro2:: Span ) ,
4549 Unbounded ( proc_macro2:: Span ) ,
4650 WhitelistStorage ( proc_macro2:: Span ) ,
51+ ProofSize ( ProofSizeAttribute , proc_macro2:: Span ) ,
52+ }
53+
54+ #[ derive( PartialEq , Debug ) ]
55+ pub enum ProofSizeAttribute {
56+ MaxEncodedLen ,
57+ Measured ,
4758}
4859
4960impl PalletStorageAttr {
@@ -52,7 +63,8 @@ impl PalletStorageAttr {
5263 Self :: Getter ( _, span) |
5364 Self :: StorageName ( _, span) |
5465 Self :: Unbounded ( span) |
55- Self :: WhitelistStorage ( span) => * span,
66+ Self :: WhitelistStorage ( span) |
67+ Self :: ProofSize ( _, span) => * span,
5668 }
5769 }
5870}
@@ -93,6 +105,23 @@ impl syn::parse::Parse for PalletStorageAttr {
93105 } else if lookahead. peek ( keyword:: whitelist_storage) {
94106 content. parse :: < keyword:: whitelist_storage > ( ) ?;
95107 Ok ( Self :: WhitelistStorage ( attr_span) )
108+ } else if lookahead. peek ( keyword:: proof_size) {
109+ content. parse :: < keyword:: proof_size > ( ) ?;
110+ content. parse :: < syn:: Token ![ =] > ( ) ?;
111+ let lookahead = content. lookahead1 ( ) ;
112+
113+ if lookahead. peek ( keyword:: MaxEncodedLen ) {
114+ content. parse :: < keyword:: MaxEncodedLen > ( ) . expect ( "Checked above" ) ;
115+ Ok ( Self :: ProofSize ( ProofSizeAttribute :: MaxEncodedLen , attr_span) )
116+ } else if lookahead. peek ( keyword:: Measured ) {
117+ content. parse :: < keyword:: Measured > ( ) . expect ( "Checked above" ) ;
118+ Ok ( Self :: ProofSize ( ProofSizeAttribute :: Measured , attr_span) )
119+ } else {
120+ Err ( syn:: Error :: new (
121+ attr_span,
122+ format ! ( "Invalid value for the proof_size attribute: {:?}" , lookahead. error( ) ) ,
123+ ) )
124+ }
96125 } else {
97126 Err ( lookahead. error ( ) )
98127 }
@@ -104,21 +133,25 @@ struct PalletStorageAttrInfo {
104133 rename_as : Option < syn:: LitStr > ,
105134 unbounded : bool ,
106135 whitelisted : bool ,
136+ proof_size : Option < ProofSizeAttribute > ,
107137}
108138
109139impl PalletStorageAttrInfo {
110140 fn from_attrs ( attrs : Vec < PalletStorageAttr > ) -> syn:: Result < Self > {
111141 let mut getter = None ;
112142 let mut rename_as = None ;
113- let mut unbounded = false ;
114- let mut whitelisted = false ;
143+ let mut proof_size = None ;
144+ let ( mut unbounded, mut whitelisted) = ( false , false ) ;
145+
115146 for attr in attrs {
116147 match attr {
117148 PalletStorageAttr :: Getter ( ident, ..) if getter. is_none ( ) => getter = Some ( ident) ,
118149 PalletStorageAttr :: StorageName ( name, ..) if rename_as. is_none ( ) =>
119150 rename_as = Some ( name) ,
120151 PalletStorageAttr :: Unbounded ( ..) if !unbounded => unbounded = true ,
121152 PalletStorageAttr :: WhitelistStorage ( ..) if !whitelisted => whitelisted = true ,
153+ PalletStorageAttr :: ProofSize ( mode, ..) if proof_size. is_none ( ) =>
154+ proof_size = Some ( mode) ,
122155 attr =>
123156 return Err ( syn:: Error :: new (
124157 attr. attr_span ( ) ,
@@ -127,7 +160,7 @@ impl PalletStorageAttrInfo {
127160 }
128161 }
129162
130- Ok ( PalletStorageAttrInfo { getter, rename_as, unbounded, whitelisted } )
163+ Ok ( PalletStorageAttrInfo { getter, rename_as, unbounded, whitelisted, proof_size } )
131164 }
132165}
133166
@@ -185,6 +218,8 @@ pub struct StorageDef {
185218 pub unbounded : bool ,
186219 /// Whether or not reads to this storage key will be ignored by benchmarking
187220 pub whitelisted : bool ,
221+ /// How the proof size should be calculated by the PoV benchmarking.
222+ pub proof_size : Option < ProofSizeAttribute > ,
188223}
189224
190225/// The parsed generic from the
@@ -687,9 +722,12 @@ impl StorageDef {
687722 } ;
688723
689724 let attrs: Vec < PalletStorageAttr > = helper:: take_item_pallet_attrs ( & mut item. attrs ) ?;
690- let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted } =
725+ let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted, proof_size } =
691726 PalletStorageAttrInfo :: from_attrs ( attrs) ?;
692727
728+ if unbounded && proof_size == Some ( ProofSizeAttribute :: MaxEncodedLen ) {
729+ return Err ( syn:: Error :: new ( item. span ( ) , "Storage item cannot be 'unbounded' ahd have 'MaxEncodedLen' proof size at the same time." ) )
730+ }
693731 // set all storages to be unbounded if dev_mode is enabled
694732 unbounded |= dev_mode;
695733 let cfg_attrs = helper:: get_item_cfg_attrs ( & item. attrs ) ;
@@ -832,6 +870,7 @@ impl StorageDef {
832870 named_generics,
833871 unbounded,
834872 whitelisted,
873+ proof_size,
835874 } )
836875 }
837876}
0 commit comments