The question is about both types of pallets-coupling. let's say we have 3 pallets A,B, and C.
C is tightly coupled to B (C Config is added in B Config), and we want to do a loose Coupling of A and B in order to use functions and types available in B and C (in pallet A, I do a pub use pallet_B::pallet as B;
and in order to use types defined in B, inside A/pub mod pallet{..}, I do: use pallet_B::{Type0, Type1, Type2};
).
Now, this all work fine except in one particular case: for Types defined in B as Type Type_x<T>=<T as C::Config>::Type_y;
. If I try to import Type_x in A from B, I get an Error saying that some traits from C::Config are missing, and this is what I don't understand. My perception is that if B is already accessing everything in C through tight-coupling, then there is no need to call C from A's pallet or A's runtime....What am I misunderstanding?
For a concrete example of what I am trying to do, you can take a look at https://github.com/Fair-Squares/fair-squares/tree/structure_template/pallets
A --> Template, B-->nft, C-->orml-nft
Make sure you're looking at the "structure_template" branch.
EDIT:
lib.rs
pub mod pallet1;
pub mod pallet2;
pub mod bad_pallet3;
pallet1.rs
#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config {
type ClassId: Parameter + Member + Default + Copy;
}
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
#[pallet::storage]
pub type MyValue<T: Config> = StorageValue<_, u32, ValueQuery>;
}
impl<T: Config> Pallet<T> {
pub fn get_value() -> u32 {
<MyValue<T>>::get()
}
}
pallet2.rs
#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use crate::pallet1;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: frame_system::Config + pallet1::Config {}
pub type ClassIdOf<T> = <T as pallet1::Config>::ClassId;
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
pub fn get_value_directly(_origin: OriginFor<T>) -> DispatchResult {
let _value = pallet1::MyValue::<T>::get();
Ok(())
}
#[pallet::weight(0)]
pub fn set_value_directly(_origin: OriginFor<T>, value: u32) -> DispatchResult {
pallet1::MyValue::<T>::put(value);
Ok(())
}
#[pallet::weight(0)]
pub fn get_value_public_function(_origin: OriginFor<T>) -> DispatchResult {
let _value = pallet1::Pallet::<T>::get_value();
Ok(())
}
}
}
bad_pallet3.rs
#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use crate::{pallet2};
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use pallet2::pallet::ClassIdOf;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: frame_system::Config{}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
pub fn get_value_directly(_origin: OriginFor<T>, _cl: ClassIdOf<T>) -> DispatchResult {
let _value = 5;
Ok(())
}
#[pallet::weight(0)]
pub fn set_value_directly(_origin: OriginFor<T>, value: u32) -> DispatchResult {
let _val=value;
Ok(())
}
}
}
ClassIdOf in Bad_pallet3 is my problem…I only need ClassIdOf in pallet3, so I leave out pallet2::Config, which is probably the source of the error—-> is there a way to do this without adding pallet2::Config to pallet3::Config (which is a tight-coupling if I understand things correctly…)