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