I'd like to save a record from PalletA in PalletB by simply passing the raw data and waiting for the return.
I have tried following:
// ./PalletB/lib.rs
pub trait PutInStorage {
fn put_rule_in_storage(value: u32);
}
impl<T: Trait> PutInStorage for Module<T> {
fn put_rule_in_storage(value: u32) {
SimpleCounter::put(value);
}
}
then in
// ./PalletA/lib.rs
use palletB::{PutInStorage, Trait as PalletBTrait};
///The pallet's configuration trait.
pub trait Trait: system::Trait + PalletBTrait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type ExternalStorage: PutInStorage;
}
then I added the definition to the runtime like this:
// ./runtime/lib.rs
// near the construct_runtime macro
impl palletA::Trait for Runtime {
type Event = Event;
type ExternalStorage = palletB::Module<Runtime>;
}
So far this passes the check but not the test. The test configuration for the trait is like this:
use palletB::{PutInStorage, Trait as PalletBTrait};
impl Trait for Test {
type Event = ();
type ExternalStorage = PutInStorage;
}
and this fails with the:
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^ help: use `dyn`: `dyn PutInStorage`
impl Trait for Test
------------------- in this `impl` item
type Event = ();
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `pallet_rules::PutInStorage` cannot be made into an object
I tried all the suggestions the Rust compiler gives me but without any luck. Before someone asks why do I need this in my test, it's because a dispatchable fn in decl_module!
checks does a certain record exists before starts processing and saving its own records. It is dependent on record to exist.
To make the compiler happy, your test config must also have an instance of PalletB, or anything else that implements PutInStorage
.
Similar to what you've done already in ./runtime/lib.rs
:
impl Trait for Test {
type Event = ();
type ExternalStorage = palletB::Module<Test>;
}
Note that now struct Test
is the one playing the role of Runtime
. I think this is the only thing that you are missing.
That being said, you seem to be on the wrong track in the overall design.
PalletA
already depends on PalletB
. Given that you also have a trait to link the two PutInStorage
, this is not a good design. Generally, you should try and always chose one of the following:
PalletB
has a storage item called pub Foo: u32
in decl_storage
and PutInStorage
writes to this. If this is the case, there's no need for a trait. From PalletA
you can just say: palletB::Foo::put(value)
.Note that this approach should be chosen with care, otherwise you might end up with a lot of pallets depending on one another which is not good.
PutInStorage
. Your code seem to be aligned with this approach, except you define PalletA's Trait as pub trait Trait: system::Trait
. There's no need to depend on PalletB here, and of course you can wipe it from Cargo.toml
as well.