shibuya_runtime/
xcm_config.rs

1// This file is part of Astar.
2
3// Copyright (C) Stake Technologies Pte.Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6// Astar is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// Astar is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with Astar. If not, see <http://www.gnu.org/licenses/>.
18
19use super::{
20    AccountId, AllPalletsWithSystem, AssetId, Assets, Balance, Balances, DealWithFees,
21    MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
22    RuntimeOrigin, ShibuyaAssetLocationIdConverter, TreasuryAccountId, XcAssetConfig,
23    XcmWeightToFee, XcmpQueue,
24};
25use crate::weights;
26use frame_support::{
27    parameter_types,
28    traits::{ConstU32, Contains, Everything, Nothing},
29    weights::Weight,
30};
31use frame_system::EnsureRoot;
32use sp_runtime::traits::{Convert, MaybeEquivalence};
33
34// Polkadot imports
35use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
36use frame_support::traits::{Disabled, TransformOrigin};
37use parachains_common::{
38    message_queue::ParaIdToSibling, xcm_config::ParentRelayOrSiblingParachains,
39};
40use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
41use xcm::{latest::prelude::*, v5::ROCOCO_GENESIS_HASH};
42use xcm_builder::{
43    AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowUnpaidExecutionFrom,
44    ConvertedConcreteId, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin,
45    FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter, HashedDescription, IsConcrete,
46    NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
47    SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
48    SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
49    WeightInfoBounds, WithComputedOrigin,
50};
51use xcm_executor::{traits::JustTry, XcmExecutor};
52
53// ORML imports
54use orml_xcm_support::DisabledParachainFee;
55
56// Astar imports
57use astar_primitives::xcm::{
58    AbsoluteAndRelativeReserveProvider, AccountIdToMultiLocation, AllowTopLevelPaidExecutionFrom,
59    FixedRateOfForeignAsset, ReserveAssetFilter, XcmFungibleFeeHandler, MAX_ASSETS,
60};
61
62parameter_types! {
63    pub RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(ROCOCO_GENESIS_HASH));
64    pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
65    pub UniversalLocation: InteriorLocation =
66    [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into();
67    pub const ShibuyaLocation: Location = Here.into_location();
68    pub DummyCheckingAccount: AccountId = PolkadotXcm::check_account();
69}
70
71/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
72/// when determining ownership of accounts for asset transacting and when attempting to use XCM
73/// `Transact` in order to determine the dispatch Origin.
74pub type LocationToAccountId = (
75    // The parent (Relay-chain) origin converts to the default `AccountId`.
76    ParentIsPreset<AccountId>,
77    // Sibling parachain origins convert to AccountId via the `ParaId::into`.
78    SiblingParachainConvertsVia<polkadot_parachain::primitives::Sibling, AccountId>,
79    // Straight up local `AccountId32` origins just alias directly to `AccountId`.
80    AccountId32Aliases<RelayNetwork, AccountId>,
81    // Generates private `AccountId`s from `Location`s, in a stable & safe way.
82    // Replaces the old `Account32Hash` approach.
83    HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
84);
85
86/// Means for transacting the native currency on this chain.
87pub type CurrencyTransactor = FungibleAdapter<
88    // Use this currency:
89    Balances,
90    // Use this currency when it is a fungible asset matching the given location or name:
91    IsConcrete<ShibuyaLocation>,
92    // Convert an XCM Location into a local account id:
93    LocationToAccountId,
94    // Our chain's account ID type (we can't get away without mentioning it explicitly):
95    AccountId,
96    // We don't track any teleports of `Balances`.
97    (),
98>;
99
100/// Means for transacting assets besides the native currency on this chain.
101pub type FungiblesTransactor = FungiblesAdapter<
102    // Use this fungibles implementation:
103    Assets,
104    // Use this currency when it is a fungible asset matching the given location or name:
105    ConvertedConcreteId<AssetId, Balance, ShibuyaAssetLocationIdConverter, JustTry>,
106    // Convert an XCM Location into a local account id:
107    LocationToAccountId,
108    // Our chain's account ID type (we can't get away without mentioning it explicitly):
109    AccountId,
110    // We don't support teleport so no need to check any assets.
111    NoChecking,
112    // We don't support teleport so this is just a dummy account.
113    DummyCheckingAccount,
114>;
115
116/// Means for transacting assets on this chain.
117pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor);
118
119/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
120/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
121/// biases the kind of local `Origin` it will become.
122pub type XcmOriginToTransactDispatchOrigin = (
123    // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
124    // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
125    // foreign chains who want to have a local sovereign account on this chain which they control.
126    SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
127    // Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when
128    // recognised.
129    RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
130    // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
131    // recognised.
132    SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
133    // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
134    // transaction from the Root origin.
135    ParentAsSuperuser<RuntimeOrigin>,
136    // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
137    pallet_xcm::XcmPassthrough<RuntimeOrigin>,
138    // Native signed account converter; this just converts an `AccountId32` origin into a normal
139    // `Origin::Signed` origin of the same 32-byte value.
140    SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
141);
142
143parameter_types! {
144    // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate.
145    // For the PoV size, we estimate 4 kB per instruction. This will be changed when we benchmark the instructions.
146    pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 4 * 1024);
147    pub const MaxInstructions: u32 = 100;
148    pub const MaxAssetsIntoHolding: u32 = MAX_ASSETS as u32;
149}
150
151pub struct ParentOrParentsPlurality;
152impl Contains<Location> for ParentOrParentsPlurality {
153    fn contains(location: &Location) -> bool {
154        matches!(location.unpack(), (1, []) | (1, [Plurality { .. }]))
155    }
156}
157
158pub type XcmBarrier = TrailingSetTopicAsId<(
159    TakeWeightCredit,
160    // Expected responses are OK.
161    AllowKnownQueryResponses<PolkadotXcm>,
162    // Allow XCMs with some computed origins to pass through.
163    WithComputedOrigin<
164        (
165            // If the message is one that immediately attempts to pay for execution, then allow it.
166            AllowTopLevelPaidExecutionFrom<Everything>,
167            // Subscriptions for version tracking are OK.
168            AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
169        ),
170        UniversalLocation,
171        ConstU32<8>,
172    >,
173    // Parent and its plurality get free execution
174    AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
175)>;
176
177// Used to handle XCM fee deposit into treasury account
178pub type ShibuyaXcmFungibleFeeHandler = XcmFungibleFeeHandler<
179    AccountId,
180    ConvertedConcreteId<AssetId, Balance, ShibuyaAssetLocationIdConverter, JustTry>,
181    Assets,
182    TreasuryAccountId,
183>;
184
185pub type Weigher =
186    WeightInfoBounds<weights::xcm::XcmWeight<Runtime, RuntimeCall>, RuntimeCall, MaxInstructions>;
187
188pub struct XcmConfig;
189impl xcm_executor::Config for XcmConfig {
190    type RuntimeCall = RuntimeCall;
191    type XcmSender = XcmRouter;
192    type AssetTransactor = AssetTransactors;
193    type OriginConverter = XcmOriginToTransactDispatchOrigin;
194    type IsReserve = ReserveAssetFilter;
195    type IsTeleporter = ();
196    type UniversalLocation = UniversalLocation;
197    type Barrier = XcmBarrier;
198    type Weigher = Weigher;
199    type Trader = (
200        UsingComponents<XcmWeightToFee, ShibuyaLocation, AccountId, Balances, DealWithFees>,
201        FixedRateOfForeignAsset<XcAssetConfig, ShibuyaXcmFungibleFeeHandler>,
202    );
203    type ResponseHandler = PolkadotXcm;
204    type AssetTrap = PolkadotXcm;
205    type AssetClaims = PolkadotXcm;
206    type SubscriptionService = PolkadotXcm;
207
208    type PalletInstancesInfo = AllPalletsWithSystem;
209    type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
210    type AssetLocker = ();
211    type AssetExchanger = ();
212    type FeeManager = ();
213    type MessageExporter = ();
214    type UniversalAliases = Nothing;
215    type CallDispatcher = RuntimeCall;
216    type SafeCallFilter = Everything;
217    type Aliasers = Nothing;
218    type TransactionalProcessor = FrameTransactionalProcessor;
219
220    type HrmpNewChannelOpenRequestHandler = ();
221    type HrmpChannelAcceptedHandler = ();
222    type HrmpChannelClosingHandler = ();
223    type XcmRecorder = PolkadotXcm;
224    type XcmEventEmitter = PolkadotXcm;
225}
226
227/// Local origins on this chain are allowed to dispatch XCM sends/executions.
228pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
229
230/// The means for routing XCM messages which are not for local execution into the right message
231/// queues.
232pub type XcmRouter = (
233    // Two routers - use UMP to communicate with the relay chain:
234    cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, ()>,
235    // ..and XCMP to communicate with the sibling chains.
236    XcmpQueue,
237);
238
239impl pallet_xcm::Config for Runtime {
240    const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
241
242    type RuntimeEvent = RuntimeEvent;
243    type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
244    type XcmRouter = XcmRouter;
245    type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
246    type XcmExecuteFilter = Nothing;
247    type XcmExecutor = XcmExecutor<XcmConfig>;
248    type XcmTeleportFilter = Nothing;
249    type XcmReserveTransferFilter = Everything;
250    type Weigher = Weigher;
251    type UniversalLocation = UniversalLocation;
252    type RuntimeOrigin = RuntimeOrigin;
253    type RuntimeCall = RuntimeCall;
254    type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
255    type Currency = Balances;
256    type CurrencyMatcher = ();
257    type TrustedLockers = ();
258    type SovereignAccountOf = LocationToAccountId;
259    type MaxLockers = ConstU32<0>;
260    type WeightInfo = weights::pallet_xcm::SubstrateWeight<Runtime>;
261    type MaxRemoteLockConsumers = ConstU32<0>;
262    type RemoteLockConsumerIdentifier = ();
263    type AdminOrigin = EnsureRoot<AccountId>;
264    type AuthorizedAliasConsideration = Disabled;
265}
266
267impl cumulus_pallet_xcm::Config for Runtime {
268    type RuntimeEvent = RuntimeEvent;
269    type XcmExecutor = XcmExecutor<XcmConfig>;
270}
271
272impl cumulus_pallet_xcmp_queue::Config for Runtime {
273    type RuntimeEvent = RuntimeEvent;
274    type ChannelInfo = ParachainSystem;
275    type VersionWrapper = PolkadotXcm;
276    type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
277    type MaxInboundSuspended = ConstU32<1_000>;
278    type MaxActiveOutboundChannels = ConstU32<128>;
279    type MaxPageSize = ConstU32<{ 128 * 1024 }>;
280    type ControllerOrigin = EnsureRoot<AccountId>;
281    type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
282    type PriceForSiblingDelivery = NoPriceForMessageDelivery<ParaId>;
283    type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight<Runtime>;
284}
285
286parameter_types! {
287    /// The absolute location in perspective of the whole network.
288    pub ShibuyaLocationAbsolute: Location = Location {
289        parents: 1,
290        interior: Parachain(ParachainInfo::parachain_id().into()).into()
291
292    };
293    /// Max asset types for one cross-chain transfer. `2` covers all current use cases.
294    /// Can be updated with extra test cases in the future if needed.
295    pub const MaxAssetsForTransfer: usize = 2;
296}
297
298/// Convert `AssetId` to optional `Location`. The impl is a wrapper
299/// on `ShibuyaAssetLocationIdConverter`.
300pub struct AssetIdConvert;
301impl Convert<AssetId, Option<Location>> for AssetIdConvert {
302    fn convert(asset_id: AssetId) -> Option<Location> {
303        ShibuyaAssetLocationIdConverter::convert_back(&asset_id)
304    }
305}
306
307impl orml_xtokens::Config for Runtime {
308    type Balance = Balance;
309    type CurrencyId = AssetId;
310    type CurrencyIdConvert = AssetIdConvert;
311    type AccountIdToLocation = AccountIdToMultiLocation;
312    type SelfLocation = ShibuyaLocation;
313    type XcmExecutor = XcmExecutor<XcmConfig>;
314    type Weigher = Weigher;
315    type BaseXcmWeight = UnitWeightCost;
316    type UniversalLocation = UniversalLocation;
317    type MaxAssetsForTransfer = MaxAssetsForTransfer;
318    // Default impl. Refer to `orml-xtokens` docs for more details.
319    type MinXcmFee = DisabledParachainFee;
320    type LocationsFilter = Everything;
321    type ReserveProvider = AbsoluteAndRelativeReserveProvider<ShibuyaLocationAbsolute>;
322    type RateLimiter = ();
323    type RateLimiterId = ();
324}