I am trying to understand the constrains in the batching function.

fn batched_calls_limit() -> u32 {
    let allocator_limit = sp_core::MAX_POSSIBLE_ALLOCATION;
    let call_size = ((sp_std::mem::size_of::<<T as Config>::Call>() as u32 + CALL_ALIGN -
        1) / CALL_ALIGN) * CALL_ALIGN;
    // The margin to take into account vec doubling capacity.
    let margin_factor = 3;

    allocator_limit / margin_factor / call_size

Can someone please explain these constraints in more detail? Why do we need these?

1 Answer 1


Within the Wasm environment, there is a limited memory size available and accessible by the memory allocator.

This code attempts to calculate the safe limits of nested calls which would not cause memory allocation errors.

  • Curious. Why is this check done at the extrinsic level instead of the transaction pool with a Signed Extensions? It seems that we were concern with memory limits we would want to do this check before propagating the transaction to the network
    – Yatusabes
    Commented Jul 6, 2022 at 17:29
  • Could be done either way, but adding a signed extension is non-trivial since it needs to be explicitly included in each node. So building the check into the extrinsic is safer when updating a pallet used by all the chains.
    – Shawn Tabrizi
    Commented Jul 6, 2022 at 17:55
  • I can see that it is more practical to add it to the extrinsic. It definitely makes it easier to maintain. Are those call functions held in memory? If we manage to exceed it I would expect it to throw an error before reaching that validation. Similar to an overflow?
    – Yatusabes
    Commented Jul 6, 2022 at 19:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.