1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
#[cfg(feature = "runtime-benchmarks")]
18
use crate::{CollatorAssignment, Session, System};
19
#[cfg(feature = "runtime-benchmarks")]
20
use pallet_session::ShouldEndSession;
21
#[cfg(feature = "runtime-benchmarks")]
22
use sp_std::{collections::btree_map::BTreeMap, vec};
23
#[cfg(feature = "runtime-benchmarks")]
24
use tp_traits::GetContainerChainAuthor;
25
use xcm::latest::WESTEND_GENESIS_HASH;
26
use {
27
    super::{
28
        currency::MICRODANCE, weights::xcm::XcmWeight as XcmGenericWeights, AccountId,
29
        AllPalletsWithSystem, AssetRate, Balance, Balances, BlockNumber, ForeignAssets,
30
        ForeignAssetsCreator, MaintenanceMode, MessageQueue, ParachainInfo, ParachainSystem,
31
        PolkadotXcm, Registrar, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent,
32
        RuntimeOrigin, TransactionByteFee, WeightToFee, XcmpQueue,
33
    },
34
    crate::{get_para_id_authorities, weights, AuthorNoting},
35
    cumulus_primitives_core::{AggregateMessageOrigin, ParaId},
36
    frame_support::{
37
        parameter_types,
38
        traits::{Disabled, Equals, Everything, Nothing, PalletInfoAccess, TransformOrigin},
39
        weights::Weight,
40
    },
41
    frame_system::{pallet_prelude::BlockNumberFor, EnsureRoot},
42
    nimbus_primitives::NimbusId,
43
    pallet_xcm::XcmPassthrough,
44
    pallet_xcm_core_buyer::{
45
        CheckCollatorValidity, GetParathreadMaxCorePrice, GetParathreadParams, GetPurchaseCoreCall,
46
        ParaIdIntoAccountTruncating, XCMNotifier,
47
    },
48
    parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling},
49
    parity_scale_codec::{Decode, DecodeWithMemTracking, Encode},
50
    polkadot_runtime_common::xcm_sender::ExponentialPrice,
51
    scale_info::TypeInfo,
52
    sp_consensus_slots::Slot,
53
    sp_core::{ConstU32, MaxEncodedLen},
54
    sp_runtime::{transaction_validity::TransactionPriority, Perbill},
55
    sp_std::vec::Vec,
56
    tp_traits::ParathreadParams,
57
    tp_xcm_commons::NativeAssetReserve,
58
    xcm::latest::prelude::*,
59
    xcm_builder::{
60
        AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
61
        AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, FungibleAdapter,
62
        FungiblesAdapter, IsConcrete, NoChecking, ParentIsPreset, RelayChainAsNative,
63
        SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
64
        SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
65
        UsingComponents, WeightInfoBounds, WithComputedOrigin, XcmFeeManagerFromComponents,
66
    },
67
    xcm_executor::{traits::JustTry, XcmExecutor},
68
};
69

            
70
parameter_types! {
71
    // Self Reserve location, defines the multilocation identifiying the self-reserve currency
72
    // This is used to match it also against our Balances pallet when we receive such
73
    // a Location: (Self Balances pallet index)
74
    // We use the RELATIVE multilocation
75
    pub SelfReserve: Location = Location {
76
        parents: 0,
77
        interior: [
78
            PalletInstance(<Balances as PalletInfoAccess>::index() as u8)
79
        ].into()
80
    };
81

            
82
    // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate.
83
    pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
84

            
85
    // TODO: revisit
86
    pub const RelayNetwork: NetworkId = NetworkId::ByGenesis(WESTEND_GENESIS_HASH);
87

            
88
    // The relay chain Origin type
89
    pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
90

            
91
    pub const MaxAssetsIntoHolding: u32 = 64;
92

            
93
    /// Maximum number of instructions in a single XCM fragment. A sanity check against
94
    /// weight caculations getting too crazy.
95
    pub MaxInstructions: u32 = 100;
96

            
97
    // The universal location within the global consensus system
98
    pub UniversalLocation: InteriorLocation =
99
    [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into();
100

            
101
    pub const BaseDeliveryFee: u128 = 100 * MICRODANCE;
102
    pub RootLocation: Location = Location::here();
103
}
104

            
105
#[cfg(feature = "runtime-benchmarks")]
106
parameter_types! {
107
    pub ReachableDest: Option<Location> = Some(Parent.into());
108
}
109

            
110
pub type XcmBarrier = (
111
    // Weight that is paid for may be consumed.
112
    TakeWeightCredit,
113
    // Expected responses are OK.
114
    TrailingSetTopicAsId<AllowKnownQueryResponses<PolkadotXcm>>,
115
    WithComputedOrigin<
116
        (
117
            // If the message is one that immediately attemps to pay for execution, then allow it.
118
            AllowTopLevelPaidExecutionFrom<Everything>,
119
            // Subscriptions for version tracking are OK.
120
            AllowSubscriptionsFrom<Everything>,
121
        ),
122
        UniversalLocation,
123
        ConstU32<8>,
124
    >,
125
);
126

            
127
/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
128
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
129
/// `Transact` in order to determine the dispatch Origin.
130
pub type LocationToAccountId = (
131
    // The parent (Relay-chain) origin converts to the default `AccountId`.
132
    ParentIsPreset<AccountId>,
133
    // Sibling parachain origins convert to AccountId via the `ParaId::into`.
134
    SiblingParachainConvertsVia<polkadot_parachain_primitives::primitives::Sibling, AccountId>,
135
    // If we receive a Location of type AccountKey20, just generate a native account
136
    AccountId32Aliases<RelayNetwork, AccountId>,
137
    // Generate remote accounts according to polkadot standards
138
    xcm_builder::HashedDescription<
139
        AccountId,
140
        xcm_builder::DescribeFamily<xcm_builder::DescribeAllTerminal>,
141
    >,
142
);
143

            
144
/// Local origins on this chain are allowed to dispatch XCM sends/executions.
145
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
146

            
147
/// Means for transacting the native currency on this chain.
148
pub type CurrencyTransactor = FungibleAdapter<
149
    // Use this currency:
150
    Balances,
151
    // Use this currency when it is a fungible asset matching the given location or name:
152
    IsConcrete<SelfReserve>,
153
    // Convert an XCM Location into a local account id:
154
    LocationToAccountId,
155
    // Our chain's account ID type (we can't get away without mentioning it explicitly):
156
    AccountId,
157
    // We don't track any teleports of `Balances`.
158
    (),
159
>;
160

            
161
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
162
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
163
/// biases the kind of local `Origin` it will become.
164
pub type XcmOriginToTransactDispatchOrigin = (
165
    // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
166
    // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
167
    // foreign chains who want to have a local sovereign account on this chain which they control.
168
    SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
169
    // Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when
170
    // recognised.
171
    RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
172
    // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
173
    // recognised.
174
    SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
175
    // Native signed account converter; this just converts an `AccountId32` origin into a normal
176
    // `RuntimeOrigin::Signed` origin of the same 32-byte value.
177
    SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
178
    // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
179
    XcmPassthrough<RuntimeOrigin>,
180
);
181

            
182
/// Means for transacting assets on this chain.
183
pub type AssetTransactors = (CurrencyTransactor, ForeignFungiblesTransactor);
184
pub type XcmWeigher =
185
    WeightInfoBounds<XcmGenericWeights<RuntimeCall>, RuntimeCall, MaxInstructions>;
186

            
187
/// The means for routing XCM messages which are not for local execution into the right message
188
/// queues.
189
pub type XcmRouter = (
190
    // Two routers - use UMP to communicate with the relay chain:
191
    cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, PriceForParentDelivery>,
192
    // ..and XCMP to communicate with the sibling chains.
193
    XcmpQueue,
194
);
195

            
196
pub struct XcmConfig;
197
impl xcm_executor::Config for XcmConfig {
198
    type RuntimeCall = RuntimeCall;
199
    type XcmSender = XcmRouter;
200
    type AssetTransactor = AssetTransactors;
201
    type OriginConverter = XcmOriginToTransactDispatchOrigin;
202
    type IsReserve = NativeAssetReserve;
203
    type IsTeleporter = ();
204
    type UniversalLocation = UniversalLocation;
205
    type Barrier = XcmBarrier;
206
    type Weigher = XcmWeigher;
207
    // Local token trader only
208
    // TODO: update once we have a way to do fees
209
    type Trader = (
210
        UsingComponents<WeightToFee, SelfReserve, AccountId, Balances, ()>,
211
        cumulus_primitives_utility::TakeFirstAssetTrader<
212
            AccountId,
213
            AssetRateAsMultiplier,
214
            // Use this currency when it is a fungible asset matching the given location or name:
215
            (ConvertedConcreteId<AssetId, Balance, ForeignAssetsCreator, JustTry>,),
216
            ForeignAssets,
217
            (),
218
        >,
219
    );
220
    type ResponseHandler = PolkadotXcm;
221
    type AssetTrap = PolkadotXcm;
222
    type AssetClaims = PolkadotXcm;
223
    type SubscriptionService = PolkadotXcm;
224
    type PalletInstancesInfo = AllPalletsWithSystem;
225
    type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
226
    type AssetLocker = ();
227
    type AssetExchanger = ();
228
    type FeeManager = XcmFeeManagerFromComponents<Equals<RootLocation>, ()>;
229
    type MessageExporter = ();
230
    type UniversalAliases = Nothing;
231
    type CallDispatcher = RuntimeCall;
232
    type SafeCallFilter = Everything;
233
    type Aliasers = Nothing;
234
    type TransactionalProcessor = xcm_builder::FrameTransactionalProcessor;
235
    type HrmpNewChannelOpenRequestHandler = ();
236
    type HrmpChannelAcceptedHandler = ();
237
    type HrmpChannelClosingHandler = ();
238
    type XcmRecorder = ();
239
    type XcmEventEmitter = PolkadotXcm;
240
}
241

            
242
impl pallet_xcm::Config for Runtime {
243
    type RuntimeEvent = RuntimeEvent;
244
    type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
245
    type XcmRouter = XcmRouter;
246
    type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
247
    type XcmExecuteFilter = Everything;
248
    type XcmExecutor = XcmExecutor<XcmConfig>;
249
    type XcmTeleportFilter = Nothing;
250
    type XcmReserveTransferFilter = Everything;
251
    type Weigher = XcmWeigher;
252
    type UniversalLocation = UniversalLocation;
253
    type RuntimeOrigin = RuntimeOrigin;
254
    type RuntimeCall = RuntimeCall;
255
    const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
256
    type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
257
    type Currency = Balances;
258
    type CurrencyMatcher = ();
259
    type TrustedLockers = ();
260
    type SovereignAccountOf = LocationToAccountId;
261
    type MaxLockers = ConstU32<8>;
262
    type MaxRemoteLockConsumers = ConstU32<0>;
263
    type RemoteLockConsumerIdentifier = ();
264
    // TODO pallet-xcm weights
265
    type WeightInfo = weights::pallet_xcm::SubstrateWeight<Runtime>;
266
    type AdminOrigin = EnsureRoot<AccountId>;
267
    type AuthorizedAliasConsideration = Disabled;
268
}
269

            
270
pub type PriceForSiblingParachainDelivery =
271
    ExponentialPrice<SelfReserve, BaseDeliveryFee, TransactionByteFee, XcmpQueue>;
272

            
273
pub type PriceForParentDelivery =
274
    ExponentialPrice<SelfReserve, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
275

            
276
impl cumulus_pallet_xcmp_queue::Config for Runtime {
277
    type RuntimeEvent = RuntimeEvent;
278
    type ChannelInfo = ParachainSystem;
279
    type VersionWrapper = PolkadotXcm;
280
    type ControllerOrigin = EnsureRoot<AccountId>;
281
    type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
282
    type WeightInfo = weights::cumulus_pallet_xcmp_queue::SubstrateWeight<Runtime>;
283
    type PriceForSiblingDelivery = PriceForSiblingParachainDelivery;
284
    // Enqueue XCMP messages from siblings for later processing.
285
    type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
286
    type MaxInboundSuspended = sp_core::ConstU32<1_000>;
287
    type MaxActiveOutboundChannels = ConstU32<128>;
288
    type MaxPageSize = ConstU32<{ 103 * 1024 }>;
289
}
290

            
291
impl cumulus_pallet_xcm::Config for Runtime {
292
    type RuntimeEvent = RuntimeEvent;
293
    type XcmExecutor = XcmExecutor<XcmConfig>;
294
}
295

            
296
parameter_types! {
297
    // we just reuse the same deposits
298
    pub const ForeignAssetsAssetDeposit: Balance = 0;
299
    pub const ForeignAssetsAssetAccountDeposit: Balance = 0;
300
    pub const ForeignAssetsApprovalDeposit: Balance = 0;
301
    pub const ForeignAssetsAssetsStringLimit: u32 = 50;
302
    pub const ForeignAssetsMetadataDepositBase: Balance = 0;
303
    pub const ForeignAssetsMetadataDepositPerByte: Balance = 0;
304
    pub CheckingAccount: AccountId = PolkadotXcm::check_account();
305
}
306

            
307
#[cfg(feature = "runtime-benchmarks")]
308
/// Simple conversion of `u32` into an `AssetId` for use in benchmarking.
309
pub struct ForeignAssetBenchmarkHelper;
310
#[cfg(feature = "runtime-benchmarks")]
311
impl pallet_assets::BenchmarkHelper<AssetId> for ForeignAssetBenchmarkHelper {
312
    fn create_asset_id_parameter(id: u32) -> AssetId {
313
        id.try_into()
314
            .expect("number too large to create benchmarks")
315
    }
316
}
317
#[cfg(feature = "runtime-benchmarks")]
318
impl pallet_asset_rate::AssetKindFactory<AssetId> for ForeignAssetBenchmarkHelper {
319
    fn create_asset_kind(id: u32) -> AssetId {
320
        id.try_into()
321
            .expect("number too large to create benchmarks")
322
    }
323
}
324

            
325
pub type AssetId = u16;
326
pub type ForeignAssetsInstance = pallet_assets::Instance1;
327
impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
328
    type RuntimeEvent = RuntimeEvent;
329
    type Balance = Balance;
330
    type AssetId = AssetId;
331
    type AssetIdParameter = AssetId;
332
    type Currency = Balances;
333
    type CreateOrigin = frame_support::traits::NeverEnsureOrigin<AccountId>;
334
    type ForceOrigin = EnsureRoot<AccountId>;
335
    type AssetDeposit = ForeignAssetsAssetDeposit;
336
    type MetadataDepositBase = ForeignAssetsMetadataDepositBase;
337
    type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte;
338
    type ApprovalDeposit = ForeignAssetsApprovalDeposit;
339
    type StringLimit = ForeignAssetsAssetsStringLimit;
340
    type Freezer = ();
341
    type Extra = ();
342
    type WeightInfo = weights::pallet_assets::SubstrateWeight<Runtime>;
343
    type CallbackHandle = ();
344
    type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit;
345
    type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
346
    type Holder = ();
347
    #[cfg(feature = "runtime-benchmarks")]
348
    type BenchmarkHelper = ForeignAssetBenchmarkHelper;
349
}
350

            
351
impl pallet_foreign_asset_creator::Config for Runtime {
352
    type RuntimeEvent = RuntimeEvent;
353
    type ForeignAsset = Location;
354
    type ForeignAssetCreatorOrigin = EnsureRoot<AccountId>;
355
    type ForeignAssetModifierOrigin = EnsureRoot<AccountId>;
356
    type ForeignAssetDestroyerOrigin = EnsureRoot<AccountId>;
357
    type Fungibles = ForeignAssets;
358
    type WeightInfo = weights::pallet_foreign_asset_creator::SubstrateWeight<Runtime>;
359
    type OnForeignAssetCreated = ();
360
    type OnForeignAssetDestroyed = ();
361
}
362

            
363
impl pallet_asset_rate::Config for Runtime {
364
    type CreateOrigin = EnsureRoot<AccountId>;
365
    type RemoveOrigin = EnsureRoot<AccountId>;
366
    type UpdateOrigin = EnsureRoot<AccountId>;
367
    type Currency = Balances;
368
    type AssetKind = AssetId;
369
    type RuntimeEvent = RuntimeEvent;
370
    type WeightInfo = weights::pallet_asset_rate::SubstrateWeight<Runtime>;
371
    #[cfg(feature = "runtime-benchmarks")]
372
    type BenchmarkHelper = ForeignAssetBenchmarkHelper;
373
}
374

            
375
/// Means for transacting foreign assets from different global consensus.
376
pub type ForeignFungiblesTransactor = FungiblesAdapter<
377
    // Use this fungibles implementation:
378
    ForeignAssets,
379
    // Use this currency when it is a fungible asset matching the given location or name:
380
    (ConvertedConcreteId<AssetId, Balance, ForeignAssetsCreator, JustTry>,),
381
    // Convert an XCM Location into a local account id:
382
    LocationToAccountId,
383
    // Our chain's account ID type (we can't get away without mentioning it explicitly):
384
    AccountId,
385
    // We dont need to check teleports here.
386
    NoChecking,
387
    // The account to use for tracking teleports.
388
    CheckingAccount,
389
>;
390

            
391
/// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance.
392
pub type AssetRateAsMultiplier =
393
    parachains_common::xcm_config::AssetFeeAsExistentialDepositMultiplier<
394
        Runtime,
395
        WeightToFee,
396
        AssetRate,
397
        ForeignAssetsInstance,
398
    >;
399

            
400
parameter_types! {
401
    pub MessageQueueServiceWeight: Weight = Perbill::from_percent(25) * RuntimeBlockWeights::get().max_block;
402
}
403

            
404
impl pallet_message_queue::Config for Runtime {
405
    type RuntimeEvent = RuntimeEvent;
406
    type WeightInfo = weights::pallet_message_queue::SubstrateWeight<Runtime>;
407
    #[cfg(feature = "runtime-benchmarks")]
408
    type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor<
409
        cumulus_primitives_core::AggregateMessageOrigin,
410
    >;
411
    #[cfg(not(feature = "runtime-benchmarks"))]
412
    type MessageProcessor =
413
        xcm_builder::ProcessXcmMessage<AggregateMessageOrigin, XcmExecutor<XcmConfig>, RuntimeCall>;
414
    type Size = u32;
415
    // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
416
    type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
417
    // NarrowOriginToSibling calls XcmpQueue's is_pause if Origin is sibling. Allows all other origins
418
    type QueuePausedQuery = (MaintenanceMode, NarrowOriginToSibling<XcmpQueue>);
419
    // TODO verify values
420
    type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>;
421
    type MaxStale = sp_core::ConstU32<8>;
422
    type ServiceWeight = MessageQueueServiceWeight;
423
    type IdleMaxServiceWeight = MessageQueueServiceWeight;
424
}
425

            
426
parameter_types! {
427
    pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::MAX;
428
    pub const XcmBuyExecutionDotRococo: u128 = XCM_BUY_EXECUTION_COST_ROCOCO;
429
}
430

            
431
pub const XCM_BUY_EXECUTION_COST_ROCOCO: u128 = 70_000_000 + 126_666_399;
432

            
433
pub struct XCMNotifierImpl;
434

            
435
impl XCMNotifier<Runtime> for XCMNotifierImpl {
436
24
    fn new_notify_query(
437
24
        responder: impl Into<Location>,
438
24
        notify: impl Into<RuntimeCall>,
439
24
        timeout: BlockNumberFor<Runtime>,
440
24
        match_querier: impl Into<Location>,
441
24
    ) -> u64 {
442
24
        pallet_xcm::Pallet::<Runtime>::new_notify_query(responder, notify, timeout, match_querier)
443
24
    }
444
}
445

            
446
parameter_types! {
447
    // TODO: used to be 100 but TS tests failed if we set it to 100, previously it used AdditionalTtlForInflightOrders with value 5
448
    pub const CoreBuyingXCMQueryTtl: BlockNumber = 5;
449
    pub const AdditionalTtlForInflightOrders: BlockNumber = 5;
450
    pub const PendingBlockTtl: BlockNumber = 10;
451
    pub BuyCoreSlotDrift: Slot = Slot::from(5u64);
452
}
453

            
454
impl pallet_xcm_core_buyer::Config for Runtime {
455
    type RuntimeEvent = RuntimeEvent;
456
    type Currency = Balances;
457

            
458
    type XcmSender = XcmRouter;
459
    type GetPurchaseCoreCall = EncodedCallToBuyCore;
460
    type GetParathreadAccountId = ParaIdIntoAccountTruncating;
461
    type GetParathreadMaxCorePrice = GetMaxCorePriceFromServicesPayment;
462
    type SelfParaId = parachain_info::Pallet<Runtime>;
463
    type RelayChain = RelayChain;
464
    type GetParathreadParams = GetParathreadParamsImpl;
465
    type CheckCollatorValidity = CheckCollatorValidityImpl;
466
    type UnsignedPriority = ParasUnsignedPriority;
467
    type PendingBlocksTtl = PendingBlockTtl;
468
    type CoreBuyingXCMQueryTtl = CoreBuyingXCMQueryTtl;
469
    type AdditionalTtlForInflightOrders = AdditionalTtlForInflightOrders;
470
    type BuyCoreSlotDrift = BuyCoreSlotDrift;
471
    type UniversalLocation = UniversalLocation;
472
    type RuntimeOrigin = RuntimeOrigin;
473
    type RuntimeCall = RuntimeCall;
474
    type XCMNotifier = XCMNotifierImpl;
475
    type LatestAuthorInfoFetcher = AuthorNoting;
476
    type SlotBeacon = dp_consensus::AuraDigestSlotBeacon<Runtime>;
477
    type CollatorPublicKey = NimbusId;
478
    type WeightInfo = weights::pallet_xcm_core_buyer::SubstrateWeight<Runtime>;
479
}
480

            
481
pub struct GetParathreadParamsImpl;
482

            
483
impl GetParathreadParams for GetParathreadParamsImpl {
484
96
    fn get_parathread_params(para_id: ParaId) -> Option<ParathreadParams> {
485
96
        Registrar::parathread_params(para_id)
486
96
    }
487

            
488
    #[cfg(feature = "runtime-benchmarks")]
489
    fn set_parathread_params(para_id: ParaId, parathread_params: Option<ParathreadParams>) {
490
        if let Some(parathread_params) = parathread_params {
491
            pallet_registrar::ParathreadParams::<Runtime>::insert(para_id, parathread_params);
492
        } else {
493
            pallet_registrar::ParathreadParams::<Runtime>::remove(para_id);
494
        }
495
    }
496
}
497

            
498
pub struct CheckCollatorValidityImpl;
499

            
500
impl CheckCollatorValidity<AccountId, NimbusId> for CheckCollatorValidityImpl {
501
66
    fn is_valid_collator(para_id: ParaId, public_key: NimbusId) -> bool {
502
66
        let maybe_public_keys = get_para_id_authorities(para_id);
503
66
        maybe_public_keys.is_some_and(|public_keys| public_keys.contains(&public_key))
504
66
    }
505

            
506
    #[cfg(feature = "runtime-benchmarks")]
507
    fn set_valid_collator(para_id: ParaId, account_id: AccountId, public_key: NimbusId) {
508
        let parent_number = System::block_number();
509
        let should_end_session =
510
            <Runtime as pallet_session::Config>::ShouldEndSession::should_end_session(
511
                parent_number + 1,
512
            );
513

            
514
        let session_index = if should_end_session {
515
            Session::current_index() + 1
516
        } else {
517
            Session::current_index()
518
        };
519

            
520
        pallet_authority_mapping::AuthorityIdMapping::<Runtime>::insert(
521
            session_index,
522
            BTreeMap::from_iter([(public_key, account_id.clone())]),
523
        );
524

            
525
        CollatorAssignment::set_authors_for_para_id(para_id, vec![account_id]);
526
    }
527
}
528

            
529
/// Relay chains supported by pallet_xcm_core_buyer, each relay chain has different
530
/// pallet indices for pallet_on_demand_assignment_provider
531
#[derive(
532
    Debug,
533
    Default,
534
    Clone,
535
    PartialEq,
536
    Eq,
537
    Encode,
538
    Decode,
539
1236
    TypeInfo,
540
    MaxEncodedLen,
541
    DecodeWithMemTracking,
542
)]
543
pub enum RelayChain {
544
    #[default]
545
    Westend,
546
12
    Rococo,
547
}
548

            
549
pub struct EncodedCallToBuyCore;
550

            
551
impl GetPurchaseCoreCall<RelayChain> for EncodedCallToBuyCore {
552
96
    fn get_encoded(relay_chain: RelayChain, max_amount: u128, para_id: ParaId) -> Vec<u8> {
553
96
        match relay_chain {
554
            RelayChain::Westend => {
555
12
                let call = tanssi_relay_encoder::westend::RelayCall::OnDemandAssignmentProvider(
556
12
                    tanssi_relay_encoder::westend::OnDemandAssignmentProviderCall::PlaceOrderAllowDeath {
557
12
                        max_amount,
558
12
                        para_id,
559
12
                    },
560
12
                );
561
12

            
562
12
                call.encode()
563
            }
564
            RelayChain::Rococo => {
565
84
                let call = tanssi_relay_encoder::rococo::RelayCall::OnDemandAssignmentProvider(
566
84
                    tanssi_relay_encoder::rococo::OnDemandAssignmentProviderCall::PlaceOrderAllowDeath {
567
84
                        max_amount,
568
84
                        para_id,
569
84
                    },
570
84
                );
571
84

            
572
84
                call.encode()
573
            }
574
        }
575
96
    }
576
}
577

            
578
pub struct GetMaxCorePriceFromServicesPayment;
579

            
580
impl GetParathreadMaxCorePrice for GetMaxCorePriceFromServicesPayment {
581
96
    fn get_max_core_price(para_id: ParaId) -> Option<u128> {
582
96
        pallet_services_payment::MaxCorePrice::<Runtime>::get(para_id)
583
96
    }
584
}