diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs
index da4d5b393b47..13816f8ce711 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs
@@ -15,11 +15,12 @@
// along with Cumulus. If not, see .
use super::{
- AccountId, AllPalletsWithSystem, Balances, BaseDeliveryFee, FeeAssetId, ParachainInfo,
+ AccountId, AllPalletsWithSystem, Balances, BaseDeliveryFee, Broker, FeeAssetId, ParachainInfo,
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TransactionByteFee, WeightToFee, XcmpQueue,
};
use frame_support::{
+ pallet_prelude::PalletInfoAccess,
parameter_types,
traits::{ConstU32, Contains, Equals, Everything, Nothing},
};
@@ -42,11 +43,12 @@ use xcm_builder::CurrencyAdapter;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain,
- DenyThenTry, EnsureXcmOrigin, FrameTransactionalProcessor, IsConcrete, ParentAsSuperuser,
- ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
- SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
- TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
- XcmFeeManagerFromComponents, XcmFeeToAccount,
+ DenyThenTry, EnsureXcmOrigin, FrameTransactionalProcessor, IsConcrete, NonFungibleAdapter,
+ ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
+ SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
+ SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
+ WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
+ XcmFeeToAccount,
};
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};
@@ -56,6 +58,8 @@ parameter_types! {
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorLocation =
[GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into();
+ pub BrokerPalletLocation: Location =
+ PalletInstance(::index() as u8).into();
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub const GovernanceLocation: Location = Location::parent();
@@ -90,6 +94,23 @@ pub type CurrencyTransactor = CurrencyAdapter<
(),
>;
+/// Means for transacting coretime regions on this chain.
+pub type RegionTransactor = NonFungibleAdapter<
+ // Use this non-fungible implementation:
+ Broker,
+ // This adapter will handle coretime regions from the broker pallet.
+ IsConcrete,
+ // Convert an XCM Location into a local account id:
+ LocationToAccountId,
+ // Our chain's account ID type (we can't get away without mentioning it explicitly):
+ AccountId,
+ // We don't track any teleports.
+ (),
+>;
+
+/// Means for transacting assets on this chain.
+pub type AssetTransactors = (CurrencyTransactor, RegionTransactor);
+
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
/// ready for dispatching a transaction with XCM's `Transact`. There is an `OriginKind` that can
/// bias the kind of local `Origin` it will become.
@@ -205,7 +226,7 @@ pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type RuntimeCall = RuntimeCall;
type XcmSender = XcmRouter;
- type AssetTransactor = CurrencyTransactor;
+ type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
// Coretime chain does not recognize a reserve location for any asset. Users must teleport ROC
// where allowed (e.g. with the Relay Chain).
diff --git a/prdoc/pr_3077.prdoc b/prdoc/pr_3077.prdoc
new file mode 100644
index 000000000000..d82ecffb937f
--- /dev/null
+++ b/prdoc/pr_3077.prdoc
@@ -0,0 +1,13 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Enable cross-chain Coretime region transfers on Rococo Coretime chain
+
+doc:
+ - audience: Runtime User
+ description: |
+ This PR allows Coretime regions to be cross-chain transferred from the Rococo Coretime chain.
+
+crates:
+ - name: pallet-broker
+ - name: coretime-rococo-runtime
diff --git a/substrate/frame/broker/src/nonfungible_impl.rs b/substrate/frame/broker/src/nonfungible_impl.rs
index fe95438cb1af..b2e88bf09a0e 100644
--- a/substrate/frame/broker/src/nonfungible_impl.rs
+++ b/substrate/frame/broker/src/nonfungible_impl.rs
@@ -18,7 +18,7 @@
use super::*;
use frame_support::{
pallet_prelude::{DispatchResult, *},
- traits::nonfungible::{Inspect, Transfer},
+ traits::nonfungible::{Inspect, Mutate, Transfer},
};
use sp_std::vec::Vec;
@@ -50,3 +50,7 @@ impl Transfer for Pallet {
Self::do_transfer((*index).into(), None, dest.clone()).map_err(Into::into)
}
}
+
+// We don't allow any of the mutate operations, so the default implementation is used, which will
+// return `TokenError::Unsupported` in case any of the operations is called.
+impl Mutate for Pallet {}
diff --git a/substrate/frame/broker/src/tests.rs b/substrate/frame/broker/src/tests.rs
index 6aa9ca84fc41..e5efb70ae8d5 100644
--- a/substrate/frame/broker/src/tests.rs
+++ b/substrate/frame/broker/src/tests.rs
@@ -20,11 +20,11 @@
use crate::{core_mask::*, mock::*, *};
use frame_support::{
assert_noop, assert_ok,
- traits::nonfungible::{Inspect as NftInspect, Transfer},
+ traits::nonfungible::{Inspect as NftInspect, Mutate, Transfer},
BoundedVec,
};
use frame_system::RawOrigin::Root;
-use sp_runtime::traits::Get;
+use sp_runtime::{traits::Get, TokenError};
use CoreAssignment::*;
use CoretimeTraceItem::*;
use Finality::*;
@@ -197,6 +197,26 @@ fn transfer_works() {
});
}
+#[test]
+fn mutate_operations_unsupported_for_regions() {
+ TestExt::new().execute_with(|| {
+ let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::complete() };
+ assert_noop!(
+ >::mint_into(®ion_id.into(), &2),
+ TokenError::Unsupported
+ );
+ assert_noop!(>::burn(®ion_id.into(), None), TokenError::Unsupported);
+ assert_noop!(
+ >::set_attribute(®ion_id.into(), &[], &[]),
+ TokenError::Unsupported
+ );
+ assert_noop!(
+ >::set_typed_attribute::(®ion_id.into(), &0, &0),
+ TokenError::Unsupported
+ );
+ });
+}
+
#[test]
fn permanent_is_not_reassignable() {
TestExt::new().endow(1, 1000).execute_with(|| {