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