local_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#![cfg_attr(not(feature = "std"), no_std)]
20// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
21#![recursion_limit = "256"]
22
23// Make the WASM binary available.
24#[cfg(feature = "std")]
25include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
26
27extern crate alloc;
28extern crate core;
29
30use alloc::{borrow::Cow, collections::btree_map::BTreeMap, vec, vec::Vec};
31use core::marker::PhantomData;
32
33use ethereum::AuthorizationList;
34use frame_support::{
35    construct_runtime, genesis_builder_helper, parameter_types,
36    traits::{
37        fungible::{Balanced, Credit, HoldConsideration},
38        AsEnsureOriginWithArg, ConstU128, ConstU32, ConstU64, ConstU8, Contains,
39        EqualPrivilegeOnly, FindAuthor, Get, InsideBoth, InstanceFilter, LinearStoragePrice,
40        Nothing, OnFinalize, WithdrawReasons,
41    },
42    weights::{
43        constants::{ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND},
44        ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients,
45        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_evm_precompile_assets_erc20::AddressToAssetId;
56use pallet_grandpa::{fg_primitives, AuthorityList as GrandpaAuthorityList};
57use pallet_transaction_payment::{FungibleAdapter, Multiplier, TargetedFeeAdjustment};
58use parity_scale_codec::{Compact, Decode, Encode, MaxEncodedLen};
59use sp_api::impl_runtime_apis;
60use sp_core::{
61    crypto::KeyTypeId, sr25519, ConstBool, DecodeWithMemTracking, OpaqueMetadata, H160, H256, U256,
62};
63use sp_runtime::{
64    generic, impl_opaque_keys,
65    traits::{
66        AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto,
67        DispatchInfoOf, Dispatchable, NumberFor, PostDispatchInfoOf, UniqueSaturatedInto,
68    },
69    transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
70    ApplyExtrinsicResult, FixedPointNumber, Perbill, Permill, Perquintill, RuntimeDebug,
71};
72
73use astar_primitives::{
74    dapp_staking::{
75        CycleConfiguration, DAppId, EraNumber, PeriodNumber, RankedTier, SmartContract,
76    },
77    evm::{EvmRevertCodeHandler, HashedDefaultMappings},
78    governance::{
79        CommunityCouncilCollectiveInst, CommunityCouncilMembershipInst, CommunityTreasuryInst,
80        EnsureRootOrAllMainCouncil, EnsureRootOrAllTechnicalCommittee,
81        EnsureRootOrHalfTechnicalCommittee, EnsureRootOrTwoThirdsCommunityCouncil,
82        EnsureRootOrTwoThirdsMainCouncil, EnsureRootOrTwoThirdsTechnicalCommittee,
83        MainCouncilCollectiveInst, MainCouncilMembershipInst, MainTreasuryInst,
84        TechnicalCommitteeCollectiveInst, TechnicalCommitteeMembershipInst,
85    },
86    Address, AssetId, Balance, BlockNumber, Hash, Header, Nonce,
87};
88
89pub use astar_primitives::{AccountId, Signature};
90pub use pallet_dapp_staking::TierThreshold;
91
92pub use crate::precompiles::WhitelistedCalls;
93#[cfg(feature = "std")]
94use sp_version::NativeVersion;
95use sp_version::RuntimeVersion;
96
97pub use frame_system::Call as SystemCall;
98pub use pallet_balances::Call as BalancesCall;
99pub use pallet_grandpa::AuthorityId as GrandpaId;
100pub use pallet_inflation::InflationParameters;
101pub use pallet_timestamp::Call as TimestampCall;
102pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
103#[cfg(any(feature = "std", test))]
104pub use sp_runtime::BuildStorage;
105
106#[cfg(feature = "std")]
107/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics.
108pub fn wasm_binary_unwrap() -> &'static [u8] {
109    WASM_BINARY.expect(
110        "Development wasm binary is not available. This means the client is \
111                        built with `BUILD_DUMMY_WASM_BINARY` flag and it is only usable for \
112                        production chains. Please rebuild with the flag disabled.",
113    )
114}
115
116#[sp_version::runtime_version]
117pub const VERSION: RuntimeVersion = RuntimeVersion {
118    spec_name: Cow::Borrowed("local"),
119    impl_name: Cow::Borrowed("local"),
120    authoring_version: 1,
121    spec_version: 1,
122    impl_version: 1,
123    apis: RUNTIME_API_VERSIONS,
124    transaction_version: 1,
125    system_version: 1,
126};
127
128impl_opaque_keys! {
129    pub struct SessionKeys {
130        pub aura: Aura,
131        pub grandpa: Grandpa,
132    }
133}
134
135mod precompiles;
136pub use precompiles::{LocalPrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX};
137pub type Precompiles = LocalPrecompiles<Runtime>;
138
139mod chain_extensions;
140pub use chain_extensions::LocalChainExtensions;
141
142pub mod genesis_config;
143mod weights;
144
145/// Constant values used within the runtime.
146pub const MICROAST: Balance = 1_000_000_000_000;
147pub const MILLIAST: Balance = 1_000 * MICROAST;
148pub const AST: Balance = 1_000 * MILLIAST;
149
150pub const STORAGE_BYTE_FEE: Balance = 100 * MICROAST;
151
152/// Charge fee for stored bytes and items.
153pub const fn deposit(items: u32, bytes: u32) -> Balance {
154    items as Balance * 1 * AST + (bytes as Balance) * STORAGE_BYTE_FEE
155}
156
157/// This determines the average expected block time that we are targeting.
158/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`.
159/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
160/// up by `pallet_aura` to implement `fn slot_duration()`.
161///
162/// Change this to adjust the block time.
163pub const MILLISECS_PER_BLOCK: u64 = 2000;
164pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
165
166// Time is measured by number of blocks.
167pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
168pub const HOURS: BlockNumber = MINUTES * 60;
169pub const DAYS: BlockNumber = HOURS * 24;
170
171impl AddressToAssetId<AssetId> for Runtime {
172    fn address_to_asset_id(address: H160) -> Option<AssetId> {
173        let mut data = [0u8; 16];
174        let address_bytes: [u8; 20] = address.into();
175        if ASSET_PRECOMPILE_ADDRESS_PREFIX.eq(&address_bytes[0..4]) {
176            data.copy_from_slice(&address_bytes[4..20]);
177            Some(u128::from_be_bytes(data))
178        } else {
179            None
180        }
181    }
182
183    fn asset_id_to_address(asset_id: AssetId) -> H160 {
184        let mut data = [0u8; 20];
185        data[0..4].copy_from_slice(ASSET_PRECOMPILE_ADDRESS_PREFIX);
186        data[4..20].copy_from_slice(&asset_id.to_be_bytes());
187        H160::from(data)
188    }
189}
190
191/// The version information used to identify this runtime when compiled natively.
192#[cfg(feature = "std")]
193pub fn native_version() -> NativeVersion {
194    NativeVersion {
195        runtime_version: VERSION,
196        can_author_with: Default::default(),
197    }
198}
199
200/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
201/// by  Operational  extrinsics.
202const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
203
204parameter_types! {
205    pub const Version: RuntimeVersion = VERSION;
206    pub const BlockHashCount: BlockNumber = 2400;
207    /// We allow for 1 seconds of compute with a 2 second average block time.
208    pub RuntimeBlockWeights: BlockWeights = BlockWeights
209        ::with_sensible_defaults(Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND, u64::MAX), NORMAL_DISPATCH_RATIO);
210    pub RuntimeBlockLength: BlockLength = BlockLength
211        ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
212    pub const SS58Prefix: u8 = 5;
213}
214
215// Configure FRAME pallets to include in runtime.
216impl frame_system::Config for Runtime {
217    /// The basic call filter to use in dispatchable.
218    type BaseCallFilter = InsideBoth<SafeMode, TxPause>;
219    /// Block & extrinsics weights: base values and limits.
220    type BlockWeights = RuntimeBlockWeights;
221    /// The maximum length of a block (in bytes).
222    type BlockLength = RuntimeBlockLength;
223    /// The identifier used to distinguish between accounts.
224    type AccountId = AccountId;
225    /// The aggregated dispatch type that is available for extrinsics.
226    type RuntimeCall = RuntimeCall;
227    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
228    type Lookup = (AccountIdLookup<AccountId, ()>, UnifiedAccounts);
229    /// The nonce type for storing how many extrinsics an account has signed.
230    type Nonce = Nonce;
231    /// The type for blocks.
232    type Block = Block;
233    /// The type for hashing blocks and tries.
234    type Hash = Hash;
235    /// The hashing algorithm used.
236    type Hashing = BlakeTwo256;
237    /// The ubiquitous event type.
238    type RuntimeEvent = RuntimeEvent;
239    /// The ubiquitous origin type.
240    type RuntimeOrigin = RuntimeOrigin;
241    /// The aggregated RuntimeTask type.
242    type RuntimeTask = RuntimeTask;
243    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
244    type BlockHashCount = BlockHashCount;
245    /// The weight of database operations that the runtime can invoke.
246    type DbWeight = RocksDbWeight;
247    /// Version of the runtime.
248    type Version = Version;
249    /// Converts a module to the index of the module in `construct_runtime!`.
250    ///
251    /// This type is being generated by `construct_runtime!`.
252    type PalletInfo = PalletInfo;
253    /// What to do if a new account is created.
254    type OnNewAccount = ();
255    /// What to do if an account is fully reaped from the system.
256    type OnKilledAccount = pallet_unified_accounts::KillAccountMapping<Self>;
257    /// The data to be stored in an account.
258    type AccountData = pallet_balances::AccountData<Balance>;
259    /// Weight information for the extrinsics of this pallet.
260    type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
261    /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
262    type SS58Prefix = SS58Prefix;
263    /// The set code logic, just the default since we're not a parachain.
264    type OnSetCode = ();
265    type MaxConsumers = frame_support::traits::ConstU32<16>;
266    type SingleBlockMigrations = ();
267    type MultiBlockMigrator = ();
268    type PreInherents = ();
269    type PostInherents = ();
270    type PostTransactions = ();
271    type ExtensionsWeightInfo = ();
272}
273
274impl pallet_aura::Config for Runtime {
275    type AuthorityId = AuraId;
276    type DisabledValidators = ();
277    type MaxAuthorities = ConstU32<50>;
278    type SlotDuration = pallet_aura::MinimumPeriodTimesTwo<Runtime>;
279    type AllowMultipleBlocksPerSlot = ConstBool<false>;
280}
281
282impl pallet_grandpa::Config for Runtime {
283    type RuntimeEvent = RuntimeEvent;
284
285    type KeyOwnerProof = sp_core::Void;
286    type EquivocationReportSystem = ();
287
288    type WeightInfo = ();
289    type MaxAuthorities = ConstU32<50>;
290    type MaxSetIdSessionEntries = ConstU64<0>;
291    type MaxNominators = ConstU32<0>;
292}
293
294parameter_types! {
295    pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
296}
297
298impl pallet_timestamp::Config for Runtime {
299    /// A timestamp: milliseconds since the unix epoch.
300    type Moment = u64;
301    type OnTimestampSet = Aura;
302    type MinimumPeriod = MinimumPeriod;
303    type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
304}
305
306impl pallet_insecure_randomness_collective_flip::Config for Runtime {}
307
308parameter_types! {
309    pub const ExistentialDeposit: u128 = 500;
310    pub const MaxLocks: u32 = 50;
311}
312
313impl pallet_balances::Config for Runtime {
314    type MaxLocks = MaxLocks;
315    type MaxReserves = ();
316    type ReserveIdentifier = [u8; 8];
317    /// The type for recording an account's balance.
318    type Balance = Balance;
319    /// The ubiquitous event type.
320    type RuntimeEvent = RuntimeEvent;
321    type DustRemoval = ();
322    type ExistentialDeposit = ExistentialDeposit;
323    type AccountStore = System;
324    type WeightInfo = weights::pallet_balances::SubstrateWeight<Runtime>;
325    type RuntimeHoldReason = RuntimeHoldReason;
326    type RuntimeFreezeReason = RuntimeFreezeReason;
327    type FreezeIdentifier = RuntimeFreezeReason;
328    type MaxFreezes = ConstU32<1>;
329    type DoneSlashHandler = ();
330}
331
332parameter_types! {
333    pub const AssetDeposit: Balance = 1 * AST;
334    pub const AssetsStringLimit: u32 = 50;
335    /// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
336    // https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
337    pub const MetadataDepositBase: Balance = deposit(1, 68);
338    pub const MetadataDepositPerByte: Balance = deposit(0, 1);
339    pub const AssetAccountDeposit: Balance = deposit(1, 18);
340}
341
342impl pallet_assets::Config for Runtime {
343    type RuntimeEvent = RuntimeEvent;
344    type Balance = Balance;
345    type AssetId = AssetId;
346    type Currency = Balances;
347    type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
348    type ForceOrigin = EnsureRoot<AccountId>;
349    type AssetDeposit = AssetDeposit;
350    type MetadataDepositBase = MetadataDepositBase;
351    type MetadataDepositPerByte = MetadataDepositPerByte;
352    type AssetAccountDeposit = AssetAccountDeposit;
353    type ApprovalDeposit = ExistentialDeposit;
354    type StringLimit = AssetsStringLimit;
355    type Freezer = ();
356    type Extra = ();
357    type Holder = ();
358    type WeightInfo = weights::pallet_assets::SubstrateWeight<Runtime>;
359    type RemoveItemsLimit = ConstU32<1000>;
360    type AssetIdParameter = Compact<AssetId>;
361    type CallbackHandle = EvmRevertCodeHandler<Self, Self>;
362    #[cfg(feature = "runtime-benchmarks")]
363    type BenchmarkHelper = astar_primitives::benchmarks::AssetsBenchmarkHelper;
364}
365
366// These values are based on the Astar 2.0 Tokenomics Modeling report.
367parameter_types! {
368    pub const TransactionLengthFeeFactor: Balance = 23_500_000_000_000; // 0.000_023_500_000_000_000 AST per byte
369    pub const WeightFeeFactor: Balance = 30_855_000_000_000_000; // Around 0.03 AST per unit of ref time.
370    pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
371    pub const OperationalFeeMultiplier: u8 = 5;
372    pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(000_015, 1_000_000); // 0.000_015
373    pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10); // 0.1
374    pub MaximumMultiplier: Multiplier = Multiplier::saturating_from_integer(10); // 10
375}
376
377/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
378/// node's balance type.
379///
380/// This should typically create a mapping between the following ranges:
381///   - [0, MAXIMUM_BLOCK_WEIGHT]
382///   - [Balance::min, Balance::max]
383///
384/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
385///   - Setting it to `0` will essentially disable the weight fee.
386///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
387pub struct WeightToFee;
388impl WeightToFeePolynomial for WeightToFee {
389    type Balance = Balance;
390    fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
391        let p = WeightFeeFactor::get();
392        let q = Balance::from(ExtrinsicBaseWeight::get().ref_time());
393        smallvec::smallvec![WeightToFeeCoefficient {
394            degree: 1,
395            negative: false,
396            coeff_frac: Perbill::from_rational(p % q, q),
397            coeff_integer: p / q,
398        }]
399    }
400}
401
402impl pallet_transaction_payment::Config for Runtime {
403    type RuntimeEvent = RuntimeEvent;
404    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
405    type WeightToFee = WeightToFee;
406    type OperationalFeeMultiplier = OperationalFeeMultiplier;
407    type FeeMultiplierUpdate = TargetedFeeAdjustment<
408        Self,
409        TargetBlockFullness,
410        AdjustmentVariable,
411        MinimumMultiplier,
412        MaximumMultiplier,
413    >;
414    type LengthToFee = ConstantMultiplier<Balance, TransactionLengthFeeFactor>;
415    type WeightInfo = ();
416}
417
418parameter_types! {
419    pub DefaultBaseFeePerGas: U256 = U256::from(1_470_000_000_000_u128);
420    pub MinBaseFeePerGas: U256 = U256::from(800_000_000_000_u128);
421    pub MaxBaseFeePerGas: U256 = U256::from(80_000_000_000_000_u128);
422    pub StepLimitRatio: Perquintill = Perquintill::from_rational(5_u128, 100_000);
423}
424
425/// Simple wrapper for fetching current native transaction fee weight fee multiplier.
426pub struct AdjustmentFactorGetter;
427impl Get<Multiplier> for AdjustmentFactorGetter {
428    fn get() -> Multiplier {
429        pallet_transaction_payment::NextFeeMultiplier::<Runtime>::get()
430    }
431}
432
433impl pallet_dynamic_evm_base_fee::Config for Runtime {
434    type DefaultBaseFeePerGas = DefaultBaseFeePerGas;
435    type MinBaseFeePerGas = MinBaseFeePerGas;
436    type MaxBaseFeePerGas = MaxBaseFeePerGas;
437    type AdjustmentFactor = AdjustmentFactorGetter;
438    type WeightFactor = WeightFeeFactor;
439    type StepLimitRatio = StepLimitRatio;
440    type WeightInfo = pallet_dynamic_evm_base_fee::weights::SubstrateWeight<Runtime>;
441}
442
443parameter_types! {
444    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
445    pub const DappsStakingPalletId: PalletId = PalletId(*b"py/dpsst");
446}
447
448impl pallet_static_price_provider::Config for Runtime {}
449
450#[cfg(feature = "runtime-benchmarks")]
451pub struct BenchmarkHelper<SC, ACC>(PhantomData<(SC, ACC)>);
452#[cfg(feature = "runtime-benchmarks")]
453impl pallet_dapp_staking::BenchmarkHelper<SmartContract<AccountId>, AccountId>
454    for BenchmarkHelper<SmartContract<AccountId>, AccountId>
455{
456    fn get_smart_contract(id: u32) -> SmartContract<AccountId> {
457        SmartContract::Wasm(AccountId::from([id as u8; 32]))
458    }
459
460    fn set_balance(account: &AccountId, amount: Balance) {
461        use frame_support::traits::fungible::Unbalanced as FunUnbalanced;
462        Balances::write_balance(account, amount)
463            .expect("Must succeed in test/benchmark environment.");
464    }
465}
466
467impl pallet_dapp_staking::Config for Runtime {
468    type RuntimeEvent = RuntimeEvent;
469    type RuntimeFreezeReason = RuntimeFreezeReason;
470    type Currency = Balances;
471    type SmartContract = SmartContract<AccountId>;
472    type ContractRegisterOrigin = EnsureRootOrTwoThirdsCommunityCouncil;
473    type ContractUnregisterOrigin = EnsureRoot<AccountId>;
474    type ManagerOrigin = EnsureRootOrTwoThirdsTechnicalCommittee;
475    type StakingRewardHandler = Inflation;
476    type CycleConfiguration = InflationCycleConfig;
477    type Observers = Inflation;
478    type AccountCheck = ();
479    type EraRewardSpanLength = ConstU32<8>;
480    type RewardRetentionInPeriods = ConstU32<2>;
481    type MaxNumberOfContracts = ConstU32<100>;
482    type MaxNumberOfContractsLegacy = ConstU32<100>;
483    type MaxUnlockingChunks = ConstU32<5>;
484    type MinimumLockedAmount = ConstU128<AST>;
485    type UnlockingPeriod = ConstU32<2>;
486    type MaxNumberOfStakedContracts = ConstU32<3>;
487    type MinimumStakeAmount = ConstU128<AST>;
488    type NumberOfTiers = ConstU32<4>;
489    type RankingEnabled = ConstBool<true>;
490    type MaxBonusSafeMovesPerPeriod = ConstU8<0>;
491    type WeightInfo = pallet_dapp_staking::weights::SubstrateWeight<Runtime>;
492    #[cfg(feature = "runtime-benchmarks")]
493    type BenchmarkHelper = BenchmarkHelper<SmartContract<AccountId>, AccountId>;
494}
495
496pub struct InflationPayoutPerBlock;
497impl pallet_inflation::PayoutPerBlock<Credit<AccountId, Balances>> for InflationPayoutPerBlock {
498    fn treasury(reward: Credit<AccountId, Balances>) {
499        let _ = Balances::resolve(&TreasuryPalletId::get().into_account_truncating(), reward);
500    }
501
502    fn collators(_reward: Credit<AccountId, Balances>) {
503        // no collators for local dev node
504    }
505}
506
507pub struct InflationCycleConfig;
508impl CycleConfiguration for InflationCycleConfig {
509    fn periods_per_cycle() -> PeriodNumber {
510        4
511    }
512
513    fn eras_per_voting_subperiod() -> EraNumber {
514        2
515    }
516
517    fn eras_per_build_and_earn_subperiod() -> EraNumber {
518        22
519    }
520
521    fn blocks_per_era() -> BlockNumber {
522        30
523    }
524}
525
526impl pallet_inflation::Config for Runtime {
527    type Currency = Balances;
528    type PayoutPerBlock = InflationPayoutPerBlock;
529    type CycleConfiguration = InflationCycleConfig;
530    type WeightInfo = pallet_inflation::weights::SubstrateWeight<Runtime>;
531}
532
533impl pallet_utility::Config for Runtime {
534    type RuntimeEvent = RuntimeEvent;
535    type RuntimeCall = RuntimeCall;
536    type PalletsOrigin = OriginCaller;
537    type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
538}
539
540parameter_types! {
541    // 2 storage items with value size 20 and 32
542    pub const AccountMappingStorageFee: u128 = deposit(2, 32 + 20);
543}
544
545impl pallet_unified_accounts::Config for Runtime {
546    type Currency = Balances;
547    type DefaultMappings = HashedDefaultMappings<BlakeTwo256>;
548    type ChainId = ChainId;
549    type AccountMappingStorageFee = AccountMappingStorageFee;
550    type WeightInfo = pallet_unified_accounts::weights::SubstrateWeight<Self>;
551}
552
553parameter_types! {
554    pub ReservedXcmpWeight: Weight = Weight::zero();
555}
556
557impl pallet_ethereum_checked::Config for Runtime {
558    type ReservedXcmpWeight = ReservedXcmpWeight;
559    type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
560    type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
561    type AddressMapper = UnifiedAccounts;
562    type XcmTransactOrigin = pallet_ethereum_checked::EnsureXcmEthereumTx<AccountId>;
563    type WeightInfo = pallet_ethereum_checked::weights::SubstrateWeight<Runtime>;
564}
565
566/// Current approximation of the gas/s consumption considering
567/// EVM execution over compiled WASM (on 4.4Ghz CPU).
568/// Given the 500ms Weight, from which 75% only are used for transactions,
569/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000.
570pub const GAS_PER_SECOND: u64 = 40_000_000;
571
572/// Approximate ratio of the amount of Weight per Gas.
573/// u64 works for approximations because Weight is a very small unit compared to gas.
574pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND.saturating_div(GAS_PER_SECOND);
575
576pub struct FindAuthorTruncated<F>(PhantomData<F>);
577impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
578    fn find_author<'a, I>(digests: I) -> Option<H160>
579    where
580        I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
581    {
582        if let Some(author_index) = F::find_author(digests) {
583            let authority_id =
584                pallet_aura::Authorities::<Runtime>::get()[author_index as usize].clone();
585            return Some(H160::from_slice(&authority_id.encode()[4..24]));
586        }
587
588        None
589    }
590}
591
592parameter_types! {
593    /// Ethereum-compatible chain_id:
594    /// * Dusty:   80
595    /// * Shibuya: 81
596    /// * Shiden: 336
597    /// * Local: 4369
598    pub ChainId: u64 = 0x1111;
599    /// EVM gas limit
600    pub BlockGasLimit: U256 = U256::from(
601        NORMAL_DISPATCH_RATIO * WEIGHT_REF_TIME_PER_SECOND / WEIGHT_PER_GAS
602    );
603    pub PrecompilesValue: Precompiles = LocalPrecompiles::<_>::new();
604    pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
605    /// The amount of gas per PoV size. Value is calculated as:
606    ///
607    /// max_gas_limit = max_tx_ref_time / WEIGHT_PER_GAS = max_pov_size * gas_limit_pov_size_ratio
608    /// gas_limit_pov_size_ratio = ceil((max_tx_ref_time / WEIGHT_PER_GAS) / max_pov_size)
609    ///
610    /// Local runtime has no strict bounds as parachain, but we keep the value set to 4 for consistency.
611    pub const GasLimitPovSizeRatio: u64 = 4;
612}
613
614impl pallet_evm::Config for Runtime {
615    type FeeCalculator = DynamicEvmBaseFee;
616    type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
617    type WeightPerGas = WeightPerGas;
618    type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Runtime>;
619    type CallOrigin = pallet_evm::EnsureAddressRoot<AccountId>;
620    type WithdrawOrigin = pallet_evm::EnsureAddressTruncated;
621    type AddressMapping = UnifiedAccounts;
622    type Currency = Balances;
623    type Runner = pallet_evm::runner::stack::Runner<Self>;
624    type PrecompilesType = Precompiles;
625    type PrecompilesValue = PrecompilesValue;
626    type ChainId = ChainId;
627    type OnChargeTransaction = pallet_evm::EVMFungibleAdapter<Balances, ()>;
628    type BlockGasLimit = BlockGasLimit;
629    type Timestamp = Timestamp;
630    type OnCreate = ();
631    type FindAuthor = FindAuthorTruncated<Aura>;
632    type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
633    type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
634    // gas based storage limit not enabled
635    type GasLimitStorageGrowthRatio = ConstU64<0>;
636    type CreateOriginFilter = ();
637    type CreateInnerOriginFilter = ();
638    type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
639}
640
641parameter_types! {
642    pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
643}
644
645impl pallet_ethereum::Config for Runtime {
646    type StateRoot =
647        pallet_ethereum::IntermediateStateRoot<<Self as frame_system::Config>::Version>;
648    type PostLogContent = PostBlockAndTxnHashes;
649    // Maximum length (in bytes) of revert message to include in Executed event
650    type ExtraDataLength = ConstU32<30>;
651}
652
653parameter_types! {
654    pub MaximumSchedulerWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
655}
656
657impl pallet_scheduler::Config for Runtime {
658    type RuntimeEvent = RuntimeEvent;
659    type RuntimeOrigin = RuntimeOrigin;
660    type PalletsOrigin = OriginCaller;
661    type RuntimeCall = RuntimeCall;
662    type MaximumWeight = MaximumSchedulerWeight;
663    type ScheduleOrigin = EnsureRoot<AccountId>;
664    type MaxScheduledPerBlock = ConstU32<50>;
665    // TODO: re-bench pallet_scheduler weights or use default weights.
666    type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
667    type OriginPrivilegeCmp = EqualPrivilegeOnly;
668    type Preimages = Preimage;
669    type BlockNumberProvider = System;
670}
671
672parameter_types! {
673    pub const PreimageBaseDeposit: Balance = deposit(1, 0);
674    pub const PreimageByteDeposit: Balance = deposit(0, 1);
675    pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
676}
677
678impl pallet_preimage::Config for Runtime {
679    type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
680    type RuntimeEvent = RuntimeEvent;
681    type Currency = Balances;
682    type ManagerOrigin = EnsureRoot<AccountId>;
683    type Consideration = HoldConsideration<
684        AccountId,
685        Balances,
686        PreimageHoldReason,
687        LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
688    >;
689}
690
691parameter_types! {
692    pub const MinVestedTransfer: Balance = 1 * AST;
693    pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
694        WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
695}
696
697impl pallet_vesting::Config for Runtime {
698    type RuntimeEvent = RuntimeEvent;
699    type Currency = Balances;
700    type BlockNumberToBalance = ConvertInto;
701    type MinVestedTransfer = MinVestedTransfer;
702    type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
703    type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
704    type BlockNumberProvider = System;
705    // `VestingInfo` encode length is 36bytes. 28 schedules gets encoded as 1009 bytes, which is the
706    // highest number of schedules that encodes less than 2^10.
707    const MAX_VESTING_SCHEDULES: u32 = 28;
708}
709
710parameter_types! {
711    pub const DepositPerItem: Balance = deposit(1, 0);
712    pub const DepositPerByte: Balance = deposit(0, 1);
713    // Fallback value if storage deposit limit not set by the user
714    pub const DefaultDepositLimit: Balance = deposit(16, 16 * 1024);
715    pub const MaxDelegateDependencies: u32 = 32;
716    pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(10);
717    pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
718}
719
720impl pallet_contracts::Config for Runtime {
721    type Time = Timestamp;
722    type Randomness = RandomnessCollectiveFlip;
723    type Currency = Balances;
724    type RuntimeEvent = RuntimeEvent;
725    type RuntimeCall = RuntimeCall;
726    /// The safest default is to allow no calls at all.
727    ///
728    /// Runtimes should whitelist dispatchables that are allowed to be called from contracts
729    /// and make sure they are stable. Dispatchables exposed to contracts are not allowed to
730    /// change because that would break already deployed contracts. The `Call` structure itself
731    /// is not allowed to change the indices of existing pallets, too.
732    type CallFilter = Nothing;
733    type DepositPerItem = DepositPerItem;
734    type DepositPerByte = DepositPerByte;
735    type DefaultDepositLimit = DefaultDepositLimit;
736    type CallStack = [pallet_contracts::Frame<Self>; 5];
737    type WeightPrice = pallet_transaction_payment::Pallet<Self>;
738    type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
739    type ChainExtension = LocalChainExtensions<Self, UnifiedAccounts>;
740    type Schedule = Schedule;
741    type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
742    type MaxCodeLen = ConstU32<{ 123 * 1024 }>;
743    type MaxStorageKeyLen = ConstU32<128>;
744    type UnsafeUnstableInterface = ConstBool<true>;
745    type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
746    type MaxDelegateDependencies = MaxDelegateDependencies;
747    type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
748    type RuntimeHoldReason = RuntimeHoldReason;
749    type Debug = ();
750    type Environment = ();
751    type Migrations = ();
752    type Xcm = ();
753    type UploadOrigin = EnsureSigned<<Self as frame_system::Config>::AccountId>;
754    type InstantiateOrigin = EnsureSigned<<Self as frame_system::Config>::AccountId>;
755    type ApiVersion = ();
756    type MaxTransientStorageSize = ConstU32<{ 1 * 1024 * 1024 }>;
757}
758
759impl pallet_sudo::Config for Runtime {
760    type RuntimeEvent = RuntimeEvent;
761    type RuntimeCall = RuntimeCall;
762    type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
763}
764
765/// The type used to represent the kinds of proxying allowed.
766#[derive(
767    Copy,
768    Clone,
769    Eq,
770    PartialEq,
771    Ord,
772    PartialOrd,
773    Encode,
774    Decode,
775    DecodeWithMemTracking,
776    RuntimeDebug,
777    MaxEncodedLen,
778    scale_info::TypeInfo,
779)]
780pub enum ProxyType {
781    /// Allows all runtime calls for proxy account
782    Any,
783    /// Allows only NonTransfer runtime calls for proxy account
784    /// To know exact calls check InstanceFilter implementation for ProxyTypes
785    NonTransfer,
786    /// All Runtime calls from Pallet Balances allowed for proxy account
787    Balances,
788    /// All Runtime calls from Pallet Assets allowed for proxy account
789    Assets,
790    /// Only reject_announcement call from pallet proxy allowed for proxy account
791    CancelProxy,
792    /// All runtime calls from pallet DappStaking allowed for proxy account
793    DappStaking,
794    /// Only claim_staker call from pallet DappStaking allowed for proxy account
795    StakerRewardClaim,
796    /// All governance related calls allowed for proxy account
797    Governance,
798}
799
800impl Default for ProxyType {
801    fn default() -> Self {
802        Self::Any
803    }
804}
805
806impl InstanceFilter<RuntimeCall> for ProxyType {
807    fn filter(&self, c: &RuntimeCall) -> bool {
808        match self {
809            // Always allowed RuntimeCall::Utility no matter type.
810            // Only transactions allowed by Proxy.filter can be executed
811            _ if matches!(c, RuntimeCall::Utility(..)) => true,
812            // Allows all runtime calls for proxy account
813            ProxyType::Any => true,
814            // Allows only NonTransfer runtime calls for proxy account
815            ProxyType::NonTransfer => {
816                matches!(
817                    c,
818                    RuntimeCall::System(..)
819                        | RuntimeCall::Proxy(..)
820                        | RuntimeCall::Vesting(
821                            pallet_vesting::Call::vest { .. }
822                                | pallet_vesting::Call::vest_other { .. }
823                        )
824                        | RuntimeCall::DappStaking(..)
825                )
826            }
827            // All Runtime calls from Pallet Balances allowed for proxy account
828            ProxyType::Balances => {
829                matches!(c, RuntimeCall::Balances(..))
830            }
831            // All Runtime calls from Pallet Assets allowed for proxy account
832            ProxyType::Assets => {
833                matches!(c, RuntimeCall::Assets(..))
834            }
835            // Only reject_announcement call from pallet proxy allowed for proxy account
836            ProxyType::CancelProxy => {
837                matches!(
838                    c,
839                    RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
840                )
841            }
842            // All runtime calls from pallet DappStaking allowed for proxy account
843            ProxyType::DappStaking => {
844                matches!(c, RuntimeCall::DappStaking(..))
845            }
846            ProxyType::StakerRewardClaim => {
847                matches!(
848                    c,
849                    RuntimeCall::DappStaking(
850                        pallet_dapp_staking::Call::claim_staker_rewards { .. }
851                    )
852                )
853            }
854            ProxyType::Governance => {
855                matches!(
856                    c,
857                    RuntimeCall::Democracy(..)
858                        | RuntimeCall::Council(..)
859                        | RuntimeCall::TechnicalCommittee(..)
860                        | RuntimeCall::CommunityCouncil(..)
861                )
862            }
863        }
864    }
865
866    fn is_superset(&self, o: &Self) -> bool {
867        match (self, o) {
868            (x, y) if x == y => true,
869            (ProxyType::Any, _) => true,
870            (_, ProxyType::Any) => false,
871            (ProxyType::NonTransfer, _) => true,
872            (ProxyType::DappStaking, ProxyType::StakerRewardClaim) => true,
873            _ => false,
874        }
875    }
876}
877
878impl pallet_proxy::Config for Runtime {
879    type RuntimeEvent = RuntimeEvent;
880    type RuntimeCall = RuntimeCall;
881    type Currency = Balances;
882    type ProxyType = ProxyType;
883    // One storage item; key size 32, value size 8; .
884    type ProxyDepositBase = ConstU128<{ AST * 10 }>;
885    // Additional storage item size of 33 bytes.
886    type ProxyDepositFactor = ConstU128<{ MILLIAST * 330 }>;
887    type MaxProxies = ConstU32<32>;
888    type WeightInfo = pallet_proxy::weights::SubstrateWeight<Runtime>;
889    type MaxPending = ConstU32<32>;
890    type CallHasher = BlakeTwo256;
891    // Key size 32 + 1 item
892    type AnnouncementDepositBase = ConstU128<{ AST * 10 }>;
893    // Acc Id + Hash + block number
894    type AnnouncementDepositFactor = ConstU128<{ MILLIAST * 660 }>;
895    type BlockNumberProvider = System;
896}
897
898parameter_types! {
899    pub const CouncilMaxMembers: u32 = 5;
900    pub const TechnicalCommitteeMaxMembers: u32 = 3;
901    pub const CommunityCouncilMaxMembers: u32 = 10;
902}
903
904impl pallet_membership::Config<MainCouncilMembershipInst> for Runtime {
905    type RuntimeEvent = RuntimeEvent;
906    type AddOrigin = EnsureRootOrTwoThirdsMainCouncil;
907    type RemoveOrigin = EnsureRootOrTwoThirdsMainCouncil;
908    type SwapOrigin = EnsureRootOrTwoThirdsMainCouncil;
909    type ResetOrigin = EnsureRootOrTwoThirdsMainCouncil;
910    type PrimeOrigin = EnsureRootOrTwoThirdsMainCouncil;
911    type MembershipInitialized = Council;
912    type MembershipChanged = Council;
913    type MaxMembers = CouncilMaxMembers;
914    type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
915}
916
917impl pallet_membership::Config<TechnicalCommitteeMembershipInst> for Runtime {
918    type RuntimeEvent = RuntimeEvent;
919    type AddOrigin = EnsureRootOrTwoThirdsMainCouncil;
920    type RemoveOrigin = EnsureRootOrTwoThirdsMainCouncil;
921    type SwapOrigin = EnsureRootOrTwoThirdsMainCouncil;
922    type ResetOrigin = EnsureRootOrTwoThirdsMainCouncil;
923    type PrimeOrigin = EnsureRootOrTwoThirdsMainCouncil;
924    type MembershipInitialized = TechnicalCommittee;
925    type MembershipChanged = TechnicalCommittee;
926    type MaxMembers = TechnicalCommitteeMaxMembers;
927    type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
928}
929
930impl pallet_membership::Config<CommunityCouncilMembershipInst> for Runtime {
931    type RuntimeEvent = RuntimeEvent;
932    type AddOrigin = EnsureRootOrTwoThirdsMainCouncil;
933    type RemoveOrigin = EnsureRootOrTwoThirdsMainCouncil;
934    type SwapOrigin = EnsureRootOrTwoThirdsMainCouncil;
935    type ResetOrigin = EnsureRootOrTwoThirdsMainCouncil;
936    type PrimeOrigin = EnsureRootOrTwoThirdsMainCouncil;
937    type MembershipInitialized = CommunityCouncil;
938    type MembershipChanged = CommunityCouncil;
939    type MaxMembers = CommunityCouncilMaxMembers;
940    type WeightInfo = pallet_membership::weights::SubstrateWeight<Runtime>;
941}
942
943parameter_types! {
944    pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block;
945}
946
947impl pallet_collective::Config<MainCouncilCollectiveInst> for Runtime {
948    type RuntimeOrigin = RuntimeOrigin;
949    type Proposal = RuntimeCall;
950    type RuntimeEvent = RuntimeEvent;
951    type MotionDuration = ConstU32<{ 5 * MINUTES }>;
952    type MaxProposals = ConstU32<16>;
953    type MaxMembers = CouncilMaxMembers;
954    type DefaultVote = pallet_collective::PrimeDefaultVote;
955    type SetMembersOrigin = EnsureRoot<AccountId>;
956    type MaxProposalWeight = MaxProposalWeight;
957    type KillOrigin = EnsureRoot<AccountId>;
958    type DisapproveOrigin = EnsureRoot<AccountId>;
959    type Consideration = ();
960    type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
961}
962
963impl pallet_collective::Config<TechnicalCommitteeCollectiveInst> for Runtime {
964    type RuntimeOrigin = RuntimeOrigin;
965    type Proposal = RuntimeCall;
966    type RuntimeEvent = RuntimeEvent;
967    type MotionDuration = ConstU32<{ 5 * MINUTES }>;
968    type MaxProposals = ConstU32<16>;
969    type MaxMembers = TechnicalCommitteeMaxMembers;
970    type DefaultVote = pallet_collective::PrimeDefaultVote;
971    type SetMembersOrigin = EnsureRoot<AccountId>;
972    type MaxProposalWeight = MaxProposalWeight;
973    type KillOrigin = EnsureRoot<AccountId>;
974    type DisapproveOrigin = EnsureRoot<AccountId>;
975    type Consideration = ();
976    type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
977}
978
979impl pallet_collective::Config<CommunityCouncilCollectiveInst> for Runtime {
980    type RuntimeOrigin = RuntimeOrigin;
981    type Proposal = RuntimeCall;
982    type RuntimeEvent = RuntimeEvent;
983    type MotionDuration = ConstU32<{ 5 * MINUTES }>;
984    type MaxProposals = ConstU32<16>;
985    type MaxMembers = CommunityCouncilMaxMembers;
986    type DefaultVote = pallet_collective::PrimeDefaultVote;
987    type SetMembersOrigin = EnsureRoot<AccountId>;
988    type MaxProposalWeight = MaxProposalWeight;
989    type KillOrigin = EnsureRoot<AccountId>;
990    type DisapproveOrigin = EnsureRoot<AccountId>;
991    type Consideration = ();
992    type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
993}
994
995impl pallet_democracy::Config for Runtime {
996    type RuntimeEvent = RuntimeEvent;
997    type Currency = Balances;
998    type EnactmentPeriod = ConstU32<{ 5 * MINUTES }>;
999    type LaunchPeriod = ConstU32<{ 5 * MINUTES }>;
1000    type VotingPeriod = ConstU32<{ 5 * MINUTES }>;
1001    type VoteLockingPeriod = ConstU32<{ 2 * MINUTES }>;
1002    type MinimumDeposit = ConstU128<{ 10 * AST }>;
1003    type FastTrackVotingPeriod = ConstU32<{ MINUTES / 2 }>;
1004    type CooloffPeriod = ConstU32<{ 2 * MINUTES }>;
1005
1006    type MaxVotes = ConstU32<128>;
1007    type MaxProposals = ConstU32<128>;
1008    type MaxDeposits = ConstU32<128>;
1009    type MaxBlacklisted = ConstU32<128>;
1010
1011    /// A two third majority of the Council can choose the next external "super majority approve" proposal.
1012    type ExternalOrigin = EnsureRootOrTwoThirdsMainCouncil;
1013    /// A two third majority of the Council can choose the next external "majority approve" proposal. Also bypasses blacklist filter.
1014    type ExternalMajorityOrigin = EnsureRootOrTwoThirdsMainCouncil;
1015    /// Unanimous approval of the Council can choose the next external "super majority against" proposal.
1016    type ExternalDefaultOrigin = EnsureRootOrAllMainCouncil;
1017    /// A two third majority of the Technical Committee can have an external proposal tabled immediately
1018    /// for a _fast track_ vote, and a custom enactment period.
1019    type FastTrackOrigin = EnsureRootOrTwoThirdsTechnicalCommittee;
1020    /// Unanimous approval of the Technical Committee can have an external proposal tabled immediately
1021    /// for a completely custom _voting period length_ vote, and a custom enactment period.
1022    type InstantOrigin = EnsureRootOrAllTechnicalCommittee;
1023    type InstantAllowed = ConstBool<true>;
1024
1025    /// A two third majority of the Council can cancel a passed proposal. Can happen only once per unique proposal.
1026    type CancellationOrigin = EnsureRootOrTwoThirdsMainCouncil;
1027    /// Only a passed public referendum can permanently blacklist a proposal.
1028    type BlacklistOrigin = EnsureRoot<AccountId>;
1029    /// An unanimous Technical Committee can cancel a public proposal, slashing the deposit(s).
1030    type CancelProposalOrigin = EnsureRootOrAllTechnicalCommittee;
1031    /// 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.
1032    type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCommitteeCollectiveInst>;
1033
1034    type SubmitOrigin = EnsureSigned<AccountId>;
1035    type PalletsOrigin = OriginCaller;
1036    type Preimages = Preimage;
1037    type Scheduler = Scheduler;
1038    type Slash = ();
1039    type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
1040}
1041
1042parameter_types! {
1043    pub const ProposalBond: Permill = Permill::from_percent(5);
1044    pub MainTreasuryAccount: AccountId = Treasury::account_id();
1045}
1046
1047impl pallet_treasury::Config<MainTreasuryInst> for Runtime {
1048    type PalletId = TreasuryPalletId;
1049    type Currency = Balances;
1050    type RuntimeEvent = RuntimeEvent;
1051
1052    // Two origins which can either approve or reject the spending proposal
1053    type ApproveOrigin = EnsureRootOrTwoThirdsMainCouncil;
1054    type RejectOrigin = EnsureRootOrTwoThirdsMainCouncil;
1055
1056    type OnSlash = Treasury;
1057    type ProposalBond = ProposalBond;
1058    type ProposalBondMinimum = ConstU128<{ 10 * AST }>;
1059    type ProposalBondMaximum = ConstU128<{ 100 * AST }>;
1060    type SpendPeriod = ConstU32<{ 1 * MINUTES }>;
1061
1062    // We don't do periodic burns of the treasury
1063    type Burn = ();
1064    type BurnDestination = ();
1065    type SpendFunds = ();
1066    type MaxApprovals = ConstU32<64>;
1067
1068    type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
1069}
1070
1071parameter_types! {
1072    pub const CommunityTreasuryPalletId: PalletId = PalletId(*b"py/comtr");
1073}
1074
1075impl pallet_treasury::Config<CommunityTreasuryInst> for Runtime {
1076    type PalletId = CommunityTreasuryPalletId;
1077    type Currency = Balances;
1078    type RuntimeEvent = RuntimeEvent;
1079
1080    // Two origins which can either approve or reject the spending proposal
1081    type ApproveOrigin = EnsureRootOrTwoThirdsCommunityCouncil;
1082    type RejectOrigin = EnsureRootOrTwoThirdsCommunityCouncil;
1083
1084    type OnSlash = CommunityTreasury;
1085    type ProposalBond = ProposalBond;
1086    type ProposalBondMinimum = ConstU128<{ 10 * AST }>;
1087    type ProposalBondMaximum = ConstU128<{ 100 * AST }>;
1088    type SpendPeriod = ConstU32<{ 1 * MINUTES }>;
1089
1090    // We don't do periodic burns of the community treasury
1091    type Burn = ();
1092    type BurnDestination = ();
1093    type SpendFunds = ();
1094    type MaxApprovals = ConstU32<64>;
1095
1096    type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
1097}
1098
1099parameter_types! {
1100    pub CommunityTreasuryAccountId: AccountId = CommunityTreasuryPalletId::get().into_account_truncating();
1101}
1102
1103#[derive(Default)]
1104pub struct CommunityCouncilCallFilter;
1105impl InstanceFilter<RuntimeCall> for CommunityCouncilCallFilter {
1106    fn filter(&self, c: &RuntimeCall) -> bool {
1107        matches!(
1108            c,
1109            RuntimeCall::DappStaking(..)
1110                | RuntimeCall::System(frame_system::Call::remark { .. })
1111                | RuntimeCall::Utility(pallet_utility::Call::batch { .. })
1112                | RuntimeCall::Utility(pallet_utility::Call::batch_all { .. })
1113        )
1114    }
1115}
1116
1117impl pallet_collective_proxy::Config for Runtime {
1118    type RuntimeCall = RuntimeCall;
1119    type CollectiveProxy = EnsureRootOrTwoThirdsCommunityCouncil;
1120    type ProxyAccountId = CommunityTreasuryAccountId;
1121    type CallFilter = CommunityCouncilCallFilter;
1122    type WeightInfo = pallet_collective_proxy::weights::SubstrateWeight<Runtime>;
1123}
1124
1125/// Calls that can bypass the safe-mode pallet.
1126pub struct SafeModeWhitelistedCalls;
1127impl Contains<RuntimeCall> for SafeModeWhitelistedCalls {
1128    fn contains(call: &RuntimeCall) -> bool {
1129        match call {
1130            // System and Timestamp are required for block production
1131            RuntimeCall::System(_)
1132            | RuntimeCall::Timestamp(_)
1133            | RuntimeCall::Sudo(_)
1134            | RuntimeCall::TxPause(_) => true,
1135            _ => false,
1136        }
1137    }
1138}
1139
1140impl pallet_safe_mode::Config for Runtime {
1141    type RuntimeEvent = RuntimeEvent;
1142    type Currency = Balances;
1143    type RuntimeHoldReason = RuntimeHoldReason;
1144    type WhitelistedCalls = SafeModeWhitelistedCalls;
1145    type EnterDuration = ConstU32<{ 5 * MINUTES }>;
1146    type EnterDepositAmount = ();
1147    type ExtendDuration = ConstU32<{ 2 * MINUTES }>;
1148    type ExtendDepositAmount = ();
1149    // The 'Success' values below represent the number of blocks that the origin may induce safe mode
1150    type ForceEnterOrigin =
1151        EnsureWithSuccess<EnsureRootOrHalfTechnicalCommittee, AccountId, ConstU32<{ 5 * MINUTES }>>;
1152    type ForceExtendOrigin =
1153        EnsureWithSuccess<EnsureRootOrHalfTechnicalCommittee, AccountId, ConstU32<{ 2 * MINUTES }>>;
1154    type ForceExitOrigin = EnsureRootOrTwoThirdsTechnicalCommittee;
1155    type ForceDepositOrigin = EnsureRootOrTwoThirdsTechnicalCommittee;
1156    type ReleaseDelay = ();
1157    type Notify = DappStaking;
1158    type WeightInfo = pallet_safe_mode::weights::SubstrateWeight<Runtime>;
1159}
1160
1161impl pallet_tx_pause::Config for Runtime {
1162    type RuntimeEvent = RuntimeEvent;
1163    type RuntimeCall = RuntimeCall;
1164    type PauseOrigin = EnsureRootOrHalfTechnicalCommittee;
1165    type UnpauseOrigin = EnsureRootOrHalfTechnicalCommittee;
1166    type WhitelistedCalls = ();
1167    type MaxNameLen = ConstU32<256>;
1168    type WeightInfo = pallet_tx_pause::weights::SubstrateWeight<Runtime>;
1169}
1170
1171construct_runtime!(
1172    pub struct Runtime {
1173        System: frame_system = 10,
1174        Utility: pallet_utility = 11,
1175        Timestamp: pallet_timestamp = 13,
1176        RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 16,
1177        Scheduler: pallet_scheduler = 17,
1178        Proxy: pallet_proxy = 18,
1179
1180        TransactionPayment: pallet_transaction_payment = 30,
1181        Balances: pallet_balances = 31,
1182        Vesting: pallet_vesting = 32,
1183        DappStaking: pallet_dapp_staking = 34,
1184        Inflation: pallet_inflation = 35,
1185        Assets: pallet_assets = 36,
1186        StaticPriceProvider: pallet_static_price_provider = 37,
1187
1188        Aura: pallet_aura = 43,
1189        Grandpa: pallet_grandpa = 44,
1190
1191        EVM: pallet_evm = 60,
1192        Ethereum: pallet_ethereum = 61,
1193        DynamicEvmBaseFee: pallet_dynamic_evm_base_fee = 62,
1194        EthereumChecked: pallet_ethereum_checked = 64,
1195        UnifiedAccounts: pallet_unified_accounts = 65,
1196
1197        Contracts: pallet_contracts = 70,
1198
1199        Preimage: pallet_preimage = 84,
1200
1201        // skip 90 - for runtimes consistency (pallet_xvm previously)
1202
1203        // Governance
1204        Sudo: pallet_sudo = 99,
1205        CouncilMembership: pallet_membership::<Instance2> = 100,
1206        TechnicalCommitteeMembership: pallet_membership::<Instance3> = 101,
1207        CommunityCouncilMembership: pallet_membership::<Instance4> = 102,
1208        Council: pallet_collective::<Instance2> = 103,
1209        TechnicalCommittee: pallet_collective::<Instance3> = 104,
1210        CommunityCouncil: pallet_collective::<Instance4> = 105,
1211        Democracy: pallet_democracy = 106,
1212        Treasury: pallet_treasury::<Instance1> = 107,
1213        CommunityTreasury: pallet_treasury::<Instance2> = 108,
1214        CollectiveProxy: pallet_collective_proxy = 109,
1215        SafeMode: pallet_safe_mode = 110,
1216        TxPause: pallet_tx_pause = 111,
1217    }
1218);
1219
1220/// Block type as expected by this runtime.
1221pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1222/// A Block signed with a Justification
1223pub type SignedBlock = generic::SignedBlock<Block>;
1224/// BlockId type as expected by this runtime.
1225pub type BlockId = generic::BlockId<Block>;
1226/// The SignedExtension to the basic transaction logic.
1227pub type SignedExtra = (
1228    frame_system::CheckSpecVersion<Runtime>,
1229    frame_system::CheckTxVersion<Runtime>,
1230    frame_system::CheckGenesis<Runtime>,
1231    frame_system::CheckEra<Runtime>,
1232    frame_system::CheckNonce<Runtime>,
1233    frame_system::CheckWeight<Runtime>,
1234    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1235    frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1236);
1237/// Unchecked extrinsic type as expected by this runtime.
1238pub type UncheckedExtrinsic =
1239    fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
1240/// Extrinsic type that has already been checked.
1241pub type CheckedExtrinsic =
1242    fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra, H160>;
1243/// The payload being signed in transactions.
1244pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
1245/// Executive: handles dispatch to the various modules.
1246pub type Executive = frame_executive::Executive<
1247    Runtime,
1248    Block,
1249    frame_system::ChainContext<Runtime>,
1250    Runtime,
1251    AllPalletsWithSystem,
1252    Migrations,
1253>;
1254
1255pub type Migrations = ();
1256
1257type EventRecord = frame_system::EventRecord<
1258    <Runtime as frame_system::Config>::RuntimeEvent,
1259    <Runtime as frame_system::Config>::Hash,
1260>;
1261
1262impl fp_self_contained::SelfContainedCall for RuntimeCall {
1263    type SignedInfo = H160;
1264
1265    fn is_self_contained(&self) -> bool {
1266        match self {
1267            RuntimeCall::Ethereum(call) => call.is_self_contained(),
1268            _ => false,
1269        }
1270    }
1271
1272    fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
1273        match self {
1274            RuntimeCall::Ethereum(call) => call.check_self_contained(),
1275            _ => None,
1276        }
1277    }
1278
1279    fn validate_self_contained(
1280        &self,
1281        info: &Self::SignedInfo,
1282        dispatch_info: &DispatchInfoOf<RuntimeCall>,
1283        len: usize,
1284    ) -> Option<TransactionValidity> {
1285        match self {
1286            RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
1287            _ => None,
1288        }
1289    }
1290
1291    fn pre_dispatch_self_contained(
1292        &self,
1293        info: &Self::SignedInfo,
1294        dispatch_info: &DispatchInfoOf<RuntimeCall>,
1295        len: usize,
1296    ) -> Option<Result<(), TransactionValidityError>> {
1297        match self {
1298            RuntimeCall::Ethereum(call) => {
1299                call.pre_dispatch_self_contained(info, dispatch_info, len)
1300            }
1301            _ => None,
1302        }
1303    }
1304
1305    fn apply_self_contained(
1306        self,
1307        info: Self::SignedInfo,
1308    ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
1309        match self {
1310            call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => {
1311                Some(call.dispatch(RuntimeOrigin::from(
1312                    pallet_ethereum::RawOrigin::EthereumTransaction(info),
1313                )))
1314            }
1315            _ => None,
1316        }
1317    }
1318}
1319
1320#[cfg(feature = "runtime-benchmarks")]
1321#[macro_use]
1322extern crate frame_benchmarking;
1323
1324#[cfg(feature = "runtime-benchmarks")]
1325mod benches {
1326    define_benchmarks!(
1327        [frame_benchmarking, BaselineBench::<Runtime>]
1328        [pallet_assets, pallet_assets::Pallet::<Runtime>]
1329        [frame_system, SystemBench::<Runtime>]
1330        [frame_system_extensions, SystemExtensionsBench::<Runtime>]
1331        [pallet_balances, Balances]
1332        [pallet_timestamp, Timestamp]
1333        [pallet_transaction_payment, TransactionPayment]
1334        [pallet_ethereum_checked, EthereumChecked]
1335        [pallet_dapp_staking, DappStaking]
1336        [pallet_inflation, Inflation]
1337        [pallet_dynamic_evm_base_fee, DynamicEvmBaseFee]
1338        [pallet_tx_pause, TxPause]
1339        [pallet_safe_mode, SafeMode]
1340    );
1341}
1342
1343impl_runtime_apis! {
1344    impl sp_api::Core<Block> for Runtime {
1345        fn version() -> RuntimeVersion {
1346            VERSION
1347        }
1348
1349        fn execute_block(block: Block) {
1350            Executive::execute_block(block);
1351        }
1352
1353        fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
1354            Executive::initialize_block(header)
1355        }
1356    }
1357
1358    impl sp_api::Metadata<Block> for Runtime {
1359        fn metadata() -> OpaqueMetadata {
1360            OpaqueMetadata::new(Runtime::metadata().into())
1361        }
1362
1363        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1364            Runtime::metadata_at_version(version)
1365        }
1366
1367        fn metadata_versions() -> Vec<u32> {
1368            Runtime::metadata_versions()
1369        }
1370    }
1371
1372    impl sp_block_builder::BlockBuilder<Block> for Runtime {
1373        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
1374            Executive::apply_extrinsic(extrinsic)
1375        }
1376
1377        fn finalize_block() -> <Block as BlockT>::Header {
1378            Executive::finalize_block()
1379        }
1380
1381        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
1382            data.create_extrinsics()
1383        }
1384
1385        fn check_inherents(
1386            block: Block,
1387            data: sp_inherents::InherentData,
1388        ) -> sp_inherents::CheckInherentsResult {
1389            data.check_extrinsics(&block)
1390        }
1391    }
1392
1393    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1394        fn validate_transaction(
1395            source: TransactionSource,
1396            tx: <Block as BlockT>::Extrinsic,
1397            block_hash: <Block as BlockT>::Hash,
1398        ) -> TransactionValidity {
1399            Executive::validate_transaction(source, tx, block_hash)
1400        }
1401    }
1402
1403    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
1404        fn offchain_worker(header: &<Block as BlockT>::Header) {
1405            Executive::offchain_worker(header)
1406        }
1407    }
1408
1409    impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
1410        fn slot_duration() -> sp_consensus_aura::SlotDuration {
1411            sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
1412        }
1413
1414        fn authorities() -> Vec<AuraId> {
1415            pallet_aura::Authorities::<Runtime>::get().into_inner()
1416        }
1417    }
1418
1419    impl sp_session::SessionKeys<Block> for Runtime {
1420        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
1421            SessionKeys::generate(seed)
1422        }
1423
1424        fn decode_session_keys(
1425            encoded: Vec<u8>,
1426        ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
1427            SessionKeys::decode_into_raw_public_keys(&encoded)
1428        }
1429    }
1430
1431    impl fg_primitives::GrandpaApi<Block> for Runtime {
1432        fn grandpa_authorities() -> GrandpaAuthorityList {
1433            Grandpa::grandpa_authorities()
1434        }
1435
1436        fn current_set_id() -> fg_primitives::SetId {
1437            Grandpa::current_set_id()
1438        }
1439
1440        fn submit_report_equivocation_unsigned_extrinsic(
1441            _equivocation_proof: fg_primitives::EquivocationProof<
1442                <Block as BlockT>::Hash,
1443                NumberFor<Block>,
1444            >,
1445            _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
1446        ) -> Option<()> {
1447            None
1448        }
1449
1450        fn generate_key_ownership_proof(
1451            _set_id: fg_primitives::SetId,
1452            _authority_id: GrandpaId,
1453        ) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
1454            // NOTE: this is the only implementation possible since we've
1455            // defined our key owner proof type as a bottom type (i.e. a type
1456            // with no values).
1457            None
1458        }
1459    }
1460
1461    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
1462        fn account_nonce(account: AccountId) -> Nonce {
1463            System::account_nonce(account)
1464        }
1465    }
1466
1467    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
1468        fn query_info(
1469            uxt: <Block as BlockT>::Extrinsic,
1470            len: u32,
1471        ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
1472            TransactionPayment::query_info(uxt, len)
1473        }
1474        fn query_fee_details(
1475            uxt: <Block as BlockT>::Extrinsic,
1476            len: u32,
1477        ) -> pallet_transaction_payment::FeeDetails<Balance> {
1478            TransactionPayment::query_fee_details(uxt, len)
1479        }
1480        fn query_weight_to_fee(weight: Weight) -> Balance {
1481            TransactionPayment::weight_to_fee(weight)
1482        }
1483        fn query_length_to_fee(length: u32) -> Balance {
1484            TransactionPayment::length_to_fee(length)
1485        }
1486    }
1487
1488    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
1489        for Runtime
1490    {
1491        fn query_call_info(
1492            call: RuntimeCall,
1493            len: u32,
1494        ) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
1495            TransactionPayment::query_call_info(call, len)
1496        }
1497        fn query_call_fee_details(
1498            call: RuntimeCall,
1499            len: u32,
1500        ) -> pallet_transaction_payment::FeeDetails<Balance> {
1501            TransactionPayment::query_call_fee_details(call, len)
1502        }
1503        fn query_weight_to_fee(weight: Weight) -> Balance {
1504            TransactionPayment::weight_to_fee(weight)
1505        }
1506
1507        fn query_length_to_fee(length: u32) -> Balance {
1508            TransactionPayment::length_to_fee(length)
1509        }
1510    }
1511
1512    impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
1513        fn chain_id() -> u64 {
1514            ChainId::get()
1515        }
1516
1517        fn account_basic(address: H160) -> pallet_evm::Account {
1518            let (account, _) = EVM::account_basic(&address);
1519            account
1520        }
1521
1522        fn gas_price() -> U256 {
1523            let (gas_price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
1524            gas_price
1525        }
1526
1527        fn account_code_at(address: H160) -> Vec<u8> {
1528            pallet_evm::AccountCodes::<Runtime>::get(address)
1529        }
1530
1531        fn author() -> H160 {
1532            <pallet_evm::Pallet<Runtime>>::find_author()
1533        }
1534
1535        fn storage_at(address: H160, index: U256) -> H256 {
1536            let tmp: [u8; 32] = index.to_big_endian();
1537            pallet_evm::AccountStorages::<Runtime>::get(address, H256::from_slice(&tmp[..]))
1538        }
1539
1540        fn call(
1541            from: H160,
1542            to: H160,
1543            data: Vec<u8>,
1544            value: U256,
1545            gas_limit: U256,
1546            max_fee_per_gas: Option<U256>,
1547            max_priority_fee_per_gas: Option<U256>,
1548            nonce: Option<U256>,
1549            estimate: bool,
1550            access_list: Option<Vec<(H160, Vec<H256>)>>,
1551            authorization_list: Option<AuthorizationList>,
1552        ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
1553            let config = if estimate {
1554                let mut config = <Runtime as pallet_evm::Config>::config().clone();
1555                config.estimate = true;
1556                Some(config)
1557            } else {
1558                None
1559            };
1560
1561            let is_transactional = false;
1562            let validate = true;
1563
1564            // Reused approach from Moonbeam since Frontier implementation doesn't support this
1565            let mut estimated_transaction_len = data.len() +
1566                // to: 20
1567                // from: 20
1568                // value: 32
1569                // gas_limit: 32
1570                // nonce: 32
1571                // 1 byte transaction action variant
1572                // chain id 8 bytes
1573                // 65 bytes signature
1574                210;
1575            if max_fee_per_gas.is_some() {
1576                estimated_transaction_len += 32;
1577            }
1578            if max_priority_fee_per_gas.is_some() {
1579                estimated_transaction_len += 32;
1580            }
1581            if access_list.is_some() {
1582                estimated_transaction_len += access_list.encoded_size();
1583            }
1584
1585            let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
1586            let without_base_extrinsic_weight = true;
1587
1588            let (weight_limit, proof_size_base_cost) =
1589                match <Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(
1590                    gas_limit,
1591                    without_base_extrinsic_weight
1592                ) {
1593                    weight_limit if weight_limit.proof_size() > 0 => {
1594                        (Some(weight_limit), Some(estimated_transaction_len as u64))
1595                    }
1596                    _ => (None, None),
1597                };
1598
1599            <Runtime as pallet_evm::Config>::Runner::call(
1600                from,
1601                to,
1602                data,
1603                value,
1604                gas_limit.unique_saturated_into(),
1605                max_fee_per_gas,
1606                max_priority_fee_per_gas,
1607                nonce,
1608                access_list.unwrap_or_default(),
1609                authorization_list.unwrap_or_default(),
1610                is_transactional,
1611                validate,
1612                weight_limit,
1613                proof_size_base_cost,
1614                config
1615                    .as_ref()
1616                    .unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
1617            )
1618            .map_err(|err| err.error.into())
1619        }
1620
1621        fn create(
1622            from: H160,
1623            data: Vec<u8>,
1624            value: U256,
1625            gas_limit: U256,
1626            max_fee_per_gas: Option<U256>,
1627            max_priority_fee_per_gas: Option<U256>,
1628            nonce: Option<U256>,
1629            estimate: bool,
1630            access_list: Option<Vec<(H160, Vec<H256>)>>,
1631            authorization_list: Option<AuthorizationList>,
1632        ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
1633            let config = if estimate {
1634                let mut config = <Runtime as pallet_evm::Config>::config().clone();
1635                config.estimate = true;
1636                Some(config)
1637            } else {
1638                None
1639            };
1640
1641            let is_transactional = false;
1642            let validate = true;
1643
1644            // Reused approach from Moonbeam since Frontier implementation doesn't support this
1645            let mut estimated_transaction_len = data.len() +
1646                // to: 20
1647                // from: 20
1648                // value: 32
1649                // gas_limit: 32
1650                // nonce: 32
1651                // 1 byte transaction action variant
1652                // chain id 8 bytes
1653                // 65 bytes signature
1654                210;
1655            if max_fee_per_gas.is_some() {
1656                estimated_transaction_len += 32;
1657            }
1658            if max_priority_fee_per_gas.is_some() {
1659                estimated_transaction_len += 32;
1660            }
1661            if access_list.is_some() {
1662                estimated_transaction_len += access_list.encoded_size();
1663            }
1664
1665            let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
1666            let without_base_extrinsic_weight = true;
1667
1668            let (weight_limit, proof_size_base_cost) =
1669                match <Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(
1670                    gas_limit,
1671                    without_base_extrinsic_weight
1672                ) {
1673                    weight_limit if weight_limit.proof_size() > 0 => {
1674                        (Some(weight_limit), Some(estimated_transaction_len as u64))
1675                    }
1676                    _ => (None, None),
1677                };
1678
1679            #[allow(clippy::or_fun_call)] // suggestion not helpful here
1680            <Runtime as pallet_evm::Config>::Runner::create(
1681                from,
1682                data,
1683                value,
1684                gas_limit.unique_saturated_into(),
1685                max_fee_per_gas,
1686                max_priority_fee_per_gas,
1687                nonce,
1688                access_list.unwrap_or_default(),
1689                authorization_list.unwrap_or_default(),
1690                is_transactional,
1691                validate,
1692                weight_limit,
1693                proof_size_base_cost,
1694                config
1695                    .as_ref()
1696                    .unwrap_or(<Runtime as pallet_evm::Config>::config()),
1697                )
1698                .map_err(|err| err.error.into())
1699        }
1700
1701        fn current_transaction_statuses() -> Option<Vec<fp_rpc::TransactionStatus>> {
1702            pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
1703        }
1704
1705        fn current_block() -> Option<pallet_ethereum::Block> {
1706            pallet_ethereum::CurrentBlock::<Runtime>::get()
1707        }
1708
1709        fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
1710            pallet_ethereum::CurrentReceipts::<Runtime>::get()
1711        }
1712
1713        fn current_all() -> (
1714            Option<pallet_ethereum::Block>,
1715            Option<Vec<pallet_ethereum::Receipt>>,
1716            Option<Vec<fp_rpc::TransactionStatus>>,
1717        ) {
1718            (
1719                pallet_ethereum::CurrentBlock::<Runtime>::get(),
1720                pallet_ethereum::CurrentReceipts::<Runtime>::get(),
1721                pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
1722            )
1723        }
1724
1725        fn extrinsic_filter(
1726            xts: Vec<<Block as BlockT>::Extrinsic>,
1727        ) -> Vec<pallet_ethereum::Transaction> {
1728            xts.into_iter().filter_map(|xt| match xt.0.function {
1729                RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
1730                _ => None
1731            }).collect::<Vec<pallet_ethereum::Transaction>>()
1732        }
1733
1734        fn elasticity() -> Option<Permill> {
1735            Some(Permill::zero())
1736        }
1737
1738        fn gas_limit_multiplier_support() {}
1739
1740        fn pending_block(
1741            xts: Vec<<Block as BlockT>::Extrinsic>,
1742        ) -> (Option<pallet_ethereum::Block>, Option<Vec<fp_rpc::TransactionStatus>>) {
1743            for ext in xts.into_iter() {
1744                let _ = Executive::apply_extrinsic(ext);
1745            }
1746
1747            Ethereum::on_finalize(System::block_number() + 1);
1748
1749            (
1750                pallet_ethereum::CurrentBlock::<Runtime>::get(),
1751                pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
1752            )
1753        }
1754
1755        fn initialize_pending_block(header: &<Block as BlockT>::Header) {
1756            Executive::initialize_block(header);
1757        }
1758    }
1759
1760    impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
1761        fn convert_transaction(
1762            transaction: pallet_ethereum::Transaction
1763        ) -> <Block as BlockT>::Extrinsic {
1764            UncheckedExtrinsic::new_bare(
1765                pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1766            )
1767        }
1768    }
1769
1770    impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord> for Runtime {
1771        fn call(
1772            origin: AccountId,
1773            dest: AccountId,
1774            value: Balance,
1775            gas_limit: Option<Weight>,
1776            storage_deposit_limit: Option<Balance>,
1777            input_data: Vec<u8>,
1778        ) -> pallet_contracts::ContractExecResult<Balance, EventRecord> {
1779            let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
1780            Contracts::bare_call(
1781                origin,
1782                dest,
1783                value,
1784                gas_limit,
1785                storage_deposit_limit,
1786                input_data,
1787                pallet_contracts::DebugInfo::UnsafeDebug,
1788                pallet_contracts::CollectEvents::UnsafeCollect,
1789                pallet_contracts::Determinism::Enforced,
1790            )
1791        }
1792
1793        fn instantiate(
1794            origin: AccountId,
1795            value: Balance,
1796            gas_limit: Option<Weight>,
1797            storage_deposit_limit: Option<Balance>,
1798            code: pallet_contracts::Code<Hash>,
1799            data: Vec<u8>,
1800            salt: Vec<u8>,
1801        ) -> pallet_contracts::ContractInstantiateResult<AccountId, Balance, EventRecord> {
1802            let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
1803            Contracts::bare_instantiate(
1804                origin,
1805                value,
1806                gas_limit,
1807                storage_deposit_limit,
1808                code,
1809                data,
1810                salt,
1811                pallet_contracts::DebugInfo::UnsafeDebug,
1812                pallet_contracts::CollectEvents::UnsafeCollect,
1813            )
1814        }
1815
1816        fn upload_code(
1817            origin: AccountId,
1818            code: Vec<u8>,
1819            storage_deposit_limit: Option<Balance>,
1820            determinism: pallet_contracts::Determinism,
1821        ) -> pallet_contracts::CodeUploadResult<Hash, Balance>
1822        {
1823            Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism)
1824        }
1825
1826        fn get_storage(
1827            address: AccountId,
1828            key: Vec<u8>,
1829        ) -> pallet_contracts::GetStorageResult {
1830            Contracts::get_storage(address, key)
1831        }
1832    }
1833
1834    impl dapp_staking_runtime_api::DappStakingApi<Block> for Runtime {
1835        fn periods_per_cycle() -> PeriodNumber {
1836            InflationCycleConfig::periods_per_cycle()
1837        }
1838
1839        fn eras_per_voting_subperiod() -> EraNumber {
1840            InflationCycleConfig::eras_per_voting_subperiod()
1841        }
1842
1843        fn eras_per_build_and_earn_subperiod() -> EraNumber {
1844            InflationCycleConfig::eras_per_build_and_earn_subperiod()
1845        }
1846
1847        fn blocks_per_era() -> BlockNumber {
1848            InflationCycleConfig::blocks_per_era()
1849        }
1850
1851        fn get_dapp_tier_assignment() -> BTreeMap<DAppId, RankedTier> {
1852            DappStaking::get_dapp_tier_assignment()
1853        }
1854    }
1855
1856
1857    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
1858
1859        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
1860            genesis_builder_helper::build_state::<RuntimeGenesisConfig>(config)
1861        }
1862
1863        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
1864            genesis_builder_helper::get_preset::<RuntimeGenesisConfig>(id, &genesis_config::get_preset)
1865        }
1866
1867        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
1868            vec![
1869                sp_genesis_builder::PresetId::from("development"),
1870            ]
1871        }
1872    }
1873
1874    #[cfg(feature = "runtime-benchmarks")]
1875    impl frame_benchmarking::Benchmark<Block> for Runtime {
1876        fn benchmark_metadata(extra: bool) -> (
1877            Vec<frame_benchmarking::BenchmarkList>,
1878            Vec<frame_support::traits::StorageInfo>,
1879        ) {
1880            use frame_benchmarking::{baseline, BenchmarkList};
1881            use frame_support::traits::StorageInfoTrait;
1882            pub use frame_system_benchmarking::{
1883                extensions::Pallet as SystemExtensionsBench, Pallet as SystemBench
1884            };
1885            use baseline::Pallet as BaselineBench;
1886
1887            let mut list = Vec::<BenchmarkList>::new();
1888            list_benchmarks!(list, extra);
1889
1890            let storage_info = AllPalletsWithSystem::storage_info();
1891
1892            (list, storage_info)
1893        }
1894
1895        #[allow(non_local_definitions)]
1896        fn dispatch_benchmark(
1897            config: frame_benchmarking::BenchmarkConfig
1898        ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
1899            use frame_benchmarking::{baseline, BenchmarkBatch};
1900            pub use frame_system_benchmarking::{
1901                extensions::Pallet as SystemExtensionsBench, Pallet as SystemBench
1902            };
1903            use baseline::Pallet as BaselineBench;
1904
1905            impl frame_system_benchmarking::Config for Runtime {}
1906            impl baseline::Config for Runtime {}
1907
1908            use frame_support::traits::{WhitelistedStorageKeys, TrackedStorageKey};
1909            let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
1910
1911            let mut batches = Vec::<BenchmarkBatch>::new();
1912            let params = (&config, &whitelist);
1913            add_benchmarks!(params, batches);
1914
1915            if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
1916            Ok(batches)
1917        }
1918    }
1919
1920    impl moonbeam_rpc_primitives_debug::DebugRuntimeApi<Block> for Runtime {
1921        fn trace_transaction(
1922            extrinsics: Vec<<Block as BlockT>::Extrinsic>,
1923            traced_transaction: &pallet_ethereum::Transaction,
1924            header: &<Block as BlockT>::Header,
1925        ) -> Result<
1926            (),
1927            sp_runtime::DispatchError,
1928        > {
1929            use moonbeam_evm_tracer::tracer::EvmTracer;
1930
1931            // We need to follow the order when replaying the transactions.
1932            // Block initialize happens first then apply_extrinsic.
1933            Executive::initialize_block(header);
1934
1935            // Apply the a subset of extrinsics: all the substrate-specific or ethereum
1936            // transactions that preceded the requested transaction.
1937            for ext in extrinsics.into_iter() {
1938                let _ = match &ext.0.function {
1939                    RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => {
1940                        if transaction == traced_transaction {
1941                            EvmTracer::new().trace(|| Executive::apply_extrinsic(ext));
1942                            return Ok(());
1943                        } else {
1944                            Executive::apply_extrinsic(ext)
1945                        }
1946                    }
1947                    _ => Executive::apply_extrinsic(ext),
1948                };
1949            }
1950            Err(sp_runtime::DispatchError::Other(
1951                "Failed to find Ethereum transaction among the extrinsics.",
1952            ))
1953        }
1954
1955        fn trace_block(
1956            extrinsics: Vec<<Block as BlockT>::Extrinsic>,
1957            known_transactions: Vec<H256>,
1958            header: &<Block as BlockT>::Header,
1959        ) -> Result<
1960            (),
1961            sp_runtime::DispatchError,
1962        > {
1963            use moonbeam_evm_tracer::tracer::EvmTracer;
1964
1965            let mut config = <Runtime as pallet_evm::Config>::config().clone();
1966            config.estimate = true;
1967
1968            // We need to follow the order when replaying the transactions.
1969            // Block initialize happens first then apply_extrinsic.
1970            Executive::initialize_block(header);
1971
1972            // Apply all extrinsics. Ethereum extrinsics are traced.
1973            for ext in extrinsics.into_iter() {
1974                match &ext.0.function {
1975                    RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => {
1976                        if known_transactions.contains(&transaction.hash()) {
1977                            // Each known extrinsic is a new call stack.
1978                            EvmTracer::emit_new();
1979                            EvmTracer::new().trace(|| Executive::apply_extrinsic(ext));
1980                        } else {
1981                            let _ = Executive::apply_extrinsic(ext);
1982                        }
1983                    }
1984                    _ => {
1985                        let _ = Executive::apply_extrinsic(ext);
1986                    }
1987                };
1988            }
1989
1990            Ok(())
1991        }
1992
1993        fn trace_call(
1994            header: &<Block as BlockT>::Header,
1995            from: H160,
1996            to: H160,
1997            data: Vec<u8>,
1998            value: U256,
1999            gas_limit: U256,
2000            max_fee_per_gas: Option<U256>,
2001            max_priority_fee_per_gas: Option<U256>,
2002            nonce: Option<U256>,
2003            access_list: Option<Vec<(H160, Vec<H256>)>>,
2004            authorization_list: Option<AuthorizationList>,
2005        ) -> Result<(), sp_runtime::DispatchError> {
2006            use moonbeam_evm_tracer::tracer::EvmTracer;
2007
2008            // Initialize block: calls the "on_initialize" hook on every pallet
2009            // in AllPalletsWithSystem.
2010            Executive::initialize_block(header);
2011
2012            EvmTracer::new().trace(|| {
2013                let is_transactional = false;
2014                let validate = true;
2015                let without_base_extrinsic_weight = true;
2016
2017
2018                // Estimated encoded transaction size must be based on the heaviest transaction
2019                // type (EIP1559Transaction) to be compatible with all transaction types.
2020                let mut estimated_transaction_len = data.len() +
2021                // pallet ethereum index: 1
2022                // transact call index: 1
2023                // Transaction enum variant: 1
2024                // chain_id 8 bytes
2025                // nonce: 32
2026                // max_priority_fee_per_gas: 32
2027                // max_fee_per_gas: 32
2028                // gas_limit: 32
2029                // action: 21 (enum varianrt + call address)
2030                // value: 32
2031                // access_list: 1 (empty vec size)
2032                // 65 bytes signature
2033                258;
2034
2035                if access_list.is_some() {
2036                    estimated_transaction_len += access_list.encoded_size();
2037                }
2038
2039                let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
2040
2041                let (weight_limit, proof_size_base_cost) =
2042                    match <Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(
2043                        gas_limit,
2044                        without_base_extrinsic_weight
2045                    ) {
2046                        weight_limit if weight_limit.proof_size() > 0 => {
2047                            (Some(weight_limit), Some(estimated_transaction_len as u64))
2048                        }
2049                        _ => (None, None),
2050                    };
2051
2052                let _ = <Runtime as pallet_evm::Config>::Runner::call(
2053                    from,
2054                    to,
2055                    data,
2056                    value,
2057                    gas_limit,
2058                    max_fee_per_gas,
2059                    max_priority_fee_per_gas,
2060                    nonce,
2061                    access_list.unwrap_or_default(),
2062                    authorization_list.unwrap_or_default(),
2063                    is_transactional,
2064                    validate,
2065                    weight_limit,
2066                    proof_size_base_cost,
2067                    <Runtime as pallet_evm::Config>::config(),
2068                );
2069            });
2070            Ok(())
2071        }
2072    }
2073
2074    impl moonbeam_rpc_primitives_txpool::TxPoolRuntimeApi<Block> for Runtime {
2075        fn extrinsic_filter(
2076            xts_ready: Vec<<Block as BlockT>::Extrinsic>,
2077            xts_future: Vec<<Block as BlockT>::Extrinsic>,
2078        ) -> moonbeam_rpc_primitives_txpool::TxPoolResponse {
2079            moonbeam_rpc_primitives_txpool::TxPoolResponse {
2080                ready: xts_ready
2081                    .into_iter()
2082                    .filter_map(|xt| match xt.0.function {
2083                        RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
2084                        _ => None,
2085                    })
2086                    .collect(),
2087                future: xts_future
2088                    .into_iter()
2089                    .filter_map(|xt| match xt.0.function {
2090                        RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
2091                        _ => None,
2092                    })
2093                    .collect(),
2094            }
2095        }
2096    }
2097
2098    #[cfg(feature = "try-runtime")]
2099    impl frame_try_runtime::TryRuntime<Block> for Runtime {
2100        fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
2101            log::info!("try-runtime::on_runtime_upgrade");
2102            let weight = Executive::try_runtime_upgrade(checks).unwrap();
2103            (weight, RuntimeBlockWeights::get().max_block)
2104        }
2105
2106        fn execute_block(
2107            block: Block,
2108            state_root_check: bool,
2109            signature_check: bool,
2110            select: frame_try_runtime::TryStateSelect
2111        ) -> Weight {
2112            log::info!(
2113                "try-runtime: executing block #{} ({:?}) / root checks: {:?} / sanity-checks: {:?}",
2114                block.header.number,
2115                block.header.hash(),
2116                state_root_check,
2117                select,
2118            );
2119            Executive::try_execute_block(block, state_root_check, signature_check, select).expect("execute-block failed")
2120        }
2121    }
2122}