shibuya_runtime/
lib.rs

1// This file is part of Astar.
2
3// Copyright (C) Stake Technologies Pte.Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6// Astar is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// Astar is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with Astar. If not, see <http://www.gnu.org/licenses/>.
18
19//! The Shibuya Network runtime. This can be compiled with ``#[no_std]`, ready for Wasm.
20
21#![cfg_attr(not(feature = "std"), no_std)]
22// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 512.
23#![recursion_limit = "512"]
24
25extern crate alloc;
26extern crate core;
27
28use alloc::{borrow::Cow, collections::btree_map::BTreeMap, vec, vec::Vec};
29use core::marker::PhantomData;
30
31use cumulus_primitives_core::AggregateMessageOrigin;
32use ethereum::AuthorizationList;
33use frame_support::{
34    dispatch::DispatchClass,
35    genesis_builder_helper, parameter_types,
36    traits::{
37        fungible::{Balanced, Credit, HoldConsideration},
38        AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, Contains,
39        EqualPrivilegeOnly, FindAuthor, Get, Imbalance, InsideBoth, InstanceFilter,
40        LinearStoragePrice, OnFinalize, OnUnbalanced, WithdrawReasons,
41    },
42    weights::{
43        constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND},
44        ConstantMultiplier, Weight, WeightToFee as WeightToFeeT, WeightToFeeCoefficient,
45        WeightToFeeCoefficients, WeightToFeePolynomial,
46    },
47    ConsensusEngineId, PalletId,
48};
49use frame_system::{
50    limits::{BlockLength, BlockWeights},
51    EnsureRoot, EnsureSigned, EnsureWithSuccess,
52};
53use pallet_ethereum::PostLogContent;
54use pallet_evm::{FeeCalculator, GasWeightMapping, Runner};
55use pallet_identity::legacy::IdentityInfo;
56use pallet_transaction_payment::{
57    FeeDetails, Multiplier, RuntimeDispatchInfo, TargetedFeeAdjustment,
58};
59use pallet_tx_pause::RuntimeCallNameOf;
60use parity_scale_codec::{Compact, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
61use polkadot_runtime_common::BlockHashCount;
62use sp_api::impl_runtime_apis;
63use sp_core::{sr25519, OpaqueMetadata, H160, H256, U256};
64use sp_inherents::{CheckInherentsResult, InherentData};
65use sp_runtime::{
66    generic, impl_opaque_keys,
67    traits::{
68        AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto,
69        DispatchInfoOf, Dispatchable, OpaqueKeys, PostDispatchInfoOf, UniqueSaturatedInto,
70    },
71    transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
72    ApplyExtrinsicResult, FixedPointNumber, Perbill, Permill, Perquintill, RuntimeDebug,
73};
74use xcm::{
75    v5::{AssetId as XcmAssetId, Location as XcmLocation},
76    IntoVersion, Version as XcmVersion, VersionedAsset, VersionedAssetId, VersionedAssets,
77    VersionedLocation, VersionedXcm,
78};
79use xcm_runtime_apis::{
80    dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
81    fees::Error as XcmPaymentApiError,
82};
83
84use astar_primitives::{
85    dapp_staking::{
86        AccountCheck as DappStakingAccountCheck, CycleConfiguration, DAppId, EraNumber,
87        PeriodNumber, RankedTier, SmartContract, FIXED_NUMBER_OF_TIER_SLOTS,
88    },
89    evm::{EVMFungibleAdapterWrapper, EvmRevertCodeHandler, TX_MAX_GAS_LIMIT},
90    governance::{
91        CommunityCouncilCollectiveInst, CommunityCouncilMembershipInst, CommunityTreasuryInst,
92        EnsureRootOrAllMainCouncil, EnsureRootOrAllTechnicalCommittee,
93        EnsureRootOrFourFifthsCommunityCouncil, EnsureRootOrHalfCommunityCouncil,
94        EnsureRootOrHalfMainCouncil, EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil,
95        EnsureRootOrHalfTechnicalCommittee, EnsureRootOrThreeFourthMainCouncil,
96        EnsureRootOrTwoThirdsMainCouncil, MainCouncilCollectiveInst, MainCouncilMembershipInst,
97        MainTreasuryInst, TechnicalCommitteeCollectiveInst, TechnicalCommitteeMembershipInst,
98    },
99    xcm::AssetLocationIdConverter,
100    Address, AssetId, BlockNumber, Hash, Header, Nonce, UnfreezeChainOnFailedMigration,
101};
102pub use astar_primitives::{AccountId, Balance, Signature};
103
104pub use pallet_dapp_staking::TierThreshold;
105pub use pallet_inflation::InflationParameters;
106
107pub use crate::precompiles::WhitelistedCalls;
108
109use pallet_evm_precompile_assets_erc20::AddressToAssetId;
110
111#[cfg(any(feature = "std", test))]
112use sp_version::NativeVersion;
113use sp_version::RuntimeVersion;
114
115pub use frame_system::Call as SystemCall;
116pub use pallet_balances::Call as BalancesCall;
117use parachains_common::message_queue::NarrowOriginToSibling;
118pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
119#[cfg(any(feature = "std", test))]
120pub use sp_runtime::BuildStorage;
121
122pub mod genesis_config;
123mod precompiles;
124pub mod xcm_config;
125
126mod weights;
127use weights::{BlockExecutionWeight, ExtrinsicBaseWeight};
128
129pub type ShibuyaAssetLocationIdConverter = AssetLocationIdConverter<AssetId, XcAssetConfig>;
130
131pub use precompiles::{ShibuyaPrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX};
132pub type Precompiles = ShibuyaPrecompiles<Runtime, ShibuyaAssetLocationIdConverter>;
133
134/// Constant values used within the runtime.
135pub const MICROSBY: Balance = 1_000_000_000_000;
136pub const MILLISBY: Balance = 1_000 * MICROSBY;
137pub const SBY: Balance = 1_000 * MILLISBY;
138
139pub const STORAGE_BYTE_FEE: Balance = MICROSBY;
140
141/// Charge fee for stored bytes and items.
142pub const fn deposit(items: u32, bytes: u32) -> Balance {
143    items as Balance * 1 * SBY + (bytes as Balance) * STORAGE_BYTE_FEE
144}
145
146/// Change this to adjust the block time.
147pub const MILLISECS_PER_BLOCK: u64 = 6000;
148pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
149
150// Time is measured by number of blocks.
151pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
152pub const HOURS: BlockNumber = MINUTES * 60;
153pub const DAYS: BlockNumber = HOURS * 24;
154
155/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included into the
156/// relay chain.
157pub const UNINCLUDED_SEGMENT_CAPACITY: u32 =
158    (2 + RELAY_PARENT_OFFSET) * BLOCK_PROCESSING_VELOCITY + 1;
159/// How many parachain blocks are processed by the relay chain per parent. Limits the number of
160/// blocks authored per slot.
161pub const BLOCK_PROCESSING_VELOCITY: u32 = 1;
162/// Relay chain slot duration, in milliseconds.
163pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
164/// Relay chain best block offset to build blocks on.
165#[cfg(not(feature = "runtime-benchmarks"))]
166const RELAY_PARENT_OFFSET: u32 = 0;
167#[cfg(feature = "runtime-benchmarks")]
168const RELAY_PARENT_OFFSET: u32 = 0;
169
170impl AddressToAssetId<AssetId> for Runtime {
171    fn address_to_asset_id(address: H160) -> Option<AssetId> {
172        let mut data = [0u8; 16];
173        let address_bytes: [u8; 20] = address.into();
174        if ASSET_PRECOMPILE_ADDRESS_PREFIX.eq(&address_bytes[0..4]) {
175            data.copy_from_slice(&address_bytes[4..20]);
176            Some(u128::from_be_bytes(data))
177        } else {
178            None
179        }
180    }
181
182    fn asset_id_to_address(asset_id: AssetId) -> H160 {
183        let mut data = [0u8; 20];
184        data[0..4].copy_from_slice(ASSET_PRECOMPILE_ADDRESS_PREFIX);
185        data[4..20].copy_from_slice(&asset_id.to_be_bytes());
186        H160::from(data)
187    }
188}
189
190// Make the WASM binary available.
191#[cfg(feature = "std")]
192include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
193
194#[cfg(feature = "std")]
195/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics.
196pub fn wasm_binary_unwrap() -> &'static [u8] {
197    WASM_BINARY.expect(
198        "Development wasm binary is not available. This means the client is \
199                        built with `BUILD_DUMMY_WASM_BINARY` flag and it is only usable for \
200                        production chains. Please rebuild with the flag disabled.",
201    )
202}
203
204/// Runtime version.
205#[sp_version::runtime_version]
206pub const VERSION: RuntimeVersion = RuntimeVersion {
207    spec_name: Cow::Borrowed("shibuya"),
208    impl_name: Cow::Borrowed("shibuya"),
209    authoring_version: 1,
210    spec_version: 2400,
211    impl_version: 0,
212    apis: RUNTIME_API_VERSIONS,
213    transaction_version: 4,
214    system_version: 1,
215};
216
217/// Native version.
218#[cfg(any(feature = "std", test))]
219pub fn native_version() -> NativeVersion {
220    NativeVersion {
221        runtime_version: VERSION,
222        can_author_with: Default::default(),
223    }
224}
225
226impl_opaque_keys! {
227    pub struct SessionKeys {
228        pub aura: Aura,
229    }
230}
231
232/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
233/// This is used to limit the maximal weight of a single extrinsic.
234const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
235/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
236/// by  Operational  extrinsics.
237const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
238/// We allow for 2 seconds of compute with a 6 second average block time.
239const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
240    WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
241    polkadot_primitives::MAX_POV_SIZE as u64,
242);
243
244parameter_types! {
245    pub const Version: RuntimeVersion = VERSION;
246    pub RuntimeBlockLength: BlockLength =
247        BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
248    pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
249        .base_block(BlockExecutionWeight::get())
250        .for_class(DispatchClass::all(), |weights| {
251            weights.base_extrinsic = ExtrinsicBaseWeight::get();
252        })
253        .for_class(DispatchClass::Normal, |weights| {
254            weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
255        })
256        .for_class(DispatchClass::Operational, |weights| {
257            weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
258            // Operational transactions have some extra reserved space, so that they
259            // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
260            weights.reserved = Some(
261                MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
262            );
263        })
264        .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
265        .build_or_panic();
266    pub SS58Prefix: u8 = 5;
267}
268
269pub struct BaseFilter;
270impl Contains<RuntimeCall> for BaseFilter {
271    fn contains(call: &RuntimeCall) -> bool {
272        match call {
273            // Filter permission-less assets creation/destroying.
274            // Custom asset's `id` should fit in `u32` as not to mix with service assets.
275            RuntimeCall::Assets(method) => match method {
276                pallet_assets::Call::create { id, .. } => *id < (u32::MAX as AssetId).into(),
277
278                _ => true,
279            },
280            // Filter cross-chain asset config, only allow registration for non-root users
281            RuntimeCall::XcAssetConfig(method) => match method {
282                pallet_xc_asset_config::Call::register_asset_location { .. } => true,
283                // registering the asset location should be good enough for users, any change can be handled via issue ticket or help request
284                _ => false,
285            },
286            // These modules are not allowed to be called by transactions:
287            // Other modules should works:
288            _ => true,
289        }
290    }
291}
292
293type SafeModeTxPauseFilter = InsideBoth<SafeMode, TxPause>;
294type BaseCallFilter = InsideBoth<BaseFilter, SafeModeTxPauseFilter>;
295
296impl frame_system::Config for Runtime {
297    /// The identifier used to distinguish between accounts.
298    type AccountId = AccountId;
299    /// The aggregated dispatch type that is available for extrinsics.
300    type RuntimeCall = RuntimeCall;
301    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
302    type Lookup = AccountIdLookup<AccountId, ()>;
303    /// The nonce type for storing how many extrinsics an account has signed.
304    type Nonce = Nonce;
305    /// The type for blocks.
306    type Block = Block;
307    /// The type for hashing blocks and tries.
308    type Hash = Hash;
309    /// The hashing algorithm used.
310    type Hashing = BlakeTwo256;
311    /// The ubiquitous event type.
312    type RuntimeEvent = RuntimeEvent;
313    /// The ubiquitous origin type.
314    type RuntimeOrigin = RuntimeOrigin;
315    /// The aggregated RuntimeTask type.
316    type RuntimeTask = RuntimeTask;
317    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
318    type BlockHashCount = BlockHashCount;
319    /// Runtime version.
320    type Version = Version;
321    /// Converts a module to an index of this module in the runtime.
322    type PalletInfo = PalletInfo;
323    type AccountData = pallet_balances::AccountData<Balance>;
324    type OnNewAccount = ();
325    type OnKilledAccount = ();
326    type DbWeight = RocksDbWeight;
327    type BaseCallFilter = BaseCallFilter;
328    type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
329    type BlockWeights = RuntimeBlockWeights;
330    type BlockLength = RuntimeBlockLength;
331    type SS58Prefix = SS58Prefix;
332    type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
333    type MaxConsumers = frame_support::traits::ConstU32<16>;
334    type SingleBlockMigrations = ();
335    type MultiBlockMigrator = MultiBlockMigrations;
336    type PreInherents = ();
337    type PostInherents = ();
338    type PostTransactions = ();
339    type ExtensionsWeightInfo = weights::frame_system_extensions::SubstrateWeight<Runtime>;
340}
341
342impl pallet_timestamp::Config for Runtime {
343    type Moment = u64;
344    type OnTimestampSet = Aura;
345    type MinimumPeriod = ConstU64<0>;
346    type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
347}
348
349parameter_types! {
350    pub const BasicDeposit: Balance = deposit(1, 258);  // 258 bytes on-chain
351    pub const ByteDeposit: Balance = deposit(0, 1);
352    pub const SubAccountDeposit: Balance = deposit(1, 53);  // 53 bytes on-chain
353    pub const UsernameDeposit: Balance = deposit(0, 32);
354    pub const MaxSubAccounts: u32 = 100;
355    pub const MaxAdditionalFields: u32 = 100;
356    pub const MaxRegistrars: u32 = 20;
357}
358
359impl pallet_identity::Config for Runtime {
360    type RuntimeEvent = RuntimeEvent;
361    type Currency = Balances;
362    type BasicDeposit = BasicDeposit;
363    type ByteDeposit = ByteDeposit;
364    type SubAccountDeposit = SubAccountDeposit;
365    type MaxSubAccounts = MaxSubAccounts;
366    type IdentityInformation = IdentityInfo<MaxAdditionalFields>;
367    type MaxRegistrars = MaxRegistrars;
368    type Slashed = ();
369    type ForceOrigin = EnsureRoot<AccountId>;
370    type RegistrarOrigin = EnsureRoot<AccountId>;
371    type OffchainSignature = Signature;
372    type SigningPublicKey = <Signature as sp_runtime::traits::Verify>::Signer;
373    type UsernameAuthorityOrigin = EnsureRoot<<Self as frame_system::Config>::AccountId>;
374    type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>;
375    type MaxSuffixLength = ConstU32<7>;
376    type MaxUsernameLength = ConstU32<32>;
377    type WeightInfo = pallet_identity::weights::SubstrateWeight<Runtime>;
378    type UsernameDeposit = UsernameDeposit;
379    type UsernameGracePeriod = ConstU32<{ 7 * DAYS }>;
380    #[cfg(feature = "runtime-benchmarks")]
381    type BenchmarkHelper = ();
382}
383
384parameter_types! {
385    // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
386    pub const DepositBase: Balance = deposit(1, 88);
387    // Additional storage item size of 32 bytes.
388    pub const DepositFactor: Balance = deposit(0, 32);
389}
390
391impl pallet_multisig::Config for Runtime {
392    type RuntimeEvent = RuntimeEvent;
393    type RuntimeCall = RuntimeCall;
394    type Currency = Balances;
395    type DepositBase = DepositBase;
396    type DepositFactor = DepositFactor;
397    type MaxSignatories = ConstU32<100>;
398    type BlockNumberProvider = System;
399    type WeightInfo = pallet_multisig::weights::SubstrateWeight<Runtime>;
400}
401
402parameter_types! {
403    pub MaximumSchedulerWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
404}
405
406impl pallet_scheduler::Config for Runtime {
407    type RuntimeEvent = RuntimeEvent;
408    type RuntimeOrigin = RuntimeOrigin;
409    type PalletsOrigin = OriginCaller;
410    type RuntimeCall = RuntimeCall;
411    type BlockNumberProvider = System;
412    type MaximumWeight = MaximumSchedulerWeight;
413    type ScheduleOrigin = EnsureRoot<AccountId>;
414    type MaxScheduledPerBlock = ConstU32<50>;
415    // TODO: re-bench pallet_scheduler weights or use default weights.
416    type WeightInfo = weights::pallet_scheduler::SubstrateWeight<Runtime>;
417    type OriginPrivilegeCmp = EqualPrivilegeOnly;
418    type Preimages = Preimage;
419}
420
421parameter_types! {
422    pub const PreimageBaseDeposit: Balance = deposit(1, 0);
423    pub const PreimageByteDeposit: Balance = deposit(0, 1);
424    pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
425}
426
427impl pallet_preimage::Config for Runtime {
428    type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
429    type RuntimeEvent = RuntimeEvent;
430    type Currency = Balances;
431    type ManagerOrigin = EnsureRoot<AccountId>;
432    type Consideration = HoldConsideration<
433        AccountId,
434        Balances,
435        PreimageHoldReason,
436        LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
437    >;
438}
439
440#[cfg(feature = "runtime-benchmarks")]
441pub struct DAppStakingBenchmarkHelper<SC, ACC>(PhantomData<(SC, ACC)>);
442#[cfg(feature = "runtime-benchmarks")]
443impl pallet_dapp_staking::BenchmarkHelper<SmartContract<AccountId>, AccountId>
444    for DAppStakingBenchmarkHelper<SmartContract<AccountId>, AccountId>
445{
446    fn get_smart_contract(id: u32) -> SmartContract<AccountId> {
447        // Wasm smart contracts are no longer supported, only EVM ones can be registered.
448        let id_bytes = id.to_le_bytes();
449        let mut address = [0u8; 20];
450        address[..id_bytes.len()].copy_from_slice(&id_bytes);
451
452        SmartContract::Evm(H160::from(address))
453    }
454
455    fn set_balance(account: &AccountId, amount: Balance) {
456        use frame_support::traits::fungible::Unbalanced as FunUnbalanced;
457        Balances::write_balance(account, amount)
458            .expect("Must succeed in test/benchmark environment.");
459    }
460}
461
462pub struct AccountCheck;
463impl DappStakingAccountCheck<AccountId> for AccountCheck {
464    fn allowed_to_stake(account: &AccountId) -> bool {
465        !CollatorSelection::is_account_candidate(account)
466    }
467}
468
469parameter_types! {
470    pub const MinimumStakingAmount: Balance = 5 * SBY;
471}
472
473impl pallet_dapp_staking::Config for Runtime {
474    type RuntimeEvent = RuntimeEvent;
475    type RuntimeFreezeReason = RuntimeFreezeReason;
476    type Currency = Balances;
477    type SmartContract = SmartContract<AccountId>;
478    type ContractRegisterOrigin = EnsureRootOrHalfCommunityCouncil;
479    type ContractUnregisterOrigin = EnsureRootOrFourFifthsCommunityCouncil;
480    type ManagerOrigin = EnsureRootOrHalfTechnicalCommittee;
481    type StakingRewardHandler = Inflation;
482    type CycleConfiguration = InflationCycleConfig;
483    type Observers = Inflation;
484    type AccountCheck = AccountCheck;
485    type EraRewardSpanLength = ConstU32<16>;
486    type RewardRetentionInPeriods = ConstU32<2>;
487    type MaxNumberOfContracts = ConstU32<{ FIXED_NUMBER_OF_TIER_SLOTS as u32 }>;
488    type MaxUnlockingChunks = ConstU32<8>;
489    type MinimumLockedAmount = MinimumStakingAmount;
490    type UnlockingPeriod = ConstU32<4>;
491    type MaxNumberOfStakedContracts = ConstU32<8>;
492    type MinimumStakeAmount = MinimumStakingAmount;
493    type NumberOfTiers = ConstU32<4>;
494    type RankingEnabled = ConstBool<true>;
495    type MaxBonusSafeMovesPerPeriod = ConstU8<2>;
496    type WeightInfo = weights::pallet_dapp_staking::SubstrateWeight<Runtime>;
497    #[cfg(feature = "runtime-benchmarks")]
498    type BenchmarkHelper = DAppStakingBenchmarkHelper<SmartContract<AccountId>, AccountId>;
499}
500
501pub struct InflationPayoutPerBlock;
502impl pallet_inflation::PayoutPerBlock<Credit<AccountId, Balances>> for InflationPayoutPerBlock {
503    fn treasury(reward: Credit<AccountId, Balances>) {
504        let _ = Balances::resolve(&TreasuryPalletId::get().into_account_truncating(), reward);
505    }
506
507    fn collators(reward: Credit<AccountId, Balances>) {
508        CollatorRewardPot::on_unbalanced(reward);
509    }
510}
511
512pub struct InflationCycleConfig;
513impl CycleConfiguration for InflationCycleConfig {
514    fn periods_per_cycle() -> PeriodNumber {
515        1
516    }
517
518    fn eras_per_voting_subperiod() -> EraNumber {
519        1
520    }
521
522    fn eras_per_build_and_earn_subperiod() -> EraNumber {
523        27
524    }
525
526    fn blocks_per_era() -> BlockNumber {
527        6 * HOURS
528    }
529}
530
531impl pallet_inflation::Config for Runtime {
532    type Currency = Balances;
533    type PayoutPerBlock = InflationPayoutPerBlock;
534    type CycleConfiguration = InflationCycleConfig;
535    type WeightInfo = weights::pallet_inflation::SubstrateWeight<Runtime>;
536}
537
538impl pallet_utility::Config for Runtime {
539    type RuntimeEvent = RuntimeEvent;
540    type RuntimeCall = RuntimeCall;
541    type PalletsOrigin = OriginCaller;
542    type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
543}
544
545parameter_types! {
546    pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
547    pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
548    pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
549    pub const RelayParentOffset: u32 = RELAY_PARENT_OFFSET;
550}
551
552impl cumulus_pallet_parachain_system::Config for Runtime {
553    type RuntimeEvent = RuntimeEvent;
554    type OnSystemEvent = ();
555    type SelfParaId = parachain_info::Pallet<Runtime>;
556    type OutboundXcmpMessageSource = XcmpQueue;
557    type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
558    type ReservedDmpWeight = ReservedDmpWeight;
559    type XcmpMessageHandler = XcmpQueue;
560    type ReservedXcmpWeight = ReservedXcmpWeight;
561    // Shibuya is subject to relay changes so we don't enforce increasing relay number
562    type CheckAssociatedRelayNumber = cumulus_pallet_parachain_system::AnyRelayNumber;
563    type ConsensusHook = ConsensusHook;
564    type WeightInfo = cumulus_pallet_parachain_system::weights::SubstrateWeight<Runtime>;
565    type RelayParentOffset = RelayParentOffset;
566}
567
568type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
569    Runtime,
570    RELAY_CHAIN_SLOT_DURATION_MILLIS,
571    BLOCK_PROCESSING_VELOCITY,
572    UNINCLUDED_SEGMENT_CAPACITY,
573>;
574
575impl parachain_info::Config for Runtime {}
576
577impl pallet_aura::Config for Runtime {
578    type AuthorityId = AuraId;
579    type DisabledValidators = ();
580    type MaxAuthorities = ConstU32<250>;
581    type SlotDuration = ConstU64<SLOT_DURATION>;
582    type AllowMultipleBlocksPerSlot = ConstBool<true>;
583}
584
585impl cumulus_pallet_aura_ext::Config for Runtime {}
586
587impl pallet_authorship::Config for Runtime {
588    type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
589    type EventHandler = (CollatorSelection,);
590}
591
592parameter_types! {
593    pub const SessionPeriod: BlockNumber = HOURS;
594    pub const SessionOffset: BlockNumber = 0;
595}
596
597impl pallet_session::Config for Runtime {
598    type RuntimeEvent = RuntimeEvent;
599    type ValidatorId = <Self as frame_system::Config>::AccountId;
600    type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
601    type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
602    type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
603    type SessionManager = CollatorSelection;
604    type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
605    type Keys = SessionKeys;
606    type DisablingStrategy = ();
607    type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
608    type Currency = Balances;
609    type KeyDeposit = ();
610}
611
612parameter_types! {
613    pub const PotId: PalletId = PalletId(*b"PotStake");
614    pub const MaxCandidates: u32 = 148;
615    pub const MinCandidates: u32 = 1;
616    pub const MaxInvulnerables: u32 = 48;
617    pub const SlashRatio: Perbill = Perbill::from_percent(1);
618    pub const KickThreshold: BlockNumber = 2 * HOURS; // 2 SessionPeriod
619}
620
621pub struct CollatorSelectionAccountCheck;
622impl pallet_collator_selection::AccountCheck<AccountId> for CollatorSelectionAccountCheck {
623    fn allowed_candidacy(account: &AccountId) -> bool {
624        !DappStaking::is_staker(account)
625    }
626}
627
628impl pallet_collator_selection::Config for Runtime {
629    type Currency = Balances;
630    type UpdateOrigin = EnsureRoot<AccountId>;
631    type ForceRemovalOrigin = EnsureRootOrThreeFourthMainCouncil;
632    type GovernanceOrigin = EnsureRootOrTwoThirdsMainCouncil;
633    type PotId = PotId;
634    type MaxCandidates = MaxCandidates;
635    type MinCandidates = MinCandidates;
636    type MaxInvulnerables = MaxInvulnerables;
637    // should be a multiple of session or things will get inconsistent
638    type KickThreshold = KickThreshold;
639    type ValidatorId = <Self as frame_system::Config>::AccountId;
640    type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
641    type ValidatorRegistration = Session;
642    type ValidatorSet = Session;
643    type SlashRatio = SlashRatio;
644    type AccountCheck = CollatorSelectionAccountCheck;
645    type WeightInfo = pallet_collator_selection::weights::SubstrateWeight<Runtime>;
646}
647
648parameter_types! {
649    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
650    pub const DappsStakingPalletId: PalletId = PalletId(*b"py/dpsst");
651    pub TreasuryAccountId: AccountId = TreasuryPalletId::get().into_account_truncating();
652}
653
654pub struct CollatorRewardPot;
655impl OnUnbalanced<Credit<AccountId, Balances>> for CollatorRewardPot {
656    fn on_nonzero_unbalanced(amount: Credit<AccountId, Balances>) {
657        let staking_pot = PotId::get().into_account_truncating();
658        let _ = Balances::resolve(&staking_pot, amount);
659    }
660}
661
662parameter_types! {
663    pub const ExistentialDeposit: Balance = 1_000_000;
664    pub const MaxLocks: u32 = 50;
665    pub const MaxReserves: u32 = 50;
666}
667
668impl pallet_balances::Config for Runtime {
669    type Balance = Balance;
670    type DustRemoval = ();
671    type RuntimeEvent = RuntimeEvent;
672    type MaxLocks = MaxLocks;
673    type MaxReserves = MaxReserves;
674    type ReserveIdentifier = [u8; 8];
675    type ExistentialDeposit = ExistentialDeposit;
676    type AccountStore = frame_system::Pallet<Runtime>;
677    type WeightInfo = weights::pallet_balances::SubstrateWeight<Runtime>;
678    type RuntimeHoldReason = RuntimeHoldReason;
679    type RuntimeFreezeReason = RuntimeFreezeReason;
680    type FreezeIdentifier = RuntimeFreezeReason;
681    type MaxFreezes = ConstU32<1>;
682    type DoneSlashHandler = ();
683}
684
685parameter_types! {
686    pub const AssetDeposit: Balance = 10 * SBY;
687    pub const AssetsStringLimit: u32 = 50;
688    /// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
689    // https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
690    pub const MetadataDepositBase: Balance = deposit(1, 68);
691    pub const MetadataDepositPerByte: Balance = deposit(0, 1);
692    pub const AssetAccountDeposit: Balance = deposit(1, 18);
693}
694
695impl pallet_assets::Config for Runtime {
696    type RuntimeEvent = RuntimeEvent;
697    type Balance = Balance;
698    type AssetId = AssetId;
699    type Currency = Balances;
700    type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
701    type ForceOrigin = EnsureRoot<AccountId>;
702    type AssetDeposit = AssetDeposit;
703    type MetadataDepositBase = MetadataDepositBase;
704    type MetadataDepositPerByte = MetadataDepositPerByte;
705    type AssetAccountDeposit = AssetAccountDeposit;
706    type ApprovalDeposit = ExistentialDeposit;
707    type StringLimit = AssetsStringLimit;
708    type Freezer = ();
709    type Extra = ();
710    type Holder = ();
711    type WeightInfo = weights::pallet_assets::SubstrateWeight<Runtime>;
712    type RemoveItemsLimit = ConstU32<1000>;
713    type AssetIdParameter = Compact<AssetId>;
714    type ReserveData = ();
715    type CallbackHandle = EvmRevertCodeHandler<Self, Self>;
716    #[cfg(feature = "runtime-benchmarks")]
717    type BenchmarkHelper = astar_primitives::benchmarks::AssetsBenchmarkHelper;
718}
719
720parameter_types! {
721    pub const MinVestedTransfer: Balance = 1 * SBY;
722    pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
723        WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
724}
725
726impl pallet_vesting::Config for Runtime {
727    type RuntimeEvent = RuntimeEvent;
728    type Currency = Balances;
729    type BlockNumberToBalance = ConvertInto;
730    #[cfg(feature = "runtime-benchmarks")]
731    type MinVestedTransfer = ConstU128<1>;
732    #[cfg(not(feature = "runtime-benchmarks"))]
733    type MinVestedTransfer = MinVestedTransfer;
734    type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
735    type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
736    type BlockNumberProvider = System;
737    // `VestingInfo` encode length is 36bytes. 28 schedules gets encoded as 1009 bytes, which is the
738    // highest number of schedules that encodes less than 2^10.
739    const MAX_VESTING_SCHEDULES: u32 = 28;
740}
741
742// These values are based on the Astar 2.0 Tokenomics Modeling report.
743parameter_types! {
744    pub const TransactionLengthFeeFactor: Balance = 23_500_000_000_000; // 0.000_023_500_000_000_000 SBY per byte
745    pub const WeightFeeFactor: Balance = 30_855_000_000_000_000; // Around 0.03 SBY per unit of base weight.
746    pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
747    pub const OperationalFeeMultiplier: u8 = 5;
748    pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(000_015, 1_000_000); // 0.000_015
749    pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10); // 0.1
750    pub MaximumMultiplier: Multiplier = Multiplier::saturating_from_integer(10); // 10
751}
752
753/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
754/// node's balance type.
755///
756/// This should typically create a mapping between the following ranges:
757///   - [0, MAXIMUM_BLOCK_WEIGHT]
758///   - [Balance::min, Balance::max]
759///
760/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
761///   - Setting it to `0` will essentially disable the weight fee.
762///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
763pub struct WeightToFee;
764impl WeightToFeePolynomial for WeightToFee {
765    type Balance = Balance;
766    fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
767        #[cfg(feature = "runtime-benchmarks")]
768        let (p, q) = (Balance::from(1u128), Balance::from(1u128));
769
770        #[cfg(not(feature = "runtime-benchmarks"))]
771        let (p, q) = (
772            WeightFeeFactor::get(),
773            Balance::from(ExtrinsicBaseWeight::get().ref_time()),
774        );
775
776        smallvec::smallvec![WeightToFeeCoefficient {
777            degree: 1,
778            negative: false,
779            coeff_frac: Perbill::from_rational(p % q, q),
780            coeff_integer: p / q,
781        }]
782    }
783}
784
785/// Handles converting weight consumed by XCM into native currency fee.
786///
787/// Similar to standard `WeightToFee` handler, but force uses the minimum multiplier.
788pub struct XcmWeightToFee;
789impl WeightToFeeT for XcmWeightToFee {
790    type Balance = Balance;
791
792    fn weight_to_fee(n: &Weight) -> Self::Balance {
793        MinimumMultiplier::get().saturating_mul_int(WeightToFee::weight_to_fee(&n))
794    }
795}
796
797pub struct DealWithFees;
798impl OnUnbalanced<Credit<AccountId, Balances>> for DealWithFees {
799    fn on_unbalanceds(mut fees_then_tips: impl Iterator<Item = Credit<AccountId, Balances>>) {
800        if let Some(fees) = fees_then_tips.next() {
801            // Burn 80% of fees, rest goes to collator, including 100% of the tips.
802            let (to_burn, mut collator) = fees.ration(80, 20);
803            if let Some(tips) = fees_then_tips.next() {
804                tips.merge_into(&mut collator);
805            }
806
807            // burn part of the fees
808            drop(to_burn);
809
810            // pay fees to collator
811            <CollatorRewardPot as OnUnbalanced<_>>::on_unbalanced(collator);
812        }
813    }
814
815    fn on_unbalanced(amount: Credit<AccountId, Balances>) {
816        Self::on_unbalanceds(Some(amount).into_iter());
817    }
818}
819
820impl pallet_transaction_payment::Config for Runtime {
821    type RuntimeEvent = RuntimeEvent;
822    type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, DealWithFees>;
823    type WeightToFee = WeightToFee;
824    type OperationalFeeMultiplier = OperationalFeeMultiplier;
825    type FeeMultiplierUpdate = TargetedFeeAdjustment<
826        Self,
827        TargetBlockFullness,
828        AdjustmentVariable,
829        MinimumMultiplier,
830        MaximumMultiplier,
831    >;
832    #[cfg(not(feature = "runtime-benchmarks"))]
833    type LengthToFee = ConstantMultiplier<Balance, TransactionLengthFeeFactor>;
834    #[cfg(feature = "runtime-benchmarks")]
835    type LengthToFee = ConstantMultiplier<Balance, sp_core::ConstU128<1>>;
836    type WeightInfo = weights::pallet_transaction_payment::SubstrateWeight<Self>;
837}
838
839parameter_types! {
840    pub DefaultBaseFeePerGas: U256 = U256::from(1_470_000_000_000_u128);
841    pub MinBaseFeePerGas: U256 = U256::from(800_000_000_000_u128);
842    pub MaxBaseFeePerGas: U256 = U256::from(80_000_000_000_000_u128);
843    pub StepLimitRatio: Perquintill = Perquintill::from_rational(5_u128, 100_000);
844}
845
846/// Simple wrapper for fetching current native transaction fee weight fee multiplier.
847pub struct AdjustmentFactorGetter;
848impl Get<Multiplier> for AdjustmentFactorGetter {
849    fn get() -> Multiplier {
850        pallet_transaction_payment::NextFeeMultiplier::<Runtime>::get()
851    }
852}
853
854impl pallet_dynamic_evm_base_fee::Config for Runtime {
855    type DefaultBaseFeePerGas = DefaultBaseFeePerGas;
856    type MinBaseFeePerGas = MinBaseFeePerGas;
857    type MaxBaseFeePerGas = MaxBaseFeePerGas;
858    type AdjustmentFactor = AdjustmentFactorGetter;
859    type WeightFactor = WeightFeeFactor;
860    type StepLimitRatio = StepLimitRatio;
861    type WeightInfo = pallet_dynamic_evm_base_fee::weights::SubstrateWeight<Runtime>;
862}
863
864/// Current approximation of the gas/s consumption considering
865/// EVM execution over compiled WASM (on 4.4Ghz CPU).
866/// Given the 500ms Weight, from which 75% only are used for transactions,
867/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000.
868pub const GAS_PER_SECOND: u64 = 40_000_000;
869
870/// Approximate ratio of the amount of Weight per Gas.
871/// u64 works for approximations because Weight is a very small unit compared to gas.
872pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND.saturating_div(GAS_PER_SECOND);
873
874pub struct FindAuthorTruncated<F>(PhantomData<F>);
875impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
876    fn find_author<'a, I>(digests: I) -> Option<H160>
877    where
878        I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
879    {
880        if let Some(author_index) = F::find_author(digests) {
881            let authority_id =
882                pallet_aura::Authorities::<Runtime>::get()[author_index as usize].clone();
883            return Some(H160::from_slice(&authority_id.encode()[4..24]));
884        }
885
886        None
887    }
888}
889
890parameter_types! {
891    /// EVM gas limit
892    pub BlockGasLimit: U256 = U256::from(
893        NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS
894    );
895    pub PrecompilesValue: Precompiles = ShibuyaPrecompiles::<_, _>::new();
896    pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
897    /// The amount of gas per PoV size. Value is calculated as:
898    ///
899    /// max_gas_limit = max_tx_ref_time / WEIGHT_PER_GAS = max_pov_size * gas_limit_pov_size_ratio
900    /// gas_limit_pov_size_ratio = ceil((max_tx_ref_time / WEIGHT_PER_GAS) / max_pov_size)
901    pub const GasLimitPovSizeRatio: u64 = 8;
902    /// Maximum gas allowed per transaction (EIP-7825). Set above the EIP-7825 default
903    /// of 16,777,216 to accommodate large contract deployments and complex calls.
904    pub TransactionGasLimit: Option<U256> = Some(U256::from(TX_MAX_GAS_LIMIT));
905}
906
907impl pallet_evm::Config for Runtime {
908    type FeeCalculator = DynamicEvmBaseFee;
909    type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
910    type WeightPerGas = WeightPerGas;
911    type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Runtime>;
912    type CallOrigin = pallet_evm::EnsureAddressRoot<AccountId>;
913    type WithdrawOrigin = pallet_evm::EnsureAddressTruncated;
914    type AddressMapping = pallet_evm::HashedAddressMapping<BlakeTwo256>;
915    type Currency = Balances;
916    type Runner = pallet_evm::runner::stack::Runner<Self>;
917    type PrecompilesType = Precompiles;
918    type PrecompilesValue = PrecompilesValue;
919    // Ethereum-compatible chain_id:
920    // * Shibuya: 81
921    type ChainId = EVMChainId;
922    type OnChargeTransaction = EVMFungibleAdapterWrapper<Balances, DealWithFees, CollatorRewardPot>;
923    type BlockGasLimit = BlockGasLimit;
924    type Timestamp = Timestamp;
925    type OnCreate = ();
926    type FindAuthor = FindAuthorTruncated<Aura>;
927    type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
928    type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
929    // gas based storage limit not enabled
930    type GasLimitStorageGrowthRatio = ConstU64<0>;
931    type TransactionGasLimit = TransactionGasLimit;
932    type CreateOriginFilter = ();
933    type CreateInnerOriginFilter = ();
934    type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
935}
936
937impl pallet_evm_chain_id::Config for Runtime {}
938
939parameter_types! {
940    pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
941}
942
943impl pallet_ethereum::Config for Runtime {
944    type StateRoot =
945        pallet_ethereum::IntermediateStateRoot<<Self as frame_system::Config>::Version>;
946    type PostLogContent = PostBlockAndTxnHashes;
947    // Maximum length (in bytes) of revert message to include in Executed event
948    type ExtraDataLength = ConstU32<30>;
949    type AllowUnprotectedTxs = ConstBool<false>;
950}
951
952impl pallet_sudo::Config for Runtime {
953    type RuntimeEvent = RuntimeEvent;
954    type RuntimeCall = RuntimeCall;
955    type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
956}
957
958parameter_types! {
959    // One storage item; key size 32, value size 8.
960    pub const ProxyDepositBase: Balance = deposit(1, 8);
961    // Additional storage item size of 33 bytes.
962    pub const ProxyDepositFactor: Balance = deposit(0, 33);
963    pub const AnnouncementDepositBase: Balance = deposit(1, 8);
964    pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
965}
966
967/// The type used to represent the kinds of proxying allowed.
968#[derive(
969    Copy,
970    Clone,
971    Eq,
972    PartialEq,
973    Ord,
974    PartialOrd,
975    Encode,
976    Decode,
977    DecodeWithMemTracking,
978    RuntimeDebug,
979    MaxEncodedLen,
980    scale_info::TypeInfo,
981)]
982pub enum ProxyType {
983    /// Allows all runtime calls for proxy account
984    Any,
985    /// Allows only NonTransfer runtime calls for proxy account
986    /// To know exact calls check InstanceFilter implementation for ProxyTypes
987    NonTransfer,
988    /// All Runtime calls from Pallet Balances allowed for proxy account
989    Balances,
990    /// All Runtime calls from Pallet Assets allowed for proxy account
991    Assets,
992    /// All governance related calls allowed for proxy account
993    Governance,
994    /// Only provide_judgement call from pallet identity allowed for proxy account
995    IdentityJudgement,
996    /// Only reject_announcement call from pallet proxy allowed for proxy account
997    CancelProxy,
998    /// All runtime calls from pallet DappStaking allowed for proxy account
999    DappStaking,
1000    /// Only claim_staker call from pallet DappStaking allowed for proxy account
1001    StakerRewardClaim,
1002}
1003
1004impl Default for ProxyType {
1005    fn default() -> Self {
1006        Self::Any
1007    }
1008}
1009
1010impl InstanceFilter<RuntimeCall> for ProxyType {
1011    fn filter(&self, c: &RuntimeCall) -> bool {
1012        match self {
1013            // Always allowed RuntimeCall::Utility no matter type.
1014            // Only transactions allowed by Proxy.filter can be executed
1015            _ if matches!(c, RuntimeCall::Utility(..)) => true,
1016            // Allows all runtime calls for proxy account
1017            ProxyType::Any => true,
1018            // Allows only NonTransfer runtime calls for proxy account
1019            ProxyType::NonTransfer => {
1020                matches!(
1021                    c,
1022                    RuntimeCall::System(..)
1023                        | RuntimeCall::Identity(..)
1024                        | RuntimeCall::Multisig(..)
1025                        | RuntimeCall::Proxy(..)
1026                        | RuntimeCall::Vesting(
1027                            pallet_vesting::Call::vest { .. }
1028                                | pallet_vesting::Call::vest_other { .. }
1029                        )
1030                        | RuntimeCall::DappStaking(..)
1031                        | RuntimeCall::CollatorSelection(..)
1032                        | RuntimeCall::Session(..)
1033                )
1034            }
1035            // All Runtime calls from Pallet Balances allowed for proxy account
1036            ProxyType::Balances => {
1037                matches!(c, RuntimeCall::Balances(..))
1038            }
1039            // All Runtime calls from Pallet Assets allowed for proxy account
1040            ProxyType::Assets => {
1041                matches!(c, RuntimeCall::Assets(..))
1042            }
1043            // Only provide_judgement call from pallet identity allowed for proxy account
1044            ProxyType::IdentityJudgement => {
1045                matches!(
1046                    c,
1047                    RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. })
1048                )
1049            }
1050            // Only reject_announcement call from pallet proxy allowed for proxy account
1051            ProxyType::CancelProxy => {
1052                matches!(
1053                    c,
1054                    RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
1055                )
1056            }
1057            // All runtime calls from pallet DappStaking allowed for proxy account
1058            ProxyType::DappStaking => {
1059                matches!(c, RuntimeCall::DappStaking(..))
1060            }
1061            ProxyType::StakerRewardClaim => {
1062                matches!(
1063                    c,
1064                    RuntimeCall::DappStaking(
1065                        pallet_dapp_staking::Call::claim_staker_rewards { .. }
1066                    )
1067                )
1068            }
1069            ProxyType::Governance => {
1070                matches!(
1071                    c,
1072                    RuntimeCall::Democracy(..)
1073                        | RuntimeCall::Council(..)
1074                        | RuntimeCall::TechnicalCommittee(..)
1075                        | RuntimeCall::CommunityCouncil(..)
1076                )
1077            }
1078        }
1079    }
1080
1081    fn is_superset(&self, o: &Self) -> bool {
1082        match (self, o) {
1083            (x, y) if x == y => true,
1084            (ProxyType::Any, _) => true,
1085            (_, ProxyType::Any) => false,
1086            (ProxyType::NonTransfer, _) => true,
1087            (ProxyType::DappStaking, ProxyType::StakerRewardClaim) => true,
1088            _ => false,
1089        }
1090    }
1091}
1092
1093impl pallet_proxy::Config for Runtime {
1094    type RuntimeEvent = RuntimeEvent;
1095    type RuntimeCall = RuntimeCall;
1096    type Currency = Balances;
1097    type ProxyType = ProxyType;
1098    // One storage item; key size 32, value size 8; .
1099    type ProxyDepositBase = ProxyDepositBase;
1100    // Additional storage item size of 33 bytes.
1101    type ProxyDepositFactor = ProxyDepositFactor;
1102    type MaxProxies = ConstU32<32>;
1103    type BlockNumberProvider = System;
1104    type WeightInfo = pallet_proxy::weights::SubstrateWeight<Runtime>;
1105    type MaxPending = ConstU32<32>;
1106    type CallHasher = BlakeTwo256;
1107    // Key size 32 + 1 item
1108    type AnnouncementDepositBase = AnnouncementDepositBase;
1109    // Acc Id + Hash + block number
1110    type AnnouncementDepositFactor = AnnouncementDepositFactor;
1111}
1112
1113impl pallet_xc_asset_config::Config for Runtime {
1114    type AssetId = AssetId;
1115    // Good enough for testnet since we lack pallet-assets hooks for now
1116    type ManagerOrigin = EnsureRoot<AccountId>;
1117    type WeightInfo = pallet_xc_asset_config::weights::SubstrateWeight<Self>;
1118}
1119
1120parameter_types! {
1121    pub MessageQueueServiceWeight: Weight =
1122        Perbill::from_percent(25) * RuntimeBlockWeights::get().max_block;
1123}
1124
1125impl pallet_message_queue::Config for Runtime {
1126    type RuntimeEvent = RuntimeEvent;
1127    type WeightInfo = pallet_message_queue::weights::SubstrateWeight<Runtime>;
1128    #[cfg(feature = "runtime-benchmarks")]
1129    type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor<
1130        cumulus_primitives_core::AggregateMessageOrigin,
1131    >;
1132    #[cfg(not(feature = "runtime-benchmarks"))]
1133    type MessageProcessor = xcm_builder::ProcessXcmMessage<
1134        AggregateMessageOrigin,
1135        xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
1136        RuntimeCall,
1137    >;
1138    type Size = u32;
1139    type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
1140    type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
1141    type HeapSize = ConstU32<{ 128 * 1048 }>;
1142    type MaxStale = ConstU32<8>;
1143    type ServiceWeight = MessageQueueServiceWeight;
1144    type IdleMaxServiceWeight = MessageQueueServiceWeight;
1145}
1146
1147parameter_types! {
1148    pub const CouncilMaxMembers: u32 = 16;
1149    pub const TechnicalCommitteeMaxMembers: u32 = 8;
1150    pub const CommunityCouncilMaxMembers: u32 = 16;
1151}
1152
1153impl pallet_membership::Config<MainCouncilMembershipInst> for Runtime {
1154    type RuntimeEvent = RuntimeEvent;
1155    type AddOrigin = EnsureRootOrHalfMainCouncil;
1156    type RemoveOrigin = EnsureRootOrHalfMainCouncil;
1157    type SwapOrigin = EnsureRootOrHalfMainCouncil;
1158    type ResetOrigin = EnsureRootOrHalfMainCouncil;
1159    type PrimeOrigin = EnsureRootOrHalfMainCouncil;
1160    type MembershipInitialized = Council;
1161    type MembershipChanged = Council;
1162    type MaxMembers = CouncilMaxMembers;
1163    type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
1164}
1165
1166impl pallet_membership::Config<TechnicalCommitteeMembershipInst> for Runtime {
1167    type RuntimeEvent = RuntimeEvent;
1168    type AddOrigin = EnsureRootOrHalfMainCouncil;
1169    type RemoveOrigin = EnsureRootOrHalfMainCouncil;
1170    type SwapOrigin = EnsureRootOrHalfMainCouncil;
1171    type ResetOrigin = EnsureRootOrHalfMainCouncil;
1172    type PrimeOrigin = EnsureRootOrHalfMainCouncil;
1173    type MembershipInitialized = TechnicalCommittee;
1174    type MembershipChanged = TechnicalCommittee;
1175    type MaxMembers = TechnicalCommitteeMaxMembers;
1176    type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
1177}
1178
1179impl pallet_membership::Config<CommunityCouncilMembershipInst> for Runtime {
1180    type RuntimeEvent = RuntimeEvent;
1181    type AddOrigin = EnsureRootOrHalfMainCouncil;
1182    type RemoveOrigin = EnsureRootOrHalfMainCouncil;
1183    type SwapOrigin = EnsureRootOrHalfMainCouncil;
1184    type ResetOrigin = EnsureRootOrHalfMainCouncil;
1185    type PrimeOrigin = EnsureRootOrHalfMainCouncil;
1186    type MembershipInitialized = CommunityCouncil;
1187    type MembershipChanged = CommunityCouncil;
1188    type MaxMembers = CommunityCouncilMaxMembers;
1189    type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
1190}
1191
1192parameter_types! {
1193    pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block;
1194}
1195
1196impl pallet_collective::Config<MainCouncilCollectiveInst> for Runtime {
1197    type RuntimeOrigin = RuntimeOrigin;
1198    type Proposal = RuntimeCall;
1199    type RuntimeEvent = RuntimeEvent;
1200    type MotionDuration = ConstU32<{ 5 * DAYS }>;
1201    type MaxProposals = ConstU32<16>;
1202    type MaxMembers = CouncilMaxMembers;
1203    type DefaultVote = pallet_collective::PrimeDefaultVote;
1204    type SetMembersOrigin = EnsureRoot<AccountId>;
1205    type MaxProposalWeight = MaxProposalWeight;
1206    type KillOrigin = EnsureRoot<AccountId>;
1207    type DisapproveOrigin = EnsureRoot<AccountId>;
1208    type Consideration = ();
1209    type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
1210}
1211
1212impl pallet_collective::Config<TechnicalCommitteeCollectiveInst> for Runtime {
1213    type RuntimeOrigin = RuntimeOrigin;
1214    type Proposal = RuntimeCall;
1215    type RuntimeEvent = RuntimeEvent;
1216    type MotionDuration = ConstU32<{ 5 * DAYS }>;
1217    type MaxProposals = ConstU32<16>;
1218    type MaxMembers = TechnicalCommitteeMaxMembers;
1219    type DefaultVote = pallet_collective::PrimeDefaultVote;
1220    type SetMembersOrigin = EnsureRoot<AccountId>;
1221    type MaxProposalWeight = MaxProposalWeight;
1222    type KillOrigin = EnsureRoot<AccountId>;
1223    type DisapproveOrigin = EnsureRoot<AccountId>;
1224    type Consideration = ();
1225    type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
1226}
1227
1228impl pallet_collective::Config<CommunityCouncilCollectiveInst> for Runtime {
1229    type RuntimeOrigin = RuntimeOrigin;
1230    type Proposal = RuntimeCall;
1231    type RuntimeEvent = RuntimeEvent;
1232    type MotionDuration = ConstU32<{ 5 * DAYS }>;
1233    type MaxProposals = ConstU32<16>;
1234    type MaxMembers = CommunityCouncilMaxMembers;
1235    type DefaultVote = pallet_collective::PrimeDefaultVote;
1236    type SetMembersOrigin = EnsureRoot<AccountId>;
1237    type MaxProposalWeight = MaxProposalWeight;
1238    type KillOrigin = EnsureRoot<AccountId>;
1239    type DisapproveOrigin = EnsureRoot<AccountId>;
1240    type Consideration = ();
1241    type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
1242}
1243
1244impl pallet_democracy::Config for Runtime {
1245    type RuntimeEvent = RuntimeEvent;
1246    type Currency = Balances;
1247    type EnactmentPeriod = ConstU32<{ 2 * DAYS }>;
1248    type LaunchPeriod = ConstU32<{ 4 * DAYS }>;
1249    type VotingPeriod = ConstU32<{ 4 * DAYS }>;
1250    type VoteLockingPeriod = ConstU32<{ 1 * DAYS }>;
1251    type MinimumDeposit = ConstU128<{ 10 * SBY }>;
1252    type FastTrackVotingPeriod = ConstU32<{ 1 * HOURS }>;
1253    type CooloffPeriod = ConstU32<{ 1 * DAYS }>;
1254
1255    type MaxVotes = ConstU32<128>;
1256    type MaxProposals = ConstU32<128>;
1257    type MaxDeposits = ConstU32<128>;
1258    type MaxBlacklisted = ConstU32<128>;
1259
1260    /// A two third majority of the Council can choose the next external "super majority approve" proposal.
1261    type ExternalOrigin = EnsureRootOrHalfMainCouncil;
1262    /// A two third majority of the Council can choose the next external "majority approve" proposal. Also bypasses blacklist filter.
1263    type ExternalMajorityOrigin = EnsureRootOrHalfMainCouncil;
1264    /// Unanimous approval of the Council can choose the next external "super majority against" proposal.
1265    type ExternalDefaultOrigin = EnsureRootOrAllMainCouncil;
1266    /// A two third majority of the Technical Committee can have an external proposal tabled immediately
1267    /// for a _fast track_ vote, and a custom enactment period.
1268    type FastTrackOrigin = EnsureRootOrHalfTechnicalCommittee;
1269    /// Unanimous approval of the Technical Committee can have an external proposal tabled immediately
1270    /// for a completely custom _voting period length_ vote, and a custom enactment period.
1271    type InstantOrigin = EnsureRootOrAllTechnicalCommittee;
1272    type InstantAllowed = ConstBool<true>;
1273
1274    /// A two third majority of the Council can cancel a passed proposal. Can happen only once per unique proposal.
1275    type CancellationOrigin = EnsureRootOrHalfMainCouncil;
1276    /// Only a passed public referendum can permanently blacklist a proposal.
1277    type BlacklistOrigin = EnsureRoot<AccountId>;
1278    /// An unanimous Technical Committee can cancel a public proposal, slashing the deposit(s).
1279    type CancelProposalOrigin = EnsureRootOrAllTechnicalCommittee;
1280    /// Any member of the Technical Committee can veto Council's proposal. This can be only done once per proposal, and _veto_ lasts for a _cooloff_ period.
1281    type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCommitteeCollectiveInst>;
1282
1283    type SubmitOrigin = EnsureSigned<AccountId>;
1284    type PalletsOrigin = OriginCaller;
1285    type Preimages = Preimage;
1286    type Scheduler = Scheduler;
1287    type Slash = ();
1288    type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
1289}
1290
1291parameter_types! {
1292    pub const ProposalBond: Permill = Permill::from_percent(5);
1293    pub MainTreasuryAccount: AccountId = Treasury::account_id();
1294}
1295
1296impl pallet_treasury::Config<MainTreasuryInst> for Runtime {
1297    type PalletId = TreasuryPalletId;
1298    type Currency = Balances;
1299    type RuntimeEvent = RuntimeEvent;
1300
1301    // Two origins which can either approve or reject the spending proposal
1302    type ApproveOrigin = EnsureRootOrHalfMainCouncil;
1303    type RejectOrigin = EnsureRootOrHalfMainCouncil;
1304
1305    type OnSlash = Treasury;
1306    type ProposalBond = ProposalBond;
1307    type ProposalBondMinimum = ConstU128<{ 100 * SBY }>;
1308    type ProposalBondMaximum = ConstU128<{ 10000 * SBY }>;
1309    type SpendPeriod = ConstU32<{ 3 * DAYS }>;
1310
1311    // We don't do periodic burns of the treasury
1312    type Burn = ();
1313    type BurnDestination = ();
1314    type SpendFunds = ();
1315    type MaxApprovals = ConstU32<64>;
1316
1317    type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
1318}
1319
1320parameter_types! {
1321    pub const CommunityTreasuryPalletId: PalletId = PalletId(*b"py/comtr");
1322}
1323
1324impl pallet_treasury::Config<CommunityTreasuryInst> for Runtime {
1325    type PalletId = CommunityTreasuryPalletId;
1326    type Currency = Balances;
1327    type RuntimeEvent = RuntimeEvent;
1328
1329    // Two origins which can either approve or reject the spending proposal
1330    type ApproveOrigin = EnsureRootOrHalfCommunityCouncil;
1331    type RejectOrigin = EnsureRootOrHalfCommunityCouncil;
1332
1333    type OnSlash = CommunityTreasury;
1334    type ProposalBond = ProposalBond;
1335    type ProposalBondMinimum = ConstU128<{ 100 * SBY }>;
1336    type ProposalBondMaximum = ConstU128<{ 10000 * SBY }>;
1337    type SpendPeriod = ConstU32<{ 3 * DAYS }>;
1338
1339    // We don't do periodic burns of the community treasury
1340    type Burn = ();
1341    type BurnDestination = ();
1342    type SpendFunds = ();
1343    type MaxApprovals = ConstU32<64>;
1344
1345    type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
1346}
1347
1348parameter_types! {
1349    pub CommunityTreasuryAccountId: AccountId = CommunityTreasuryPalletId::get().into_account_truncating();
1350}
1351
1352#[derive(Default)]
1353pub struct CommunityCouncilCallFilter;
1354impl InstanceFilter<RuntimeCall> for CommunityCouncilCallFilter {
1355    fn filter(&self, c: &RuntimeCall) -> bool {
1356        matches!(
1357            c,
1358            RuntimeCall::DappStaking(..)
1359                | RuntimeCall::System(frame_system::Call::remark { .. })
1360                | RuntimeCall::Utility(pallet_utility::Call::batch { .. })
1361                | RuntimeCall::Utility(pallet_utility::Call::batch_all { .. })
1362        )
1363    }
1364}
1365
1366impl pallet_collective_proxy::Config for Runtime {
1367    type RuntimeCall = RuntimeCall;
1368    type CollectiveProxy = EnsureRootOrHalfCommunityCouncil;
1369    type ProxyAccountId = CommunityTreasuryAccountId;
1370    type CallFilter = CommunityCouncilCallFilter;
1371    type WeightInfo = pallet_collective_proxy::weights::SubstrateWeight<Runtime>;
1372}
1373
1374parameter_types! {
1375    pub MbmServiceWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block;
1376    /// Storage prefix of the decommissioned `pallet-contracts`.
1377    pub const ContractsPalletName: &'static str = "Contracts";
1378    /// Storage prefix of the decommissioned `pallet-insecure-randomness-collective-flip`.
1379    pub const RandomnessPalletName: &'static str = "RandomnessCollectiveFlip";
1380}
1381
1382/// Benchmarked weights backing the contract decommission migrations.
1383type ContractsMbmWeights = contracts_mbm::weights::SubstrateWeight<Runtime>;
1384
1385/// Multi-block migrations executed by `pallet-migrations`.
1386///
1387/// Step two of decommissioning Wasm (ink!) smart contracts: `pallet-contracts` is gone, so the
1388/// storage it left behind is purged over multiple blocks. The purge also hands back the consumer
1389/// reference the pallet took on every live contract account - without it those accounts could
1390/// never be reaped. Registered dApps pointing at Wasm contracts are expected to have been
1391/// unregistered from dApp staking by governance beforehand.
1392pub type MultiBlockMigrationsList = (
1393    // Must come first: it needs the `trie_id`s stored under the `Contracts` prefix.
1394    contracts_mbm::PurgeContractsChildTries<Runtime, ContractsPalletName, ContractsMbmWeights>,
1395    contracts_mbm::RemovePalletStepped<ContractsPalletName, ContractsMbmWeights>,
1396    contracts_mbm::RemovePalletStepped<RandomnessPalletName, ContractsMbmWeights>,
1397);
1398
1399// Carries no storage and no calls, it only exists so the migrations above can be
1400// benchmarked. Deliberately not part of the production runtime.
1401#[cfg(feature = "runtime-benchmarks")]
1402impl contracts_mbm::Config for Runtime {}
1403
1404impl pallet_migrations::Config for Runtime {
1405    type RuntimeEvent = RuntimeEvent;
1406    #[cfg(not(feature = "runtime-benchmarks"))]
1407    type Migrations = MultiBlockMigrationsList;
1408    // Benchmarks need mocked migrations to guarantee that they succeed.
1409    #[cfg(feature = "runtime-benchmarks")]
1410    type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1411    type CursorMaxLen = ConstU32<65_536>;
1412    type IdentifierMaxLen = ConstU32<256>;
1413    type MigrationStatusHandler = ();
1414    type FailedMigrationHandler = UnfreezeChainOnFailedMigration;
1415    type MaxServiceWeight = MbmServiceWeight;
1416    type WeightInfo = pallet_migrations::weights::SubstrateWeight<Runtime>;
1417}
1418
1419/// Calls that can bypass the safe-mode pallet.
1420pub struct SafeModeWhitelistedCalls;
1421impl Contains<RuntimeCall> for SafeModeWhitelistedCalls {
1422    fn contains(call: &RuntimeCall) -> bool {
1423        match call {
1424            // System and Timestamp are required for block production
1425            RuntimeCall::System(_)
1426            | RuntimeCall::Timestamp(_)
1427            | RuntimeCall::ParachainSystem(_)
1428            | RuntimeCall::Council(_)
1429            | RuntimeCall::TechnicalCommittee(_)
1430            | RuntimeCall::Sudo(_)
1431            | RuntimeCall::Democracy(
1432                pallet_democracy::Call::external_propose_majority { .. }
1433                | pallet_democracy::Call::external_propose_default { .. }
1434                | pallet_democracy::Call::fast_track { .. }
1435                | pallet_democracy::Call::emergency_cancel { .. }
1436                | pallet_democracy::Call::cancel_referendum { .. }
1437                | pallet_democracy::Call::vote { .. }
1438                | pallet_democracy::Call::remove_vote { .. }
1439                | pallet_democracy::Call::veto_external { .. },
1440            )
1441            | RuntimeCall::Proxy(_)
1442            | RuntimeCall::Multisig(_)
1443            | RuntimeCall::Preimage(_)
1444            | RuntimeCall::Utility(_)
1445            | RuntimeCall::TxPause(_)
1446            | RuntimeCall::SafeMode(_) => true,
1447            _ => false,
1448        }
1449    }
1450}
1451
1452/// Calls that cannot be paused by the tx-pause pallet.
1453pub struct TxPauseWhitelistedCalls;
1454impl frame_support::traits::Contains<RuntimeCallNameOf<Runtime>> for TxPauseWhitelistedCalls {
1455    fn contains(full_name: &RuntimeCallNameOf<Runtime>) -> bool {
1456        let pallet_name = full_name.0.as_slice();
1457        matches!(
1458            pallet_name,
1459            b"System"
1460                | b"Timestamp"
1461                | b"ParachainSystem"
1462                | b"Council"
1463                | b"TechnicalCommittee"
1464                | b"Sudo"
1465                | b"TxPause"
1466                | b"SafeMode"
1467        )
1468    }
1469}
1470
1471impl pallet_safe_mode::Config for Runtime {
1472    type RuntimeEvent = RuntimeEvent;
1473    type Currency = Balances;
1474    type RuntimeHoldReason = RuntimeHoldReason;
1475    type WhitelistedCalls = SafeModeWhitelistedCalls;
1476    type EnterDuration = ConstU32<{ 4 * HOURS }>;
1477    type EnterDepositAmount = ();
1478    type ExtendDuration = ConstU32<{ 2 * HOURS }>;
1479    type ExtendDepositAmount = ();
1480    // The 'Success' values below represent the number of blocks that the origin may induce safe mode
1481    type ForceEnterOrigin = EnsureWithSuccess<
1482        EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil,
1483        AccountId,
1484        ConstU32<{ 4 * HOURS }>,
1485    >;
1486    type ForceExtendOrigin = EnsureWithSuccess<
1487        EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil,
1488        AccountId,
1489        ConstU32<{ 2 * HOURS }>,
1490    >;
1491    type ForceExitOrigin = EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil;
1492    type ForceDepositOrigin = EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil;
1493    type ReleaseDelay = ();
1494    type Notify = DappStaking;
1495    type WeightInfo = pallet_safe_mode::weights::SubstrateWeight<Runtime>;
1496}
1497
1498impl pallet_tx_pause::Config for Runtime {
1499    type RuntimeEvent = RuntimeEvent;
1500    type RuntimeCall = RuntimeCall;
1501    type PauseOrigin = EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil;
1502    type UnpauseOrigin = EnsureRootOrHalfTechCommitteeOrTwoThirdCouncil;
1503    type WhitelistedCalls = TxPauseWhitelistedCalls;
1504    type MaxNameLen = ConstU32<256>;
1505    type WeightInfo = pallet_tx_pause::weights::SubstrateWeight<Runtime>;
1506}
1507
1508#[frame_support::runtime]
1509mod runtime {
1510    #[runtime::runtime]
1511    #[runtime::derive(
1512        RuntimeCall,
1513        RuntimeEvent,
1514        RuntimeError,
1515        RuntimeOrigin,
1516        RuntimeFreezeReason,
1517        RuntimeHoldReason,
1518        RuntimeSlashReason,
1519        RuntimeLockId,
1520        RuntimeTask
1521    )]
1522    pub struct Runtime;
1523
1524    #[runtime::pallet_index(10)]
1525    pub type System = frame_system;
1526    #[runtime::pallet_index(11)]
1527    pub type Utility = pallet_utility;
1528    #[runtime::pallet_index(12)]
1529    pub type Identity = pallet_identity;
1530    #[runtime::pallet_index(13)]
1531    pub type Timestamp = pallet_timestamp;
1532    #[runtime::pallet_index(14)]
1533    pub type Multisig = pallet_multisig;
1534    // skip 16 - pallet_insecure_randomness_collective_flip previously
1535    #[runtime::pallet_index(17)]
1536    pub type Scheduler = pallet_scheduler;
1537    #[runtime::pallet_index(18)]
1538    pub type Proxy = pallet_proxy;
1539
1540    #[runtime::pallet_index(20)]
1541    pub type ParachainSystem = cumulus_pallet_parachain_system;
1542    #[runtime::pallet_index(21)]
1543    pub type ParachainInfo = parachain_info;
1544
1545    #[runtime::pallet_index(30)]
1546    pub type TransactionPayment = pallet_transaction_payment;
1547    #[runtime::pallet_index(31)]
1548    pub type Balances = pallet_balances;
1549    #[runtime::pallet_index(32)]
1550    pub type Vesting = pallet_vesting;
1551    #[runtime::pallet_index(34)]
1552    pub type DappStaking = pallet_dapp_staking;
1553    #[runtime::pallet_index(35)]
1554    pub type Inflation = pallet_inflation;
1555    #[runtime::pallet_index(36)]
1556    pub type Assets = pallet_assets;
1557    // skip 37 - price_aggregator previously
1558    // skip 38/39 - oracle and oracle_membership previously
1559    #[runtime::pallet_index(40)]
1560    pub type Authorship = pallet_authorship;
1561    #[runtime::pallet_index(41)]
1562    pub type CollatorSelection = pallet_collator_selection;
1563    #[runtime::pallet_index(42)]
1564    pub type Session = pallet_session;
1565    #[runtime::pallet_index(43)]
1566    pub type Aura = pallet_aura;
1567    #[runtime::pallet_index(44)]
1568    pub type AuraExt = cumulus_pallet_aura_ext;
1569
1570    #[runtime::pallet_index(50)]
1571    pub type XcmpQueue = cumulus_pallet_xcmp_queue;
1572    #[runtime::pallet_index(51)]
1573    pub type PolkadotXcm = pallet_xcm;
1574    #[runtime::pallet_index(52)]
1575    pub type CumulusXcm = cumulus_pallet_xcm;
1576    // skip 53 - cumulus_pallet_dmp_queue previously
1577    #[runtime::pallet_index(54)]
1578    pub type XcAssetConfig = pallet_xc_asset_config;
1579    // skip 55 - orml_xtokens previously
1580    #[runtime::pallet_index(56)]
1581    pub type MessageQueue = pallet_message_queue;
1582
1583    #[runtime::pallet_index(60)]
1584    pub type EVM = pallet_evm;
1585    #[runtime::pallet_index(61)]
1586    pub type Ethereum = pallet_ethereum;
1587    #[runtime::pallet_index(62)]
1588    pub type DynamicEvmBaseFee = pallet_dynamic_evm_base_fee;
1589    #[runtime::pallet_index(63)]
1590    pub type EVMChainId = pallet_evm_chain_id;
1591    // skip 64 - pallet_ethereum_checked previously
1592    // skip 65 - pallet_unified_accounts previously
1593
1594    // skip 70 - pallet_contracts previously
1595
1596    #[runtime::pallet_index(84)]
1597    pub type Preimage = pallet_preimage;
1598
1599    // skip 90 - pallet_xvm previously
1600
1601    #[runtime::pallet_index(99)]
1602    pub type Sudo = pallet_sudo;
1603    #[runtime::pallet_index(100)]
1604    pub type CouncilMembership = pallet_membership<Instance2>;
1605    #[runtime::pallet_index(101)]
1606    pub type TechnicalCommitteeMembership = pallet_membership<Instance3>;
1607    #[runtime::pallet_index(102)]
1608    pub type CommunityCouncilMembership = pallet_membership<Instance4>;
1609    #[runtime::pallet_index(103)]
1610    pub type Council = pallet_collective<Instance2>;
1611    #[runtime::pallet_index(104)]
1612    pub type TechnicalCommittee = pallet_collective<Instance3>;
1613    #[runtime::pallet_index(105)]
1614    pub type CommunityCouncil = pallet_collective<Instance4>;
1615    #[runtime::pallet_index(106)]
1616    pub type Democracy = pallet_democracy;
1617    #[runtime::pallet_index(107)]
1618    pub type Treasury = pallet_treasury<Instance1>;
1619    #[runtime::pallet_index(108)]
1620    pub type CommunityTreasury = pallet_treasury<Instance2>;
1621    #[runtime::pallet_index(109)]
1622    pub type CollectiveProxy = pallet_collective_proxy;
1623    #[runtime::pallet_index(110)]
1624    pub type SafeMode = pallet_safe_mode;
1625    #[runtime::pallet_index(111)]
1626    pub type TxPause = pallet_tx_pause;
1627
1628    #[runtime::pallet_index(120)]
1629    pub type MultiBlockMigrations = pallet_migrations;
1630
1631    #[runtime::pallet_index(250)]
1632    #[cfg(feature = "runtime-benchmarks")]
1633    pub type ContractsMBM = contracts_mbm;
1634}
1635
1636/// Block type as expected by this runtime.
1637pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1638/// A Block signed with a Justification
1639pub type SignedBlock = generic::SignedBlock<Block>;
1640/// BlockId type as expected by this runtime.
1641pub type BlockId = generic::BlockId<Block>;
1642/// The SignedExtension to the basic transaction logic.
1643pub type SignedExtra = (
1644    frame_system::CheckSpecVersion<Runtime>,
1645    frame_system::CheckTxVersion<Runtime>,
1646    frame_system::CheckGenesis<Runtime>,
1647    frame_system::CheckEra<Runtime>,
1648    frame_system::CheckNonce<Runtime>,
1649    frame_system::CheckWeight<Runtime>,
1650    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1651    frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1652);
1653/// Unchecked extrinsic type as expected by this runtime.
1654pub type UncheckedExtrinsic =
1655    fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
1656/// Extrinsic type that has already been checked.
1657pub type CheckedExtrinsic =
1658    fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra, H160>;
1659/// The payload being signed in transactions.
1660pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
1661/// Executive: handles dispatch to the various modules.
1662pub type Executive = frame_executive::Executive<
1663    Runtime,
1664    Block,
1665    frame_system::ChainContext<Runtime>,
1666    Runtime,
1667    AllPalletsWithSystem,
1668    Migrations,
1669>;
1670
1671/// All migrations that will run on the next runtime upgrade.
1672///
1673/// __NOTE:__ THE ORDER IS IMPORTANT.
1674pub type Migrations = (Unreleased, Permanent);
1675
1676/// Unreleased migrations. Add new ones here:
1677pub type Unreleased = (frame_support::migrations::RemovePallet<XTokensPalletName, RocksDbWeight>,);
1678
1679parameter_types! {
1680    pub const XTokensPalletName: &'static str = "XTokens";
1681}
1682
1683/// Migrations/checks that do not need to be versioned and can run on every upgrade.
1684pub type Permanent = (pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,);
1685
1686impl fp_self_contained::SelfContainedCall for RuntimeCall {
1687    type SignedInfo = H160;
1688
1689    fn is_self_contained(&self) -> bool {
1690        match self {
1691            RuntimeCall::Ethereum(call) => call.is_self_contained(),
1692            _ => false,
1693        }
1694    }
1695
1696    fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
1697        match self {
1698            RuntimeCall::Ethereum(call) => call.check_self_contained(),
1699            _ => None,
1700        }
1701    }
1702
1703    fn validate_self_contained(
1704        &self,
1705        info: &Self::SignedInfo,
1706        dispatch_info: &DispatchInfoOf<RuntimeCall>,
1707        len: usize,
1708    ) -> Option<TransactionValidity> {
1709        match self {
1710            RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
1711            _ => None,
1712        }
1713    }
1714
1715    fn pre_dispatch_self_contained(
1716        &self,
1717        info: &Self::SignedInfo,
1718        dispatch_info: &DispatchInfoOf<RuntimeCall>,
1719        len: usize,
1720    ) -> Option<Result<(), TransactionValidityError>> {
1721        match self {
1722            RuntimeCall::Ethereum(call) => {
1723                call.pre_dispatch_self_contained(info, dispatch_info, len)
1724            }
1725            _ => None,
1726        }
1727    }
1728
1729    fn apply_self_contained(
1730        self,
1731        info: Self::SignedInfo,
1732    ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
1733        match self {
1734            call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => {
1735                Some(call.dispatch(RuntimeOrigin::from(
1736                    pallet_ethereum::RawOrigin::EthereumTransaction(info),
1737                )))
1738            }
1739            _ => None,
1740        }
1741    }
1742}
1743
1744#[cfg(feature = "runtime-benchmarks")]
1745#[macro_use]
1746extern crate frame_benchmarking;
1747
1748#[cfg(feature = "runtime-benchmarks")]
1749mod benches {
1750    define_benchmarks!(
1751        [frame_benchmarking, BaselineBench::<Runtime>]
1752        [frame_system, SystemBench::<Runtime>]
1753        [frame_system_extensions, SystemExtensionsBench::<Runtime>]
1754        [pallet_assets, pallet_assets::Pallet::<Runtime>]
1755        [pallet_balances, Balances]
1756        [pallet_timestamp, Timestamp]
1757        [pallet_transaction_payment, TransactionPayment]
1758        [pallet_dapp_staking, DappStaking]
1759        [pallet_inflation, Inflation]
1760        [pallet_migrations, MultiBlockMigrations]
1761        [contracts_mbm, ContractsMBM]
1762        [pallet_xc_asset_config, XcAssetConfig]
1763        [pallet_collator_selection, CollatorSelection]
1764        [pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1765        [pallet_dynamic_evm_base_fee, DynamicEvmBaseFee]
1766        [xcm_benchmarks_generic, XcmGeneric]
1767        [xcm_benchmarks_fungible, XcmFungible]
1768        [pallet_collective_proxy, CollectiveProxy]
1769        [pallet_tx_pause, TxPause]
1770        [pallet_safe_mode, SafeMode]
1771    );
1772}
1773
1774impl_runtime_apis! {
1775    impl sp_api::Core<Block> for Runtime {
1776        fn version() -> RuntimeVersion {
1777            VERSION
1778        }
1779
1780        fn execute_block(block: <Block as BlockT>::LazyBlock) {
1781            Executive::execute_block(block)
1782        }
1783
1784        fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
1785            Executive::initialize_block(header)
1786        }
1787    }
1788
1789    impl sp_api::Metadata<Block> for Runtime {
1790        fn metadata() -> OpaqueMetadata {
1791            OpaqueMetadata::new(Runtime::metadata().into())
1792        }
1793
1794        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1795            Runtime::metadata_at_version(version)
1796        }
1797
1798        fn metadata_versions() -> Vec<u32> {
1799            Runtime::metadata_versions()
1800        }
1801    }
1802
1803    impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
1804        fn slot_duration() -> sp_consensus_aura::SlotDuration {
1805            sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
1806        }
1807
1808        fn authorities() -> Vec<AuraId> {
1809            pallet_aura::Authorities::<Runtime>::get().into_inner()
1810        }
1811    }
1812
1813    impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
1814        fn can_build_upon(
1815            included_hash: <Block as BlockT>::Hash,
1816            slot: cumulus_primitives_aura::Slot,
1817        ) -> bool {
1818            ConsensusHook::can_build_upon(included_hash, slot)
1819        }
1820    }
1821
1822    impl sp_block_builder::BlockBuilder<Block> for Runtime {
1823        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
1824            Executive::apply_extrinsic(extrinsic)
1825        }
1826
1827        fn finalize_block() -> <Block as BlockT>::Header {
1828            Executive::finalize_block()
1829        }
1830
1831        fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
1832            data.create_extrinsics()
1833        }
1834
1835        fn check_inherents(block: <Block as BlockT>::LazyBlock, data: InherentData) -> CheckInherentsResult {
1836            data.check_extrinsics(&block)
1837        }
1838    }
1839
1840    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1841        fn validate_transaction(
1842            source: TransactionSource,
1843            tx: <Block as BlockT>::Extrinsic,
1844            block_hash: <Block as BlockT>::Hash,
1845        ) -> TransactionValidity {
1846            Executive::validate_transaction(source, tx, block_hash)
1847        }
1848    }
1849
1850    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
1851        fn offchain_worker(header: &<Block as BlockT>::Header) {
1852            Executive::offchain_worker(header)
1853        }
1854    }
1855
1856    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
1857        fn account_nonce(account: AccountId) -> Nonce {
1858            System::account_nonce(account)
1859        }
1860    }
1861
1862    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
1863        Block,
1864        Balance,
1865    > for Runtime {
1866        fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
1867            TransactionPayment::query_info(uxt, len)
1868        }
1869        fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
1870            TransactionPayment::query_fee_details(uxt, len)
1871        }
1872        fn query_weight_to_fee(weight: Weight) -> Balance {
1873            TransactionPayment::weight_to_fee(weight)
1874        }
1875        fn query_length_to_fee(length: u32) -> Balance {
1876            TransactionPayment::length_to_fee(length)
1877        }
1878    }
1879
1880    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
1881        for Runtime
1882    {
1883        fn query_call_info(
1884            call: RuntimeCall,
1885            len: u32,
1886        ) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
1887            TransactionPayment::query_call_info(call, len)
1888        }
1889        fn query_call_fee_details(
1890            call: RuntimeCall,
1891            len: u32,
1892        ) -> pallet_transaction_payment::FeeDetails<Balance> {
1893            TransactionPayment::query_call_fee_details(call, len)
1894        }
1895        fn query_weight_to_fee(weight: Weight) -> Balance {
1896            TransactionPayment::weight_to_fee(weight)
1897        }
1898
1899        fn query_length_to_fee(length: u32) -> Balance {
1900            TransactionPayment::length_to_fee(length)
1901        }
1902    }
1903
1904    impl sp_session::SessionKeys<Block> for Runtime {
1905        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
1906            SessionKeys::generate(seed)
1907        }
1908
1909        fn decode_session_keys(
1910            encoded: Vec<u8>,
1911        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
1912            SessionKeys::decode_into_raw_public_keys(&encoded)
1913        }
1914    }
1915
1916    impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
1917        fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
1918            ParachainSystem::collect_collation_info(header)
1919        }
1920    }
1921
1922    impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
1923        fn relay_parent_offset() -> u32 {
1924            RelayParentOffset::get()
1925        }
1926    }
1927
1928    impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
1929        fn chain_id() -> u64 {
1930            EVMChainId::get()
1931        }
1932
1933        fn account_basic(address: H160) -> pallet_evm::Account {
1934            let (account, _) = EVM::account_basic(&address);
1935            account
1936        }
1937
1938        fn gas_price() -> U256 {
1939            let (gas_price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
1940            gas_price
1941        }
1942
1943        fn account_code_at(address: H160) -> Vec<u8> {
1944            pallet_evm::AccountCodes::<Runtime>::get(address)
1945        }
1946
1947        fn author() -> H160 {
1948            <pallet_evm::Pallet<Runtime>>::find_author()
1949        }
1950
1951        fn storage_at(address: H160, index: U256) -> H256 {
1952            let tmp: [u8; 32] = index.to_big_endian();
1953            pallet_evm::AccountStorages::<Runtime>::get(address, H256::from_slice(&tmp[..]))
1954        }
1955
1956        fn call(
1957            from: H160,
1958            to: H160,
1959            data: Vec<u8>,
1960            value: U256,
1961            gas_limit: U256,
1962            max_fee_per_gas: Option<U256>,
1963            max_priority_fee_per_gas: Option<U256>,
1964            nonce: Option<U256>,
1965            estimate: bool,
1966            access_list: Option<Vec<(H160, Vec<H256>)>>,
1967            authorization_list: Option<AuthorizationList>,
1968        ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
1969            let config = if estimate {
1970                let mut config = <Runtime as pallet_evm::Config>::config().clone();
1971                config.estimate = true;
1972                Some(config)
1973            } else {
1974                None
1975            };
1976
1977            let is_transactional = false;
1978            let validate = true;
1979
1980            // Reused approach from Moonbeam since Frontier implementation doesn't support this
1981            let mut estimated_transaction_len = data.len() +
1982                // to: 20
1983                // from: 20
1984                // value: 32
1985                // gas_limit: 32
1986                // nonce: 32
1987                // 1 byte transaction action variant
1988                // chain id 8 bytes
1989                // 65 bytes signature
1990                210;
1991            if max_fee_per_gas.is_some() {
1992                estimated_transaction_len += 32;
1993            }
1994            if max_priority_fee_per_gas.is_some() {
1995                estimated_transaction_len += 32;
1996            }
1997            if access_list.is_some() {
1998                estimated_transaction_len += access_list.encoded_size();
1999            }
2000
2001            let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
2002            let without_base_extrinsic_weight = true;
2003
2004            let (weight_limit, proof_size_base_cost) =
2005                match <Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(
2006                    gas_limit,
2007                    without_base_extrinsic_weight
2008                ) {
2009                    weight_limit if weight_limit.proof_size() > 0 => {
2010                        (Some(weight_limit), Some(estimated_transaction_len as u64))
2011                    }
2012                    _ => (None, None),
2013                };
2014
2015            <Runtime as pallet_evm::Config>::Runner::call(
2016                from,
2017                to,
2018                data,
2019                value,
2020                gas_limit.unique_saturated_into(),
2021                max_fee_per_gas,
2022                max_priority_fee_per_gas,
2023                nonce,
2024                access_list.unwrap_or_default(),
2025                authorization_list.unwrap_or_default(),
2026                is_transactional,
2027                validate,
2028                weight_limit,
2029                proof_size_base_cost,
2030                config
2031                    .as_ref()
2032                    .unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
2033            )
2034            .map_err(|err| err.error.into())
2035        }
2036
2037        fn create(
2038            from: H160,
2039            data: Vec<u8>,
2040            value: U256,
2041            gas_limit: U256,
2042            max_fee_per_gas: Option<U256>,
2043            max_priority_fee_per_gas: Option<U256>,
2044            nonce: Option<U256>,
2045            estimate: bool,
2046            access_list: Option<Vec<(H160, Vec<H256>)>>,
2047            authorization_list: Option<AuthorizationList>,
2048        ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
2049            let config = if estimate {
2050                let mut config = <Runtime as pallet_evm::Config>::config().clone();
2051                config.estimate = true;
2052                Some(config)
2053            } else {
2054                None
2055            };
2056
2057            let is_transactional = false;
2058            let validate = true;
2059
2060            // Reused approach from Moonbeam since Frontier implementation doesn't support this
2061            let mut estimated_transaction_len = data.len() +
2062                // to: 20
2063                // from: 20
2064                // value: 32
2065                // gas_limit: 32
2066                // nonce: 32
2067                // 1 byte transaction action variant
2068                // chain id 8 bytes
2069                // 65 bytes signature
2070                210;
2071            if max_fee_per_gas.is_some() {
2072                estimated_transaction_len += 32;
2073            }
2074            if max_priority_fee_per_gas.is_some() {
2075                estimated_transaction_len += 32;
2076            }
2077            if access_list.is_some() {
2078                estimated_transaction_len += access_list.encoded_size();
2079            }
2080
2081            let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
2082            let without_base_extrinsic_weight = true;
2083
2084            let (weight_limit, proof_size_base_cost) =
2085                match <Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(
2086                    gas_limit,
2087                    without_base_extrinsic_weight
2088                ) {
2089                    weight_limit if weight_limit.proof_size() > 0 => {
2090                        (Some(weight_limit), Some(estimated_transaction_len as u64))
2091                    }
2092                    _ => (None, None),
2093                };
2094
2095            #[allow(clippy::or_fun_call)] // suggestion not helpful here
2096            <Runtime as pallet_evm::Config>::Runner::create(
2097                from,
2098                data,
2099                value,
2100                gas_limit.unique_saturated_into(),
2101                max_fee_per_gas,
2102                max_priority_fee_per_gas,
2103                nonce,
2104                access_list.unwrap_or_default(),
2105                authorization_list.unwrap_or_default(),
2106                is_transactional,
2107                validate,
2108                weight_limit,
2109                proof_size_base_cost,
2110                config
2111                    .as_ref()
2112                    .unwrap_or(<Runtime as pallet_evm::Config>::config()),
2113                )
2114                .map_err(|err| err.error.into())
2115        }
2116
2117        fn current_transaction_statuses() -> Option<Vec<fp_rpc::TransactionStatus>> {
2118            pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
2119        }
2120
2121        fn current_block() -> Option<pallet_ethereum::Block> {
2122            pallet_ethereum::CurrentBlock::<Runtime>::get()
2123        }
2124
2125        fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
2126            pallet_ethereum::CurrentReceipts::<Runtime>::get()
2127        }
2128
2129        fn current_all() -> (
2130            Option<pallet_ethereum::Block>,
2131            Option<Vec<pallet_ethereum::Receipt>>,
2132            Option<Vec<fp_rpc::TransactionStatus>>,
2133        ) {
2134            (
2135                pallet_ethereum::CurrentBlock::<Runtime>::get(),
2136                pallet_ethereum::CurrentReceipts::<Runtime>::get(),
2137                pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
2138            )
2139        }
2140
2141        fn extrinsic_filter(
2142            xts: Vec<<Block as BlockT>::Extrinsic>,
2143        ) -> Vec<pallet_ethereum::Transaction> {
2144            xts.into_iter().filter_map(|xt| match xt.0.function {
2145                RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
2146                _ => None
2147            }).collect::<Vec<pallet_ethereum::Transaction>>()
2148        }
2149
2150        fn elasticity() -> Option<Permill> {
2151            Some(Permill::zero())
2152        }
2153
2154        fn gas_limit_multiplier_support() {}
2155
2156        fn pending_block(
2157            xts: Vec<<Block as BlockT>::Extrinsic>,
2158        ) -> (Option<pallet_ethereum::Block>, Option<Vec<fp_rpc::TransactionStatus>>) {
2159            for ext in xts.into_iter() {
2160                let _ = Executive::apply_extrinsic(ext);
2161            }
2162
2163            Ethereum::on_finalize(System::block_number() + 1);
2164
2165            (
2166                pallet_ethereum::CurrentBlock::<Runtime>::get(),
2167                pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
2168            )
2169        }
2170
2171        fn initialize_pending_block(header: &<Block as BlockT>::Header) {
2172            Executive::initialize_block(header);
2173        }
2174    }
2175
2176    impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
2177        fn convert_transaction(
2178            transaction: pallet_ethereum::Transaction
2179        ) -> <Block as BlockT>::Extrinsic {
2180            UncheckedExtrinsic::new_bare(
2181                pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
2182            )
2183        }
2184    }
2185
2186    impl dapp_staking_runtime_api::DappStakingApi<Block> for Runtime {
2187        fn periods_per_cycle() -> PeriodNumber {
2188            InflationCycleConfig::periods_per_cycle()
2189        }
2190
2191        fn eras_per_voting_subperiod() -> EraNumber {
2192            InflationCycleConfig::eras_per_voting_subperiod()
2193        }
2194
2195        fn eras_per_build_and_earn_subperiod() -> EraNumber {
2196            InflationCycleConfig::eras_per_build_and_earn_subperiod()
2197        }
2198
2199        fn blocks_per_era() -> BlockNumber {
2200            InflationCycleConfig::blocks_per_era()
2201        }
2202
2203        fn get_dapp_tier_assignment() -> BTreeMap<DAppId, RankedTier> {
2204            DappStaking::get_dapp_tier_assignment()
2205        }
2206    }
2207
2208    impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
2209        fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
2210            if !matches!(xcm_version, xcm::v3::VERSION | xcm::v4::VERSION | xcm::v5::VERSION) {
2211                return Err(XcmPaymentApiError::UnhandledXcmVersion);
2212            }
2213
2214            // Native asset is always supported
2215            let mut acceptable_assets = vec![XcmAssetId::from(xcm_config::ShibuyaLocation::get())];
2216
2217            // Add foreign assets that have 'units per second' configured
2218            acceptable_assets.extend(
2219                pallet_xc_asset_config::AssetLocationUnitsPerSecond::<Runtime>::iter_keys().filter_map(
2220                    |asset_location| match XcmLocation::try_from(asset_location) {
2221                        Ok(location) => Some(XcmAssetId::from(location)),
2222                        Err(_) => None,
2223                    },
2224                ),
2225            );
2226
2227            PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
2228        }
2229
2230        fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
2231            let asset = asset.into_version(xcm::v5::VERSION).map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
2232            let asset_id: XcmAssetId = asset.try_into().map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
2233
2234            // for native token
2235            if asset_id.0 == xcm_config::ShibuyaLocation::get() {
2236                Ok(XcmWeightToFee::weight_to_fee(&weight))
2237            }
2238            // for foreign assets with “units per second” configurations
2239            else {
2240                let versioned_location = VersionedLocation::V5(asset_id.0);
2241
2242                match pallet_xc_asset_config::AssetLocationUnitsPerSecond::<Runtime>::get(versioned_location) {
2243                    Some(units_per_sec) => {
2244                        Ok(pallet_xc_asset_config::Pallet::<Runtime>::weight_to_fee(weight, units_per_sec))
2245                    }
2246                    None => Err(XcmPaymentApiError::AssetNotFound),
2247                }
2248            }
2249        }
2250
2251        fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
2252            PolkadotXcm::query_xcm_weight(message)
2253        }
2254
2255        fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>, asset_id: VersionedAssetId) -> Result<VersionedAssets, XcmPaymentApiError> {
2256            type AssetExchanger = <xcm_config::XcmConfig as xcm_executor::Config>::AssetExchanger;
2257            PolkadotXcm::query_delivery_fees::<AssetExchanger>(destination, message, asset_id)
2258        }
2259    }
2260
2261    impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
2262        fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2263            PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
2264        }
2265
2266        fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
2267            PolkadotXcm::dry_run_xcm::<xcm_config::XcmRouter>(origin_location, xcm)
2268        }
2269    }
2270
2271    impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
2272        fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
2273            PolkadotXcm::is_trusted_reserve(asset, location)
2274        }
2275        fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
2276            PolkadotXcm::is_trusted_teleporter(asset, location)
2277        }
2278    }
2279
2280    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
2281
2282        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
2283            genesis_builder_helper::build_state::<RuntimeGenesisConfig>(config)
2284        }
2285
2286        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
2287            genesis_builder_helper::get_preset::<RuntimeGenesisConfig>(id, &genesis_config::get_preset)
2288        }
2289
2290        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
2291            vec![
2292                sp_genesis_builder::PresetId::from("development"),
2293            ]
2294        }
2295    }
2296
2297    #[cfg(feature = "runtime-benchmarks")]
2298    impl frame_benchmarking::Benchmark<Block> for Runtime {
2299        fn benchmark_metadata(extra: bool) -> (
2300            Vec<frame_benchmarking::BenchmarkList>,
2301            Vec<frame_support::traits::StorageInfo>,
2302        ) {
2303            use frame_benchmarking::{baseline, BenchmarkList};
2304            use frame_support::traits::StorageInfoTrait;
2305            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2306            pub use frame_system_benchmarking::{
2307                extensions::Pallet as SystemExtensionsBench, Pallet as SystemBench
2308            };
2309            use baseline::Pallet as BaselineBench;
2310
2311            // This is defined once again in dispatch_benchmark, because list_benchmarks!
2312            // and add_benchmarks! are macros exported by define_benchmarks! macros and those types
2313            // are referenced in that call.
2314            type XcmFungible = astar_xcm_benchmarks::fungible::benchmarking::XcmFungibleBenchmarks::<Runtime>;
2315            type XcmGeneric = astar_xcm_benchmarks::generic::benchmarking::XcmGenericBenchmarks::<Runtime>;
2316
2317            let mut list = Vec::<BenchmarkList>::new();
2318            list_benchmarks!(list, extra);
2319
2320            let storage_info = AllPalletsWithSystem::storage_info();
2321
2322            (list, storage_info)
2323        }
2324
2325        #[allow(non_local_definitions)]
2326        fn dispatch_benchmark(
2327            config: frame_benchmarking::BenchmarkConfig
2328        ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
2329            use alloc::boxed::Box;
2330            use frame_benchmarking::{baseline, BenchmarkBatch, BenchmarkError};
2331            pub use frame_system_benchmarking::{
2332                extensions::Pallet as SystemExtensionsBench, Pallet as SystemBench
2333            };
2334            use frame_support::{traits::{WhitelistedStorageKeys, TrackedStorageKey, tokens::fungible::{ItemOf}}, assert_ok};
2335            use baseline::Pallet as BaselineBench;
2336            use xcm::latest::prelude::*;
2337            use xcm_builder::MintLocation;
2338            use astar_primitives::{benchmarks::XcmBenchmarkHelper, xcm::ASSET_HUB_PARA_ID};
2339            // Needed to run `set_code` and `apply_authorized_upgrade` frame_system benchmarks
2340            // https://github.com/paritytech/cumulus/pull/2766
2341            impl frame_system_benchmarking::Config for Runtime {
2342                fn setup_set_code_requirements(code: &Vec<u8>) -> Result<(), BenchmarkError> {
2343                    ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
2344                    Ok(())
2345                }
2346
2347                fn verify_set_code() {
2348                    System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
2349                }
2350            }
2351            impl baseline::Config for Runtime {}
2352            use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
2353
2354            pub struct TestDeliveryHelper;
2355            impl xcm_builder::EnsureDelivery for TestDeliveryHelper {
2356                fn ensure_successful_delivery(
2357                    origin_ref: &Location,
2358                    dest: &Location,
2359                    _fee_reason: xcm_executor::traits::FeeReason,
2360                ) -> (Option<xcm_executor::FeesMode>, Option<Assets>) {
2361                    use xcm_executor::traits::ConvertLocation;
2362
2363                    // This sets up the necessary infrastructure (HostConfiguration) for sending XCM messages
2364                    <xcm_config::XcmRouter as xcm::latest::SendXcm>::ensure_successful_delivery(
2365                        Some(dest.clone())
2366                    );
2367
2368                    // Open HRMP channel for sibling parachain destinations
2369                    if let Some(Parachain(para_id)) = dest.interior().first() {
2370                        ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
2371                            (*para_id).into()
2372                        );
2373                    }
2374
2375                    if let Some(account) = xcm_config::LocationToAccountId::convert_location(origin_ref) {
2376                        // Give the account some balance to ensure delivery
2377                        let balance = ExistentialDeposit::get() * 1000u128; // Give more than just ED
2378                        let _ = <Balances as frame_support::traits::Currency<_>>::
2379                            make_free_balance_be(&account.into(), balance);
2380                    }
2381
2382                    (None, None)
2383                }
2384            }
2385
2386            impl pallet_xcm::benchmarking::Config for Runtime {
2387                type DeliveryHelper = TestDeliveryHelper;
2388
2389                fn reachable_dest() -> Option<Location> {
2390                    Some(AssetHubLocation::get())
2391                }
2392
2393                fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
2394                    None
2395                }
2396
2397                fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
2398                    let random_para_id = 43211234;
2399                    ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
2400                        random_para_id.into()
2401                    );
2402                    Some((
2403                        Asset {
2404                            fun: Fungible(ExistentialDeposit::get()),
2405                            id: AssetId(Here.into())
2406                        },
2407                        ParentThen(Parachain(random_para_id).into()).into(),
2408                    ))
2409                }
2410
2411                fn set_up_complex_asset_transfer(
2412                ) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
2413                    XcmBenchmarkHelper::<Runtime>::set_up_complex_asset_transfer()
2414                }
2415
2416                fn get_asset() -> Asset {
2417                    Asset {
2418                        id: AssetId(Here.into()),
2419                        fun: Fungible(ExistentialDeposit::get()),
2420                    }
2421                }
2422            }
2423
2424            // XCM Benchmarks
2425            impl astar_xcm_benchmarks::Config for Runtime {}
2426            impl astar_xcm_benchmarks::generic::Config for Runtime {}
2427            impl astar_xcm_benchmarks::fungible::Config for Runtime {}
2428
2429            impl pallet_xcm_benchmarks::Config for Runtime {
2430                type XcmConfig = xcm_config::XcmConfig;
2431                type AccountIdConverter = xcm_config::LocationToAccountId;
2432                type DeliveryHelper = TestDeliveryHelper;
2433
2434                // destination location to be used in benchmarks
2435                fn valid_destination() -> Result<Location, BenchmarkError> {
2436                    let asset_hub = AssetHubLocation::get();
2437                    assert_ok!(PolkadotXcm::force_xcm_version(RuntimeOrigin::root(), Box::new(asset_hub.clone()), xcm::v5::VERSION));
2438
2439                    // This sets up the necessary infrastructure (HostConfiguration) for sending XCM messages
2440                    <xcm_config::XcmRouter as xcm::latest::SendXcm>::ensure_successful_delivery(
2441                        Some(asset_hub.clone())
2442                    );
2443
2444                    // Open HRMP channel for sibling parachain destinations
2445                    ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
2446                        AssetHubParaId::get().into()
2447                    );
2448
2449                    Ok(asset_hub)
2450                }
2451                fn worst_case_holding(_depositable_count: u32) -> Assets {
2452                   XcmBenchmarkHelper::<Runtime>::worst_case_holding()
2453                }
2454            }
2455
2456            impl pallet_xcm_benchmarks::generic::Config for Runtime {
2457                type RuntimeCall = RuntimeCall;
2458                type TransactAsset = Balances;
2459                fn worst_case_response() -> (u64, Response) {
2460                    (0u64, Response::Version(Default::default()))
2461                }
2462                fn worst_case_asset_exchange()
2463                    -> Result<(Assets, Assets), BenchmarkError> {
2464                    Err(BenchmarkError::Skip)
2465                }
2466
2467                fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
2468                    Err(BenchmarkError::Skip)
2469                }
2470                fn transact_origin_and_runtime_call()
2471                    -> Result<(Location, RuntimeCall), BenchmarkError> {
2472                    assert_ok!(PolkadotXcm::force_xcm_version(RuntimeOrigin::root(), Box::new(Location::parent()), xcm::v5::VERSION));
2473                    Ok((Location::parent(), frame_system::Call::remark_with_event {
2474                        remark: vec![]
2475                    }.into()))
2476                }
2477                fn subscribe_origin() -> Result<Location, BenchmarkError> {
2478                    assert_ok!(PolkadotXcm::force_xcm_version(RuntimeOrigin::root(), Box::new(Location::parent()), xcm::v5::VERSION));
2479                    Ok(Location::parent())
2480                }
2481                fn claimable_asset()
2482                    -> Result<(Location, Location, Assets), BenchmarkError> {
2483                    let origin = Location::parent();
2484                    let assets: Assets = (AssetId(Location::parent()), 1_000u128)
2485                        .into();
2486                    let ticket = Location { parents: 0, interior: Here };
2487                    Ok((origin, ticket, assets))
2488                }
2489                fn unlockable_asset()
2490                    -> Result<(Location, Location, Asset), BenchmarkError> {
2491                    Err(BenchmarkError::Skip)
2492                }
2493                fn export_message_origin_and_destination(
2494                ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> {
2495                    Err(BenchmarkError::Skip)
2496                }
2497                fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
2498                    Err(BenchmarkError::Skip)
2499                }
2500                fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
2501                    Ok((
2502                        (AssetId(Here.into()), 1_000_000_000_000_000_000u128).into(),
2503                        Limited(Weight::from_parts(5000, 5000)),
2504                    ))
2505                }
2506            }
2507
2508            parameter_types! {
2509                pub const NoCheckingAccount: Option<(AccountId, MintLocation)> = None;
2510                pub const NoTeleporter: Option<(Location, Asset)> = None;
2511                pub const TransactAssetId: u128 = 1001;
2512                pub TransactAssetLocation: Location = Location { parents: 0, interior: [GeneralIndex(TransactAssetId::get())].into() };
2513
2514                pub const AssetHubParaId: u32 = ASSET_HUB_PARA_ID;
2515                pub AssetHubLocation: Location = Location::new(1, [Parachain(AssetHubParaId::get())]);
2516                pub TrustedReserveLocation: Location = AssetHubLocation::get();
2517                pub TrustedReserveAsset: Asset = Asset { id: AssetId(TrustedReserveLocation::get()), fun: Fungible(1_000_000) };
2518                pub TrustedReserve: Option<(Location, Asset)> = Some((TrustedReserveLocation::get(), TrustedReserveAsset::get()));
2519            }
2520
2521            impl pallet_xcm_benchmarks::fungible::Config for Runtime {
2522                type TransactAsset = ItemOf<pallet_assets::Pallet<Runtime>, TransactAssetId, AccountId>;
2523                type CheckedAccount = NoCheckingAccount;
2524                type TrustedTeleporter = NoTeleporter;
2525                type TrustedReserve = TrustedReserve;
2526
2527                fn get_asset() -> Asset {
2528                    let min_balance = 100u128;
2529                    // create the transact asset and make it sufficient
2530                    assert_ok!(pallet_assets::Pallet::<Runtime>::force_create(
2531                        RuntimeOrigin::root(),
2532                        TransactAssetId::get().into(),
2533                        Address::Id([0u8; 32].into()),
2534                        true,
2535                        // min balance
2536                        min_balance
2537                    ));
2538
2539                    // convert mapping for asset id
2540                    assert_ok!(
2541                        XcAssetConfig::register_asset_location(
2542                            RuntimeOrigin::root(),
2543                            Box::new(TransactAssetLocation::get().into_versioned()),
2544                            TransactAssetId::get(),
2545                        )
2546                    );
2547
2548                    Asset {
2549                        id: AssetId(TransactAssetLocation::get()),
2550                        fun: Fungible(min_balance * 100),
2551                    }
2552                }
2553            }
2554
2555            type XcmFungible = astar_xcm_benchmarks::fungible::benchmarking::XcmFungibleBenchmarks::<Runtime>;
2556            type XcmGeneric = astar_xcm_benchmarks::generic::benchmarking::XcmGenericBenchmarks::<Runtime>;
2557
2558            let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
2559
2560            let mut batches = Vec::<BenchmarkBatch>::new();
2561            let params = (&config, &whitelist);
2562            add_benchmarks!(params, batches);
2563
2564            if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
2565            Ok(batches)
2566        }
2567    }
2568
2569    #[cfg(feature = "evm-tracing")]
2570    impl moonbeam_rpc_primitives_debug::DebugRuntimeApi<Block> for Runtime {
2571        fn trace_transaction(
2572            extrinsics: Vec<<Block as BlockT>::Extrinsic>,
2573            traced_transaction: &pallet_ethereum::Transaction,
2574            header: &<Block as BlockT>::Header,
2575        ) -> Result<
2576            (),
2577            sp_runtime::DispatchError,
2578        > {
2579            use moonbeam_evm_tracer::tracer::EvmTracer;
2580
2581            // We need to follow the order when replaying the transactions.
2582            // Block initialize happens first then apply_extrinsic.
2583            Executive::initialize_block(header);
2584
2585            // Apply the a subset of extrinsics: all the substrate-specific or ethereum
2586            // transactions that preceded the requested transaction.
2587            for ext in extrinsics.into_iter() {
2588                let _ = match &ext.0.function {
2589                    RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => {
2590                        if transaction == traced_transaction {
2591                            EvmTracer::new().trace(|| Executive::apply_extrinsic(ext));
2592                            return Ok(());
2593                        } else {
2594                            Executive::apply_extrinsic(ext)
2595                        }
2596                    }
2597                    _ => Executive::apply_extrinsic(ext),
2598                };
2599            }
2600            Err(sp_runtime::DispatchError::Other(
2601                "Failed to find Ethereum transaction among the extrinsics.",
2602            ))
2603        }
2604
2605        fn trace_block(
2606            extrinsics: Vec<<Block as BlockT>::Extrinsic>,
2607            known_transactions: Vec<H256>,
2608            header: &<Block as BlockT>::Header,
2609        ) -> Result<
2610            (),
2611            sp_runtime::DispatchError,
2612        > {
2613            use moonbeam_evm_tracer::tracer::EvmTracer;
2614
2615            let mut config = <Runtime as pallet_evm::Config>::config().clone();
2616            config.estimate = true;
2617
2618            // We need to follow the order when replaying the transactions.
2619            // Block initialize happens first then apply_extrinsic.
2620            Executive::initialize_block(header);
2621
2622            // Apply all extrinsics. Ethereum extrinsics are traced.
2623            for ext in extrinsics.into_iter() {
2624                match &ext.0.function {
2625                    RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => {
2626                        if known_transactions.contains(&transaction.hash()) {
2627                            // Each known extrinsic is a new call stack.
2628                            EvmTracer::emit_new();
2629                            EvmTracer::new().trace(|| Executive::apply_extrinsic(ext));
2630                        } else {
2631                            let _ = Executive::apply_extrinsic(ext);
2632                        }
2633                    }
2634                    _ => {
2635                        let _ = Executive::apply_extrinsic(ext);
2636                    }
2637                };
2638            }
2639
2640            Ok(())
2641        }
2642
2643        fn trace_call(
2644            header: &<Block as BlockT>::Header,
2645            from: H160,
2646            to: H160,
2647            data: Vec<u8>,
2648            value: U256,
2649            gas_limit: U256,
2650            max_fee_per_gas: Option<U256>,
2651            max_priority_fee_per_gas: Option<U256>,
2652            nonce: Option<U256>,
2653            access_list: Option<Vec<(H160, Vec<H256>)>>,
2654            authorization_list: Option<AuthorizationList>,
2655        ) -> Result<(), sp_runtime::DispatchError> {
2656            use moonbeam_evm_tracer::tracer::EvmTracer;
2657
2658            // Initialize block: calls the "on_initialize" hook on every pallet
2659            // in AllPalletsWithSystem.
2660            Executive::initialize_block(header);
2661
2662            EvmTracer::new().trace(|| {
2663                let is_transactional = false;
2664                let validate = true;
2665                let without_base_extrinsic_weight = true;
2666
2667                // Estimated encoded transaction size must be based on the heaviest transaction
2668                // type (EIP1559Transaction) to be compatible with all transaction types.
2669                let mut estimated_transaction_len = data.len() +
2670                // pallet ethereum index: 1
2671                // transact call index: 1
2672                // Transaction enum variant: 1
2673                // chain_id 8 bytes
2674                // nonce: 32
2675                // max_priority_fee_per_gas: 32
2676                // max_fee_per_gas: 32
2677                // gas_limit: 32
2678                // action: 21 (enum varianrt + call address)
2679                // value: 32
2680                // access_list: 1 (empty vec size)
2681                // 65 bytes signature
2682                258;
2683
2684                if access_list.is_some() {
2685                    estimated_transaction_len += access_list.encoded_size();
2686                }
2687
2688                let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
2689
2690                let (weight_limit, proof_size_base_cost) =
2691                    match <Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(
2692                        gas_limit,
2693                        without_base_extrinsic_weight
2694                    ) {
2695                        weight_limit if weight_limit.proof_size() > 0 => {
2696                            (Some(weight_limit), Some(estimated_transaction_len as u64))
2697                        }
2698                        _ => (None, None),
2699                    };
2700
2701                let _ = <Runtime as pallet_evm::Config>::Runner::call(
2702                    from,
2703                    to,
2704                    data,
2705                    value,
2706                    gas_limit,
2707                    max_fee_per_gas,
2708                    max_priority_fee_per_gas,
2709                    nonce,
2710                    access_list.unwrap_or_default(),
2711                    authorization_list.unwrap_or_default(),
2712                    is_transactional,
2713                    validate,
2714                    weight_limit,
2715                    proof_size_base_cost,
2716                    <Runtime as pallet_evm::Config>::config(),
2717                );
2718            });
2719            Ok(())
2720        }
2721    }
2722
2723    #[cfg(feature = "evm-tracing")]
2724    impl moonbeam_rpc_primitives_txpool::TxPoolRuntimeApi<Block> for Runtime {
2725        fn extrinsic_filter(
2726            xts_ready: Vec<<Block as BlockT>::Extrinsic>,
2727            xts_future: Vec<<Block as BlockT>::Extrinsic>,
2728        ) -> moonbeam_rpc_primitives_txpool::TxPoolResponse {
2729            moonbeam_rpc_primitives_txpool::TxPoolResponse {
2730                ready: xts_ready
2731                    .into_iter()
2732                    .filter_map(|xt| match xt.0.function {
2733                        RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
2734                        _ => None,
2735                    })
2736                    .collect(),
2737                future: xts_future
2738                    .into_iter()
2739                    .filter_map(|xt| match xt.0.function {
2740                        RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
2741                        _ => None,
2742                    })
2743                    .collect(),
2744            }
2745        }
2746    }
2747
2748    #[cfg(feature = "try-runtime")]
2749    impl frame_try_runtime::TryRuntime<Block> for Runtime {
2750        fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2751            log::info!("try-runtime::on_runtime_upgrade");
2752            let weight = Executive::try_runtime_upgrade(checks).unwrap();
2753            (weight, RuntimeBlockWeights::get().max_block)
2754        }
2755
2756        fn execute_block(
2757            block: <Block as BlockT>::LazyBlock,
2758            state_root_check: bool,
2759            signature_check: bool,
2760            select: frame_try_runtime::TryStateSelect
2761        ) -> Weight {
2762            log::info!(
2763                "try-runtime: executing block #{} ({:?}) / root checks: {:?} / sanity-checks: {:?}",
2764                block.header.number,
2765                block.header.hash(),
2766                state_root_check,
2767                select,
2768            );
2769            Executive::try_execute_block(block, state_root_check, signature_check, select).expect("execute-block failed")
2770        }
2771    }
2772}
2773
2774cumulus_pallet_parachain_system::register_validate_block! {
2775    Runtime = Runtime,
2776    BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
2777}