5

The source code of this vest() function from pallet_vesting https://docs.substrate.io/rustdocs/latest/pallet_vesting/pallet/enum.Call.html :

#[pallet::call]
impl<T: Config> Pallet<T> {
  //pallet_vesting::pallet::Pallet  ... this line is from Rust-Analyzer
        pub fn vest(origin: OriginFor<T>) -> DispatchResult {
        let who = ensure_signed(origin)?;
        Self::do_vest(who)
    }

in my own pallet:

use pallet_vesting;
...
    pub fn vest(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
        let who = ensure_signed(origin)?;
        pallet_vesting::Pallet::<T>::vest(origin);
        Ok(().into())
    }

I am not sure about the T above... what type should I use?

The error message I got:

    the function or associated item `vest` exists for 
struct `pallet_vesting::Pallet<T>`, 
but .. the following trait bounds were not satisfied:
    T: pallet_vesting::Config`

Then I replaced the T above, so the function now is...

pallet_vesting::Pallet::<T: Config + pallet_vesting::Config>::vest(origin);

Then I got two errors:

error[E0658]: associated type bounds are unstable
error[E0229]: associated type bindings are not allowed here

and I tried the following for the T above... but couldn't get it to work...

  where T::pallet_vesting::Config
  T: pallet_vesting::Config
  T: Config

Please help!

1
  • Could you expand your code sample a bit? It misses a bit of context needed on the pallet decl besides others.
    – drahnr
    Commented Mar 24, 2022 at 15:38

3 Answers 3

5

You have two options for coupling in substrate:

LOOSE COUPLING:

Ideally one might want to call:

T::MyVesting::vest(origin);

MyVesting is an associated type that one would define on your pallet's Config. However T::MyVesting must be a trait that has the vest fn on it. The eagle eyed will notice that the only trait that the vesting pallet currently implements is the VestingSchedule trait which does not, alas, have the vest fn on it. So it would need a PR to be submitted to substrate to add such a trait to the Vesting pallet. (not too scary and we'd hand hold you through it)

TIGHT COUPLING:

Shawn says the alternative is to do "tight coupling": make your pallet explicitly depend on the pallet_vesting crate (via Cargo.toml), and then making your pallet's Config depend on the one you wish to call, so your pallet's Config trait would now start like this:

trait Config: frame_system::Config + pallet_vesting::Config {

(ensuring all the trait bounds are satisfied.)

With that done you can call it like this:

pallet_vesting::pallet::Pallet::<T>::vest(origin)?;

If you're the end user then tight coupling is not too bad; but if it was part of a library of pallets that people might use in a variety of ways, then one would prefer loose coupling for the added flexibility.

1
  • Thank you so much
    – Russo
    Commented Mar 25, 2022 at 12:38
6

T: Config + pallet_vesting::Config is correct.

2
  • Hi drahnr thank you. I have updated my question. could you have a look?
    – Russo
    Commented Mar 24, 2022 at 15:57
  • Thank you. your answer works
    – Russo
    Commented Mar 25, 2022 at 12:40
1

I also cannot give you a full answer, but you can get some inspiration from the aura_ext pallet, which does not have much code, but demonstrates some of the problems you can run into when depending on another pallet.

I think you need to use the #[pallet::config] declaration in your pallet probably.

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.