I've recently posted a question about this topic, but I want to make it more general, as people might have the same issue as me.
I've checked some substrate based repositories like subsocial or debio, and I was wondering when should I create a different pallet to model certain behaviour. For example, let's say I have a pallet composed of two items somewhat related:
pub struct Item1 {
pub id: u32,
pub value: u32,
}
pub struct Item1_History {
pub item1_id: u32,
pub values: Vec<u32>,
}
/// Pallet storage
#[pallet::storage]
pub(super) type Items1<T: Config> = StorageMap<_, Twox64Concat, u32, Item1<T>>;
#[pallet::storage]
pub(super) type Items2<T: Config> = StorageMap<_, Twox64Concat, u32, Item2<T>>;
When creating an item
of type Item1
, I want to also generate another item
of type Item2
. This Item2
stores a vector of values, and if a new value is inserted, then it should also update the Item1
with the latest value.
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
pub fn create_item1(origin: OriginFor<T>, id: u32, value: u32) -> DispatchResult {
let who = ensure_signed(origin)?;
<Items1<T>>::insert(&id, Item1 {id, value});
// Create new vector with the first value provided
let mut values = Vec::new();
values.push(value);
<items2<T>>::insert(&id, Item2 {id, values};
}
#[pallet::weight(0)]
pub fn add_new_value_to_item2(origin: OriginFor<T>, id: u32, new_value: u32) -> DispatchResult {
let who = ensure_signed(origin)?;
// Get the item2 and push a new value
let mut item2 = <Items2<T>>::get(id).ok_or(<AnyError>);
item2.values.push(new_value);
<Items2<T>>::insert(id, item2);
// Get the item1 and update the value
let mut item = <Items1<T>>::get(id).ok_or(<AnyError>);
item.value = new_value;
<Items1<T>>::insert(id, item);
}
}
Can this logic be split into two pallets? or because both items interact in a close way it's better to keep them both on the same pallet?