frame_support_procedural/pallet/expand/
hooks.rs
1use crate::pallet::Def;
19
20pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream {
22 let (where_clause, span, has_runtime_upgrade) = match def.hooks.as_ref() {
23 Some(hooks) => {
24 let where_clause = hooks.where_clause.clone();
25 let span = hooks.attr_span;
26 let has_runtime_upgrade = hooks.has_runtime_upgrade;
27 (where_clause, span, has_runtime_upgrade)
28 },
29 None => (def.config.where_clause.clone(), def.pallet_struct.attr_span, false),
30 };
31
32 let frame_support = &def.frame_support;
33 let type_impl_gen = &def.type_impl_generics(span);
34 let type_use_gen = &def.type_use_generics(span);
35 let pallet_ident = &def.pallet_struct.pallet;
36 let frame_system = &def.frame_system;
37 let pallet_name = quote::quote! {
38 <
39 <T as #frame_system::Config>::PalletInfo
40 as
41 #frame_support::traits::PalletInfo
42 >::name::<Self>().unwrap_or("<unknown pallet name>")
43 };
44
45 let initialize_on_chain_storage_version = if let Some(in_code_version) =
46 &def.pallet_struct.storage_version
47 {
48 quote::quote! {
49 #frame_support::__private::log::info!(
50 target: #frame_support::LOG_TARGET,
51 "🐥 New pallet {:?} detected in the runtime. Initializing the on-chain storage version to match the storage version defined in the pallet: {:?}",
52 #pallet_name,
53 #in_code_version
54 );
55 #in_code_version.put::<Self>();
56 }
57 } else {
58 quote::quote! {
59 let default_version = #frame_support::traits::StorageVersion::new(0);
60 #frame_support::__private::log::info!(
61 target: #frame_support::LOG_TARGET,
62 "🐥 New pallet {:?} detected in the runtime. The pallet has no defined storage version, so the on-chain version is being initialized to {:?}.",
63 #pallet_name,
64 default_version
65 );
66 default_version.put::<Self>();
67 }
68 };
69
70 let log_runtime_upgrade = if has_runtime_upgrade {
71 quote::quote! {
73 #frame_support::__private::log::info!(
74 target: #frame_support::LOG_TARGET,
75 "⚠️ {} declares internal migrations (which *might* execute). \
76 On-chain `{:?}` vs in-code storage version `{:?}`",
77 #pallet_name,
78 <Self as #frame_support::traits::GetStorageVersion>::on_chain_storage_version(),
79 <Self as #frame_support::traits::GetStorageVersion>::in_code_storage_version(),
80 );
81 }
82 } else {
83 quote::quote! {
85 #frame_support::__private::log::debug!(
86 target: #frame_support::LOG_TARGET,
87 "✅ no migration for {}",
88 #pallet_name,
89 );
90 }
91 };
92
93 let hooks_impl = if def.hooks.is_none() {
94 let frame_system = &def.frame_system;
95 quote::quote! {
96 impl<#type_impl_gen>
97 #frame_support::traits::Hooks<#frame_system::pallet_prelude::BlockNumberFor::<T>>
98 for #pallet_ident<#type_use_gen> #where_clause {}
99 }
100 } else {
101 proc_macro2::TokenStream::new()
102 };
103
104 let post_storage_version_check = if def.pallet_struct.storage_version.is_some() {
108 quote::quote! {
109 let on_chain_version = <Self as #frame_support::traits::GetStorageVersion>::on_chain_storage_version();
110 let in_code_version = <Self as #frame_support::traits::GetStorageVersion>::in_code_storage_version();
111
112 if on_chain_version != in_code_version {
113 #frame_support::__private::log::error!(
114 target: #frame_support::LOG_TARGET,
115 "{}: On chain storage version {:?} doesn't match in-code storage version {:?}.",
116 #pallet_name,
117 on_chain_version,
118 in_code_version,
119 );
120
121 return Err("On chain and in-code storage version do not match. Missing runtime upgrade?".into());
122 }
123 }
124 } else {
125 quote::quote! {
126 let on_chain_version = <Self as #frame_support::traits::GetStorageVersion>::on_chain_storage_version();
127
128 if on_chain_version != #frame_support::traits::StorageVersion::new(0) {
129 #frame_support::__private::log::error!(
130 target: #frame_support::LOG_TARGET,
131 "{}: On chain storage version {:?} is set to non zero, \
132 while the pallet is missing the `#[pallet::storage_version(VERSION)]` attribute.",
133 #pallet_name,
134 on_chain_version,
135 );
136
137 return Err("On chain storage version set, while the pallet doesn't \
138 have the `#[pallet::storage_version(VERSION)]` attribute.".into());
139 }
140 }
141 };
142
143 quote::quote_spanned!(span =>
144 #hooks_impl
145
146 impl<#type_impl_gen>
147 #frame_support::traits::OnFinalize<#frame_system::pallet_prelude::BlockNumberFor::<T>>
148 for #pallet_ident<#type_use_gen> #where_clause
149 {
150 fn on_finalize(n: #frame_system::pallet_prelude::BlockNumberFor::<T>) {
151 #frame_support::__private::sp_tracing::enter_span!(
152 #frame_support::__private::sp_tracing::trace_span!("on_finalize")
153 );
154 <
155 Self as #frame_support::traits::Hooks<
156 #frame_system::pallet_prelude::BlockNumberFor::<T>
157 >
158 >::on_finalize(n)
159 }
160 }
161
162 impl<#type_impl_gen>
163 #frame_support::traits::OnIdle<#frame_system::pallet_prelude::BlockNumberFor::<T>>
164 for #pallet_ident<#type_use_gen> #where_clause
165 {
166 fn on_idle(
167 n: #frame_system::pallet_prelude::BlockNumberFor::<T>,
168 remaining_weight: #frame_support::weights::Weight
169 ) -> #frame_support::weights::Weight {
170 <
171 Self as #frame_support::traits::Hooks<
172 #frame_system::pallet_prelude::BlockNumberFor::<T>
173 >
174 >::on_idle(n, remaining_weight)
175 }
176 }
177
178 impl<#type_impl_gen>
179 #frame_support::traits::OnPoll<#frame_system::pallet_prelude::BlockNumberFor::<T>>
180 for #pallet_ident<#type_use_gen> #where_clause
181 {
182 fn on_poll(
183 n: #frame_system::pallet_prelude::BlockNumberFor::<T>,
184 weight: &mut #frame_support::weights::WeightMeter
185 ) {
186 <
187 Self as #frame_support::traits::Hooks<
188 #frame_system::pallet_prelude::BlockNumberFor::<T>
189 >
190 >::on_poll(n, weight);
191 }
192 }
193
194 impl<#type_impl_gen>
195 #frame_support::traits::OnInitialize<#frame_system::pallet_prelude::BlockNumberFor::<T>>
196 for #pallet_ident<#type_use_gen> #where_clause
197 {
198 fn on_initialize(
199 n: #frame_system::pallet_prelude::BlockNumberFor::<T>
200 ) -> #frame_support::weights::Weight {
201 #frame_support::__private::sp_tracing::enter_span!(
202 #frame_support::__private::sp_tracing::trace_span!("on_initialize")
203 );
204 <
205 Self as #frame_support::traits::Hooks<
206 #frame_system::pallet_prelude::BlockNumberFor::<T>
207 >
208 >::on_initialize(n)
209 }
210 }
211
212 impl<#type_impl_gen>
213 #frame_support::traits::BeforeAllRuntimeMigrations
214 for #pallet_ident<#type_use_gen> #where_clause
215 {
216 fn before_all_runtime_migrations() -> #frame_support::weights::Weight {
217 use #frame_support::traits::{Get, PalletInfoAccess};
218 use #frame_support::__private::hashing::twox_128;
219 use #frame_support::storage::unhashed::contains_prefixed_key;
220 #frame_support::__private::sp_tracing::enter_span!(
221 #frame_support::__private::sp_tracing::trace_span!("before_all")
222 );
223
224 let pallet_hashed_prefix = <Self as PalletInfoAccess>::name_hash();
228 let exists = contains_prefixed_key(&pallet_hashed_prefix);
229 if !exists {
230 #initialize_on_chain_storage_version
231 <T as #frame_system::Config>::DbWeight::get().reads_writes(1, 1)
232 } else {
233 <T as #frame_system::Config>::DbWeight::get().reads(1)
234 }
235 }
236 }
237
238 impl<#type_impl_gen>
239 #frame_support::traits::OnRuntimeUpgrade
240 for #pallet_ident<#type_use_gen> #where_clause
241 {
242 fn on_runtime_upgrade() -> #frame_support::weights::Weight {
243 #frame_support::__private::sp_tracing::enter_span!(
244 #frame_support::__private::sp_tracing::trace_span!("on_runtime_update")
245 );
246
247 #log_runtime_upgrade
249
250 <
251 Self as #frame_support::traits::Hooks<
252 #frame_system::pallet_prelude::BlockNumberFor::<T>
253 >
254 >::on_runtime_upgrade()
255 }
256
257 #frame_support::try_runtime_enabled! {
258 fn pre_upgrade() -> Result<#frame_support::__private::Vec<u8>, #frame_support::sp_runtime::TryRuntimeError> {
259 <
260 Self
261 as
262 #frame_support::traits::Hooks<#frame_system::pallet_prelude::BlockNumberFor::<T>>
263 >::pre_upgrade()
264 }
265
266 fn post_upgrade(state: #frame_support::__private::Vec<u8>) -> Result<(), #frame_support::sp_runtime::TryRuntimeError> {
267 #post_storage_version_check
268
269 <
270 Self
271 as
272 #frame_support::traits::Hooks<#frame_system::pallet_prelude::BlockNumberFor::<T>>
273 >::post_upgrade(state)
274 }
275 }
276 }
277
278 impl<#type_impl_gen>
279 #frame_support::traits::OffchainWorker<#frame_system::pallet_prelude::BlockNumberFor::<T>>
280 for #pallet_ident<#type_use_gen> #where_clause
281 {
282 fn offchain_worker(n: #frame_system::pallet_prelude::BlockNumberFor::<T>) {
283 <
284 Self as #frame_support::traits::Hooks<
285 #frame_system::pallet_prelude::BlockNumberFor::<T>
286 >
287 >::offchain_worker(n)
288 }
289 }
290
291 #frame_support::std_enabled! {
293 impl<#type_impl_gen>
294 #frame_support::traits::IntegrityTest
295 for #pallet_ident<#type_use_gen> #where_clause
296 {
297 fn integrity_test() {
298 #frame_support::__private::sp_io::TestExternalities::default().execute_with(|| {
299 <
300 Self as #frame_support::traits::Hooks<
301 #frame_system::pallet_prelude::BlockNumberFor::<T>
302 >
303 >::integrity_test()
304 });
305 }
306 }
307 }
308
309 #frame_support::try_runtime_enabled! {
310 impl<#type_impl_gen>
311 #frame_support::traits::TryState<#frame_system::pallet_prelude::BlockNumberFor::<T>>
312 for #pallet_ident<#type_use_gen> #where_clause
313 {
314 fn try_state(
315 n: #frame_system::pallet_prelude::BlockNumberFor::<T>,
316 _s: #frame_support::traits::TryStateSelect
317 ) -> Result<(), #frame_support::sp_runtime::TryRuntimeError> {
318 #frame_support::__private::log::info!(
319 target: #frame_support::LOG_TARGET,
320 "🩺 Running {:?} try-state checks",
321 #pallet_name,
322 );
323 <
324 Self as #frame_support::traits::Hooks<
325 #frame_system::pallet_prelude::BlockNumberFor::<T>
326 >
327 >::try_state(n).inspect_err(|err| {
328 #frame_support::__private::log::error!(
329 target: #frame_support::LOG_TARGET,
330 "❌ {:?} try_state checks failed: {:?}",
331 #pallet_name,
332 err
333 );
334 })
335 }
336 }
337 }
338 )
339}