From 3ae11a7cead2bea34be84837a9162b4f60012a75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 29 Oct 2021 18:51:20 +0200 Subject: [PATCH 1/2] pallet-utility: Fix possible mismatch between native/wasm The `batched_calls_limit` constant value includes the `size_of` of the runtime `Call`. As we compile the runtime for native/wasm, we need to align the call size to ensure that it is the same on wasm/native. This also solves the problem of different metadata outputs for the same runtime. --- frame/utility/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 54de87c4740c8..e6918b8c9b685 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -117,7 +117,13 @@ pub mod pallet { /// The limit on the number of batched calls. fn batched_calls_limit() -> u32 { let allocator_limit = sp_core::MAX_POSSIBLE_ALLOCATION; - let call_size = core::mem::size_of::<::Call>() as u32; + // Align the call size to 1KB. As we are currently compiling the runtime for native/wasm + // the `size_of` of the `Call` can be different. To ensure that this don't leads to + // mismatches between native/wasm or to different metadata for the same runtime, we + // algin the call size. The value is choosen big enough to hopefully never reach it. + let call_align = 1024; + let call_size = ((core::mem::size_of::<::Call>() as u32 + call_align - 1) / + call_align) * call_align; // The margin to take into account vec doubling capacity. let margin_factor = 3; From 6073f87b4a62c8fc699ac2c5cb519c71af6c3150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 29 Oct 2021 21:10:51 +0200 Subject: [PATCH 2/2] Review feedback --- frame/utility/src/lib.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index e6918b8c9b685..8712cf74f451b 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -112,18 +112,19 @@ pub mod pallet { ItemCompleted, } + // Align the call size to 1KB. As we are currently compiling the runtime for native/wasm + // the `size_of` of the `Call` can be different. To ensure that this don't leads to + // mismatches between native/wasm or to different metadata for the same runtime, we + // algin the call size. The value is choosen big enough to hopefully never reach it. + const CALL_ALIGN: u32 = 1024; + #[pallet::extra_constants] impl Pallet { /// The limit on the number of batched calls. fn batched_calls_limit() -> u32 { let allocator_limit = sp_core::MAX_POSSIBLE_ALLOCATION; - // Align the call size to 1KB. As we are currently compiling the runtime for native/wasm - // the `size_of` of the `Call` can be different. To ensure that this don't leads to - // mismatches between native/wasm or to different metadata for the same runtime, we - // algin the call size. The value is choosen big enough to hopefully never reach it. - let call_align = 1024; - let call_size = ((core::mem::size_of::<::Call>() as u32 + call_align - 1) / - call_align) * call_align; + let call_size = ((sp_std::mem::size_of::<::Call>() as u32 + CALL_ALIGN - + 1) / CALL_ALIGN) * CALL_ALIGN; // The margin to take into account vec doubling capacity. let margin_factor = 3; @@ -131,6 +132,18 @@ pub mod pallet { } } + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + // If you hit this error, you need to try to `Box` big dispatchable parameters. + assert!( + sp_std::mem::size_of::<::Call>() as u32 <= CALL_ALIGN, + "Call enum size should be smaller than {} bytes.", + CALL_ALIGN, + ); + } + } + #[pallet::error] pub enum Error { /// Too many calls batched.