4

there are cases when we want to Box an argument of a dispatchable. One such case is when the type is large, for instance, xcm::MultiLocation and we do not want to blow the size of Call type.

these types might be exposed as generic types via the pallet's config. in this situation, we technically have two ways to box that type:

  1. on a pallet level: fn do_something(..., asset: Box<Config::AssetKind>)
  2. on a client level: impl Config { AssetKind = Box<MultiLocation>}

the second option seems incorrect to me, at least because a library/pallet might not anticipate it, and we're somewhat misrepresenting what AssetKind truly is in this context.

do you see any concrete reasons to avoid option 2? or perhaps reasons why it might be fine?

let's consider a case when AssetKind is referenced in one of the events like Created {asset: Config::AssetKind} and stored in a storage item. also let's thing about a chain metadata.

from rust perspective, it appears that most cases would be handled since a boxed type would eventually be dereferenced.

1
  • 1
    With option 2 the user of the pallet gets full control, where as with option 1 the user of the pallet is forced to box. I would suggest that substrate pallets should be as un-opinionated as possible given that they could be used in a variety of ways.
    – Squirrel
    Sep 27, 2023 at 8:50

1 Answer 1

1

one reason I see not to use option 2 relates to what I've already mentioned in the questions. In this case, we misrepresent what AssetKind is, which leads to some problems.

let's examine the example:

mod pallet_dream {
  ..
  pub trait Config {
    ..
    AssetKind: ..,
    Assets: fungibles::Inspect<.., AssetId = Self::AssetKind>, // (1)
  }

  impl<AssetKind = Config::AssetKind> 
   frame_support::Pay<AssetKind> for Pallet { // (2)
    ...
  }
}

mod wizard {
  trait Magic {
    fn leviosa();
  }
  ...
  impl<
    AssetKind, 
    From: frame_support::Pay<AssetKind>, // (3)
    To: frame_support::Oven<AssetId = Self::AssetKind>> 
     Magic for Burn {

  }
}

in case if AssetKind = Box<...>,

(1) any bounds within the pallet that reference that AssetKind will expect implementation over a Boxed type. this will make the usage of any common implementations impossible since they implemented over an actual type, not a box of it.

(2) any implementation the pallet provides for some low level contract (aka trait) which references the AssetKind will result an implementation over Box of AssetKind.

(3) if a general implementation like Burn is supplied with Pay implemented over Box, then an implementation of Oven also has to be defined over Box.

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.