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
// Make the WASM binary available.
22
#[cfg(feature = "std")]
23
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
24

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

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

            
32
pub mod migrations;
33
pub mod weights;
34

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

            
90
pub mod xcm_config;
91

            
92
// Polkadot imports
93
use polkadot_runtime_common::BlockHashCount;
94

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

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

            
102
/// Balance of an account.
103
pub type Balance = u128;
104

            
105
/// Index of a transaction in the chain.
106
pub type Index = u32;
107

            
108
/// A hash of some data used by the chain.
109
pub type Hash = sp_core::H256;
110

            
111
/// An index to a block.
112
pub type BlockNumber = u32;
113

            
114
/// The address format for describing accounts.
115
pub type Address = MultiAddress<AccountId, ()>;
116

            
117
/// Block header type as expected by this runtime.
118
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
119

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

            
123
/// A Block signed with a Justification
124
pub type SignedBlock = generic::SignedBlock<Block>;
125

            
126
/// BlockId type as expected by this runtime.
127
pub type BlockId = generic::BlockId<Block>;
128

            
129
/// The SignedExtension to the basic transaction logic.
130
pub type SignedExtra = (
131
    frame_system::CheckNonZeroSender<Runtime>,
132
    frame_system::CheckSpecVersion<Runtime>,
133
    frame_system::CheckTxVersion<Runtime>,
134
    frame_system::CheckGenesis<Runtime>,
135
    frame_system::CheckEra<Runtime>,
136
    frame_system::CheckNonce<Runtime>,
137
    frame_system::CheckWeight<Runtime>,
138
    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
139
    cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
140
);
141

            
142
/// Unchecked extrinsic type as expected by this runtime.
143
pub type UncheckedExtrinsic =
144
    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
145

            
146
/// Extrinsic type that has already been checked.
147
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra>;
148

            
149
/// Executive: handles dispatch to the various modules.
150
pub type Executive = frame_executive::Executive<
151
    Runtime,
152
    Block,
153
    frame_system::ChainContext<Runtime>,
154
    Runtime,
155
    AllPalletsWithSystem,
156
>;
157

            
158
pub mod currency {
159
    use super::Balance;
160

            
161
    pub const MICROUNIT: Balance = 1_000_000;
162
    pub const MILLIUNIT: Balance = 1_000_000_000;
163
    pub const UNIT: Balance = 1_000_000_000_000;
164
    pub const KILOUNIT: Balance = 1_000_000_000_000_000;
165

            
166
    pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT;
167

            
168
    pub const fn deposit(items: u32, bytes: u32) -> Balance {
169
        items as Balance * 100 * MILLIUNIT + (bytes as Balance) * STORAGE_BYTE_FEE
170
    }
171
}
172

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

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

            
210
    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
211
    /// Opaque block header type.
212
    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
213
    /// Opaque block type.
214
    pub type Block = generic::Block<Header, UncheckedExtrinsic>;
215
    /// Opaque block identifier type.
216
    pub type BlockId = generic::BlockId<Block>;
217
}
218

            
219
impl_opaque_keys! {
220
    pub struct SessionKeys { }
221
}
222

            
223
#[sp_version::runtime_version]
224
pub const VERSION: RuntimeVersion = RuntimeVersion {
225
    spec_name: create_runtime_str!("container-chain-template"),
226
    impl_name: create_runtime_str!("container-chain-template"),
227
    authoring_version: 1,
228
    spec_version: 1100,
229
    impl_version: 0,
230
    apis: RUNTIME_API_VERSIONS,
231
    transaction_version: 1,
232
    state_version: 1,
233
};
234

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

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

            
247
// Time is measured by number of blocks.
248
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
249
pub const HOURS: BlockNumber = MINUTES * 60;
250
pub const DAYS: BlockNumber = HOURS * 24;
251

            
252
pub const SUPPLY_FACTOR: Balance = 100;
253

            
254
// Unit = the base number of indivisible units for balances
255
pub const UNIT: Balance = 1_000_000_000_000;
256
pub const MILLIUNIT: Balance = 1_000_000_000;
257
pub const MICROUNIT: Balance = 1_000_000;
258

            
259
pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT * SUPPLY_FACTOR;
260

            
261
pub const fn deposit(items: u32, bytes: u32) -> Balance {
262
    items as Balance * 100 * MILLIUNIT * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
263
}
264

            
265
/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
266
pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
267

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

            
272
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
273
/// `Operational` extrinsics.
274
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
275

            
276
/// We allow for 2 seconds of compute with a 6 second average block time
277
const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
278
    WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
279
    cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
280
);
281

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

            
291
parameter_types! {
292
    pub const Version: RuntimeVersion = VERSION;
293

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

            
321
// Configure FRAME pallets to include in runtime.
322

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

            
377
parameter_types! {
378
    pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
379
}
380

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

            
399
parameter_types! {
400
    pub const TransactionByteFee: Balance = 1;
401
}
402

            
403
impl pallet_transaction_payment::Config for Runtime {
404
    type RuntimeEvent = RuntimeEvent;
405
    // This will burn the fees
406
    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
407
    type OperationalFeeMultiplier = ConstU8<5>;
408
    type WeightToFee = WeightToFee;
409
    type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
410
    type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
411
}
412

            
413
parameter_types! {
414
    pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
415
    pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
416
    pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
417
}
418

            
419
pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
420
pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
421
pub const BLOCK_PROCESSING_VELOCITY: u32 = 1;
422

            
423
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
424
    Runtime,
425
    BLOCK_PROCESSING_VELOCITY,
426
    UNINCLUDED_SEGMENT_CAPACITY,
427
>;
428

            
429
impl cumulus_pallet_parachain_system::Config for Runtime {
430
    type WeightInfo = weights::cumulus_pallet_parachain_system::SubstrateWeight<Runtime>;
431
    type RuntimeEvent = RuntimeEvent;
432
    type OnSystemEvent = ();
433
    type OutboundXcmpMessageSource = XcmpQueue;
434
    type SelfParaId = parachain_info::Pallet<Runtime>;
435
    type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
436
    type ReservedDmpWeight = ReservedDmpWeight;
437
    type XcmpMessageHandler = XcmpQueue;
438
    type ReservedXcmpWeight = ReservedXcmpWeight;
439
    type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
440
    type ConsensusHook = ConsensusHook;
441
}
442

            
443
pub struct ParaSlotProvider;
444
impl sp_core::Get<(Slot, SlotDuration)> for ParaSlotProvider {
445
63
    fn get() -> (Slot, SlotDuration) {
446
63
        let slot = u64::from(<Runtime as pallet_author_inherent::Config>::SlotBeacon::slot());
447
63
        (Slot::from(slot), SlotDuration::from_millis(SLOT_DURATION))
448
63
    }
449
}
450

            
451
parameter_types! {
452
    pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
453
}
454

            
455
impl pallet_async_backing::Config for Runtime {
456
    type AllowMultipleBlocksPerSlot = ConstBool<true>;
457
    type GetAndVerifySlot =
458
        pallet_async_backing::ParaSlot<RELAY_CHAIN_SLOT_DURATION_MILLIS, ParaSlotProvider>;
459
    type ExpectedBlockTime = ExpectedBlockTime;
460
}
461

            
462
impl parachain_info::Config for Runtime {}
463

            
464
parameter_types! {
465
    pub const Period: u32 = 6 * HOURS;
466
    pub const Offset: u32 = 0;
467
}
468

            
469
impl pallet_sudo::Config for Runtime {
470
    type RuntimeCall = RuntimeCall;
471
    type RuntimeEvent = RuntimeEvent;
472
    type WeightInfo = weights::pallet_sudo::SubstrateWeight<Runtime>;
473
}
474

            
475
impl pallet_utility::Config for Runtime {
476
    type RuntimeEvent = RuntimeEvent;
477
    type RuntimeCall = RuntimeCall;
478
    type PalletsOrigin = OriginCaller;
479
    type WeightInfo = weights::pallet_utility::SubstrateWeight<Runtime>;
480
}
481

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

            
512
impl Default for ProxyType {
513
    fn default() -> Self {
514
        Self::Any
515
    }
516
}
517

            
518
impl InstanceFilter<RuntimeCall> for ProxyType {
519
    fn filter(&self, c: &RuntimeCall) -> bool {
520
        // Since proxy filters are respected in all dispatches of the Utility
521
        // pallet, it should never need to be filtered by any proxy.
522
        if let RuntimeCall::Utility(..) = c {
523
            return true;
524
        }
525

            
526
        match self {
527
            ProxyType::Any => true,
528
            ProxyType::NonTransfer => {
529
                matches!(
530
                    c,
531
                    RuntimeCall::System(..)
532
                        | RuntimeCall::ParachainSystem(..)
533
                        | RuntimeCall::Timestamp(..)
534
                        | RuntimeCall::Proxy(..)
535
                )
536
            }
537
            // We don't have governance yet
538
            ProxyType::Governance => false,
539
            ProxyType::CancelProxy => matches!(
540
                c,
541
                RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
542
            ),
543
            ProxyType::Balances => {
544
                matches!(c, RuntimeCall::Balances(..))
545
            }
546
        }
547
    }
548

            
549
    fn is_superset(&self, o: &Self) -> bool {
550
        match (self, o) {
551
            (x, y) if x == y => true,
552
            (ProxyType::Any, _) => true,
553
            (_, ProxyType::Any) => false,
554
            _ => false,
555
        }
556
    }
557
}
558

            
559
impl pallet_proxy::Config for Runtime {
560
    type RuntimeEvent = RuntimeEvent;
561
    type RuntimeCall = RuntimeCall;
562
    type Currency = Balances;
563
    type ProxyType = ProxyType;
564
    // One storage item; key size 32, value size 8
565
    type ProxyDepositBase = ConstU128<{ deposit(1, 8) }>;
566
    // Additional storage item size of 33 bytes (32 bytes AccountId + 1 byte sizeof(ProxyType)).
567
    type ProxyDepositFactor = ConstU128<{ deposit(0, 33) }>;
568
    type MaxProxies = ConstU32<32>;
569
    type MaxPending = ConstU32<32>;
570
    type CallHasher = BlakeTwo256;
571
    type AnnouncementDepositBase = ConstU128<{ deposit(1, 8) }>;
572
    // Additional storage item size of 68 bytes:
573
    // - 32 bytes AccountId
574
    // - 32 bytes Hasher (Blake2256)
575
    // - 4 bytes BlockNumber (u32)
576
    type AnnouncementDepositFactor = ConstU128<{ deposit(0, 68) }>;
577
    type WeightInfo = weights::pallet_proxy::SubstrateWeight<Runtime>;
578
}
579

            
580
pub struct XcmExecutionManager;
581
impl xcm_primitives::PauseXcmExecution for XcmExecutionManager {
582
    fn suspend_xcm_execution() -> DispatchResult {
583
        XcmpQueue::suspend_xcm_execution(RuntimeOrigin::root())
584
    }
585
    fn resume_xcm_execution() -> DispatchResult {
586
        XcmpQueue::resume_xcm_execution(RuntimeOrigin::root())
587
    }
588
}
589

            
590
impl pallet_migrations::Config for Runtime {
591
    type RuntimeEvent = RuntimeEvent;
592
    type MigrationsList = (migrations::TemplateMigrations<Runtime, XcmpQueue, PolkadotXcm>,);
593
    type XcmExecutionManager = XcmExecutionManager;
594
}
595

            
596
/// Maintenance mode Call filter
597
pub struct MaintenanceFilter;
598
impl Contains<RuntimeCall> for MaintenanceFilter {
599
    fn contains(c: &RuntimeCall) -> bool {
600
        !matches!(c, RuntimeCall::Balances(_) | RuntimeCall::PolkadotXcm(_))
601
    }
602
}
603

            
604
/// Normal Call Filter
605
/// We dont allow to create nor mint assets, this for now is disabled
606
/// We only allow transfers. For now creation of assets will go through
607
/// asset-manager, while minting/burning only happens through xcm messages
608
/// This can change in the future
609
pub struct NormalFilter;
610
impl Contains<RuntimeCall> for NormalFilter {
611
    fn contains(_c: &RuntimeCall) -> bool {
612
        true
613
    }
614
}
615

            
616
impl pallet_maintenance_mode::Config for Runtime {
617
    type RuntimeEvent = RuntimeEvent;
618
    type NormalCallFilter = NormalFilter;
619
    type MaintenanceCallFilter = MaintenanceFilter;
620
    type MaintenanceOrigin = EnsureRoot<AccountId>;
621
    type XcmExecutionManager = XcmExecutionManager;
622
}
623

            
624
impl pallet_root_testing::Config for Runtime {
625
    type RuntimeEvent = RuntimeEvent;
626
}
627

            
628
impl pallet_tx_pause::Config for Runtime {
629
    type RuntimeEvent = RuntimeEvent;
630
    type RuntimeCall = RuntimeCall;
631
    type PauseOrigin = EnsureRoot<AccountId>;
632
    type UnpauseOrigin = EnsureRoot<AccountId>;
633
    type WhitelistedCalls = ();
634
    type MaxNameLen = ConstU32<256>;
635
    type WeightInfo = weights::pallet_tx_pause::SubstrateWeight<Runtime>;
636
}
637

            
638
impl dp_impl_tanssi_pallets_config::Config for Runtime {
639
    const SLOT_DURATION: u64 = SLOT_DURATION;
640
    type TimestampWeights = weights::pallet_timestamp::SubstrateWeight<Runtime>;
641
    type AuthorInherentWeights = weights::pallet_author_inherent::SubstrateWeight<Runtime>;
642
    type AuthoritiesNotingWeights = weights::pallet_cc_authorities_noting::SubstrateWeight<Runtime>;
643
}
644

            
645
parameter_types! {
646
    // One storage item; key size 32; value is size 4+4+16+32. Total = 1 * (32 + 56)
647
    pub const DepositBase: Balance = currency::deposit(1, 88);
648
    // Additional storage item size of 32 bytes.
649
    pub const DepositFactor: Balance = currency::deposit(0, 32);
650
    pub const MaxSignatories: u32 = 100;
651
}
652

            
653
impl pallet_multisig::Config for Runtime {
654
    type RuntimeEvent = RuntimeEvent;
655
    type RuntimeCall = RuntimeCall;
656
    type Currency = Balances;
657
    type DepositBase = DepositBase;
658
    type DepositFactor = DepositFactor;
659
    type MaxSignatories = MaxSignatories;
660
    type WeightInfo = weights::pallet_multisig::SubstrateWeight<Runtime>;
661
}
662

            
663
impl frame_system::offchain::SigningTypes for Runtime {
664
    type Public = <Signature as sp_runtime::traits::Verify>::Signer;
665
    type Signature = Signature;
666
}
667

            
668
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
669
where
670
    RuntimeCall: From<C>,
671
{
672
    type Extrinsic = UncheckedExtrinsic;
673
    type OverarchingCall = RuntimeCall;
674
}
675

            
676
impl pallet_ocw_testing::Config for Runtime {
677
    type RuntimeEvent = RuntimeEvent;
678
    type UnsignedInterval = ConstU32<6>;
679
}
680

            
681
impl_tanssi_pallets_config!(Runtime);
682

            
683
// Create the runtime by composing the FRAME pallets that were previously configured.
684
16162
construct_runtime!(
685
1695
    pub enum Runtime
686
1695
    {
687
1695
        // System support stuff.
688
1695
        System: frame_system = 0,
689
1695
        ParachainSystem: cumulus_pallet_parachain_system = 1,
690
1695
        Timestamp: pallet_timestamp = 2,
691
1695
        ParachainInfo: parachain_info = 3,
692
1695
        Sudo: pallet_sudo = 4,
693
1695
        Utility: pallet_utility = 5,
694
1695
        Proxy: pallet_proxy = 6,
695
1695
        Migrations: pallet_migrations = 7,
696
1695
        MaintenanceMode: pallet_maintenance_mode = 8,
697
1695
        TxPause: pallet_tx_pause = 9,
698
1695

            
699
1695
        // Monetary stuff.
700
1695
        Balances: pallet_balances = 10,
701
1695
        TransactionPayment: pallet_transaction_payment = 11,
702
1695

            
703
1695
        // Other utilities
704
1695
        Multisig: pallet_multisig = 16,
705
1695

            
706
1695
        // ContainerChain Author Verification
707
1695
        AuthoritiesNoting: pallet_cc_authorities_noting = 50,
708
1695
        AuthorInherent: pallet_author_inherent = 51,
709
1695

            
710
1695
        // XCM
711
1695
        XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Storage, Event<T>} = 70,
712
1695
        CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 71,
713
1695
        PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 73,
714
1695
        MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 74,
715
1695
        ForeignAssets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 75,
716
1695
        ForeignAssetsCreator: pallet_foreign_asset_creator::{Pallet, Call, Storage, Event<T>} = 76,
717
1695
        AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event<T>} = 77,
718
1695
        XcmExecutorUtils: pallet_xcm_executor_utils::{Pallet, Call, Storage, Event<T>} = 78,
719
1695

            
720
1695
        RootTesting: pallet_root_testing = 100,
721
1695
        AsyncBacking: pallet_async_backing::{Pallet, Storage} = 110,
722
1695

            
723
1695
        OffchainWorker: pallet_ocw_testing::{Pallet, Call, Storage, Event<T>, ValidateUnsigned} = 120,
724
1695
    }
725
16327
);
726

            
727
#[cfg(feature = "runtime-benchmarks")]
728
mod benches {
729
    frame_benchmarking::define_benchmarks!(
730
        [frame_system, frame_system_benchmarking::Pallet::<Runtime>]
731
        [cumulus_pallet_parachain_system, ParachainSystem]
732
        [pallet_timestamp, Timestamp]
733
        [pallet_sudo, Sudo]
734
        [pallet_utility, Utility]
735
        [pallet_proxy, Proxy]
736
        [pallet_tx_pause, TxPause]
737
        [pallet_balances, Balances]
738
        [pallet_multisig, Multisig]
739
        [pallet_cc_authorities_noting, AuthoritiesNoting]
740
        [pallet_author_inherent, AuthorInherent]
741
        [cumulus_pallet_xcmp_queue, XcmpQueue]
742
        [pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
743
        [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::<Runtime>]
744
        [pallet_message_queue, MessageQueue]
745
        [pallet_assets, ForeignAssets]
746
        [pallet_foreign_asset_creator, ForeignAssetsCreator]
747
        [pallet_asset_rate, AssetRate]
748
        [pallet_xcm_executor_utils, XcmExecutorUtils]
749
    );
750
}
751

            
752
6514
impl_runtime_apis! {
753
4998
    impl sp_api::Core<Block> for Runtime {
754
4998
        fn version() -> RuntimeVersion {
755
4998
            VERSION
756
4998
        }
757
4998

            
758
4998
        fn execute_block(block: Block) {
759
4998
            Executive::execute_block(block)
760
4998
        }
761
4998

            
762
4998
        fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
763
4998
            Executive::initialize_block(header)
764
4998
        }
765
4998
    }
766
4998

            
767
4998
    impl sp_api::Metadata<Block> for Runtime {
768
4998
        fn metadata() -> OpaqueMetadata {
769
4998
            OpaqueMetadata::new(Runtime::metadata().into())
770
4998
        }
771
4998

            
772
4998
        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
773
4998
            Runtime::metadata_at_version(version)
774
4998
        }
775
4998

            
776
4998
        fn metadata_versions() -> Vec<u32> {
777
4998
            Runtime::metadata_versions()
778
4998
        }
779
4998
    }
780
4998

            
781
4998
    impl sp_block_builder::BlockBuilder<Block> for Runtime {
782
4998
        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
783
4998
            Executive::apply_extrinsic(extrinsic)
784
4998
        }
785
4998

            
786
4998
        fn finalize_block() -> <Block as BlockT>::Header {
787
4998
            Executive::finalize_block()
788
4998
        }
789
4998

            
790
4998
        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
791
4998
            data.create_extrinsics()
792
4998
        }
793
4998

            
794
4998
        fn check_inherents(
795
4998
            block: Block,
796
4998
            data: sp_inherents::InherentData,
797
4998
        ) -> sp_inherents::CheckInherentsResult {
798
4998
            data.check_extrinsics(&block)
799
4998
        }
800
4998
    }
801
4998

            
802
4998
    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
803
4998
        fn validate_transaction(
804
4998
            source: TransactionSource,
805
4998
            tx: <Block as BlockT>::Extrinsic,
806
4998
            block_hash: <Block as BlockT>::Hash,
807
4998
        ) -> TransactionValidity {
808
4998
            Executive::validate_transaction(source, tx, block_hash)
809
4998
        }
810
4998
    }
811
4998

            
812
4998
    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
813
4998
        fn offchain_worker(header: &<Block as BlockT>::Header) {
814
4998
            Executive::offchain_worker(header)
815
4998
        }
816
4998
    }
817
4998

            
818
4998
    impl sp_session::SessionKeys<Block> for Runtime {
819
4998
        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
820
4998
            SessionKeys::generate(seed)
821
4998
        }
822
4998

            
823
4998
        fn decode_session_keys(
824
4998
            encoded: Vec<u8>,
825
4998
        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
826
4998
            SessionKeys::decode_into_raw_public_keys(&encoded)
827
4998
        }
828
4998
    }
829
4998

            
830
4998
    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
831
4998
        fn account_nonce(account: AccountId) -> Index {
832
4998
            System::account_nonce(account)
833
4998
        }
834
4998
    }
835
4998

            
836
4998
    impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
837
4998
        fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
838
4998
            ParachainSystem::collect_collation_info(header)
839
4998
        }
840
4998
    }
841
4998

            
842
4998
    impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
843
4998
        fn can_build_upon(
844
4998
            included_hash: <Block as BlockT>::Hash,
845
4998
            slot: async_backing_primitives::Slot,
846
4998
        ) -> bool {
847
4998
            ConsensusHook::can_build_upon(included_hash, slot)
848
4998
        }
849
4998
    }
850
4998

            
851
4998
    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
852
4998
        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
853
4998
            build_state::<RuntimeGenesisConfig>(config)
854
4998
        }
855
4998

            
856
4998
        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
857
4998
            get_preset::<RuntimeGenesisConfig>(id, |_| None)
858
4998
        }
859
4998
        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
860
4998
            vec![]
861
4998
        }
862
4998
    }
863
4998

            
864
4998
    #[cfg(feature = "runtime-benchmarks")]
865
4998
    impl frame_benchmarking::Benchmark<Block> for Runtime {
866
4998
        fn benchmark_metadata(
867
4998
            extra: bool,
868
4998
        ) -> (
869
4998
            Vec<frame_benchmarking::BenchmarkList>,
870
4998
            Vec<frame_support::traits::StorageInfo>,
871
4998
        ) {
872
4998
            use frame_benchmarking::{Benchmarking, BenchmarkList};
873
4998
            use frame_support::traits::StorageInfoTrait;
874
4998
            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
875
4998

            
876
4998
            let mut list = Vec::<BenchmarkList>::new();
877
4998
            list_benchmarks!(list, extra);
878
4998

            
879
4998
            let storage_info = AllPalletsWithSystem::storage_info();
880
4998
            (list, storage_info)
881
4998
        }
882
4998

            
883
4998
        fn dispatch_benchmark(
884
4998
            config: frame_benchmarking::BenchmarkConfig,
885
4998
        ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
886
4998
            use frame_benchmarking::{BenchmarkBatch, Benchmarking, BenchmarkError};
887
4998
            use sp_core::storage::TrackedStorageKey;
888
4998
            use staging_xcm::latest::prelude::*;
889
4998
            impl frame_system_benchmarking::Config for Runtime {
890
4998
                fn setup_set_code_requirements(code: &sp_std::vec::Vec<u8>) -> Result<(), BenchmarkError> {
891
4998
                    ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
892
4998
                    Ok(())
893
4998
                }
894
4998

            
895
4998
                fn verify_set_code() {
896
4998
                    System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
897
4998
                }
898
4998
            }
899
4998
            use crate::xcm_config::SelfReserve;
900
4998
            parameter_types! {
901
4998
                pub ExistentialDepositAsset: Option<Asset> = Some((
902
4998
                    SelfReserve::get(),
903
4998
                    ExistentialDeposit::get()
904
4998
                ).into());
905
4998
            }
906
4998

            
907
4998
            impl pallet_xcm_benchmarks::Config for Runtime {
908
4998
                type XcmConfig = xcm_config::XcmConfig;
909
4998
                type AccountIdConverter = xcm_config::LocationToAccountId;
910
4998
                type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
911
4998
                xcm_config::XcmConfig,
912
4998
                ExistentialDepositAsset,
913
4998
                xcm_config::PriceForParentDelivery,
914
4998
                >;
915
4998
                fn valid_destination() -> Result<Location, BenchmarkError> {
916
4998
                    Ok(Location::parent())
917
4998
                }
918
4998
                fn worst_case_holding(_depositable_count: u32) -> Assets {
919
4998
                    // We only care for native asset until we support others
920
4998
                    // TODO: refactor this case once other assets are supported
921
4998
                    vec![Asset{
922
4998
                        id: AssetId(SelfReserve::get()),
923
4998
                        fun: Fungible(u128::MAX),
924
4998
                    }].into()
925
4998
                }
926
4998
            }
927
4998

            
928
4998
            impl pallet_xcm_benchmarks::generic::Config for Runtime {
929
4998
                type TransactAsset = Balances;
930
4998
                type RuntimeCall = RuntimeCall;
931
4998

            
932
4998
                fn worst_case_response() -> (u64, Response) {
933
4998
                    (0u64, Response::Version(Default::default()))
934
4998
                }
935
4998

            
936
4998
                fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
937
4998
                    Err(BenchmarkError::Skip)
938
4998
                }
939
4998

            
940
4998
                fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
941
4998
                    Err(BenchmarkError::Skip)
942
4998
                }
943
4998

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

            
948
4998
                fn subscribe_origin() -> Result<Location, BenchmarkError> {
949
4998
                    Ok(Location::parent())
950
4998
                }
951
4998

            
952
4998
                fn fee_asset() -> Result<Asset, BenchmarkError> {
953
4998
                    Ok(Asset {
954
4998
                        id: AssetId(SelfReserve::get()),
955
4998
                        fun: Fungible(ExistentialDeposit::get()*100),
956
4998
                    })
957
4998
                }
958
4998

            
959
4998
                fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
960
4998
                    let origin = Location::parent();
961
4998
                    let assets: Assets = (Location::parent(), 1_000u128).into();
962
4998
                    let ticket = Location { parents: 0, interior: Here };
963
4998
                    Ok((origin, ticket, assets))
964
4998
                }
965
4998

            
966
4998
                fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
967
4998
                    Err(BenchmarkError::Skip)
968
4998
                }
969
4998

            
970
4998
                fn export_message_origin_and_destination(
971
4998
                ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
972
4998
                    Err(BenchmarkError::Skip)
973
4998
                }
974
4998

            
975
4998
                fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
976
4998
                    Err(BenchmarkError::Skip)
977
4998
                }
978
4998
            }
979
4998

            
980
4998
            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
981
4998
            impl pallet_xcm::benchmarking::Config for Runtime {
982
4998
                type DeliveryHelper = ();
983
4998
                fn get_asset() -> Asset {
984
4998
                    Asset {
985
4998
                        id: AssetId(SelfReserve::get()),
986
4998
                        fun: Fungible(ExistentialDeposit::get()),
987
4998
                    }
988
4998
                }
989
4998

            
990
4998
                fn reachable_dest() -> Option<Location> {
991
4998
                    Some(Parent.into())
992
4998
                }
993
4998

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
4998
            add_benchmarks!(params, batches);
4998

            
4998
            Ok(batches)
4998
        }
4998
    }
4998

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

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

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

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

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

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

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

            
4998
    impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
4998
        fn query_acceptable_payment_assets(xcm_version: staging_xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
4998
            if !matches!(xcm_version, 3 | 4) {
4998
                return Err(XcmPaymentApiError::UnhandledXcmVersion);
4998
            }
4998

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

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

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

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

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

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

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

            
4998
    impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
4998
        fn convert_location(location: VersionedLocation) -> Result<
4998
            AccountId,
4998
            xcm_runtime_apis::conversions::Error
4998
        > {
4998
            xcm_runtime_apis::conversions::LocationToAccountHelper::<
4998
                AccountId,
4998
                xcm_config::LocationToAccountId,
4998
            >::convert_location(location)
4998
        }
4998
    }
6514
}
#[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,
                sp_std::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>,
}