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.