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::{MultiAddress, Perbill, Permill};
36
use {
37
    cumulus_primitives_core::AggregateMessageOrigin,
38
    dp_impl_tanssi_pallets_config::impl_tanssi_pallets_config,
39
    frame_support::{
40
        construct_runtime,
41
        dispatch::DispatchClass,
42
        genesis_builder_helper::{build_state, get_preset},
43
        pallet_prelude::DispatchResult,
44
        parameter_types,
45
        traits::{
46
            ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, Contains, InsideBoth, InstanceFilter,
47
        },
48
        weights::{
49
            constants::{
50
                BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
51
                WEIGHT_REF_TIME_PER_SECOND,
52
            },
53
            ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients,
54
            WeightToFeePolynomial,
55
        },
56
    },
57
    frame_system::{
58
        limits::{BlockLength, BlockWeights},
59
        EnsureRoot,
60
    },
61
    nimbus_primitives::{NimbusId, SlotBeacon},
62
    pallet_transaction_payment::FungibleAdapter,
63
    parity_scale_codec::{Decode, Encode},
64
    polkadot_runtime_common::SlowAdjustingFeeUpdate,
65
    scale_info::TypeInfo,
66
    smallvec::smallvec,
67
    sp_api::impl_runtime_apis,
68
    sp_consensus_slots::{Slot, SlotDuration},
69
    sp_core::{MaxEncodedLen, OpaqueMetadata},
70
    sp_runtime::{
71
        create_runtime_str, generic, impl_opaque_keys,
72
        traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
73
        transaction_validity::{TransactionSource, TransactionValidity},
74
        ApplyExtrinsicResult, MultiSignature,
75
    },
76
    sp_std::prelude::*,
77
    sp_version::RuntimeVersion,
78
};
79

            
80
pub mod xcm_config;
81

            
82
// Polkadot imports
83
use polkadot_runtime_common::BlockHashCount;
84

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

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

            
92
/// Balance of an account.
93
pub type Balance = u128;
94

            
95
/// Index of a transaction in the chain.
96
pub type Index = u32;
97

            
98
/// A hash of some data used by the chain.
99
pub type Hash = sp_core::H256;
100

            
101
/// An index to a block.
102
pub type BlockNumber = u32;
103

            
104
/// The address format for describing accounts.
105
pub type Address = MultiAddress<AccountId, ()>;
106

            
107
/// Block header type as expected by this runtime.
108
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
109

            
110
/// Block type as expected by this runtime.
111
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
112

            
113
/// A Block signed with a Justification
114
pub type SignedBlock = generic::SignedBlock<Block>;
115

            
116
/// BlockId type as expected by this runtime.
117
pub type BlockId = generic::BlockId<Block>;
118

            
119
/// The SignedExtension to the basic transaction logic.
120
pub type SignedExtra = (
121
    frame_system::CheckNonZeroSender<Runtime>,
122
    frame_system::CheckSpecVersion<Runtime>,
123
    frame_system::CheckTxVersion<Runtime>,
124
    frame_system::CheckGenesis<Runtime>,
125
    frame_system::CheckEra<Runtime>,
126
    frame_system::CheckNonce<Runtime>,
127
    frame_system::CheckWeight<Runtime>,
128
    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
129
    cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
130
);
131

            
132
/// Unchecked extrinsic type as expected by this runtime.
133
pub type UncheckedExtrinsic =
134
    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
135

            
136
/// Extrinsic type that has already been checked.
137
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra>;
138

            
139
/// Executive: handles dispatch to the various modules.
140
pub type Executive = frame_executive::Executive<
141
    Runtime,
142
    Block,
143
    frame_system::ChainContext<Runtime>,
144
    Runtime,
145
    AllPalletsWithSystem,
146
>;
147

            
148
pub mod currency {
149
    use super::Balance;
150

            
151
    pub const MICROUNIT: Balance = 1_000_000;
152
    pub const MILLIUNIT: Balance = 1_000_000_000;
153
    pub const UNIT: Balance = 1_000_000_000_000;
154
    pub const KILOUNIT: Balance = 1_000_000_000_000_000;
155

            
156
    pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT;
157

            
158
    pub const fn deposit(items: u32, bytes: u32) -> Balance {
159
        items as Balance * 100 * MILLIUNIT + (bytes as Balance) * STORAGE_BYTE_FEE
160
    }
161
}
162

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

            
190
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
191
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
192
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
193
/// to even the core data structures.
194
pub mod opaque {
195
    use {
196
        super::*,
197
        sp_runtime::{generic, traits::BlakeTwo256},
198
    };
199

            
200
    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
201
    /// Opaque block header type.
202
    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
203
    /// Opaque block type.
204
    pub type Block = generic::Block<Header, UncheckedExtrinsic>;
205
    /// Opaque block identifier type.
206
    pub type BlockId = generic::BlockId<Block>;
207
}
208

            
209
impl_opaque_keys! {
210
    pub struct SessionKeys { }
211
}
212

            
213
#[sp_version::runtime_version]
214
pub const VERSION: RuntimeVersion = RuntimeVersion {
215
    spec_name: create_runtime_str!("container-chain-template"),
216
    impl_name: create_runtime_str!("container-chain-template"),
217
    authoring_version: 1,
218
    spec_version: 800,
219
    impl_version: 0,
220
    apis: RUNTIME_API_VERSIONS,
221
    transaction_version: 1,
222
    state_version: 1,
223
};
224

            
225
/// This determines the average expected block time that we are targeting.
226
/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`.
227
/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
228
/// up by `pallet_aura` to implement `fn slot_duration()`.
229
///
230
/// Change this to adjust the block time.
231
pub const MILLISECS_PER_BLOCK: u64 = 6000;
232

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

            
237
// Time is measured by number of blocks.
238
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
239
pub const HOURS: BlockNumber = MINUTES * 60;
240
pub const DAYS: BlockNumber = HOURS * 24;
241

            
242
pub const SUPPLY_FACTOR: Balance = 100;
243

            
244
// Unit = the base number of indivisible units for balances
245
pub const UNIT: Balance = 1_000_000_000_000;
246
pub const MILLIUNIT: Balance = 1_000_000_000;
247
pub const MICROUNIT: Balance = 1_000_000;
248

            
249
pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT * SUPPLY_FACTOR;
250

            
251
pub const fn deposit(items: u32, bytes: u32) -> Balance {
252
    items as Balance * 100 * MILLIUNIT * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
253
}
254

            
255
/// The existential deposit. Set to 1/10 of the Connected Relay Chain.
256
pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
257

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

            
262
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
263
/// `Operational` extrinsics.
264
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
265

            
266
/// We allow for 0.5 of a second of compute with a 12 second average block time.
267
const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
268
    WEIGHT_REF_TIME_PER_SECOND.saturating_div(2),
269
    cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64,
270
);
271

            
272
/// The version information used to identify this runtime when compiled natively.
273
#[cfg(feature = "std")]
274
pub fn native_version() -> NativeVersion {
275
    NativeVersion {
276
        runtime_version: VERSION,
277
        can_author_with: Default::default(),
278
    }
279
}
280

            
281
parameter_types! {
282
    pub const Version: RuntimeVersion = VERSION;
283

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

            
311
// Configure FRAME pallets to include in runtime.
312

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

            
367
parameter_types! {
368
    pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
369
}
370

            
371
impl pallet_balances::Config for Runtime {
372
    type MaxLocks = ConstU32<50>;
373
    /// The type for recording an account's balance.
374
    type Balance = Balance;
375
    /// The ubiquitous event type.
376
    type RuntimeEvent = RuntimeEvent;
377
    type DustRemoval = ();
378
    type ExistentialDeposit = ExistentialDeposit;
379
    type AccountStore = System;
380
    type MaxReserves = ConstU32<50>;
381
    type ReserveIdentifier = [u8; 8];
382
    type FreezeIdentifier = RuntimeFreezeReason;
383
    type MaxFreezes = ConstU32<0>;
384
    type RuntimeHoldReason = RuntimeHoldReason;
385
    type RuntimeFreezeReason = RuntimeFreezeReason;
386
    type WeightInfo = weights::pallet_balances::SubstrateWeight<Runtime>;
387
}
388

            
389
parameter_types! {
390
    pub const TransactionByteFee: Balance = 1;
391
}
392

            
393
impl pallet_transaction_payment::Config for Runtime {
394
    type RuntimeEvent = RuntimeEvent;
395
    // This will burn the fees
396
    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
397
    type OperationalFeeMultiplier = ConstU8<5>;
398
    type WeightToFee = WeightToFee;
399
    type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
400
    type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
401
}
402

            
403
parameter_types! {
404
    pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
405
    pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
406
    pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
407
}
408

            
409
pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
410
pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
411
pub const BLOCK_PROCESSING_VELOCITY: u32 = 1;
412

            
413
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
414
    Runtime,
415
    BLOCK_PROCESSING_VELOCITY,
416
    UNINCLUDED_SEGMENT_CAPACITY,
417
>;
418

            
419
impl cumulus_pallet_parachain_system::Config for Runtime {
420
    type WeightInfo = weights::cumulus_pallet_parachain_system::SubstrateWeight<Runtime>;
421
    type RuntimeEvent = RuntimeEvent;
422
    type OnSystemEvent = ();
423
    type OutboundXcmpMessageSource = XcmpQueue;
424
    type SelfParaId = parachain_info::Pallet<Runtime>;
425
    type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
426
    type ReservedDmpWeight = ReservedDmpWeight;
427
    type XcmpMessageHandler = XcmpQueue;
428
    type ReservedXcmpWeight = ReservedXcmpWeight;
429
    type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
430
    type ConsensusHook = ConsensusHook;
431
}
432

            
433
pub struct ParaSlotProvider;
434
impl sp_core::Get<(Slot, SlotDuration)> for ParaSlotProvider {
435
114
    fn get() -> (Slot, SlotDuration) {
436
114
        let slot = u64::from(<Runtime as pallet_author_inherent::Config>::SlotBeacon::slot());
437
114
        (Slot::from(slot), SlotDuration::from_millis(SLOT_DURATION))
438
114
    }
439
}
440

            
441
parameter_types! {
442
    pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
443
}
444

            
445
impl pallet_async_backing::Config for Runtime {
446
    type AllowMultipleBlocksPerSlot = ConstBool<true>;
447
    type GetAndVerifySlot =
448
        pallet_async_backing::ParaSlot<RELAY_CHAIN_SLOT_DURATION_MILLIS, ParaSlotProvider>;
449
    type ExpectedBlockTime = ExpectedBlockTime;
450
}
451

            
452
impl parachain_info::Config for Runtime {}
453

            
454
parameter_types! {
455
    pub const Period: u32 = 6 * HOURS;
456
    pub const Offset: u32 = 0;
457
}
458

            
459
impl pallet_sudo::Config for Runtime {
460
    type RuntimeCall = RuntimeCall;
461
    type RuntimeEvent = RuntimeEvent;
462
    type WeightInfo = weights::pallet_sudo::SubstrateWeight<Runtime>;
463
}
464

            
465
impl pallet_utility::Config for Runtime {
466
    type RuntimeEvent = RuntimeEvent;
467
    type RuntimeCall = RuntimeCall;
468
    type PalletsOrigin = OriginCaller;
469
    type WeightInfo = weights::pallet_utility::SubstrateWeight<Runtime>;
470
}
471

            
472
/// The type used to represent the kinds of proxying allowed.
473
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
474
#[derive(
475
    Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, MaxEncodedLen, TypeInfo,
476
)]
477
#[allow(clippy::unnecessary_cast)]
478
pub enum ProxyType {
479
    /// All calls can be proxied. This is the trivial/most permissive filter.
480
    Any = 0,
481
    /// Only extrinsics that do not transfer funds.
482
    NonTransfer = 1,
483
    /// Only extrinsics related to governance (democracy and collectives).
484
    Governance = 2,
485
    /// Allow to veto an announced proxy call.
486
    CancelProxy = 3,
487
    /// Allow extrinsic related to Balances.
488
    Balances = 4,
489
}
490

            
491
impl Default for ProxyType {
492
    fn default() -> Self {
493
        Self::Any
494
    }
495
}
496

            
497
impl InstanceFilter<RuntimeCall> for ProxyType {
498
    fn filter(&self, c: &RuntimeCall) -> bool {
499
        // Since proxy filters are respected in all dispatches of the Utility
500
        // pallet, it should never need to be filtered by any proxy.
501
        if let RuntimeCall::Utility(..) = c {
502
            return true;
503
        }
504

            
505
        match self {
506
            ProxyType::Any => true,
507
            ProxyType::NonTransfer => {
508
                matches!(
509
                    c,
510
                    RuntimeCall::System(..)
511
                        | RuntimeCall::ParachainSystem(..)
512
                        | RuntimeCall::Timestamp(..)
513
                        | RuntimeCall::Proxy(..)
514
                )
515
            }
516
            // We don't have governance yet
517
            ProxyType::Governance => false,
518
            ProxyType::CancelProxy => matches!(
519
                c,
520
                RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
521
            ),
522
            ProxyType::Balances => {
523
                matches!(c, RuntimeCall::Balances(..))
524
            }
525
        }
526
    }
527

            
528
    fn is_superset(&self, o: &Self) -> bool {
529
        match (self, o) {
530
            (x, y) if x == y => true,
531
            (ProxyType::Any, _) => true,
532
            (_, ProxyType::Any) => false,
533
            _ => false,
534
        }
535
    }
536
}
537

            
538
impl pallet_proxy::Config for Runtime {
539
    type RuntimeEvent = RuntimeEvent;
540
    type RuntimeCall = RuntimeCall;
541
    type Currency = Balances;
542
    type ProxyType = ProxyType;
543
    // One storage item; key size 32, value size 8
544
    type ProxyDepositBase = ConstU128<{ deposit(1, 8) }>;
545
    // Additional storage item size of 33 bytes (32 bytes AccountId + 1 byte sizeof(ProxyType)).
546
    type ProxyDepositFactor = ConstU128<{ deposit(0, 33) }>;
547
    type MaxProxies = ConstU32<32>;
548
    type MaxPending = ConstU32<32>;
549
    type CallHasher = BlakeTwo256;
550
    type AnnouncementDepositBase = ConstU128<{ deposit(1, 8) }>;
551
    // Additional storage item size of 68 bytes:
552
    // - 32 bytes AccountId
553
    // - 32 bytes Hasher (Blake2256)
554
    // - 4 bytes BlockNumber (u32)
555
    type AnnouncementDepositFactor = ConstU128<{ deposit(0, 68) }>;
556
    type WeightInfo = weights::pallet_proxy::SubstrateWeight<Runtime>;
557
}
558

            
559
pub struct XcmExecutionManager;
560
impl xcm_primitives::PauseXcmExecution for XcmExecutionManager {
561
    fn suspend_xcm_execution() -> DispatchResult {
562
        XcmpQueue::suspend_xcm_execution(RuntimeOrigin::root())
563
    }
564
    fn resume_xcm_execution() -> DispatchResult {
565
        XcmpQueue::resume_xcm_execution(RuntimeOrigin::root())
566
    }
567
}
568

            
569
impl pallet_migrations::Config for Runtime {
570
    type RuntimeEvent = RuntimeEvent;
571
    type MigrationsList = (migrations::TemplateMigrations<Runtime, XcmpQueue, PolkadotXcm>,);
572
    type XcmExecutionManager = XcmExecutionManager;
573
}
574

            
575
/// Maintenance mode Call filter
576
pub struct MaintenanceFilter;
577
impl Contains<RuntimeCall> for MaintenanceFilter {
578
    fn contains(c: &RuntimeCall) -> bool {
579
        !matches!(c, RuntimeCall::Balances(_) | RuntimeCall::PolkadotXcm(_))
580
    }
581
}
582

            
583
/// Normal Call Filter
584
/// We dont allow to create nor mint assets, this for now is disabled
585
/// We only allow transfers. For now creation of assets will go through
586
/// asset-manager, while minting/burning only happens through xcm messages
587
/// This can change in the future
588
pub struct NormalFilter;
589
impl Contains<RuntimeCall> for NormalFilter {
590
    fn contains(_c: &RuntimeCall) -> bool {
591
        true
592
    }
593
}
594

            
595
impl pallet_maintenance_mode::Config for Runtime {
596
    type RuntimeEvent = RuntimeEvent;
597
    type NormalCallFilter = NormalFilter;
598
    type MaintenanceCallFilter = MaintenanceFilter;
599
    type MaintenanceOrigin = EnsureRoot<AccountId>;
600
    type XcmExecutionManager = XcmExecutionManager;
601
}
602

            
603
impl pallet_root_testing::Config for Runtime {
604
    type RuntimeEvent = RuntimeEvent;
605
}
606

            
607
impl pallet_tx_pause::Config for Runtime {
608
    type RuntimeEvent = RuntimeEvent;
609
    type RuntimeCall = RuntimeCall;
610
    type PauseOrigin = EnsureRoot<AccountId>;
611
    type UnpauseOrigin = EnsureRoot<AccountId>;
612
    type WhitelistedCalls = ();
613
    type MaxNameLen = ConstU32<256>;
614
    type WeightInfo = weights::pallet_tx_pause::SubstrateWeight<Runtime>;
615
}
616

            
617
impl dp_impl_tanssi_pallets_config::Config for Runtime {
618
    const SLOT_DURATION: u64 = SLOT_DURATION;
619
    type TimestampWeights = weights::pallet_timestamp::SubstrateWeight<Runtime>;
620
    type AuthorInherentWeights = weights::pallet_author_inherent::SubstrateWeight<Runtime>;
621
    type AuthoritiesNotingWeights = weights::pallet_cc_authorities_noting::SubstrateWeight<Runtime>;
622
}
623

            
624
parameter_types! {
625
    // One storage item; key size 32; value is size 4+4+16+32. Total = 1 * (32 + 56)
626
    pub const DepositBase: Balance = currency::deposit(1, 88);
627
    // Additional storage item size of 32 bytes.
628
    pub const DepositFactor: Balance = currency::deposit(0, 32);
629
    pub const MaxSignatories: u32 = 100;
630
}
631

            
632
impl pallet_multisig::Config for Runtime {
633
    type RuntimeEvent = RuntimeEvent;
634
    type RuntimeCall = RuntimeCall;
635
    type Currency = Balances;
636
    type DepositBase = DepositBase;
637
    type DepositFactor = DepositFactor;
638
    type MaxSignatories = MaxSignatories;
639
    type WeightInfo = weights::pallet_multisig::SubstrateWeight<Runtime>;
640
}
641

            
642
impl_tanssi_pallets_config!(Runtime);
643

            
644
// Create the runtime by composing the FRAME pallets that were previously configured.
645
22492
construct_runtime!(
646
3284
    pub enum Runtime
647
3284
    {
648
3284
        // System support stuff.
649
3284
        System: frame_system = 0,
650
3284
        ParachainSystem: cumulus_pallet_parachain_system = 1,
651
3284
        Timestamp: pallet_timestamp = 2,
652
3284
        ParachainInfo: parachain_info = 3,
653
3284
        Sudo: pallet_sudo = 4,
654
3284
        Utility: pallet_utility = 5,
655
3284
        Proxy: pallet_proxy = 6,
656
3284
        Migrations: pallet_migrations = 7,
657
3284
        MaintenanceMode: pallet_maintenance_mode = 8,
658
3284
        TxPause: pallet_tx_pause = 9,
659
3284

            
660
3284
        // Monetary stuff.
661
3284
        Balances: pallet_balances = 10,
662
3284
        TransactionPayment: pallet_transaction_payment = 11,
663
3284

            
664
3284
        // Other utilities
665
3284
        Multisig: pallet_multisig = 16,
666
3284

            
667
3284
        // ContainerChain Author Verification
668
3284
        AuthoritiesNoting: pallet_cc_authorities_noting = 50,
669
3284
        AuthorInherent: pallet_author_inherent = 51,
670
3284

            
671
3284
        // XCM
672
3284
        XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Storage, Event<T>} = 70,
673
3284
        CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 71,
674
3284
        DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 72,
675
3284
        PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 73,
676
3284
        MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 74,
677
3284
        ForeignAssets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 75,
678
3284
        ForeignAssetsCreator: pallet_foreign_asset_creator::{Pallet, Call, Storage, Event<T>} = 76,
679
3284
        AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event<T>} = 77,
680
3284
        XcmExecutorUtils: pallet_xcm_executor_utils::{Pallet, Call, Storage, Event<T>} = 78,
681
3284

            
682
3284
        RootTesting: pallet_root_testing = 100,
683
3284
        AsyncBacking: pallet_async_backing::{Pallet, Storage} = 110,
684
3284

            
685
3284
    }
686
22492
);
687

            
688
#[cfg(feature = "runtime-benchmarks")]
689
mod benches {
690
    frame_benchmarking::define_benchmarks!(
691
        [frame_system, frame_system_benchmarking::Pallet::<Runtime>]
692
        [cumulus_pallet_parachain_system, ParachainSystem]
693
        [pallet_timestamp, Timestamp]
694
        [pallet_sudo, Sudo]
695
        [pallet_utility, Utility]
696
        [pallet_proxy, Proxy]
697
        [pallet_tx_pause, TxPause]
698
        [pallet_balances, Balances]
699
        [pallet_multisig, Multisig]
700
        [pallet_cc_authorities_noting, AuthoritiesNoting]
701
        [pallet_author_inherent, AuthorInherent]
702
        [cumulus_pallet_xcmp_queue, XcmpQueue]
703
        [cumulus_pallet_dmp_queue, DmpQueue]
704
        [pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
705
        [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::<Runtime>]
706
        [pallet_message_queue, MessageQueue]
707
        [pallet_assets, ForeignAssets]
708
        [pallet_foreign_asset_creator, ForeignAssetsCreator]
709
        [pallet_asset_rate, AssetRate]
710
        [pallet_xcm_executor_utils, XcmExecutorUtils]
711
    );
712
}
713

            
714
6532
impl_runtime_apis! {
715
4450
    impl sp_api::Core<Block> for Runtime {
716
4450
        fn version() -> RuntimeVersion {
717
            VERSION
718
        }
719
4450

            
720
4450
        fn execute_block(block: Block) {
721
            Executive::execute_block(block)
722
        }
723
4450

            
724
4450
        fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
725
            Executive::initialize_block(header)
726
        }
727
4450
    }
728
4450

            
729
4450
    impl sp_api::Metadata<Block> for Runtime {
730
4450
        fn metadata() -> OpaqueMetadata {
731
            OpaqueMetadata::new(Runtime::metadata().into())
732
        }
733
4450

            
734
4450
        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
735
            Runtime::metadata_at_version(version)
736
        }
737
4450

            
738
4450
        fn metadata_versions() -> Vec<u32> {
739
            Runtime::metadata_versions()
740
        }
741
4450
    }
742
4450

            
743
4450
    impl sp_block_builder::BlockBuilder<Block> for Runtime {
744
4450
        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
745
            Executive::apply_extrinsic(extrinsic)
746
        }
747
4450

            
748
4450
        fn finalize_block() -> <Block as BlockT>::Header {
749
            Executive::finalize_block()
750
        }
751
4450

            
752
4450
        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
753
            data.create_extrinsics()
754
        }
755
4450

            
756
4450
        fn check_inherents(
757
            block: Block,
758
            data: sp_inherents::InherentData,
759
        ) -> sp_inherents::CheckInherentsResult {
760
            data.check_extrinsics(&block)
761
        }
762
4450
    }
763
4450

            
764
4450
    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
765
4450
        fn validate_transaction(
766
            source: TransactionSource,
767
            tx: <Block as BlockT>::Extrinsic,
768
            block_hash: <Block as BlockT>::Hash,
769
        ) -> TransactionValidity {
770
            Executive::validate_transaction(source, tx, block_hash)
771
        }
772
4450
    }
773
4450

            
774
4450
    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
775
4450
        fn offchain_worker(header: &<Block as BlockT>::Header) {
776
            Executive::offchain_worker(header)
777
        }
778
4450
    }
779
4450

            
780
4450
    impl sp_session::SessionKeys<Block> for Runtime {
781
4450
        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
782
            SessionKeys::generate(seed)
783
        }
784
4450

            
785
4450
        fn decode_session_keys(
786
            encoded: Vec<u8>,
787
        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
788
            SessionKeys::decode_into_raw_public_keys(&encoded)
789
        }
790
4450
    }
791
4450

            
792
4450
    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
793
4450
        fn account_nonce(account: AccountId) -> Index {
794
            System::account_nonce(account)
795
        }
796
4450
    }
797
4450

            
798
4450
    impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
799
4450
        fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
800
            ParachainSystem::collect_collation_info(header)
801
        }
802
4450
    }
803
4450

            
804
4450
    impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
805
4450
        fn can_build_upon(
806
            included_hash: <Block as BlockT>::Hash,
807
            slot: async_backing_primitives::Slot,
808
        ) -> bool {
809
            ConsensusHook::can_build_upon(included_hash, slot)
810
        }
811
4450
    }
812
4450

            
813
4450
    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
814
4450
        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
815
            build_state::<RuntimeGenesisConfig>(config)
816
        }
817
4450

            
818
4450
        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
819
            get_preset::<RuntimeGenesisConfig>(id, |_| None)
820
        }
821
4450
        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
822
            vec![]
823
        }
824
4450
    }
825
4450

            
826
4450
    #[cfg(feature = "runtime-benchmarks")]
827
4450
    impl frame_benchmarking::Benchmark<Block> for Runtime {
828
4450
        fn benchmark_metadata(
829
4450
            extra: bool,
830
4450
        ) -> (
831
4450
            Vec<frame_benchmarking::BenchmarkList>,
832
4450
            Vec<frame_support::traits::StorageInfo>,
833
4450
        ) {
834
4450
            use frame_benchmarking::{Benchmarking, BenchmarkList};
835
4450
            use frame_support::traits::StorageInfoTrait;
836
4450
            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
837
4450

            
838
4450
            let mut list = Vec::<BenchmarkList>::new();
839
4450
            list_benchmarks!(list, extra);
840
4450

            
841
4450
            let storage_info = AllPalletsWithSystem::storage_info();
842
4450
            (list, storage_info)
843
4450
        }
844
4450

            
845
4450
        fn dispatch_benchmark(
846
4450
            config: frame_benchmarking::BenchmarkConfig,
847
4450
        ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
848
4450
            use frame_benchmarking::{BenchmarkBatch, Benchmarking, BenchmarkError};
849
4450
            use sp_core::storage::TrackedStorageKey;
850
4450
            use staging_xcm::latest::prelude::*;
851
4450
            impl frame_system_benchmarking::Config for Runtime {
852
4450
                fn setup_set_code_requirements(code: &sp_std::vec::Vec<u8>) -> Result<(), BenchmarkError> {
853
4450
                    ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
854
4450
                    Ok(())
855
4450
                }
856
4450

            
857
4450
                fn verify_set_code() {
858
4450
                    System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
859
4450
                }
860
4450
            }
861
4450
            use crate::xcm_config::SelfReserve;
862
4450
            parameter_types! {
863
4450
                pub ExistentialDepositAsset: Option<Asset> = Some((
864
4450
                    SelfReserve::get(),
865
4450
                    ExistentialDeposit::get()
866
4450
                ).into());
867
4450
            }
868
4450

            
869
4450
            impl pallet_xcm_benchmarks::Config for Runtime {
870
4450
                type XcmConfig = xcm_config::XcmConfig;
871
4450
                type AccountIdConverter = xcm_config::LocationToAccountId;
872
4450
                type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
873
4450
                xcm_config::XcmConfig,
874
4450
                ExistentialDepositAsset,
875
4450
                xcm_config::PriceForParentDelivery,
876
4450
                >;
877
4450
                fn valid_destination() -> Result<Location, BenchmarkError> {
878
4450
                    Ok(Location::parent())
879
4450
                }
880
4450
                fn worst_case_holding(_depositable_count: u32) -> Assets {
881
4450
                    // We only care for native asset until we support others
882
4450
                    // TODO: refactor this case once other assets are supported
883
4450
                    vec![Asset{
884
4450
                        id: AssetId(SelfReserve::get()),
885
4450
                        fun: Fungible(u128::MAX),
886
4450
                    }].into()
887
4450
                }
888
4450
            }
889
4450

            
890
4450
            impl pallet_xcm_benchmarks::generic::Config for Runtime {
891
4450
                type TransactAsset = Balances;
892
4450
                type RuntimeCall = RuntimeCall;
893
4450

            
894
4450
                fn worst_case_response() -> (u64, Response) {
895
4450
                    (0u64, Response::Version(Default::default()))
896
4450
                }
897
4450

            
898
4450
                fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
899
4450
                    Err(BenchmarkError::Skip)
900
4450
                }
901
4450

            
902
4450
                fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
903
4450
                    Err(BenchmarkError::Skip)
904
4450
                }
905
4450

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

            
910
4450
                fn subscribe_origin() -> Result<Location, BenchmarkError> {
911
4450
                    Ok(Location::parent())
912
4450
                }
913
4450

            
914
4450
                fn fee_asset() -> Result<Asset, BenchmarkError> {
915
4450
                    Ok(Asset {
916
4450
                        id: AssetId(SelfReserve::get()),
917
4450
                        fun: Fungible(ExistentialDeposit::get()*100),
918
4450
                    })
919
4450
                }
920
4450

            
921
4450
                fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
922
4450
                    let origin = Location::parent();
923
4450
                    let assets: Assets = (Location::parent(), 1_000u128).into();
924
4450
                    let ticket = Location { parents: 0, interior: Here };
925
4450
                    Ok((origin, ticket, assets))
926
4450
                }
927
4450

            
928
4450
                fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
929
4450
                    Err(BenchmarkError::Skip)
930
4450
                }
931
4450

            
932
4450
                fn export_message_origin_and_destination(
933
4450
                ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
934
4450
                    Err(BenchmarkError::Skip)
935
4450
                }
936
4450

            
937
4450
                fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
938
4450
                    Err(BenchmarkError::Skip)
939
4450
                }
940
4450
            }
941
4450

            
942
4450
            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
943
4450
            impl pallet_xcm::benchmarking::Config for Runtime {
944
4450
                type DeliveryHelper = ();
945
4450
                fn get_asset() -> Asset {
946
4450
                    Asset {
947
4450
                        id: AssetId(SelfReserve::get()),
948
4450
                        fun: Fungible(ExistentialDeposit::get()),
949
4450
                    }
950
4450
                }
951
4450

            
952
4450
                fn reachable_dest() -> Option<Location> {
953
4450
                    Some(Parent.into())
954
4450
                }
955
4450

            
956
4450
                fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
957
4450
                    // Relay/native token can be teleported between AH and Relay.
958
4450
                    Some((
959
4450
                        Asset {
960
4450
                            fun: Fungible(EXISTENTIAL_DEPOSIT),
961
4450
                            id: Parent.into()
962
4450
                        },
963
4450
                        Parent.into(),
964
4450
                    ))
965
4450
                }
966
4450

            
967
4450
                fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
968
4450
                    use xcm_config::SelfReserve;
969
4450
                    // AH can reserve transfer native token to some random parachain.
970
4450
                    let random_para_id = 43211234;
971
4450
                    ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
972
4450
                        random_para_id.into()
973
4450
                    );
974
4450
                    let who = frame_benchmarking::whitelisted_caller();
975
4450
                    // Give some multiple of the existential deposit
976
4450
                    let balance = EXISTENTIAL_DEPOSIT * 1000;
977
4450
                    let _ = <Balances as frame_support::traits::Currency<_>>::make_free_balance_be(
978
4450
                        &who, balance,
979
4450
                    );
980
4450
                    Some((
981
4450
                        Asset {
982
4450
                            fun: Fungible(EXISTENTIAL_DEPOSIT*10),
983
4450
                            id: SelfReserve::get().into()
984
4450
                        },
985
4450
                        ParentThen(Parachain(random_para_id).into()).into(),
986
4450
                    ))
987
4450
                }
988
4450

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

            
997
4450
                    let fee_amount = EXISTENTIAL_DEPOSIT;
998
4450
                    let fee_asset: Asset = (SelfReserve::get(), fee_amount).into();
999
4450

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

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

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

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

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

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

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

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

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

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

            
4450
            add_benchmarks!(params, batches);
4450

            
4450
            Ok(batches)
4450
        }
4450
    }
4450

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

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

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

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

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

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

            
4450
    impl dp_slot_duration_runtime_api::TanssiSlotDurationApi<Block> for Runtime {
4450
        fn slot_duration() -> u64 {
            SLOT_DURATION
        }
4450
    }
6532
}
#[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>,
}