1

My custom pallet has a couple of XCM calls, for which I have to provide the Origin in mock.rs. It implements the

    #[pallet::config]
    pub trait Config: frame_system::Config {
        ...

        type Origin: From<<Self as SystemConfig>::Origin>
            + Into<Result<CumulusOrigin, <Self as Config>::Origin>>;

        type XcmSender: SendXcm;
    }

I have tests for the "ordinary, non-XCM" functions and with now adding the XCM, this does not compile (due to requiring CumulusOrigin). I do not care for testing XCM calls, so a dummy Origin would work well, however I am not sure how to implement it. I do not find any examples with such mocking (XCM pallets on github do not have tests). How can I do this?


Stuff I tried.

I tried to mock everything:

use frame_support::{
    parameter_types,
    traits::{ConstU64, Everything},
    weights::{IdentityFee, Weight},
};
use frame_system as system;

use sp_core::{
    offchain::{testing, OffchainWorkerExt, TransactionPoolExt},
    sr25519::Signature,
    H256,
};

use sp_runtime::{
    testing::{Header, TestXt},
    traits::{BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, Verify},
};
use xcm::latest::{prelude::*, Junction, OriginKind, SendXcm, Xcm};
use xcm_builder::{
    AllowUnpaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, LocationInverter,
    SignedToAccountId32,
};
use xcm_executor::{
    traits::{InvertLocation, TransactAsset, WeightTrader},
    Assets, XcmExecutor,
};

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;

// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
    pub enum Test where
        Block = Block,
        NodeBlock = Block,
        UncheckedExtrinsic = UncheckedExtrinsic,
    {
        System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
        Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
        XcmPallet: pallet_xcm::{Pallet, Call, Event<T>, Origin, Config} = 31,
        CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 32,
        MyPallet: my_pallet::{Pallet, Call, Storage, Event<T>},
    }
);

parameter_types! {
    pub const BlockHashCount: u64 = 250;
    pub const SS58Prefix: u8 = 42;

    pub static AdvertisedXcmVersion: xcm::prelude::XcmVersion = 2;
    pub const UnitWeightCost: Weight = 10;
    pub const MaxInstructions: u32 = 100;
    pub const RelayNetwork: NetworkId = NetworkId::Any;

    pub Ancestry: MultiLocation = Parachain(2001).into();
}

impl system::Config for Test {
    type BaseCallFilter = Everything;
    type BlockWeights = ();
    type BlockLength = ();
    type DbWeight = ();
    type Origin = Origin;
    type Call = Call;
    type Index = u64;
    type BlockNumber = u64;
    type Hash = H256;
    type Hashing = BlakeTwo256;
    type AccountId = u64;
    type Lookup = IdentityLookup<Self::AccountId>;
    type Header = Header;
    type Event = Event;
    type BlockHashCount = BlockHashCount;
    type Version = ();
    type PalletInfo = PalletInfo;
    type AccountData = pallet_balances::AccountData<u64>;
    type OnNewAccount = ();
    type OnKilledAccount = ();
    type SystemWeightInfo = ();
    type SS58Prefix = SS58Prefix;
    type OnSetCode = ();
    type MaxConsumers = frame_support::traits::ConstU32<16>;
}

impl pallet_balances::Config for Test {
    type Balance = u64;
    type DustRemoval = ();
    type Event = Event;
    type ExistentialDeposit = ConstU64<1>;
    type AccountStore = System;
    type WeightInfo = ();
    type MaxLocks = ();
    type MaxReserves = ();
    type ReserveIdentifier = [u8; 8];
}

pub struct DummyWeightTrader;
impl WeightTrader for DummyWeightTrader {
    fn new() -> Self {
        DummyWeightTrader
    }

    fn buy_weight(&mut self, _weight: Weight, _payment: Assets) -> Result<Assets, XcmError> {
        Ok(Assets::default())
    }
}
pub struct DummyAssetTransactor;
impl TransactAsset for DummyAssetTransactor {
    fn deposit_asset(_what: &MultiAsset, _who: &MultiLocation) -> XcmResult {
        Ok(())
    }

    fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result<Assets, XcmError> {
        let asset: MultiAsset = (Parent, 100_000).into();
        Ok(asset.into())
    }
}
pub struct XcmConfig;
pub struct DoNothingRouter;
type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, RelayNetwork>;
pub type Barrier = AllowUnpaidExecutionFrom<Everything>;

impl SendXcm for DoNothingRouter {
    fn send_xcm(_dest: impl Into<MultiLocation>, _msg: Xcm<()>) -> SendResult {
        Ok(())
    }
}

impl xcm_executor::Config for XcmConfig {
    type Call = Call;
    type XcmSender = DoNothingRouter;
    type AssetTransactor = DummyAssetTransactor;
    type OriginConverter = pallet_xcm::XcmPassthrough<Origin>;
    type IsReserve = ();
    type IsTeleporter = ();
    type LocationInverter = LocationInverter<Ancestry>;
    type Barrier = Barrier;
    type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
    type Trader = DummyWeightTrader;
    type ResponseHandler = ();
    type AssetTrap = XcmPallet;
    type AssetClaims = XcmPallet;
    type SubscriptionService = XcmPallet;
}

impl pallet_xcm::Config for Test {
    type Event = Event;
    type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    type XcmRouter = DoNothingRouter;
    type LocationInverter = LocationInverter<Ancestry>;
    type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    type XcmExecuteFilter = Everything;
    type XcmExecutor = XcmExecutor<XcmConfig>;
    type XcmTeleportFilter = Everything;
    type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
    type XcmReserveTransferFilter = Everything;
    type Origin = Origin;
    type Call = Call;
    const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
    type AdvertisedXcmVersion = AdvertisedXcmVersion;
}

impl cumulus_pallet_xcm::Config for Test {
    type Event = Event;
    type XcmExecutor = XcmExecutor<XcmConfig>;
}

but I get:

error[E0271]: type mismatch resolving `<OriginCaller as TryInto<RawOrigin<sp_core::sr25519::Public>>>::Error == OriginCaller`
   --> my_pallet/src/mock.rs:154:26
    |
154 |     type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `OriginCaller`, found enum `std::convert::Infallible`
    |
    = note: required because of the requirements on the impl of `xcm_executor::traits::Convert<mock::Origin, xcm::v1::MultiLocation>` for `SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>`
    = note: required because of the requirements on the impl of `EnsureOrigin<mock::Origin>` for `EnsureXcmOrigin<mock::Origin, SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>>`
note: required by a bound in `pallet_xcm::Config::SendXcmOrigin`
   --> /home/user/.cargo/git/checkouts/polkadot-4038f27d5e4ea2e8/b017bad/xcm/pallet-xcm/src/lib.rs:78:65
    |
78  |         type SendXcmOrigin: EnsureOrigin<<Self as SysConfig>::Origin, Success = MultiLocation>;
    |                                                                       ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `pallet_xcm::Config::SendXcmOrigin`

error[E0277]: the trait bound `OriginCaller: From<RawOrigin<sp_core::sr25519::Public>>` is not satisfied
   --> my_pallet/src/mock.rs:154:26
    |
154 |     type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<RawOrigin<sp_core::sr25519::Public>>` is not implemented for `OriginCaller`
    |
    = help: the following other types implement trait `From<T>`:
              <OriginCaller as From<RawOrigin<u64>>>
              <OriginCaller as From<cumulus_pallet_xcm::Origin>>
              <OriginCaller as From<pallet_xcm::Origin>>
    = note: required because of the requirements on the impl of `xcm_executor::traits::Convert<mock::Origin, xcm::v1::MultiLocation>` for `SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>`
    = note: required because of the requirements on the impl of `EnsureOrigin<mock::Origin>` for `EnsureXcmOrigin<mock::Origin, SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>>`
note: required by a bound in `pallet_xcm::Config::SendXcmOrigin`
   --> /home/user/.cargo/git/checkouts/polkadot-4038f27d5e4ea2e8/b017bad/xcm/pallet-xcm/src/lib.rs:78:65
    |
78  |         type SendXcmOrigin: EnsureOrigin<<Self as SysConfig>::Origin, Success = MultiLocation>;
    |                                                                       ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `pallet_xcm::Config::SendXcmOrigin`

error[E0277]: the trait bound `RawOrigin<sp_core::sr25519::Public>: From<OriginCaller>` is not satisfied
   --> my_pallet/src/mock.rs:154:26
    |
154 |     type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<OriginCaller>` is not implemented for `RawOrigin<sp_core::sr25519::Public>`
    |
    = help: the trait `From<std::option::Option<AccountId>>` is implemented for `RawOrigin<AccountId>`
    = note: required because of the requirements on the impl of `Into<RawOrigin<sp_core::sr25519::Public>>` for `OriginCaller`
    = note: required because of the requirements on the impl of `TryFrom<OriginCaller>` for `RawOrigin<sp_core::sr25519::Public>`
    = note: required because of the requirements on the impl of `TryInto<RawOrigin<sp_core::sr25519::Public>>` for `OriginCaller`
    = note: required because of the requirements on the impl of `xcm_executor::traits::Convert<mock::Origin, xcm::v1::MultiLocation>` for `SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>`
    = note: required because of the requirements on the impl of `EnsureOrigin<mock::Origin>` for `EnsureXcmOrigin<mock::Origin, SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>>`
note: required by a bound in `pallet_xcm::Config::SendXcmOrigin`
   --> /home/user/.cargo/git/checkouts/polkadot-4038f27d5e4ea2e8/b017bad/xcm/pallet-xcm/src/lib.rs:78:65
    |
78  |         type SendXcmOrigin: EnsureOrigin<<Self as SysConfig>::Origin, Success = MultiLocation>;
    |                                                                       ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `pallet_xcm::Config::SendXcmOrigin`

error[E0271]: type mismatch resolving `<OriginCaller as TryInto<RawOrigin<sp_core::sr25519::Public>>>::Error == OriginCaller`
   --> my_pallet/src/mock.rs:157:29
    |
157 |     type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `OriginCaller`, found enum `std::convert::Infallible`
    |
    = note: required because of the requirements on the impl of `xcm_executor::traits::Convert<mock::Origin, xcm::v1::MultiLocation>` for `SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>`
    = note: required because of the requirements on the impl of `EnsureOrigin<mock::Origin>` for `EnsureXcmOrigin<mock::Origin, SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>>`
note: required by a bound in `pallet_xcm::Config::ExecuteXcmOrigin`
   --> /home/user/.cargo/git/checkouts/polkadot-4038f27d5e4ea2e8/b017bad/xcm/pallet-xcm/src/lib.rs:86:68
    |
86  |         type ExecuteXcmOrigin: EnsureOrigin<<Self as SysConfig>::Origin, Success = MultiLocation>;
    |                                                                          ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `pallet_xcm::Config::ExecuteXcmOrigin`

error[E0277]: the trait bound `OriginCaller: From<RawOrigin<sp_core::sr25519::Public>>` is not satisfied
   --> my_pallet/src/mock.rs:157:29
    |
157 |     type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<RawOrigin<sp_core::sr25519::Public>>` is not implemented for `OriginCaller`
    |
    = help: the following other types implement trait `From<T>`:
              <OriginCaller as From<RawOrigin<u64>>>
              <OriginCaller as From<cumulus_pallet_xcm::Origin>>
              <OriginCaller as From<pallet_xcm::Origin>>
    = note: required because of the requirements on the impl of `xcm_executor::traits::Convert<mock::Origin, xcm::v1::MultiLocation>` for `SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>`
    = note: required because of the requirements on the impl of `EnsureOrigin<mock::Origin>` for `EnsureXcmOrigin<mock::Origin, SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>>`
note: required by a bound in `pallet_xcm::Config::ExecuteXcmOrigin`
   --> /home/user/.cargo/git/checkouts/polkadot-4038f27d5e4ea2e8/b017bad/xcm/pallet-xcm/src/lib.rs:86:68
    |
86  |         type ExecuteXcmOrigin: EnsureOrigin<<Self as SysConfig>::Origin, Success = MultiLocation>;
    |                                                                          ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `pallet_xcm::Config::ExecuteXcmOrigin`

error[E0277]: the trait bound `RawOrigin<sp_core::sr25519::Public>: From<OriginCaller>` is not satisfied
   --> my_pallet/src/mock.rs:157:29
    |
157 |     type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<OriginCaller>` is not implemented for `RawOrigin<sp_core::sr25519::Public>`
    |
    = help: the trait `From<std::option::Option<AccountId>>` is implemented for `RawOrigin<AccountId>`
    = note: required because of the requirements on the impl of `Into<RawOrigin<sp_core::sr25519::Public>>` for `OriginCaller`
    = note: required because of the requirements on the impl of `TryFrom<OriginCaller>` for `RawOrigin<sp_core::sr25519::Public>`
    = note: required because of the requirements on the impl of `TryInto<RawOrigin<sp_core::sr25519::Public>>` for `OriginCaller`
    = note: required because of the requirements on the impl of `xcm_executor::traits::Convert<mock::Origin, xcm::v1::MultiLocation>` for `SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>`
    = note: required because of the requirements on the impl of `EnsureOrigin<mock::Origin>` for `EnsureXcmOrigin<mock::Origin, SignedToAccountId32<mock::Origin, sp_core::sr25519::Public, RelayNetwork>>`
note: required by a bound in `pallet_xcm::Config::ExecuteXcmOrigin`

At this point I've tried so many things, I am thinking of removing tests rather than making it work. I would rather not do that.

1 Answer 1

0

Take a look into the xcm-examples repository and use the setup up it has for testing, mocking the runtime and some of the features you need to mock for testing XCM calls.

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.