Enable cross-chain Coretime region transfers (#3077)

This PR allows Coretime regions to be transferable via XCM.

---------

Co-authored-by: Dónal Murray <donal.murray@parity.io>
This commit is contained in:
Sergej Sakac
2024-01-27 13:06:38 +01:00
committed by GitHub
parent 5e5341da9b
commit 30b30bee59
4 changed files with 68 additions and 10 deletions
@@ -15,11 +15,12 @@
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>. // along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
use super::{ use super::{
AccountId, AllPalletsWithSystem, Balances, BaseDeliveryFee, FeeAssetId, ParachainInfo, AccountId, AllPalletsWithSystem, Balances, BaseDeliveryFee, Broker, FeeAssetId, ParachainInfo,
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TransactionByteFee, WeightToFee, XcmpQueue, TransactionByteFee, WeightToFee, XcmpQueue,
}; };
use frame_support::{ use frame_support::{
pallet_prelude::PalletInfoAccess,
parameter_types, parameter_types,
traits::{ConstU32, Contains, Equals, Everything, Nothing}, traits::{ConstU32, Contains, Equals, Everything, Nothing},
}; };
@@ -42,11 +43,12 @@ use xcm_builder::CurrencyAdapter;
use xcm_builder::{ use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain,
DenyThenTry, EnsureXcmOrigin, FrameTransactionalProcessor, IsConcrete, ParentAsSuperuser, DenyThenTry, EnsureXcmOrigin, FrameTransactionalProcessor, IsConcrete, NonFungibleAdapter,
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
XcmFeeManagerFromComponents, XcmFeeToAccount, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
XcmFeeToAccount,
}; };
use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; use xcm_executor::{traits::WithOriginFilter, XcmExecutor};
@@ -56,6 +58,8 @@ parameter_types! {
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorLocation = pub UniversalLocation: InteriorLocation =
[GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into();
pub BrokerPalletLocation: Location =
PalletInstance(<Broker as PalletInfoAccess>::index() as u8).into();
pub const MaxInstructions: u32 = 100; pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64; pub const MaxAssetsIntoHolding: u32 = 64;
pub const GovernanceLocation: Location = Location::parent(); 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<BrokerPalletLocation>,
// 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, /// 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 /// ready for dispatching a transaction with XCM's `Transact`. There is an `OriginKind` that can
/// bias the kind of local `Origin` it will become. /// bias the kind of local `Origin` it will become.
@@ -205,7 +226,7 @@ pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig { impl xcm_executor::Config for XcmConfig {
type RuntimeCall = RuntimeCall; type RuntimeCall = RuntimeCall;
type XcmSender = XcmRouter; type XcmSender = XcmRouter;
type AssetTransactor = CurrencyTransactor; type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin; type OriginConverter = XcmOriginToTransactDispatchOrigin;
// Coretime chain does not recognize a reserve location for any asset. Users must teleport ROC // Coretime chain does not recognize a reserve location for any asset. Users must teleport ROC
// where allowed (e.g. with the Relay Chain). // where allowed (e.g. with the Relay Chain).
+13
View File
@@ -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
@@ -18,7 +18,7 @@
use super::*; use super::*;
use frame_support::{ use frame_support::{
pallet_prelude::{DispatchResult, *}, pallet_prelude::{DispatchResult, *},
traits::nonfungible::{Inspect, Transfer}, traits::nonfungible::{Inspect, Mutate, Transfer},
}; };
use sp_std::vec::Vec; use sp_std::vec::Vec;
@@ -50,3 +50,7 @@ impl<T: Config> Transfer<T::AccountId> for Pallet<T> {
Self::do_transfer((*index).into(), None, dest.clone()).map_err(Into::into) 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<T: Config> Mutate<T::AccountId> for Pallet<T> {}
+22 -2
View File
@@ -20,11 +20,11 @@
use crate::{core_mask::*, mock::*, *}; use crate::{core_mask::*, mock::*, *};
use frame_support::{ use frame_support::{
assert_noop, assert_ok, assert_noop, assert_ok,
traits::nonfungible::{Inspect as NftInspect, Transfer}, traits::nonfungible::{Inspect as NftInspect, Mutate, Transfer},
BoundedVec, BoundedVec,
}; };
use frame_system::RawOrigin::Root; use frame_system::RawOrigin::Root;
use sp_runtime::traits::Get; use sp_runtime::{traits::Get, TokenError};
use CoreAssignment::*; use CoreAssignment::*;
use CoretimeTraceItem::*; use CoretimeTraceItem::*;
use Finality::*; 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!(
<Broker as Mutate<_>>::mint_into(&region_id.into(), &2),
TokenError::Unsupported
);
assert_noop!(<Broker as Mutate<_>>::burn(&region_id.into(), None), TokenError::Unsupported);
assert_noop!(
<Broker as Mutate<_>>::set_attribute(&region_id.into(), &[], &[]),
TokenError::Unsupported
);
assert_noop!(
<Broker as Mutate<_>>::set_typed_attribute::<u8, u8>(&region_id.into(), &0, &0),
TokenError::Unsupported
);
});
}
#[test] #[test]
fn permanent_is_not_reassignable() { fn permanent_is_not_reassignable() {
TestExt::new().endow(1, 1000).execute_with(|| { TestExt::new().endow(1, 1000).execute_with(|| {