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