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_attr(not(feature = "std"), no_std)]
18
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
19
#![recursion_limit = "256"]
20

            
21
extern crate alloc;
22

            
23
// Make the WASM binary available.
24
#[cfg(feature = "std")]
25
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
26

            
27
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
28
#[cfg(feature = "std")]
29
use sp_version::NativeVersion;
30

            
31
#[cfg(any(feature = "std", test))]
32
pub use sp_runtime::BuildStorage;
33

            
34
pub mod migrations;
35
pub mod weights;
36

            
37
pub use sp_runtime::{traits::ExtrinsicLike, MultiAddress, Perbill, Permill};
38
use {
39
    alloc::vec,
40
    alloc::vec::Vec,
41
    cumulus_primitives_core::AggregateMessageOrigin,
42
    dp_impl_tanssi_pallets_config::impl_tanssi_pallets_config,
43
    frame_support::{
44
        construct_runtime,
45
        dispatch::DispatchClass,
46
        genesis_builder_helper::{build_state, get_preset},
47
        pallet_prelude::DispatchResult,
48
        parameter_types,
49
        traits::{
50
            tokens::ConversionToAssetBalance, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8,
51
            Contains, InsideBoth, InstanceFilter,
52
        },
53
        weights::{
54
            constants::{
55
                BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
56
                WEIGHT_REF_TIME_PER_SECOND,
57
            },
58
            ConstantMultiplier, Weight, WeightToFee as _, WeightToFeeCoefficient,
59
            WeightToFeeCoefficients, WeightToFeePolynomial,
60
        },
61
    },
62
    frame_system::{
63
        limits::{BlockLength, BlockWeights},
64
        EnsureRoot,
65
    },
66
    nimbus_primitives::{NimbusId, SlotBeacon},
67
    pallet_transaction_payment::FungibleAdapter,
68
    parity_scale_codec::{Decode, DecodeWithMemTracking, Encode},
69
    polkadot_runtime_common::SlowAdjustingFeeUpdate,
70
    scale_info::TypeInfo,
71
    serde::{Deserialize, Serialize},
72
    smallvec::smallvec,
73
    sp_api::impl_runtime_apis,
74
    sp_consensus_slots::{Slot, SlotDuration},
75
    sp_core::{MaxEncodedLen, OpaqueMetadata},
76
    sp_runtime::{
77
        generic,
78
        generic::SignedPayload,
79
        impl_opaque_keys,
80
        traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
81
        transaction_validity::{TransactionSource, TransactionValidity},
82
        ApplyExtrinsicResult, Cow, MultiSignature, SaturatedConversion,
83
    },
84
    sp_version::RuntimeVersion,
85
    xcm::Version as XcmVersion,
86
    xcm::{IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm},
87
    xcm_runtime_apis::{
88
        dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
89
        fees::Error as XcmPaymentApiError,
90
    },
91
};
92

            
93
pub mod xcm_config;
94

            
95
// Polkadot imports
96
use polkadot_runtime_common::BlockHashCount;
97

            
98
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
99
pub type Signature = MultiSignature;
100

            
101
/// Some way of identifying an account on the chain. We intentionally make it equivalent
102
/// to the public key of our transaction signing scheme.
103
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
104

            
105
/// Balance of an account.
106
pub type Balance = u128;
107

            
108
/// Index of a transaction in the chain.
109
pub type Index = u32;
110

            
111
/// A hash of some data used by the chain.
112
pub type Hash = sp_core::H256;
113

            
114
/// An index to a block.
115
pub type BlockNumber = u32;
116

            
117
/// The address format for describing accounts.
118
pub type Address = MultiAddress<AccountId, ()>;
119

            
120
/// Block header type as expected by this runtime.
121
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
122

            
123
/// Block type as expected by this runtime.
124
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
125

            
126
/// A Block signed with a Justification
127
pub type SignedBlock = generic::SignedBlock<Block>;
128

            
129
/// BlockId type as expected by this runtime.
130
pub type BlockId = generic::BlockId<Block>;
131

            
132
/// The SignedExtension to the basic transaction logic.
133
pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
134
    Runtime,
135
    (
136
        frame_system::CheckNonZeroSender<Runtime>,
137
        frame_system::CheckSpecVersion<Runtime>,
138
        frame_system::CheckTxVersion<Runtime>,
139
        frame_system::CheckGenesis<Runtime>,
140
        frame_system::CheckEra<Runtime>,
141
        frame_system::CheckNonce<Runtime>,
142
        frame_system::CheckWeight<Runtime>,
143
        pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
144
    ),
145
>;
146

            
147
/// Unchecked extrinsic type as expected by this runtime.
148
pub type UncheckedExtrinsic =
149
    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
150

            
151
/// Extrinsic type that has already been checked.
152
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension>;
153

            
154
/// Executive: handles dispatch to the various modules.
155
pub type Executive = frame_executive::Executive<
156
    Runtime,
157
    Block,
158
    frame_system::ChainContext<Runtime>,
159
    Runtime,
160
    AllPalletsWithSystem,
161
>;
162

            
163
pub mod currency {
164
    use super::Balance;
165

            
166
    pub const MICROUNIT: Balance = 1_000_000;
167
    pub const MILLIUNIT: Balance = 1_000_000_000;
168
    pub const UNIT: Balance = 1_000_000_000_000;
169
    pub const KILOUNIT: Balance = 1_000_000_000_000_000;
170

            
171
    pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT;
172

            
173
    pub const fn deposit(items: u32, bytes: u32) -> Balance {
174
        items as Balance * 100 * MILLIUNIT + (bytes as Balance) * STORAGE_BYTE_FEE
175
    }
176
}
177

            
178
/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
179
/// node's balance type.
180
///
181
/// This should typically create a mapping between the following ranges:
182
///   - `[0, MAXIMUM_BLOCK_WEIGHT]`
183
///   - `[Balance::min, Balance::max]`
184
///
185
/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
186
///   - Setting it to `0` will essentially disable the weight fee.
187
///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
188
pub struct WeightToFee;
189
impl WeightToFeePolynomial for WeightToFee {
190
    type Balance = Balance;
191
200
    fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
192
200
        // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT:
193
200
        // in our template, we map to 1/10 of that, or 1/10 MILLIUNIT
194
200
        let p = MILLIUNIT / 10;
195
200
        let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
196
200
        smallvec![WeightToFeeCoefficient {
197
            degree: 1,
198
            negative: false,
199
            coeff_frac: Perbill::from_rational(p % q, q),
200
            coeff_integer: p / q,
201
        }]
202
200
    }
203
}
204

            
205
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
206
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
207
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
208
/// to even the core data structures.
209
pub mod opaque {
210
    use {
211
        super::*,
212
        sp_runtime::{generic, traits::BlakeTwo256},
213
    };
214

            
215
    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
216
    /// Opaque block header type.
217
    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
218
    /// Opaque block type.
219
    pub type Block = generic::Block<Header, UncheckedExtrinsic>;
220
    /// Opaque block identifier type.
221
    pub type BlockId = generic::BlockId<Block>;
222
}
223

            
224
impl_opaque_keys! {
225
    pub struct SessionKeys { }
226
}
227

            
228
#[sp_version::runtime_version]
229
pub const VERSION: RuntimeVersion = RuntimeVersion {
230
    spec_name: Cow::Borrowed("container-chain-template"),
231
    impl_name: Cow::Borrowed("container-chain-template"),
232
    authoring_version: 1,
233
    spec_version: 1500,
234
    impl_version: 0,
235
    apis: RUNTIME_API_VERSIONS,
236
    transaction_version: 1,
237
    system_version: 1,
238
};
239

            
240
/// This determines the average expected block time that we are targeting.
241
/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`.
242
/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
243
/// up by `pallet_aura` to implement `fn slot_duration()`.
244
///
245
/// Change this to adjust the block time.
246
pub const MILLISECS_PER_BLOCK: u64 = 6000;
247

            
248
// NOTE: Currently it is not possible to change the slot duration after the chain has started.
249
//       Attempting to do so will brick block production.
250
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
251

            
252
// Time is measured by number of blocks.
253
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
254
pub const HOURS: BlockNumber = MINUTES * 60;
255
pub const DAYS: BlockNumber = HOURS * 24;
256

            
257
pub const SUPPLY_FACTOR: Balance = 100;
258

            
259
// Unit = the base number of indivisible units for balances
260
pub const UNIT: Balance = 1_000_000_000_000;
261
pub const MILLIUNIT: Balance = 1_000_000_000;
262
pub const MICROUNIT: Balance = 1_000_000;
263

            
264
pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT * SUPPLY_FACTOR;
265

            
266
pub const fn deposit(items: u32, bytes: u32) -> Balance {
267
    items as Balance * 100 * MILLIUNIT * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
268
}
269

            
270
/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
271
pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
272

            
273
/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
274
/// used to limit the maximal weight of a single extrinsic.
275
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
276

            
277
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
278
/// `Operational` extrinsics.
279
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
280

            
281
/// We allow for 2 seconds of compute with a 6 second average block time
282
const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
283
    WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
284
    cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
285
);
286

            
287
/// The version information used to identify this runtime when compiled natively.
288
#[cfg(feature = "std")]
289
pub fn native_version() -> NativeVersion {
290
    NativeVersion {
291
        runtime_version: VERSION,
292
        can_author_with: Default::default(),
293
    }
294
}
295

            
296
parameter_types! {
297
    pub const Version: RuntimeVersion = VERSION;
298

            
299
    // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
300
    //  The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
301
    // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
302
    // the lazy contract deletion.
303
    pub RuntimeBlockLength: BlockLength =
304
        BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
305
    pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
306
        .base_block(BlockExecutionWeight::get())
307
15237
        .for_class(DispatchClass::all(), |weights| {
308
15237
            weights.base_extrinsic = ExtrinsicBaseWeight::get();
309
15237
        })
310
5079
        .for_class(DispatchClass::Normal, |weights| {
311
5079
            weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
312
5079
        })
313
5079
        .for_class(DispatchClass::Operational, |weights| {
314
5079
            weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
315
5079
            // Operational transactions have some extra reserved space, so that they
316
5079
            // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
317
5079
            weights.reserved = Some(
318
5079
                MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
319
5079
            );
320
5079
        })
321
        .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
322
        .build_or_panic();
323
    pub const SS58Prefix: u16 = 42;
324
}
325

            
326
// Configure FRAME pallets to include in runtime.
327

            
328
impl frame_system::Config for Runtime {
329
    /// The identifier used to distinguish between accounts.
330
    type AccountId = AccountId;
331
    /// The aggregated dispatch type that is available for extrinsics.
332
    type RuntimeCall = RuntimeCall;
333
    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
334
    type Lookup = AccountIdLookup<AccountId, ()>;
335
    /// The index type for storing how many extrinsics an account has signed.
336
    type Nonce = Index;
337
    /// The index type for blocks.
338
    type Block = Block;
339
    /// The type for hashing blocks and tries.
340
    type Hash = Hash;
341
    /// The hashing algorithm used.
342
    type Hashing = BlakeTwo256;
343
    /// The ubiquitous event type.
344
    type RuntimeEvent = RuntimeEvent;
345
    /// The ubiquitous origin type.
346
    type RuntimeOrigin = RuntimeOrigin;
347
    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
348
    type BlockHashCount = BlockHashCount;
349
    /// Runtime version.
350
    type Version = Version;
351
    /// Converts a module to an index of this module in the runtime.
352
    type PalletInfo = PalletInfo;
353
    /// The data to be stored in an account.
354
    type AccountData = pallet_balances::AccountData<Balance>;
355
    /// What to do if a new account is created.
356
    type OnNewAccount = ();
357
    /// What to do if an account is fully reaped from the system.
358
    type OnKilledAccount = ();
359
    /// The weight of database operations that the runtime can invoke.
360
    type DbWeight = RocksDbWeight;
361
    /// The basic call filter to use in dispatchable.
362
    type BaseCallFilter = InsideBoth<MaintenanceMode, TxPause>;
363
    /// Weight information for the extrinsics of this pallet.
364
    type SystemWeightInfo = weights::frame_system::SubstrateWeight<Runtime>;
365
    /// Block & extrinsics weights: base values and limits.
366
    type BlockWeights = RuntimeBlockWeights;
367
    /// The maximum length of a block (in bytes).
368
    type BlockLength = RuntimeBlockLength;
369
    /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
370
    type SS58Prefix = SS58Prefix;
371
    /// The action to take on a Runtime Upgrade
372
    type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
373
    type MaxConsumers = frame_support::traits::ConstU32<16>;
374
    type RuntimeTask = RuntimeTask;
375
    type SingleBlockMigrations = ();
376
    type MultiBlockMigrator = MultiBlockMigrations;
377
    type PreInherents = ();
378
    type PostInherents = ();
379
    type PostTransactions = ();
380
    type ExtensionsWeightInfo = weights::frame_system_extensions::SubstrateWeight<Runtime>;
381
}
382

            
383
parameter_types! {
384
    pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
385
}
386

            
387
impl pallet_balances::Config for Runtime {
388
    type MaxLocks = ConstU32<50>;
389
    /// The type for recording an account's balance.
390
    type Balance = Balance;
391
    /// The ubiquitous event type.
392
    type RuntimeEvent = RuntimeEvent;
393
    type DustRemoval = ();
394
    type ExistentialDeposit = ExistentialDeposit;
395
    type AccountStore = System;
396
    type MaxReserves = ConstU32<50>;
397
    type ReserveIdentifier = [u8; 8];
398
    type FreezeIdentifier = RuntimeFreezeReason;
399
    type MaxFreezes = ConstU32<0>;
400
    type RuntimeHoldReason = RuntimeHoldReason;
401
    type RuntimeFreezeReason = RuntimeFreezeReason;
402
    type DoneSlashHandler = ();
403
    type WeightInfo = weights::pallet_balances::SubstrateWeight<Runtime>;
404
}
405

            
406
parameter_types! {
407
    pub const TransactionByteFee: Balance = 1;
408
}
409

            
410
impl pallet_transaction_payment::Config for Runtime {
411
    type RuntimeEvent = RuntimeEvent;
412
    // This will burn the fees
413
    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
414
    type OperationalFeeMultiplier = ConstU8<5>;
415
    type WeightToFee = WeightToFee;
416
    type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
417
    type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
418
    type WeightInfo = weights::pallet_transaction_payment::SubstrateWeight<Runtime>;
419
}
420

            
421
parameter_types! {
422
    pub ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
423
    pub ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
424
    pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
425
}
426

            
427
pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
428
pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
429
pub const BLOCK_PROCESSING_VELOCITY: u32 = 1;
430

            
431
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
432
    Runtime,
433
    BLOCK_PROCESSING_VELOCITY,
434
    UNINCLUDED_SEGMENT_CAPACITY,
435
>;
436

            
437
impl cumulus_pallet_parachain_system::Config for Runtime {
438
    type WeightInfo = weights::cumulus_pallet_parachain_system::SubstrateWeight<Runtime>;
439
    type RuntimeEvent = RuntimeEvent;
440
    type OnSystemEvent = ();
441
    type OutboundXcmpMessageSource = XcmpQueue;
442
    type SelfParaId = parachain_info::Pallet<Runtime>;
443
    type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
444
    type ReservedDmpWeight = ReservedDmpWeight;
445
    type XcmpMessageHandler = XcmpQueue;
446
    type ReservedXcmpWeight = ReservedXcmpWeight;
447
    type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
448
    type ConsensusHook = ConsensusHook;
449
    type SelectCore = cumulus_pallet_parachain_system::DefaultCoreSelector<Runtime>;
450
}
451

            
452
pub struct ParaSlotProvider;
453
impl sp_core::Get<(Slot, SlotDuration)> for ParaSlotProvider {
454
616
    fn get() -> (Slot, SlotDuration) {
455
616
        let slot = u64::from(<Runtime as pallet_author_inherent::Config>::SlotBeacon::slot());
456
616
        (Slot::from(slot), SlotDuration::from_millis(SLOT_DURATION))
457
616
    }
458
}
459

            
460
parameter_types! {
461
    pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
462
}
463

            
464
impl pallet_async_backing::Config for Runtime {
465
    type AllowMultipleBlocksPerSlot = ConstBool<true>;
466
    type GetAndVerifySlot =
467
        pallet_async_backing::ParaSlot<RELAY_CHAIN_SLOT_DURATION_MILLIS, ParaSlotProvider>;
468
    type ExpectedBlockTime = ExpectedBlockTime;
469
}
470

            
471
impl parachain_info::Config for Runtime {}
472

            
473
parameter_types! {
474
    pub const Period: u32 = 6 * HOURS;
475
    pub const Offset: u32 = 0;
476
}
477

            
478
impl pallet_sudo::Config for Runtime {
479
    type RuntimeCall = RuntimeCall;
480
    type RuntimeEvent = RuntimeEvent;
481
    type WeightInfo = weights::pallet_sudo::SubstrateWeight<Runtime>;
482
}
483

            
484
impl pallet_utility::Config for Runtime {
485
    type RuntimeEvent = RuntimeEvent;
486
    type RuntimeCall = RuntimeCall;
487
    type PalletsOrigin = OriginCaller;
488
    type WeightInfo = weights::pallet_utility::SubstrateWeight<Runtime>;
489
}
490

            
491
/// The type used to represent the kinds of proxying allowed.
492
#[derive(
493
    Copy,
494
    Clone,
495
    Eq,
496
    PartialEq,
497
    Ord,
498
    PartialOrd,
499
    Encode,
500
    Decode,
501
    Debug,
502
    MaxEncodedLen,
503
    DecodeWithMemTracking,
504
    TypeInfo,
505
    Serialize,
506
    Deserialize,
507
)]
508
#[allow(clippy::unnecessary_cast)]
509
pub enum ProxyType {
510
    /// All calls can be proxied. This is the trivial/most permissive filter.
511
    Any = 0,
512
    /// Only extrinsics that do not transfer funds.
513
    NonTransfer = 1,
514
    /// Only extrinsics related to governance (democracy and collectives).
515
    Governance = 2,
516
    /// Allow to veto an announced proxy call.
517
    CancelProxy = 3,
518
    /// Allow extrinsic related to Balances.
519
    Balances = 4,
520
}
521

            
522
impl Default for ProxyType {
523
    fn default() -> Self {
524
        Self::Any
525
    }
526
}
527

            
528
impl InstanceFilter<RuntimeCall> for ProxyType {
529
    fn filter(&self, c: &RuntimeCall) -> bool {
530
        // Since proxy filters are respected in all dispatches of the Utility
531
        // pallet, it should never need to be filtered by any proxy.
532
        if let RuntimeCall::Utility(..) = c {
533
            return true;
534
        }
535

            
536
        match self {
537
            ProxyType::Any => true,
538
            ProxyType::NonTransfer => {
539
                matches!(
540
                    c,
541
                    RuntimeCall::System(..)
542
                        | RuntimeCall::ParachainSystem(..)
543
                        | RuntimeCall::Timestamp(..)
544
                        | RuntimeCall::Proxy(..)
545
                )
546
            }
547
            // We don't have governance yet
548
            ProxyType::Governance => false,
549
            ProxyType::CancelProxy => matches!(
550
                c,
551
                RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
552
            ),
553
            ProxyType::Balances => {
554
                matches!(c, RuntimeCall::Balances(..))
555
            }
556
        }
557
    }
558

            
559
    fn is_superset(&self, o: &Self) -> bool {
560
        match (self, o) {
561
            (x, y) if x == y => true,
562
            (ProxyType::Any, _) => true,
563
            (_, ProxyType::Any) => false,
564
            _ => false,
565
        }
566
    }
567
}
568

            
569
impl pallet_proxy::Config for Runtime {
570
    type RuntimeEvent = RuntimeEvent;
571
    type RuntimeCall = RuntimeCall;
572
    type Currency = Balances;
573
    type ProxyType = ProxyType;
574
    // One storage item; key size 32, value size 8
575
    type ProxyDepositBase = ConstU128<{ deposit(1, 8) }>;
576
    // Additional storage item size of 33 bytes (32 bytes AccountId + 1 byte sizeof(ProxyType)).
577
    type ProxyDepositFactor = ConstU128<{ deposit(0, 33) }>;
578
    type MaxProxies = ConstU32<32>;
579
    type MaxPending = ConstU32<32>;
580
    type CallHasher = BlakeTwo256;
581
    type AnnouncementDepositBase = ConstU128<{ deposit(1, 8) }>;
582
    // Additional storage item size of 68 bytes:
583
    // - 32 bytes AccountId
584
    // - 32 bytes Hasher (Blake2256)
585
    // - 4 bytes BlockNumber (u32)
586
    type AnnouncementDepositFactor = ConstU128<{ deposit(0, 68) }>;
587
    type WeightInfo = weights::pallet_proxy::SubstrateWeight<Runtime>;
588
    type BlockNumberProvider = System;
589
}
590

            
591
pub struct XcmExecutionManager;
592
impl xcm_primitives::PauseXcmExecution for XcmExecutionManager {
593
    fn suspend_xcm_execution() -> DispatchResult {
594
        XcmpQueue::suspend_xcm_execution(RuntimeOrigin::root())
595
    }
596
    fn resume_xcm_execution() -> DispatchResult {
597
        XcmpQueue::resume_xcm_execution(RuntimeOrigin::root())
598
    }
599
}
600

            
601
impl pallet_migrations::Config for Runtime {
602
    type RuntimeEvent = RuntimeEvent;
603
    type MigrationsList = (migrations::TemplateMigrations<Runtime, XcmpQueue, PolkadotXcm>,);
604
    type XcmExecutionManager = XcmExecutionManager;
605
}
606

            
607
parameter_types! {
608
    pub MbmServiceWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block;
609
}
610

            
611
impl pallet_multiblock_migrations::Config for Runtime {
612
    type RuntimeEvent = RuntimeEvent;
613
    #[cfg(not(feature = "runtime-benchmarks"))]
614
    type Migrations = ();
615
    // Benchmarks need mocked migrations to guarantee that they succeed.
616
    #[cfg(feature = "runtime-benchmarks")]
617
    type Migrations = pallet_multiblock_migrations::mock_helpers::MockedMigrations;
618
    type CursorMaxLen = ConstU32<65_536>;
619
    type IdentifierMaxLen = ConstU32<256>;
620
    type MigrationStatusHandler = ();
621
    type FailedMigrationHandler = MaintenanceMode;
622
    type MaxServiceWeight = MbmServiceWeight;
623
    type WeightInfo = weights::pallet_multiblock_migrations::SubstrateWeight<Runtime>;
624
}
625

            
626
/// Maintenance mode Call filter
627
pub struct MaintenanceFilter;
628
impl Contains<RuntimeCall> for MaintenanceFilter {
629
    fn contains(c: &RuntimeCall) -> bool {
630
        !matches!(c, RuntimeCall::Balances(_) | RuntimeCall::PolkadotXcm(_))
631
    }
632
}
633

            
634
/// Normal Call Filter
635
/// We dont allow to create nor mint assets, this for now is disabled
636
/// We only allow transfers. For now creation of assets will go through
637
/// asset-manager, while minting/burning only happens through xcm messages
638
/// This can change in the future
639
pub struct NormalFilter;
640
impl Contains<RuntimeCall> for NormalFilter {
641
1232
    fn contains(_c: &RuntimeCall) -> bool {
642
1232
        true
643
1232
    }
644
}
645

            
646
impl pallet_maintenance_mode::Config for Runtime {
647
    type RuntimeEvent = RuntimeEvent;
648
    type NormalCallFilter = NormalFilter;
649
    type MaintenanceCallFilter = InsideBoth<MaintenanceFilter, NormalFilter>;
650
    type MaintenanceOrigin = EnsureRoot<AccountId>;
651
    type XcmExecutionManager = XcmExecutionManager;
652
}
653

            
654
impl pallet_root_testing::Config for Runtime {
655
    type RuntimeEvent = RuntimeEvent;
656
}
657

            
658
impl pallet_tx_pause::Config for Runtime {
659
    type RuntimeEvent = RuntimeEvent;
660
    type RuntimeCall = RuntimeCall;
661
    type PauseOrigin = EnsureRoot<AccountId>;
662
    type UnpauseOrigin = EnsureRoot<AccountId>;
663
    type WhitelistedCalls = ();
664
    type MaxNameLen = ConstU32<256>;
665
    type WeightInfo = weights::pallet_tx_pause::SubstrateWeight<Runtime>;
666
}
667

            
668
impl dp_impl_tanssi_pallets_config::Config for Runtime {
669
    const SLOT_DURATION: u64 = SLOT_DURATION;
670
    type TimestampWeights = weights::pallet_timestamp::SubstrateWeight<Runtime>;
671
    type AuthorInherentWeights = weights::pallet_author_inherent::SubstrateWeight<Runtime>;
672
    type AuthoritiesNotingWeights = weights::pallet_cc_authorities_noting::SubstrateWeight<Runtime>;
673
}
674

            
675
parameter_types! {
676
    // One storage item; key size 32; value is size 4+4+16+32. Total = 1 * (32 + 56)
677
    pub const DepositBase: Balance = currency::deposit(1, 88);
678
    // Additional storage item size of 32 bytes.
679
    pub const DepositFactor: Balance = currency::deposit(0, 32);
680
    pub const MaxSignatories: u32 = 100;
681
}
682

            
683
impl pallet_multisig::Config for Runtime {
684
    type RuntimeEvent = RuntimeEvent;
685
    type RuntimeCall = RuntimeCall;
686
    type Currency = Balances;
687
    type DepositBase = DepositBase;
688
    type DepositFactor = DepositFactor;
689
    type MaxSignatories = MaxSignatories;
690
    type WeightInfo = weights::pallet_multisig::SubstrateWeight<Runtime>;
691
    type BlockNumberProvider = System;
692
}
693

            
694
impl frame_system::offchain::SigningTypes for Runtime {
695
    type Public = <Signature as sp_runtime::traits::Verify>::Signer;
696
    type Signature = Signature;
697
}
698

            
699
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
700
/// format of the chain.
701
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
702
where
703
    RuntimeCall: From<LocalCall>,
704
{
705
    fn create_signed_transaction<
706
        C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
707
    >(
708
        call: RuntimeCall,
709
        public: <Signature as Verify>::Signer,
710
        account: AccountId,
711
        nonce: <Runtime as frame_system::Config>::Nonce,
712
    ) -> Option<UncheckedExtrinsic> {
713
        use sp_runtime::traits::StaticLookup;
714
        // take the biggest period possible.
715
        let period = u64::from(
716
            BlockHashCount::get()
717
                .checked_next_power_of_two()
718
                .map(|c| c / 2)
719
                .unwrap_or(2),
720
        );
721

            
722
        let current_block = System::block_number()
723
            .saturated_into::<u64>()
724
            // The `System::block_number` is initialized with `n+1`,
725
            // so the actual block number is `n`.
726
            .saturating_sub(1);
727
        let tip = 0;
728
        let tx_ext = TxExtension::new((
729
            frame_system::CheckNonZeroSender::<Runtime>::new(),
730
            frame_system::CheckSpecVersion::<Runtime>::new(),
731
            frame_system::CheckTxVersion::<Runtime>::new(),
732
            frame_system::CheckGenesis::<Runtime>::new(),
733
            frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
734
                period,
735
                current_block,
736
            )),
737
            frame_system::CheckNonce::<Runtime>::from(nonce),
738
            frame_system::CheckWeight::<Runtime>::new(),
739
            pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
740
            //frame_metadata_hash_extension::CheckMetadataHash::new(true),
741
        ));
742
        let raw_payload = SignedPayload::new(call, tx_ext)
743
            .map_err(|e| {
744
                log::warn!("Unable to create signed payload: {:?}", e);
745
            })
746
            .ok()?;
747
        let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
748
        let (call, tx_ext, _) = raw_payload.deconstruct();
749
        let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
750
        let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
751
        Some(transaction)
752
    }
753
}
754

            
755
impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
756
where
757
    RuntimeCall: From<C>,
758
{
759
    type Extrinsic = UncheckedExtrinsic;
760
    type RuntimeCall = RuntimeCall;
761
}
762

            
763
impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
764
where
765
    RuntimeCall: From<LocalCall>,
766
{
767
    fn create_inherent(call: RuntimeCall) -> UncheckedExtrinsic {
768
        UncheckedExtrinsic::new_bare(call)
769
    }
770
}
771

            
772
impl pallet_ocw_testing::Config for Runtime {
773
    type RuntimeEvent = RuntimeEvent;
774
    type UnsignedInterval = ConstU32<6>;
775
}
776

            
777
impl cumulus_pallet_weight_reclaim::Config for Runtime {
778
    type WeightInfo = weights::cumulus_pallet_weight_reclaim::SubstrateWeight<Runtime>;
779
}
780

            
781
impl_tanssi_pallets_config!(Runtime);
782

            
783
// Create the runtime by composing the FRAME pallets that were previously configured.
784
20499
construct_runtime!(
785
20499
    pub enum Runtime
786
20499
    {
787
20499
        // System support stuff.
788
20499
        System: frame_system = 0,
789
20499
        ParachainSystem: cumulus_pallet_parachain_system = 1,
790
20499
        Timestamp: pallet_timestamp = 2,
791
20499
        ParachainInfo: parachain_info = 3,
792
20499
        Sudo: pallet_sudo = 4,
793
20499
        Utility: pallet_utility = 5,
794
20499
        Proxy: pallet_proxy = 6,
795
20499
        Migrations: pallet_migrations = 7,
796
20499
        MultiBlockMigrations: pallet_multiblock_migrations = 121,
797
20499
        MaintenanceMode: pallet_maintenance_mode = 8,
798
20499
        TxPause: pallet_tx_pause = 9,
799
20499

            
800
20499
        // Monetary stuff.
801
20499
        Balances: pallet_balances = 10,
802
20499
        TransactionPayment: pallet_transaction_payment = 11,
803
20499

            
804
20499
        // Other utilities
805
20499
        Multisig: pallet_multisig = 16,
806
20499

            
807
20499
        // ContainerChain Author Verification
808
20499
        AuthoritiesNoting: pallet_cc_authorities_noting = 50,
809
20499
        AuthorInherent: pallet_author_inherent = 51,
810
20499

            
811
20499
        // XCM
812
20499
        XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Storage, Event<T>} = 70,
813
20499
        CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 71,
814
20499
        PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 73,
815
20499
        MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 74,
816
20499
        ForeignAssets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 75,
817
20499
        ForeignAssetsCreator: pallet_foreign_asset_creator::{Pallet, Call, Storage, Event<T>} = 76,
818
20499
        AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event<T>} = 77,
819
20499
        XcmExecutorUtils: pallet_xcm_executor_utils::{Pallet, Call, Storage, Event<T>} = 78,
820
20499

            
821
20499
        WeightReclaim: cumulus_pallet_weight_reclaim = 80,
822
20499

            
823
20499
        RootTesting: pallet_root_testing = 100,
824
20499
        AsyncBacking: pallet_async_backing::{Pallet, Storage} = 110,
825
20499

            
826
20499
        OffchainWorker: pallet_ocw_testing::{Pallet, Call, Storage, Event<T>, ValidateUnsigned} = 120,
827
20499
    }
828
20499
);
829

            
830
#[cfg(feature = "runtime-benchmarks")]
831
mod benches {
832
    frame_benchmarking::define_benchmarks!(
833
        [frame_system, frame_system_benchmarking::Pallet::<Runtime>]
834
        [frame_system_extensions, frame_system_benchmarking::extensions::Pallet::<Runtime>]
835
        [cumulus_pallet_parachain_system, ParachainSystem]
836
        [pallet_timestamp, Timestamp]
837
        [pallet_sudo, Sudo]
838
        [pallet_utility, Utility]
839
        [pallet_proxy, Proxy]
840
        [pallet_tx_pause, TxPause]
841
        [pallet_transaction_payment, TransactionPayment]
842
        [pallet_balances, Balances]
843
        [pallet_multiblock_migrations, MultiBlockMigrations]
844
        [pallet_multisig, Multisig]
845
        [pallet_cc_authorities_noting, AuthoritiesNoting]
846
        [pallet_author_inherent, AuthorInherent]
847
        [cumulus_pallet_xcmp_queue, XcmpQueue]
848
        [pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
849
        [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::<Runtime>]
850
        [pallet_message_queue, MessageQueue]
851
        [pallet_assets, ForeignAssets]
852
        [pallet_foreign_asset_creator, ForeignAssetsCreator]
853
        [pallet_asset_rate, AssetRate]
854
        [pallet_xcm_executor_utils, XcmExecutorUtils]
855
        [cumulus_pallet_weight_reclaim, WeightReclaim]
856
    );
857
}
858

            
859
5088
impl_runtime_apis! {
860
5088
    impl sp_api::Core<Block> for Runtime {
861
5088
        fn version() -> RuntimeVersion {
862
5088
            VERSION
863
5088
        }
864
5088

            
865
5088
        fn execute_block(block: Block) {
866
5088
            Executive::execute_block(block)
867
5088
        }
868
5088

            
869
5088
        fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
870
5088
            Executive::initialize_block(header)
871
5088
        }
872
5088
    }
873
5088

            
874
5088
    impl sp_api::Metadata<Block> for Runtime {
875
5088
        fn metadata() -> OpaqueMetadata {
876
5088
            OpaqueMetadata::new(Runtime::metadata().into())
877
5088
        }
878
5088

            
879
5088
        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
880
5088
            Runtime::metadata_at_version(version)
881
5088
        }
882
5088

            
883
5088
        fn metadata_versions() -> Vec<u32> {
884
5088
            Runtime::metadata_versions()
885
5088
        }
886
5088
    }
887
5088

            
888
5088
    impl sp_block_builder::BlockBuilder<Block> for Runtime {
889
5088
        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
890
5088
            Executive::apply_extrinsic(extrinsic)
891
5088
        }
892
5088

            
893
5088
        fn finalize_block() -> <Block as BlockT>::Header {
894
5088
            Executive::finalize_block()
895
5088
        }
896
5088

            
897
5088
        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
898
5088
            data.create_extrinsics()
899
5088
        }
900
5088

            
901
5088
        fn check_inherents(
902
5088
            block: Block,
903
5088
            data: sp_inherents::InherentData,
904
5088
        ) -> sp_inherents::CheckInherentsResult {
905
5088
            data.check_extrinsics(&block)
906
5088
        }
907
5088
    }
908
5088

            
909
5088
    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
910
5088
        fn validate_transaction(
911
5088
            source: TransactionSource,
912
5088
            tx: <Block as BlockT>::Extrinsic,
913
5088
            block_hash: <Block as BlockT>::Hash,
914
5088
        ) -> TransactionValidity {
915
5088
            Executive::validate_transaction(source, tx, block_hash)
916
5088
        }
917
5088
    }
918
5088

            
919
5088
    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
920
5088
        fn offchain_worker(header: &<Block as BlockT>::Header) {
921
5088
            Executive::offchain_worker(header)
922
5088
        }
923
5088
    }
924
5088

            
925
5088
    impl sp_session::SessionKeys<Block> for Runtime {
926
5088
        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
927
5088
            SessionKeys::generate(seed)
928
5088
        }
929
5088

            
930
5088
        fn decode_session_keys(
931
5088
            encoded: Vec<u8>,
932
5088
        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
933
5088
            SessionKeys::decode_into_raw_public_keys(&encoded)
934
5088
        }
935
5088
    }
936
5088

            
937
5088
    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
938
5088
        fn account_nonce(account: AccountId) -> Index {
939
5088
            System::account_nonce(account)
940
5088
        }
941
5088
    }
942
5088

            
943
5088
    impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
944
5088
        fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
945
5088
            ParachainSystem::collect_collation_info(header)
946
5088
        }
947
5088
    }
948
5088

            
949
5088
    impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
950
5088
        fn can_build_upon(
951
5088
            included_hash: <Block as BlockT>::Hash,
952
5088
            slot: async_backing_primitives::Slot,
953
5088
        ) -> bool {
954
5088
            ConsensusHook::can_build_upon(included_hash, slot)
955
5088
        }
956
5088
    }
957
5088

            
958
5088
    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
959
5088
        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
960
5088
            build_state::<RuntimeGenesisConfig>(config)
961
5088
        }
962
5088

            
963
5088
        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
964
5088
            get_preset::<RuntimeGenesisConfig>(id, |_| None)
965
5088
        }
966
5088
        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
967
5088
            vec![]
968
5088
        }
969
5088
    }
970
5088

            
971
5088
    #[cfg(feature = "runtime-benchmarks")]
972
5088
    impl frame_benchmarking::Benchmark<Block> for Runtime {
973
5088
        fn benchmark_metadata(
974
5088
            extra: bool,
975
5088
        ) -> (
976
5088
            Vec<frame_benchmarking::BenchmarkList>,
977
5088
            Vec<frame_support::traits::StorageInfo>,
978
5088
        ) {
979
5088
            use frame_benchmarking::{BenchmarkList};
980
5088
            use frame_support::traits::StorageInfoTrait;
981
5088
            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
982
5088

            
983
5088
            let mut list = Vec::<BenchmarkList>::new();
984
5088
            list_benchmarks!(list, extra);
985
5088

            
986
5088
            let storage_info = AllPalletsWithSystem::storage_info();
987
5088
            (list, storage_info)
988
5088
        }
989
5088

            
990
5088
        #[allow(non_local_definitions)]
991
5088
        fn dispatch_benchmark(
992
5088
            config: frame_benchmarking::BenchmarkConfig,
993
5088
        ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
994
5088
            use frame_benchmarking::{BenchmarkBatch, BenchmarkError};
995
5088
            use sp_core::storage::TrackedStorageKey;
996
5088
            use xcm::latest::prelude::*;
997
5088
            use alloc::boxed::Box;
998
5088

            
999
5088
            impl frame_system_benchmarking::Config for Runtime {
5088
                fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
5088
                    ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
5088
                    Ok(())
5088
                }
5088

            
5088
                fn verify_set_code() {
5088
                    System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
5088
                }
5088
            }
5088
            use crate::xcm_config::SelfReserve;
5088
            parameter_types! {
5088
                pub ExistentialDepositAsset: Option<Asset> = Some((
5088
                    SelfReserve::get(),
5088
                    ExistentialDeposit::get()
5088
                ).into());
5088
            }
5088
            impl pallet_xcm_benchmarks::Config for Runtime {
5088
                type XcmConfig = xcm_config::XcmConfig;
5088
                type AccountIdConverter = xcm_config::LocationToAccountId;
5088
                type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
5088
                xcm_config::XcmConfig,
5088
                ExistentialDepositAsset,
5088
                xcm_config::PriceForParentDelivery,
5088
                >;
5088
                fn valid_destination() -> Result<Location, BenchmarkError> {
5088
                    Ok(Location::parent())
5088
                }
5088
                fn worst_case_holding(_depositable_count: u32) -> Assets {
5088
                    // We only care for native asset until we support others
5088
                    // TODO: refactor this case once other assets are supported
5088
                    vec![Asset{
5088
                        id: AssetId(SelfReserve::get()),
5088
                        fun: Fungible(u128::MAX),
5088
                    }].into()
5088
                }
5088
            }
5088

            
5088
            impl pallet_xcm_benchmarks::generic::Config for Runtime {
5088
                type TransactAsset = Balances;
5088
                type RuntimeCall = RuntimeCall;
5088

            
5088
                fn worst_case_response() -> (u64, Response) {
5088
                    (0u64, Response::Version(Default::default()))
5088
                }
5088

            
5088
                fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
5088
                    Err(BenchmarkError::Skip)
5088
                }
5088

            
5088
                fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
5088
                    Err(BenchmarkError::Skip)
5088
                }
5088

            
5088
                fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
5088
                    Ok((Location::parent(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
5088
                }
5088

            
5088
                fn subscribe_origin() -> Result<Location, BenchmarkError> {
5088
                    Ok(Location::parent())
5088
                }
5088

            
5088
                fn fee_asset() -> Result<Asset, BenchmarkError> {
5088
                    Ok(Asset {
5088
                        id: AssetId(SelfReserve::get()),
5088
                        fun: Fungible(ExistentialDeposit::get()*100),
5088
                    })
5088
                }
5088

            
5088
                fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
5088
                    let origin = Location::parent();
5088
                    let assets: Assets = (Location::parent(), 1_000u128).into();
5088
                    let ticket = Location { parents: 0, interior: Here };
5088
                    Ok((origin, ticket, assets))
5088
                }
5088

            
5088
                fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
5088
                    Err(BenchmarkError::Skip)
5088
                }
5088

            
5088
                fn export_message_origin_and_destination(
5088
                ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
5088
                    Err(BenchmarkError::Skip)
5088
                }
5088

            
5088
                fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
5088
                    Err(BenchmarkError::Skip)
5088
                }
5088
            }
5088

            
5088
            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
5088
            impl pallet_xcm::benchmarking::Config for Runtime {
5088
                type DeliveryHelper = ();
5088
                fn get_asset() -> Asset {
5088
                    Asset {
5088
                        id: AssetId(SelfReserve::get()),
5088
                        fun: Fungible(ExistentialDeposit::get()),
5088
                    }
5088
                }
5088

            
5088
                fn reachable_dest() -> Option<Location> {
5088
                    Some(Parent.into())
5088
                }
5088

            
5088
                fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
5088
                    // Relay/native token can be teleported between AH and Relay.
5088
                    Some((
5088
                        Asset {
5088
                            fun: Fungible(EXISTENTIAL_DEPOSIT),
5088
                            id: Parent.into()
5088
                        },
5088
                        Parent.into(),
5088
                    ))
5088
                }
5088

            
5088
                fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
5088
                    use xcm_config::SelfReserve;
5088
                    // AH can reserve transfer native token to some random parachain.
5088
                    let random_para_id = 43211234;
5088
                    ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
5088
                        random_para_id.into()
5088
                    );
5088
                    let who = frame_benchmarking::whitelisted_caller();
5088
                    // Give some multiple of the existential deposit
5088
                    let balance = EXISTENTIAL_DEPOSIT * 1000;
5088
                    let _ = <Balances as frame_support::traits::Currency<_>>::make_free_balance_be(
5088
                        &who, balance,
5088
                    );
5088
                    Some((
5088
                        Asset {
5088
                            fun: Fungible(EXISTENTIAL_DEPOSIT*10),
5088
                            id: SelfReserve::get().into()
5088
                        },
5088
                        ParentThen(Parachain(random_para_id).into()).into(),
5088
                    ))
5088
                }
5088

            
5088
                fn set_up_complex_asset_transfer(
5088
                ) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
5088
                    use xcm_config::SelfReserve;
5088
                    // Transfer to Relay some local AH asset (local-reserve-transfer) while paying
5088
                    // fees using teleported native token.
5088
                    // (We don't care that Relay doesn't accept incoming unknown AH local asset)
5088
                    let dest = Parent.into();
5088

            
5088
                    let fee_amount = EXISTENTIAL_DEPOSIT;
5088
                    let fee_asset: Asset = (SelfReserve::get(), fee_amount).into();
5088

            
5088
                    let who = frame_benchmarking::whitelisted_caller();
5088
                    // Give some multiple of the existential deposit
5088
                    let balance = fee_amount + EXISTENTIAL_DEPOSIT * 1000;
5088
                    let _ = <Balances as frame_support::traits::Currency<_>>::make_free_balance_be(
5088
                        &who, balance,
5088
                    );
5088

            
5088
                    // verify initial balance
5088
                    assert_eq!(Balances::free_balance(&who), balance);
5088

            
5088
                    // set up local asset
5088
                    let asset_amount = 10u128;
5088
                    let initial_asset_amount = asset_amount * 10;
5088

            
5088
                    let (asset_id, asset_location) = pallet_foreign_asset_creator::benchmarks::create_default_minted_asset::<Runtime>(
5088
                        initial_asset_amount,
5088
                        who.clone()
5088
                    );
5088

            
5088
                    let transfer_asset: Asset = (asset_location, asset_amount).into();
5088

            
5088
                    let assets: Assets = vec![fee_asset.clone(), transfer_asset].into();
5088
                    let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 };
5088

            
5088
                    // verify transferred successfully
5088
                    let verify = Box::new(move || {
5088
                        // verify native balance after transfer, decreased by transferred fee amount
5088
                        // (plus transport fees)
5088
                        assert!(Balances::free_balance(&who) <= balance - fee_amount);
5088
                        // verify asset balance decreased by exactly transferred amount
5088
                        assert_eq!(
5088
                            ForeignAssets::balance(asset_id, &who),
5088
                            initial_asset_amount - asset_amount,
5088
                        );
5088
                    });
5088
                    Some((assets, fee_index, dest, verify))
5088
                }
5088
            }
5088

            
5088
            let whitelist: Vec<TrackedStorageKey> = vec![
5088
                // Block Number
5088
                hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac")
5088
                    .to_vec()
5088
                    .into(),
5088
                // Total Issuance
5088
                hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")
5088
                    .to_vec()
5088
                    .into(),
5088
                // Execution Phase
5088
                hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a")
5088
                    .to_vec()
5088
                    .into(),
5088
                // Event Count
5088
                hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850")
5088
                    .to_vec()
5088
                    .into(),
5088
                // System Events
5088
                hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7")
5088
                    .to_vec()
5088
                    .into(),
5088
                // The transactional storage limit.
5088
                hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a")
5088
                    .to_vec()
5088
                    .into(),
5088

            
5088
                // ParachainInfo ParachainId
5088
                hex_literal::hex!(  "0d715f2646c8f85767b5d2764bb2782604a74d81251e398fd8a0a4d55023bb3f")
5088
                    .to_vec()
5088
                    .into(),
5088
            ];
5088

            
5088
            let mut batches = Vec::<BenchmarkBatch>::new();
5088
            let params = (&config, &whitelist);
5088

            
5088
            add_benchmarks!(params, batches);
5088

            
5088
            Ok(batches)
5088
        }
5088
    }
5088

            
5088
    #[cfg(feature = "try-runtime")]
5088
    impl frame_try_runtime::TryRuntime<Block> for Runtime {
5088
        fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
5088
            let weight = Executive::try_runtime_upgrade(checks).unwrap();
5088
            (weight, RuntimeBlockWeights::get().max_block)
5088
        }
5088

            
5088
        fn execute_block(
5088
            block: Block,
5088
            state_root_check: bool,
5088
            signature_check: bool,
5088
            select: frame_try_runtime::TryStateSelect,
5088
        ) -> Weight {
5088
            // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
5088
            // have a backtrace here.
5088
            Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
5088
        }
5088
    }
5088

            
5088
    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
5088
    for Runtime {
5088
        fn query_info(
5088
            uxt: <Block as BlockT>::Extrinsic,
5088
            len: u32,
5088
        ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
5088
            TransactionPayment::query_info(uxt, len)
5088
        }
5088

            
5088
        fn query_fee_details(
5088
            uxt: <Block as BlockT>::Extrinsic,
5088
            len: u32,
5088
        ) -> pallet_transaction_payment::FeeDetails<Balance> {
5088
            TransactionPayment::query_fee_details(uxt, len)
5088
        }
5088

            
5088
        fn query_weight_to_fee(weight: Weight) -> Balance {
5088
            TransactionPayment::weight_to_fee(weight)
5088
        }
5088

            
5088
        fn query_length_to_fee(length: u32) -> Balance {
5088
            TransactionPayment::length_to_fee(length)
5088
        }
5088
    }
5088

            
5088
    impl dp_slot_duration_runtime_api::TanssiSlotDurationApi<Block> for Runtime {
5088
        fn slot_duration() -> u64 {
5088
            SLOT_DURATION
5088
        }
5088
    }
5088

            
5088
    impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
5088
        fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
5088
            if !matches!(xcm_version, 3..=5) {
5088
                return Err(XcmPaymentApiError::UnhandledXcmVersion);
5088
            }
5088

            
5088
            Ok([VersionedAssetId::V5(xcm_config::SelfReserve::get().into())]
5088
                .into_iter()
5088
                .chain(
5088
                    pallet_asset_rate::ConversionRateToNative::<Runtime>::iter_keys().filter_map(|asset_id_u16| {
5088
                        pallet_foreign_asset_creator::AssetIdToForeignAsset::<Runtime>::get(asset_id_u16).map(|location| {
5088
                            VersionedAssetId::V5(location.into())
5088
                        }).or_else(|| {
5088
                            log::warn!("Asset `{}` is present in pallet_asset_rate but not in pallet_foreign_asset_creator", asset_id_u16);
5088
                            None
5088
                        })
5088
                    })
5088
                )
5088
                .filter_map(|asset| asset.into_version(xcm_version).map_err(|e| {
5088
                    log::warn!("Failed to convert asset to version {}: {:?}", xcm_version, e);
5088
                }).ok())
5088
                .collect())
5088
        }
5088

            
5088
        fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
5088
            let local_asset = VersionedAssetId::V5(xcm_config::SelfReserve::get().into());
5088
            let asset = asset
5088
                .into_version(5)
5088
                .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
5088

            
5088
            if asset == local_asset {
5088
                Ok(WeightToFee::weight_to_fee(&weight))
5088
            } else {
5088
                let native_fee = WeightToFee::weight_to_fee(&weight);
5088
                let asset_v5: xcm::latest::AssetId = asset.try_into().map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
5088
                let location: xcm::latest::Location = asset_v5.0;
5088
                let asset_id = pallet_foreign_asset_creator::ForeignAssetToAssetId::<Runtime>::get(location).ok_or(XcmPaymentApiError::AssetNotFound)?;
5088
                let asset_rate = AssetRate::to_asset_balance(native_fee, asset_id);
5088
                match asset_rate {
5088
                    Ok(x) => Ok(x),
5088
                    Err(pallet_asset_rate::Error::UnknownAssetKind) => Err(XcmPaymentApiError::AssetNotFound),
5088
                    // Error when converting native balance to asset balance, probably overflow
5088
                    Err(_e) => Err(XcmPaymentApiError::WeightNotComputable),
5088
                }
5088
            }
5088
        }
5088

            
5088
        fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
5088
            PolkadotXcm::query_xcm_weight(message)
5088
        }
5088

            
5088
        fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
5088
            PolkadotXcm::query_delivery_fees(destination, message)
5088
        }
5088
    }
5088

            
5088
    impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
5088
        fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
5088
            PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
5088
        }
5088

            
5088
        fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
5088
            PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
5088
        }
5088
    }
5088

            
5088
    impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
5088
        fn convert_location(location: VersionedLocation) -> Result<
5088
            AccountId,
5088
            xcm_runtime_apis::conversions::Error
5088
        > {
5088
            xcm_runtime_apis::conversions::LocationToAccountHelper::<
5088
                AccountId,
5088
                xcm_config::LocationToAccountId,
5088
            >::convert_location(location)
5088
        }
5088
    }
7170
}
#[allow(dead_code)]
struct CheckInherents;
#[allow(deprecated)]
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
    fn check_inherents(
        block: &Block,
        relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
    ) -> sp_inherents::CheckInherentsResult {
        let relay_chain_slot = relay_state_proof
            .read_slot()
            .expect("Could not read the relay chain slot from the proof");
        let inherent_data =
            cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
                relay_chain_slot,
                core::time::Duration::from_secs(6),
            )
            .create_inherent_data()
            .expect("Could not create the timestamp inherent data");
        inherent_data.check_extrinsics(block)
    }
}
cumulus_pallet_parachain_system::register_validate_block! {
    Runtime = Runtime,
    CheckInherents = CheckInherents,
    BlockExecutor = pallet_author_inherent::BlockExecutor::<Runtime, Executive>,
}