shibuya_runtime/
lib.rs

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