1#![cfg_attr(not(feature = "std"), no_std)]
24#![recursion_limit = "512"]
26
27#[cfg(feature = "std")]
29include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
30
31pub mod asset_config;
32#[cfg(not(feature = "disable-genesis-builder"))]
33pub mod genesis_config_preset;
34pub mod governance;
35pub mod runtime_params;
36pub mod xcm_config;
37
38mod migrations;
39mod precompiles;
40
41extern crate alloc;
42extern crate core;
43
44use alloc::borrow::Cow;
45#[cfg(feature = "std")]
47pub use fp_evm::GenesisAccount;
48pub use moonbeam_core_primitives::{
49 AccountId, AccountIndex, Address, AssetId, Balance, BlockNumber, DigestItem, Hash, Header,
50 Index, Signature,
51};
52pub use pallet_author_slot_filter::EligibilityValue;
53pub use pallet_parachain_staking::{weights::WeightInfo, InflationInfo, Range};
54pub use precompiles::{
55 MoonbasePrecompiles, PrecompileName, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
56};
57
58use account::AccountId20;
59use cumulus_pallet_parachain_system::{
60 RelayChainStateProof, RelayStateProof, RelaychainDataProvider, ValidationData,
61};
62use cumulus_primitives_core::{relay_chain, AggregateMessageOrigin};
63use fp_rpc::TransactionStatus;
64use frame_support::{
65 construct_runtime,
66 dispatch::{DispatchClass, GetDispatchInfo, PostDispatchInfo},
67 ensure,
68 pallet_prelude::DispatchResult,
69 parameter_types,
70 traits::{
71 fungible::{Balanced, Credit, HoldConsideration, Inspect, NativeOrWithId},
72 ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EitherOf,
73 EitherOfDiverse, EqualPrivilegeOnly, FindAuthor, Get, InstanceFilter, LinearStoragePrice,
74 OnFinalize, OnUnbalanced, VariantCountOf,
75 },
76 weights::{
77 constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient,
78 WeightToFeeCoefficients, WeightToFeePolynomial,
79 },
80 PalletId,
81};
82use frame_system::{EnsureRoot, EnsureSigned};
83use governance::councils::*;
84use moonbeam_rpc_primitives_txpool::TxPoolResponse;
85use moonbeam_runtime_common::{
86 impl_asset_conversion::AssetRateConverter, impl_multiasset_paymaster::MultiAssetPaymaster,
87};
88use nimbus_primitives::CanAuthor;
89use pallet_ethereum::Call::transact;
90use pallet_ethereum::{PostLogContent, Transaction as EthereumTransaction};
91use pallet_evm::{
92 Account as EVMAccount, EVMFungibleAdapter, EnsureAddressNever, EnsureAddressRoot,
93 FeeCalculator, FrameSystemAccountProvider, GasWeightMapping, IdentityAddressMapping,
94 OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner,
95};
96use pallet_transaction_payment::{FungibleAdapter, Multiplier, TargetedFeeAdjustment};
97use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
98use runtime_params::*;
99use scale_info::TypeInfo;
100use sp_api::impl_runtime_apis;
101use sp_consensus_slots::Slot;
102use sp_core::{OpaqueMetadata, H160, H256, U256};
103use sp_runtime::generic::Preamble;
104use sp_runtime::{
105 generic, impl_opaque_keys,
106 traits::{
107 BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, IdentityLookup,
108 PostDispatchInfoOf, UniqueSaturatedInto, Zero,
109 },
110 transaction_validity::{
111 InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
112 },
113 ApplyExtrinsicResult, DispatchErrorWithPostInfo, FixedPointNumber, Perbill, Permill,
114 Perquintill,
115};
116use sp_std::{
117 convert::{From, Into},
118 prelude::*,
119};
120#[cfg(feature = "std")]
121use sp_version::NativeVersion;
122use sp_version::RuntimeVersion;
123use xcm::{
124 Version as XcmVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
125};
126use xcm_runtime_apis::{
127 dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
128 fees::Error as XcmPaymentApiError,
129};
130
131use smallvec::smallvec;
132use sp_runtime::serde::{Deserialize, Serialize};
133
134#[cfg(any(feature = "std", test))]
135pub use sp_runtime::BuildStorage;
136
137pub type Precompiles = MoonbasePrecompiles<Runtime>;
138
139mod weights;
140
141pub(crate) use weights as moonbase_weights;
142
143pub use weights::xcm as moonbase_xcm_weights;
144
145pub mod currency {
147 use super::Balance;
148
149 pub const SUPPLY_FACTOR: Balance = 1;
151
152 pub const WEI: Balance = 1;
153 pub const KILOWEI: Balance = 1_000;
154 pub const MEGAWEI: Balance = 1_000_000;
155 pub const GIGAWEI: Balance = 1_000_000_000;
156 pub const MICROUNIT: Balance = 1_000_000_000_000;
157 pub const MILLIUNIT: Balance = 1_000_000_000_000_000;
158 pub const UNIT: Balance = 1_000_000_000_000_000_000;
159 pub const KILOUNIT: Balance = 1_000_000_000_000_000_000_000;
160
161 pub const TRANSACTION_BYTE_FEE: Balance = 1 * GIGAWEI * SUPPLY_FACTOR;
162 pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT * SUPPLY_FACTOR;
163 pub const WEIGHT_FEE: Balance = 50 * KILOWEI * SUPPLY_FACTOR / 4;
164
165 pub const fn deposit(items: u32, bytes: u32) -> Balance {
166 items as Balance * 1 * UNIT * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
167 }
168}
169
170pub const MAX_POV_SIZE: u32 = 10 * 1024 * 1024;
173
174pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
176 WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
177 MAX_POV_SIZE as u64,
178);
179
180pub const MILLISECS_PER_BLOCK: u64 = 6_000;
181pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
182pub const HOURS: BlockNumber = MINUTES * 60;
183pub const DAYS: BlockNumber = HOURS * 24;
184pub const WEEKS: BlockNumber = DAYS * 7;
185pub mod opaque {
190 use super::*;
191
192 pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
193 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
194
195 impl_opaque_keys! {
196 pub struct SessionKeys {
197 pub nimbus: AuthorInherent,
198 pub vrf: session_keys_primitives::VrfSessionKey,
199 }
200 }
201}
202
203#[sp_version::runtime_version]
208pub const VERSION: RuntimeVersion = RuntimeVersion {
209 spec_name: Cow::Borrowed("moonbase"),
210 impl_name: Cow::Borrowed("moonbase"),
211 authoring_version: 4,
212 spec_version: 4200,
213 impl_version: 0,
214 apis: RUNTIME_API_VERSIONS,
215 transaction_version: 3,
216 system_version: 1,
217};
218
219#[cfg(feature = "std")]
221pub fn native_version() -> NativeVersion {
222 NativeVersion {
223 runtime_version: VERSION,
224 can_author_with: Default::default(),
225 }
226}
227
228const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
229pub const NORMAL_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_mul(3).saturating_div(4);
230pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
235
236pub struct RuntimeBlockWeights;
237impl Get<frame_system::limits::BlockWeights> for RuntimeBlockWeights {
238 fn get() -> frame_system::limits::BlockWeights {
239 frame_system::limits::BlockWeights::builder()
240 .for_class(DispatchClass::Normal, |weights| {
241 weights.base_extrinsic = EXTRINSIC_BASE_WEIGHT;
242 weights.max_total = NORMAL_WEIGHT.into();
243 })
244 .for_class(DispatchClass::Operational, |weights| {
245 weights.max_total = MAXIMUM_BLOCK_WEIGHT.into();
246 weights.reserved = (MAXIMUM_BLOCK_WEIGHT - NORMAL_WEIGHT).into();
247 })
248 .avg_block_initialization(Perbill::from_percent(10))
249 .build()
250 .expect("Provided BlockWeight definitions are valid, qed")
251 }
252}
253
254parameter_types! {
255 pub const Version: RuntimeVersion = VERSION;
256 pub BlockWeights: frame_system::limits::BlockWeights = RuntimeBlockWeights::get();
260 pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
262 ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
263}
264
265impl frame_system::Config for Runtime {
266 type AccountId = AccountId;
268 type RuntimeCall = RuntimeCall;
270 type Lookup = IdentityLookup<AccountId>;
272 type Nonce = Index;
274 type Block = Block;
276 type Hash = Hash;
278 type Hashing = BlakeTwo256;
280 type RuntimeEvent = RuntimeEvent;
282 type RuntimeOrigin = RuntimeOrigin;
284 type RuntimeTask = RuntimeTask;
286 type BlockHashCount = ConstU32<256>;
288 type BlockWeights = RuntimeBlockWeights;
290 type BlockLength = BlockLength;
292 type Version = Version;
294 type PalletInfo = PalletInfo;
295 type AccountData = pallet_balances::AccountData<Balance>;
296 type OnNewAccount = ();
297 type OnKilledAccount = ();
298 type DbWeight = moonbase_weights::db::rocksdb::constants::RocksDbWeight;
299 type BaseCallFilter = MaintenanceMode;
300 type SystemWeightInfo = moonbase_weights::frame_system::WeightInfo<Runtime>;
301 type SS58Prefix = ConstU16<1287>;
303 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
304 type MaxConsumers = frame_support::traits::ConstU32<16>;
305 type SingleBlockMigrations = migrations::SingleBlockMigrations<Runtime>;
306 type MultiBlockMigrator = MultiBlockMigrations;
307 type PreInherents = ();
308 type PostInherents = (
309 AsyncBacking,
311 );
312 type PostTransactions = ();
313 type ExtensionsWeightInfo = moonbase_weights::frame_system_extensions::WeightInfo<Runtime>;
314}
315
316impl pallet_utility::Config for Runtime {
317 type RuntimeEvent = RuntimeEvent;
318 type RuntimeCall = RuntimeCall;
319 type PalletsOrigin = OriginCaller;
320 type WeightInfo = moonbase_weights::pallet_utility::WeightInfo<Runtime>;
321}
322
323impl pallet_timestamp::Config for Runtime {
324 type Moment = u64;
326 type OnTimestampSet = ();
327 type MinimumPeriod = ConstU64<{ RELAY_CHAIN_SLOT_DURATION_MILLIS as u64 / 2 }>;
328 type WeightInfo = moonbase_weights::pallet_timestamp::WeightInfo<Runtime>;
329}
330
331#[cfg(not(feature = "runtime-benchmarks"))]
332parameter_types! {
333 pub const ExistentialDeposit: Balance = 0;
334}
335
336#[cfg(feature = "runtime-benchmarks")]
337parameter_types! {
338 pub const ExistentialDeposit: Balance = 1;
339}
340
341impl pallet_balances::Config for Runtime {
342 type MaxReserves = ConstU32<50>;
343 type ReserveIdentifier = [u8; 4];
344 type MaxLocks = ConstU32<50>;
345 type Balance = Balance;
347 type RuntimeEvent = RuntimeEvent;
349 type DustRemoval = ();
350 type ExistentialDeposit = ExistentialDeposit;
351 type AccountStore = System;
352 type FreezeIdentifier = RuntimeFreezeReason;
353 type MaxFreezes = VariantCountOf<Self::RuntimeFreezeReason>;
354 type RuntimeHoldReason = RuntimeHoldReason;
355 type RuntimeFreezeReason = RuntimeFreezeReason;
356 type WeightInfo = moonbase_weights::pallet_balances::WeightInfo<Runtime>;
357 type DoneSlashHandler = ();
358}
359
360pub struct LengthToFee;
361impl WeightToFeePolynomial for LengthToFee {
362 type Balance = Balance;
363
364 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
365 smallvec![
366 WeightToFeeCoefficient {
367 degree: 1,
368 coeff_frac: Perbill::zero(),
369 coeff_integer: currency::TRANSACTION_BYTE_FEE,
370 negative: false,
371 },
372 WeightToFeeCoefficient {
373 degree: 3,
374 coeff_frac: Perbill::zero(),
375 coeff_integer: 1 * currency::SUPPLY_FACTOR,
376 negative: false,
377 },
378 ]
379 }
380}
381
382impl pallet_transaction_payment::Config for Runtime {
383 type RuntimeEvent = RuntimeEvent;
384 type OnChargeTransaction = FungibleAdapter<
385 Balances,
386 DealWithSubstrateFeesAndTip<
387 Runtime,
388 dynamic_params::runtime_config::FeesTreasuryProportion,
389 >,
390 >;
391 type OperationalFeeMultiplier = ConstU8<5>;
392 type WeightToFee = ConstantMultiplier<Balance, ConstU128<{ currency::WEIGHT_FEE }>>;
393 type LengthToFee = LengthToFee;
394 type FeeMultiplierUpdate = FastAdjustingFeeUpdate<Runtime>;
395 type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
396}
397
398impl pallet_sudo::Config for Runtime {
399 type RuntimeCall = RuntimeCall;
400 type RuntimeEvent = RuntimeEvent;
401 type WeightInfo = moonbase_weights::pallet_sudo::WeightInfo<Runtime>;
402}
403
404impl pallet_evm_chain_id::Config for Runtime {}
405
406pub const GAS_PER_SECOND: u64 = 40_000_000;
411
412pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND;
415
416pub const BLOCK_STORAGE_LIMIT: u64 = 160 * 1024;
420
421parameter_types! {
422 pub BlockGasLimit: U256
423 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
424 pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(35);
427 pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(4, 1_000);
431 pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10);
435 pub MaximumMultiplier: Multiplier = Multiplier::from(100_000u128);
438 pub PrecompilesValue: MoonbasePrecompiles<Runtime> = MoonbasePrecompiles::<_>::new();
439 pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
440 pub const GasLimitPovSizeRatio: u64 = 8;
447 pub GasLimitStorageGrowthRatio: u64 = 366;
450}
451
452pub struct TransactionPaymentAsGasPrice;
453impl FeeCalculator for TransactionPaymentAsGasPrice {
454 fn min_gas_price() -> (U256, Weight) {
455 let min_gas_price = TransactionPayment::next_fee_multiplier()
469 .saturating_mul_int((currency::WEIGHT_FEE).saturating_mul(WEIGHT_PER_GAS as u128));
470 (
471 min_gas_price.into(),
472 <Runtime as frame_system::Config>::DbWeight::get().reads(1),
473 )
474 }
475}
476
477pub type FastAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
489 R,
490 TargetBlockFullness,
491 AdjustmentVariable,
492 MinimumMultiplier,
493 MaximumMultiplier,
494>;
495
496pub struct FindAuthorAdapter<T, U, Inner>(sp_std::marker::PhantomData<(T, U, Inner)>);
499
500impl<T, U, Inner> FindAuthor<U> for FindAuthorAdapter<T, U, Inner>
501where
502 T: Into<U>,
503 Inner: FindAuthor<T>,
504{
505 fn find_author<'a, I>(digests: I) -> Option<U>
506 where
507 I: 'a + IntoIterator<Item = (sp_runtime::ConsensusEngineId, &'a [u8])>,
508 {
509 Inner::find_author(digests).map(Into::into)
510 }
511}
512
513moonbeam_runtime_common::impl_on_charge_evm_transaction!();
514
515impl pallet_evm::Config for Runtime {
516 type FeeCalculator = TransactionPaymentAsGasPrice;
517 type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
518 type WeightPerGas = WeightPerGas;
519 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
520 type CallOrigin = EnsureAddressRoot<AccountId>;
521 type WithdrawOrigin = EnsureAddressNever<AccountId>;
522 type AddressMapping = IdentityAddressMapping;
523 type Currency = Balances;
524 type Runner = pallet_evm::runner::stack::Runner<Self>;
525 type PrecompilesType = MoonbasePrecompiles<Self>;
526 type PrecompilesValue = PrecompilesValue;
527 type ChainId = EthereumChainId;
528 type OnChargeTransaction = OnChargeEVMTransaction<
529 DealWithEthereumBaseFees<Runtime, dynamic_params::runtime_config::FeesTreasuryProportion>,
530 DealWithEthereumPriorityFees<Runtime>,
531 >;
532 type BlockGasLimit = BlockGasLimit;
533 type FindAuthor = FindAuthorAdapter<AccountId20, H160, AuthorInherent>;
534 type OnCreate = ();
535 type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
536 type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
537 type Timestamp = Timestamp;
538 type AccountProvider = FrameSystemAccountProvider<Runtime>;
539
540 type WeightInfo = moonbase_weights::pallet_evm::WeightInfo<Runtime>;
541 type CreateOriginFilter = ();
542 type CreateInnerOriginFilter = ();
543}
544
545parameter_types! {
546 pub MaxServiceWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
547 pub const NoPreimagePostponement: Option<u32> = Some(10);
548}
549
550impl pallet_scheduler::Config for Runtime {
551 type RuntimeEvent = RuntimeEvent;
552 type RuntimeOrigin = RuntimeOrigin;
553 type PalletsOrigin = OriginCaller;
554 type RuntimeCall = RuntimeCall;
555 type MaximumWeight = MaxServiceWeight;
556 type ScheduleOrigin = EnsureRoot<AccountId>;
557 type MaxScheduledPerBlock = ConstU32<50>;
558 type WeightInfo = moonbase_weights::pallet_scheduler::WeightInfo<Runtime>;
559 type OriginPrivilegeCmp = EqualPrivilegeOnly;
560 type Preimages = Preimage;
561 type BlockNumberProvider = System;
562}
563
564parameter_types! {
565 pub const PreimageBaseDeposit: Balance = 5 * currency::UNIT * currency::SUPPLY_FACTOR ;
566 pub const PreimageByteDeposit: Balance = currency::STORAGE_BYTE_FEE;
567 pub const PreimageHoldReason: RuntimeHoldReason =
568 RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
569}
570
571impl pallet_preimage::Config for Runtime {
572 type WeightInfo = moonbase_weights::pallet_preimage::WeightInfo<Runtime>;
573 type RuntimeEvent = RuntimeEvent;
574 type Currency = Balances;
575 type ManagerOrigin = EnsureRoot<AccountId>;
576 type Consideration = HoldConsideration<
577 AccountId,
578 Balances,
579 PreimageHoldReason,
580 LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
581 >;
582}
583
584parameter_types! {
585 pub const ProposalBond: Permill = Permill::from_percent(5);
586 pub const TreasuryId: PalletId = PalletId(*b"pc/trsry");
587 pub TreasuryAccount: AccountId = Treasury::account_id();
588 pub const MaxSpendBalance: crate::Balance = crate::Balance::max_value();
589}
590
591type RootOrTreasuryCouncilOrigin = EitherOfDiverse<
592 EnsureRoot<AccountId>,
593 pallet_collective::EnsureProportionMoreThan<AccountId, TreasuryCouncilInstance, 1, 2>,
594>;
595
596impl pallet_treasury::Config for Runtime {
597 type PalletId = TreasuryId;
598 type Currency = Balances;
599 type RejectOrigin = RootOrTreasuryCouncilOrigin;
601 type RuntimeEvent = RuntimeEvent;
602 type SpendPeriod = ConstU32<{ 6 * DAYS }>;
603 type Burn = ();
604 type BurnDestination = ();
605 type MaxApprovals = ConstU32<100>;
606 type WeightInfo = moonbase_weights::pallet_treasury::WeightInfo<Runtime>;
607 type SpendFunds = ();
608 type SpendOrigin =
609 frame_system::EnsureWithSuccess<RootOrTreasuryCouncilOrigin, AccountId, MaxSpendBalance>;
610 type AssetKind = NativeOrWithId<AssetId>;
611 type Beneficiary = AccountId;
612 type BeneficiaryLookup = IdentityLookup<AccountId>;
613 type Paymaster = MultiAssetPaymaster<Runtime, TreasuryAccount, Balances>;
614 type BalanceConverter = AssetRateConverter<Runtime, Balances>;
615 type PayoutPeriod = ConstU32<{ 30 * DAYS }>;
616 #[cfg(feature = "runtime-benchmarks")]
617 type BenchmarkHelper = BenchmarkHelper<Runtime>;
618 type BlockNumberProvider = System;
619}
620
621parameter_types! {
622 pub const MaxSubAccounts: u32 = 100;
623 pub const MaxAdditionalFields: u32 = 100;
624 pub const MaxRegistrars: u32 = 20;
625 pub const PendingUsernameExpiration: u32 = 7 * DAYS;
626 pub const MaxSuffixLength: u32 = 7;
627 pub const MaxUsernameLength: u32 = 32;
628}
629
630type IdentityForceOrigin =
631 EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
632type IdentityRegistrarOrigin =
633 EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
634
635impl pallet_identity::Config for Runtime {
636 type RuntimeEvent = RuntimeEvent;
637 type Currency = Balances;
638 type BasicDeposit = ConstU128<{ currency::deposit(1, 258) }>;
640 type ByteDeposit = ConstU128<{ currency::deposit(0, 1) }>;
642 type SubAccountDeposit = ConstU128<{ currency::deposit(1, 53) }>;
644 type MaxSubAccounts = MaxSubAccounts;
645 type IdentityInformation = pallet_identity::legacy::IdentityInfo<MaxAdditionalFields>;
646 type MaxRegistrars = MaxRegistrars;
647 type Slashed = Treasury;
648 type ForceOrigin = IdentityForceOrigin;
649 type RegistrarOrigin = IdentityRegistrarOrigin;
650 type OffchainSignature = Signature;
651 type SigningPublicKey = <Signature as sp_runtime::traits::Verify>::Signer;
652 type UsernameAuthorityOrigin = EnsureRoot<AccountId>;
653 type PendingUsernameExpiration = PendingUsernameExpiration;
654 type MaxSuffixLength = MaxSuffixLength;
655 type MaxUsernameLength = MaxUsernameLength;
656 type WeightInfo = moonbase_weights::pallet_identity::WeightInfo<Runtime>;
657 type UsernameDeposit = ConstU128<{ currency::deposit(0, MaxUsernameLength::get()) }>;
658 type UsernameGracePeriod = ConstU32<{ 30 * DAYS }>;
659 #[cfg(feature = "runtime-benchmarks")]
660 type BenchmarkHelper = BenchmarkHelper<Runtime>;
661}
662
663pub struct TransactionConverter;
664
665impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
666 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
667 UncheckedExtrinsic::new_bare(
668 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
669 )
670 }
671}
672
673impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
674 fn convert_transaction(
675 &self,
676 transaction: pallet_ethereum::Transaction,
677 ) -> opaque::UncheckedExtrinsic {
678 let extrinsic = UncheckedExtrinsic::new_bare(
679 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
680 );
681 let encoded = extrinsic.encode();
682 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
683 .expect("Encoded extrinsic is always valid")
684 }
685}
686
687parameter_types! {
688 pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
689}
690
691impl pallet_ethereum::Config for Runtime {
692 type StateRoot =
693 pallet_ethereum::IntermediateStateRoot<<Runtime as frame_system::Config>::Version>;
694 type PostLogContent = PostBlockAndTxnHashes;
695 type ExtraDataLength = ConstU32<30>;
696}
697
698pub struct EthereumXcmEnsureProxy;
699impl xcm_primitives::EnsureProxy<AccountId> for EthereumXcmEnsureProxy {
700 fn ensure_ok(delegator: AccountId, delegatee: AccountId) -> Result<(), &'static str> {
701 let def: pallet_proxy::ProxyDefinition<AccountId, ProxyType, BlockNumber> =
703 pallet_proxy::Pallet::<Runtime>::find_proxy(
704 &delegator,
705 &delegatee,
706 Some(ProxyType::Any),
707 )
708 .map_err(|_| "proxy error: expected `ProxyType::Any`")?;
709 ensure!(def.delay.is_zero(), "proxy delay is Non-zero`");
711 Ok(())
712 }
713}
714
715impl pallet_ethereum_xcm::Config for Runtime {
716 type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
717 type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
718 type XcmEthereumOrigin = pallet_ethereum_xcm::EnsureXcmEthereumTransaction;
719 type ReservedXcmpWeight = ReservedXcmpWeight;
720 type EnsureProxy = EthereumXcmEnsureProxy;
721 type ControllerOrigin = EnsureRoot<AccountId>;
722 type ForceOrigin = EnsureRoot<AccountId>;
723}
724
725parameter_types! {
726 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
728 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
729 pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
730}
731
732const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
734const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
737const RELAY_PARENT_OFFSET: u32 = 1;
739const BLOCK_PROCESSING_VELOCITY: u32 = 1;
742
743type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
744 Runtime,
745 RELAY_CHAIN_SLOT_DURATION_MILLIS,
746 BLOCK_PROCESSING_VELOCITY,
747 UNINCLUDED_SEGMENT_CAPACITY,
748>;
749
750impl cumulus_pallet_parachain_system::Config for Runtime {
751 type RuntimeEvent = RuntimeEvent;
752 type OnSystemEvent = ();
753 type SelfParaId = ParachainInfo;
754 type ReservedDmpWeight = ReservedDmpWeight;
755 type OutboundXcmpMessageSource = XcmpQueue;
756 type XcmpMessageHandler = XcmpQueue;
757 type ReservedXcmpWeight = ReservedXcmpWeight;
758 type CheckAssociatedRelayNumber = EmergencyParaXcm;
759 type ConsensusHook = ConsensusHook;
760 type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
761 type WeightInfo = moonbase_weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
762 type SelectCore = cumulus_pallet_parachain_system::DefaultCoreSelector<Runtime>;
763 type RelayParentOffset = ConstU32<0>;
764}
765
766impl parachain_info::Config for Runtime {}
767
768pub struct OnNewRound;
769impl pallet_parachain_staking::OnNewRound for OnNewRound {
770 fn on_new_round(round_index: pallet_parachain_staking::RoundIndex) -> Weight {
771 MoonbeamOrbiters::on_new_round(round_index)
772 }
773}
774pub struct PayoutCollatorOrOrbiterReward;
775impl pallet_parachain_staking::PayoutCollatorReward<Runtime> for PayoutCollatorOrOrbiterReward {
776 fn payout_collator_reward(
777 for_round: pallet_parachain_staking::RoundIndex,
778 collator_id: AccountId,
779 amount: Balance,
780 ) -> Weight {
781 let extra_weight =
782 if MoonbeamOrbiters::is_collator_pool_with_active_orbiter(for_round, collator_id) {
783 MoonbeamOrbiters::distribute_rewards(for_round, collator_id, amount)
784 } else {
785 ParachainStaking::mint_collator_reward(for_round, collator_id, amount)
786 };
787
788 <Runtime as frame_system::Config>::DbWeight::get()
789 .reads(1)
790 .saturating_add(extra_weight)
791 }
792}
793
794pub struct OnInactiveCollator;
795impl pallet_parachain_staking::OnInactiveCollator<Runtime> for OnInactiveCollator {
796 fn on_inactive_collator(
797 collator_id: AccountId,
798 round: pallet_parachain_staking::RoundIndex,
799 ) -> Result<Weight, DispatchErrorWithPostInfo<PostDispatchInfo>> {
800 let extra_weight = if !MoonbeamOrbiters::is_collator_pool_with_active_orbiter(
801 round,
802 collator_id.clone(),
803 ) {
804 ParachainStaking::go_offline_inner(collator_id)?;
805 <Runtime as pallet_parachain_staking::Config>::WeightInfo::go_offline(
806 pallet_parachain_staking::MAX_CANDIDATES,
807 )
808 } else {
809 Weight::zero()
810 };
811
812 Ok(<Runtime as frame_system::Config>::DbWeight::get()
813 .reads(1)
814 .saturating_add(extra_weight))
815 }
816}
817
818type MonetaryGovernanceOrigin =
819 EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
820
821pub struct RelayChainSlotProvider;
822impl Get<Slot> for RelayChainSlotProvider {
823 fn get() -> Slot {
824 let slot_info = pallet_async_backing::pallet::Pallet::<Runtime>::slot_info();
825 slot_info.unwrap_or_default().0
826 }
827}
828
829impl pallet_parachain_staking::Config for Runtime {
830 type Currency = Balances;
831 type MonetaryGovernanceOrigin = MonetaryGovernanceOrigin;
832 type MinBlocksPerRound = ConstU32<10>;
834 type MaxOfflineRounds = ConstU32<2>;
836 type LeaveCandidatesDelay = ConstU32<2>;
838 type CandidateBondLessDelay = ConstU32<2>;
840 type LeaveDelegatorsDelay = ConstU32<2>;
842 type RevokeDelegationDelay = ConstU32<2>;
844 type DelegationBondLessDelay = ConstU32<2>;
846 type RewardPaymentDelay = ConstU32<2>;
848 type MinSelectedCandidates = ConstU32<8>;
850 type MaxTopDelegationsPerCandidate = ConstU32<300>;
852 type MaxBottomDelegationsPerCandidate = ConstU32<50>;
854 type MaxDelegationsPerDelegator = ConstU32<100>;
856 type MaxScheduledRequestsPerDelegator = ConstU32<50>;
858 type MinCandidateStk = ConstU128<{ 500 * currency::UNIT * currency::SUPPLY_FACTOR }>;
860 type MinDelegation = ConstU128<{ 1 * currency::UNIT * currency::SUPPLY_FACTOR }>;
862 type BlockAuthor = AuthorInherent;
863 type OnCollatorPayout = ();
864 type PayoutCollatorReward = PayoutCollatorOrOrbiterReward;
865 type OnInactiveCollator = OnInactiveCollator;
866 type OnNewRound = OnNewRound;
867 type SlotProvider = RelayChainSlotProvider;
868 type WeightInfo = moonbase_weights::pallet_parachain_staking::WeightInfo<Runtime>;
869 type MaxCandidates = ConstU32<200>;
870 type SlotDuration = ConstU64<MILLISECS_PER_BLOCK>;
871 type BlockTime = ConstU64<MILLISECS_PER_BLOCK>;
872 type RuntimeFreezeReason = RuntimeFreezeReason;
873 type LinearInflationThreshold = ();
874}
875
876impl pallet_author_inherent::Config for Runtime {
877 type SlotBeacon = RelaychainDataProvider<Self>;
878 type AccountLookup = MoonbeamOrbiters;
879 type CanAuthor = AuthorFilter;
880 type AuthorId = AccountId;
881 type WeightInfo = moonbase_weights::pallet_author_inherent::WeightInfo<Runtime>;
882}
883
884#[cfg(test)]
885mod mock {
886 use super::*;
887 pub struct MockRandomness;
888 impl frame_support::traits::Randomness<H256, BlockNumber> for MockRandomness {
889 fn random(subject: &[u8]) -> (H256, BlockNumber) {
890 (H256(sp_io::hashing::blake2_256(subject)), 0)
891 }
892 }
893}
894
895impl pallet_author_slot_filter::Config for Runtime {
896 #[cfg(not(test))]
897 type RandomnessSource = Randomness;
898 #[cfg(test)]
899 type RandomnessSource = mock::MockRandomness;
900 type PotentialAuthors = ParachainStaking;
901 type WeightInfo = moonbase_weights::pallet_author_slot_filter::WeightInfo<Runtime>;
902}
903
904impl pallet_async_backing::Config for Runtime {
905 type AllowMultipleBlocksPerSlot = ConstBool<true>;
906 type GetAndVerifySlot = pallet_async_backing::RelaySlot;
907 type SlotDuration = ConstU64<MILLISECS_PER_BLOCK>;
908 type ExpectedBlockTime = ConstU64<MILLISECS_PER_BLOCK>;
909}
910
911parameter_types! {
912 pub const InitializationPayment: Perbill = Perbill::from_percent(30);
913 pub const RelaySignaturesThreshold: Perbill = Perbill::from_percent(100);
914 pub const SignatureNetworkIdentifier: &'static [u8] = b"moonbase-";
915
916}
917
918impl pallet_crowdloan_rewards::Config for Runtime {
919 type Initialized = ConstBool<false>;
920 type InitializationPayment = InitializationPayment;
921 type MaxInitContributors = ConstU32<500>;
922 type MinimumReward = ConstU128<0>;
924 type RewardCurrency = Balances;
925 type RelayChainAccountId = [u8; 32];
926 type RewardAddressAssociateOrigin = EnsureSigned<Self::AccountId>;
927 type RewardAddressChangeOrigin = EnsureSigned<Self::AccountId>;
928 type RewardAddressRelayVoteThreshold = RelaySignaturesThreshold;
929 type SignatureNetworkIdentifier = SignatureNetworkIdentifier;
930 type VestingBlockNumber = relay_chain::BlockNumber;
931 type VestingBlockProvider = RelaychainDataProvider<Self>;
932 type WeightInfo = moonbase_weights::pallet_crowdloan_rewards::WeightInfo<Runtime>;
933}
934
935impl pallet_author_mapping::Config for Runtime {
938 type DepositCurrency = Balances;
939 type DepositAmount = ConstU128<{ 100 * currency::UNIT * currency::SUPPLY_FACTOR }>;
940 type Keys = session_keys_primitives::VrfId;
941 type WeightInfo = moonbase_weights::pallet_author_mapping::WeightInfo<Runtime>;
942}
943
944#[derive(
946 Copy,
947 Clone,
948 Eq,
949 PartialEq,
950 Ord,
951 PartialOrd,
952 Encode,
953 Decode,
954 Debug,
955 MaxEncodedLen,
956 TypeInfo,
957 Serialize,
958 Deserialize,
959 DecodeWithMemTracking,
960)]
961pub enum ProxyType {
962 Any = 0,
964 NonTransfer = 1,
966 Governance = 2,
968 Staking = 3,
970 CancelProxy = 4,
972 Balances = 5,
974 AuthorMapping = 6,
976 IdentityJudgement = 7,
978}
979
980impl Default for ProxyType {
981 fn default() -> Self {
982 Self::Any
983 }
984}
985
986fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool {
987 matches!(
988 precompile_name,
989 PrecompileName::TreasuryCouncilInstance
990 | PrecompileName::ReferendaPrecompile
991 | PrecompileName::ConvictionVotingPrecompile
992 | PrecompileName::PreimagePrecompile
993 | PrecompileName::OpenTechCommitteeInstance,
994 )
995}
996
997impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType {
1000 fn is_evm_proxy_call_allowed(
1001 &self,
1002 call: &pallet_evm_precompile_proxy::EvmSubCall,
1003 recipient_has_code: bool,
1004 gas: u64,
1005 ) -> precompile_utils::EvmResult<bool> {
1006 Ok(match self {
1007 ProxyType::Any => {
1008 match PrecompileName::from_address(call.to.0) {
1009 Some(
1014 PrecompileName::AuthorMappingPrecompile
1015 | PrecompileName::ParachainStakingPrecompile,
1016 ) => true,
1017 Some(ref precompile) if is_governance_precompile(precompile) => true,
1018 Some(_) => false,
1020 None => {
1025 !recipient_has_code
1030 && !precompile_utils::precompile_set::is_precompile_or_fail::<Runtime>(
1031 call.to.0, gas,
1032 )?
1033 }
1034 }
1035 }
1036 ProxyType::NonTransfer => {
1037 call.value == U256::zero()
1038 && match PrecompileName::from_address(call.to.0) {
1039 Some(
1040 PrecompileName::AuthorMappingPrecompile
1041 | PrecompileName::ParachainStakingPrecompile,
1042 ) => true,
1043 Some(ref precompile) if is_governance_precompile(precompile) => true,
1044 _ => false,
1045 }
1046 }
1047 ProxyType::Governance => {
1048 call.value == U256::zero()
1049 && matches!(
1050 PrecompileName::from_address(call.to.0),
1051 Some(ref precompile) if is_governance_precompile(precompile)
1052 )
1053 }
1054 ProxyType::Staking => {
1055 call.value == U256::zero()
1056 && matches!(
1057 PrecompileName::from_address(call.to.0),
1058 Some(
1059 PrecompileName::AuthorMappingPrecompile
1060 | PrecompileName::ParachainStakingPrecompile
1061 )
1062 )
1063 }
1064 ProxyType::CancelProxy => false,
1066 ProxyType::Balances => {
1067 !recipient_has_code
1071 && !precompile_utils::precompile_set::is_precompile_or_fail::<Runtime>(
1072 call.to.0, gas,
1073 )?
1074 }
1075 ProxyType::AuthorMapping => {
1076 call.value == U256::zero()
1077 && matches!(
1078 PrecompileName::from_address(call.to.0),
1079 Some(PrecompileName::AuthorMappingPrecompile)
1080 )
1081 }
1082 ProxyType::IdentityJudgement => false,
1084 })
1085 }
1086}
1087
1088impl InstanceFilter<RuntimeCall> for ProxyType {
1090 fn filter(&self, c: &RuntimeCall) -> bool {
1091 match self {
1092 ProxyType::Any => true,
1093 ProxyType::NonTransfer => match c {
1094 RuntimeCall::Identity(
1095 pallet_identity::Call::add_sub { .. } | pallet_identity::Call::set_subs { .. },
1096 ) => false,
1097 call => {
1098 matches!(
1099 call,
1100 RuntimeCall::System(..)
1101 | RuntimeCall::ParachainSystem(..)
1102 | RuntimeCall::Timestamp(..)
1103 | RuntimeCall::ParachainStaking(..)
1104 | RuntimeCall::Referenda(..)
1105 | RuntimeCall::Preimage(..)
1106 | RuntimeCall::ConvictionVoting(..)
1107 | RuntimeCall::TreasuryCouncilCollective(..)
1108 | RuntimeCall::OpenTechCommitteeCollective(..)
1109 | RuntimeCall::Utility(..)
1110 | RuntimeCall::Proxy(..)
1111 | RuntimeCall::Identity(..)
1112 | RuntimeCall::AuthorMapping(..)
1113 | RuntimeCall::CrowdloanRewards(
1114 pallet_crowdloan_rewards::Call::claim { .. }
1115 )
1116 )
1117 }
1118 },
1119 ProxyType::Governance => matches!(
1120 c,
1121 RuntimeCall::Referenda(..)
1122 | RuntimeCall::Preimage(..)
1123 | RuntimeCall::ConvictionVoting(..)
1124 | RuntimeCall::TreasuryCouncilCollective(..)
1125 | RuntimeCall::OpenTechCommitteeCollective(..)
1126 | RuntimeCall::Utility(..)
1127 ),
1128 ProxyType::Staking => matches!(
1129 c,
1130 RuntimeCall::ParachainStaking(..)
1131 | RuntimeCall::Utility(..)
1132 | RuntimeCall::AuthorMapping(..)
1133 | RuntimeCall::MoonbeamOrbiters(..)
1134 ),
1135 ProxyType::CancelProxy => matches!(
1136 c,
1137 RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
1138 ),
1139 ProxyType::Balances => {
1140 matches!(c, RuntimeCall::Balances(..) | RuntimeCall::Utility(..))
1141 }
1142 ProxyType::AuthorMapping => matches!(c, RuntimeCall::AuthorMapping(..)),
1143 ProxyType::IdentityJudgement => matches!(
1144 c,
1145 RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. })
1146 | RuntimeCall::Utility(..)
1147 ),
1148 }
1149 }
1150
1151 fn is_superset(&self, o: &Self) -> bool {
1152 match (self, o) {
1153 (x, y) if x == y => true,
1154 (ProxyType::Any, _) => true,
1155 (_, ProxyType::Any) => false,
1156 _ => false,
1157 }
1158 }
1159}
1160
1161impl pallet_proxy::Config for Runtime {
1162 type RuntimeEvent = RuntimeEvent;
1163 type RuntimeCall = RuntimeCall;
1164 type Currency = Balances;
1165 type ProxyType = ProxyType;
1166 type ProxyDepositBase = ConstU128<{ currency::deposit(1, 8) }>;
1168 type ProxyDepositFactor = ConstU128<{ currency::deposit(0, 21) }>;
1170 type MaxProxies = ConstU32<32>;
1171 type WeightInfo = moonbase_weights::pallet_proxy::WeightInfo<Runtime>;
1172 type MaxPending = ConstU32<32>;
1173 type CallHasher = BlakeTwo256;
1174 type AnnouncementDepositBase = ConstU128<{ currency::deposit(1, 8) }>;
1175 type AnnouncementDepositFactor = ConstU128<{ currency::deposit(0, 56) }>;
1180 type BlockNumberProvider = System;
1181}
1182
1183pub type ForeignAssetMigratorOrigin = EitherOfDiverse<
1184 EnsureRoot<AccountId>,
1185 EitherOfDiverse<
1186 pallet_collective::EnsureProportionMoreThan<AccountId, OpenTechCommitteeInstance, 5, 9>,
1187 EitherOf<
1188 governance::custom_origins::GeneralAdmin,
1189 governance::custom_origins::FastGeneralAdmin,
1190 >,
1191 >,
1192>;
1193
1194impl pallet_moonbeam_lazy_migrations::Config for Runtime {
1195 type WeightInfo = moonbase_weights::pallet_moonbeam_lazy_migrations::WeightInfo<Runtime>;
1196}
1197
1198pub struct MaintenanceFilter;
1200impl Contains<RuntimeCall> for MaintenanceFilter {
1201 fn contains(c: &RuntimeCall) -> bool {
1202 match c {
1203 RuntimeCall::Balances(_) => false,
1204 RuntimeCall::CrowdloanRewards(_) => false,
1205 RuntimeCall::Ethereum(_) => false,
1206 RuntimeCall::EVM(_) => false,
1207 RuntimeCall::Identity(_) => false,
1208 RuntimeCall::ParachainStaking(_) => false,
1209 RuntimeCall::MoonbeamOrbiters(_) => false,
1210 RuntimeCall::PolkadotXcm(_) => false,
1211 RuntimeCall::Treasury(_) => false,
1212 RuntimeCall::XcmTransactor(_) => false,
1213 RuntimeCall::EthereumXcm(_) => false,
1214 _ => true,
1215 }
1216 }
1217}
1218
1219pub struct NormalFilter;
1221impl Contains<RuntimeCall> for NormalFilter {
1222 fn contains(c: &RuntimeCall) -> bool {
1223 match c {
1224 RuntimeCall::Proxy(method) => match method {
1225 pallet_proxy::Call::proxy { real, .. } => {
1226 !pallet_evm::AccountCodes::<Runtime>::contains_key(H160::from(*real))
1227 }
1228 _ => true,
1229 },
1230 RuntimeCall::EVM(_) => false,
1236 _ => true,
1237 }
1238 }
1239}
1240
1241pub struct XcmExecutionManager;
1242impl moonkit_xcm_primitives::PauseXcmExecution for XcmExecutionManager {
1243 fn suspend_xcm_execution() -> DispatchResult {
1244 XcmpQueue::suspend_xcm_execution(RuntimeOrigin::root())
1245 }
1246 fn resume_xcm_execution() -> DispatchResult {
1247 XcmpQueue::resume_xcm_execution(RuntimeOrigin::root())
1248 }
1249}
1250
1251impl pallet_maintenance_mode::Config for Runtime {
1252 type NormalCallFilter = NormalFilter;
1253 type MaintenanceCallFilter = MaintenanceFilter;
1254 type MaintenanceOrigin =
1255 pallet_collective::EnsureProportionAtLeast<AccountId, OpenTechCommitteeInstance, 5, 9>;
1256 type XcmExecutionManager = XcmExecutionManager;
1257}
1258
1259impl pallet_proxy_genesis_companion::Config for Runtime {
1260 type ProxyType = ProxyType;
1261 type BlockNumberProvider = System;
1262}
1263
1264parameter_types! {
1265 pub OrbiterReserveIdentifier: [u8; 4] = [b'o', b'r', b'b', b'i'];
1266}
1267
1268type AddCollatorOrigin =
1269 EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
1270type DelCollatorOrigin =
1271 EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
1272
1273impl pallet_moonbeam_orbiters::Config for Runtime {
1274 type AccountLookup = AuthorMapping;
1275 type AddCollatorOrigin = AddCollatorOrigin;
1276 type Currency = Balances;
1277 type DelCollatorOrigin = DelCollatorOrigin;
1278 type MaxPoolSize = ConstU32<8>;
1280 type MaxRoundArchive = ConstU32<4>;
1282 type OrbiterReserveIdentifier = OrbiterReserveIdentifier;
1283 type RotatePeriod = ConstU32<3>;
1284 type RoundIndex = pallet_parachain_staking::RoundIndex;
1286 type WeightInfo = moonbase_weights::pallet_moonbeam_orbiters::WeightInfo<Runtime>;
1287}
1288
1289fn relay_chain_state_proof<Runtime>() -> RelayChainStateProof
1291where
1292 Runtime: cumulus_pallet_parachain_system::Config,
1293{
1294 let relay_storage_root = ValidationData::<Runtime>::get()
1295 .expect("set in `set_validation_data`")
1296 .relay_parent_storage_root;
1297 let relay_chain_state =
1298 RelayStateProof::<Runtime>::get().expect("set in `set_validation_data`");
1299 RelayChainStateProof::new(ParachainInfo::get(), relay_storage_root, relay_chain_state)
1300 .expect("Invalid relay chain state proof, already constructed in `set_validation_data`")
1301}
1302
1303pub struct BabeDataGetter<Runtime>(sp_std::marker::PhantomData<Runtime>);
1304impl<Runtime> pallet_randomness::GetBabeData<u64, Option<Hash>> for BabeDataGetter<Runtime>
1305where
1306 Runtime: cumulus_pallet_parachain_system::Config,
1307{
1308 fn get_epoch_index() -> u64 {
1310 if cfg!(feature = "runtime-benchmarks") {
1311 let _relay_storage_root = ValidationData::<Runtime>::get();
1313 let _relay_chain_state = RelayStateProof::<Runtime>::get();
1314 const BENCHMARKING_NEW_EPOCH: u64 = 10u64;
1315 return BENCHMARKING_NEW_EPOCH;
1316 }
1317 relay_chain_state_proof::<Runtime>()
1318 .read_optional_entry(relay_chain::well_known_keys::EPOCH_INDEX)
1319 .ok()
1320 .flatten()
1321 .expect("expected to be able to read epoch index from relay chain state proof")
1322 }
1323 fn get_epoch_randomness() -> Option<Hash> {
1324 if cfg!(feature = "runtime-benchmarks") {
1325 let _relay_storage_root = ValidationData::<Runtime>::get();
1327 let _relay_chain_state = RelayStateProof::<Runtime>::get();
1328 let benchmarking_babe_output = Hash::default();
1329 return Some(benchmarking_babe_output);
1330 }
1331 relay_chain_state_proof::<Runtime>()
1332 .read_optional_entry(relay_chain::well_known_keys::ONE_EPOCH_AGO_RANDOMNESS)
1333 .ok()
1334 .flatten()
1335 }
1336}
1337
1338impl pallet_randomness::Config for Runtime {
1339 type AddressMapping = sp_runtime::traits::ConvertInto;
1340 type Currency = Balances;
1341 type BabeDataGetter = BabeDataGetter<Runtime>;
1342 type VrfKeyLookup = AuthorMapping;
1343 type Deposit = runtime_params::PalletRandomnessDepositU128;
1344 type MaxRandomWords = ConstU8<100>;
1345 type MinBlockDelay = ConstU32<2>;
1346 type MaxBlockDelay = ConstU32<2_000>;
1347 type BlockExpirationDelay = ConstU32<10_000>;
1348 type EpochExpirationDelay = ConstU64<10_000>;
1349 type WeightInfo = moonbase_weights::pallet_randomness::WeightInfo<Runtime>;
1350}
1351
1352impl pallet_root_testing::Config for Runtime {
1353 type RuntimeEvent = RuntimeEvent;
1354}
1355
1356parameter_types! {
1357 pub const DepositBase: Balance = currency::deposit(1, 96);
1359 pub const DepositFactor: Balance = currency::deposit(0, 20);
1361 pub const MaxSignatories: u32 = 100;
1362}
1363
1364impl pallet_multisig::Config for Runtime {
1365 type RuntimeEvent = RuntimeEvent;
1366 type RuntimeCall = RuntimeCall;
1367 type Currency = Balances;
1368 type DepositBase = DepositBase;
1369 type DepositFactor = DepositFactor;
1370 type MaxSignatories = MaxSignatories;
1371 type WeightInfo = moonbase_weights::pallet_multisig::WeightInfo<Runtime>;
1372 type BlockNumberProvider = System;
1373}
1374
1375impl pallet_relay_storage_roots::Config for Runtime {
1376 type MaxStorageRoots = ConstU32<30>;
1377 type RelaychainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider<Self>;
1378 type WeightInfo = moonbase_weights::pallet_relay_storage_roots::WeightInfo<Runtime>;
1379}
1380
1381#[cfg(feature = "runtime-benchmarks")]
1382impl pallet_precompile_benchmarks::Config for Runtime {
1383 type WeightInfo = moonbase_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>;
1384}
1385
1386impl pallet_parameters::Config for Runtime {
1387 type AdminOrigin = EnsureRoot<AccountId>;
1388 type RuntimeEvent = RuntimeEvent;
1389 type RuntimeParameters = RuntimeParameters;
1390 type WeightInfo = moonbase_weights::pallet_parameters::WeightInfo<Runtime>;
1391}
1392
1393impl cumulus_pallet_weight_reclaim::Config for Runtime {
1394 type WeightInfo = moonbase_weights::cumulus_pallet_weight_reclaim::WeightInfo<Runtime>;
1395}
1396
1397impl pallet_migrations::Config for Runtime {
1398 type RuntimeEvent = RuntimeEvent;
1399 #[cfg(not(feature = "runtime-benchmarks"))]
1400 type Migrations = migrations::MultiBlockMigrationList<Runtime>;
1401 #[cfg(feature = "runtime-benchmarks")]
1402 type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1403 type CursorMaxLen = ConstU32<65_536>;
1404 type IdentifierMaxLen = ConstU32<256>;
1405 type MigrationStatusHandler = ();
1406 type FailedMigrationHandler = MaintenanceMode;
1407 type MaxServiceWeight = MaxServiceWeight;
1408 type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
1409}
1410
1411construct_runtime! {
1412 pub enum Runtime
1413 {
1414 System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>} = 0,
1415 Utility: pallet_utility::{Pallet, Call, Event} = 1,
1416 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2,
1417 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 3,
1418 Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>} = 4,
1419 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 6,
1421 TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Config<T>, Event<T>} = 7,
1422 ParachainInfo: parachain_info::{Pallet, Storage, Config<T>} = 8,
1423 EthereumChainId: pallet_evm_chain_id::{Pallet, Storage, Config<T>} = 9,
1424 EVM: pallet_evm::{Pallet, Config<T>, Call, Storage, Event<T>} = 10,
1425 Ethereum: pallet_ethereum::{Pallet, Call, Storage, Event, Origin, Config<T>} = 11,
1426 ParachainStaking: pallet_parachain_staking::{Pallet, Call, Storage, Event<T>, Config<T>, FreezeReason} = 12,
1427 Scheduler: pallet_scheduler::{Pallet, Storage, Event<T>, Call} = 13,
1428 Treasury: pallet_treasury::{Pallet, Storage, Config<T>, Event<T>, Call} = 17,
1432 AuthorInherent: pallet_author_inherent::{Pallet, Call, Storage, Inherent} = 18,
1433 AuthorFilter: pallet_author_slot_filter::{Pallet, Call, Storage, Event, Config<T>} = 19,
1434 CrowdloanRewards: pallet_crowdloan_rewards::{Pallet, Call, Config<T>, Storage, Event<T>} = 20,
1435 AuthorMapping: pallet_author_mapping::{Pallet, Call, Config<T>, Storage, Event<T>} = 21,
1436 Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 22,
1437 MaintenanceMode: pallet_maintenance_mode::{Pallet, Call, Config<T>, Storage, Event} = 23,
1438 Identity: pallet_identity::{Pallet, Call, Storage, Event<T>} = 24,
1439 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 25,
1440 CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 26,
1441 PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 28,
1443 XcmTransactor: pallet_xcm_transactor::{Pallet, Call, Config<T>, Storage, Event<T>} = 33,
1448 ProxyGenesisCompanion: pallet_proxy_genesis_companion::{Pallet, Config<T>} = 34,
1449 MoonbeamOrbiters: pallet_moonbeam_orbiters::{Pallet, Call, Storage, Event<T>, Config<T>} = 37,
1452 EthereumXcm: pallet_ethereum_xcm::{Pallet, Call, Storage, Origin, Event<T>} = 38,
1453 Randomness: pallet_randomness::{Pallet, Call, Storage, Event<T>, Inherent} = 39,
1454 TreasuryCouncilCollective:
1455 pallet_collective::<Instance3>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 40,
1456 ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 41,
1457 Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 42,
1458 Origins: governance::custom_origins::{Origin} = 43,
1459 Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>, HoldReason} = 44,
1460 Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 45,
1461 OpenTechCommitteeCollective:
1462 pallet_collective::<Instance4>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 46,
1463 RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event<T>} = 47,
1464 Erc20XcmBridge: pallet_erc20_xcm_bridge::{Pallet} = 48,
1465 Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 49,
1466 AsyncBacking: pallet_async_backing::{Pallet, Storage} = 50,
1467 MoonbeamLazyMigrations: pallet_moonbeam_lazy_migrations::{Pallet, Call, Storage} = 51,
1468 RelayStorageRoots: pallet_relay_storage_roots::{Pallet, Storage} = 52,
1469
1470 #[cfg(feature = "runtime-benchmarks")]
1471 PrecompileBenchmarks: pallet_precompile_benchmarks::{Pallet} = 53,
1472
1473 MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 54,
1474 EmergencyParaXcm: pallet_emergency_para_xcm::{Pallet, Call, Storage, Event} = 55,
1475 EvmForeignAssets: pallet_moonbeam_foreign_assets::{Pallet, Call, Storage, Event<T>} = 56,
1476 Parameters: pallet_parameters = 57,
1477 XcmWeightTrader: pallet_xcm_weight_trader::{Pallet, Call, Storage, Event<T>} = 58,
1478 MultiBlockMigrations: pallet_migrations = 117,
1479 WeightReclaim: cumulus_pallet_weight_reclaim = 118,
1480 }
1481}
1482
1483pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1485pub type SignedBlock = generic::SignedBlock<Block>;
1487pub type BlockId = generic::BlockId<Block>;
1489
1490pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
1492 Runtime,
1493 (
1494 frame_system::CheckNonZeroSender<Runtime>,
1495 frame_system::CheckSpecVersion<Runtime>,
1496 frame_system::CheckTxVersion<Runtime>,
1497 frame_system::CheckGenesis<Runtime>,
1498 frame_system::CheckEra<Runtime>,
1499 frame_system::CheckNonce<Runtime>,
1500 frame_system::CheckWeight<Runtime>,
1501 pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1502 frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1503 ),
1504>;
1505
1506pub type UncheckedExtrinsic =
1508 fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
1509pub type CheckedExtrinsic =
1511 fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension, H160>;
1512pub type Executive = frame_executive::Executive<
1514 Runtime,
1515 Block,
1516 frame_system::ChainContext<Runtime>,
1517 Runtime,
1518 AllPalletsWithSystem,
1519>;
1520
1521#[cfg(feature = "runtime-benchmarks")]
1522use moonbeam_runtime_common::benchmarking::BenchmarkHelper;
1523use moonbeam_runtime_common::deal_with_fees::{
1524 DealWithEthereumBaseFees, DealWithEthereumPriorityFees, DealWithSubstrateFeesAndTip,
1525};
1526
1527#[cfg(feature = "runtime-benchmarks")]
1528mod benches {
1529 frame_support::parameter_types! {
1530 pub const MaxBalance: crate::Balance = crate::Balance::max_value();
1531 }
1532
1533 frame_benchmarking::define_benchmarks!(
1534 [frame_system, SystemBench::<Runtime>]
1535 [frame_system_extensions, frame_system_benchmarking::extensions::Pallet::<Runtime>]
1536 [pallet_utility, Utility]
1537 [pallet_timestamp, Timestamp]
1538 [pallet_balances, Balances]
1539 [pallet_sudo, Sudo]
1540 [pallet_evm, EVM]
1541 [pallet_parachain_staking, ParachainStaking]
1542 [pallet_scheduler, Scheduler]
1543 [pallet_treasury, Treasury]
1544 [pallet_author_inherent, AuthorInherent]
1545 [pallet_author_slot_filter, AuthorFilter]
1546 [pallet_crowdloan_rewards, CrowdloanRewards]
1547 [pallet_author_mapping, AuthorMapping]
1548 [pallet_proxy, Proxy]
1549 [pallet_transaction_payment, TransactionPaymentBenchmark::<Runtime>]
1550 [pallet_identity, Identity]
1551 [cumulus_pallet_parachain_system, ParachainSystem]
1552 [cumulus_pallet_xcmp_queue, XcmpQueue]
1553 [pallet_message_queue, MessageQueue]
1554 [pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1555 [pallet_xcm_transactor, XcmTransactor]
1556 [pallet_moonbeam_foreign_assets, EvmForeignAssets]
1557 [pallet_moonbeam_orbiters, MoonbeamOrbiters]
1558 [pallet_randomness, Randomness]
1559 [pallet_conviction_voting, ConvictionVoting]
1560 [pallet_referenda, Referenda]
1561 [pallet_preimage, Preimage]
1562 [pallet_whitelist, Whitelist]
1563 [pallet_multisig, Multisig]
1564 [pallet_migrations, MultiBlockMigrations]
1565 [pallet_relay_storage_roots, RelayStorageRoots]
1568 [pallet_precompile_benchmarks, PrecompileBenchmarks]
1569 [pallet_parameters, Parameters]
1570 [pallet_xcm_weight_trader, XcmWeightTrader]
1571 [pallet_collective, TreasuryCouncilCollective]
1572 [pallet_collective, OpenTechCommitteeCollective]
1573 [cumulus_pallet_weight_reclaim, WeightReclaim]
1574 );
1575}
1576
1577moonbeam_runtime_common::impl_runtime_apis_plus_common!(
1588 {
1589 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1590 fn validate_transaction(
1591 source: TransactionSource,
1592 xt: <Block as BlockT>::Extrinsic,
1593 block_hash: <Block as BlockT>::Hash,
1594 ) -> TransactionValidity {
1595 if !<Runtime as frame_system::Config>::BaseCallFilter::contains(&xt.0.function) {
1598 return InvalidTransaction::Call.into();
1599 }
1600
1601 let mut intermediate_valid = Executive::validate_transaction(source, xt.clone(), block_hash)?;
1616
1617 let dispatch_info = xt.get_dispatch_info();
1618
1619 Ok(match &xt.0.function {
1625 RuntimeCall::Ethereum(transact { .. }) => intermediate_valid,
1626 _ if dispatch_info.class != DispatchClass::Normal => intermediate_valid,
1627 _ => {
1628 let tip = match &xt.0.preamble {
1629 Preamble::Bare(_) => 0,
1630 Preamble::Signed(_, _, signed_extra) => {
1631 let charge_transaction_payment = &signed_extra.0.7;
1633 charge_transaction_payment.tip()
1634 },
1635 Preamble::General(_, _) => 0,
1636 };
1637
1638 let effective_gas =
1639 <Runtime as pallet_evm::Config>::GasWeightMapping::weight_to_gas(
1640 dispatch_info.total_weight()
1641 );
1642 let tip_per_gas = if effective_gas > 0 {
1643 tip.saturating_div(effective_gas as u128)
1644 } else {
1645 0
1646 };
1647
1648 intermediate_valid.priority = tip_per_gas as u64;
1650 intermediate_valid
1651 }
1652 })
1653 }
1654 }
1655
1656 impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
1657 fn can_build_upon(
1658 included_hash: <Block as BlockT>::Hash,
1659 slot: async_backing_primitives::Slot,
1660 ) -> bool {
1661 ConsensusHook::can_build_upon(included_hash, slot)
1662 }
1663 }
1664
1665 }
1666
1667 {}
1669);
1670
1671cumulus_pallet_parachain_system::register_validate_block!(
1673 Runtime = Runtime,
1674 BlockExecutor = pallet_author_inherent::BlockExecutor::<Runtime, Executive>,
1675);
1676
1677moonbeam_runtime_common::impl_self_contained_call!();
1678
1679#[macro_export]
1681macro_rules! get {
1682 ($pallet:ident, $name:ident, $type:ty) => {
1683 <<$crate::Runtime as $pallet::Config>::$name as $crate::Get<$type>>::get()
1684 };
1685}
1686
1687#[cfg(test)]
1688mod tests {
1689 use super::{currency::*, *};
1690
1691 #[test]
1692 fn call_max_size() {
1696 const CALL_ALIGN: u32 = 1024;
1697 assert!(std::mem::size_of::<pallet_evm_chain_id::Call<Runtime>>() <= CALL_ALIGN as usize);
1698 assert!(std::mem::size_of::<pallet_evm::Call<Runtime>>() <= CALL_ALIGN as usize);
1699 assert!(std::mem::size_of::<pallet_ethereum::Call<Runtime>>() <= CALL_ALIGN as usize);
1700 assert!(
1701 std::mem::size_of::<pallet_parachain_staking::Call<Runtime>>() <= CALL_ALIGN as usize
1702 );
1703 assert!(
1704 std::mem::size_of::<pallet_author_inherent::Call<Runtime>>() <= CALL_ALIGN as usize
1705 );
1706 assert!(
1707 std::mem::size_of::<pallet_author_slot_filter::Call<Runtime>>() <= CALL_ALIGN as usize
1708 );
1709 assert!(
1710 std::mem::size_of::<pallet_crowdloan_rewards::Call<Runtime>>() <= CALL_ALIGN as usize
1711 );
1712 assert!(std::mem::size_of::<pallet_author_mapping::Call<Runtime>>() <= CALL_ALIGN as usize);
1713 assert!(
1714 std::mem::size_of::<pallet_maintenance_mode::Call<Runtime>>() <= CALL_ALIGN as usize
1715 );
1716 assert!(std::mem::size_of::<pallet_migrations::Call<Runtime>>() <= CALL_ALIGN as usize);
1717 assert!(
1718 std::mem::size_of::<pallet_moonbeam_lazy_migrations::Call<Runtime>>()
1719 <= CALL_ALIGN as usize
1720 );
1721 assert!(std::mem::size_of::<pallet_xcm_transactor::Call<Runtime>>() <= CALL_ALIGN as usize);
1722 assert!(
1723 std::mem::size_of::<pallet_proxy_genesis_companion::Call<Runtime>>()
1724 <= CALL_ALIGN as usize
1725 );
1726 }
1727
1728 #[test]
1729 fn currency_constants_are_correct() {
1730 assert_eq!(SUPPLY_FACTOR, 1);
1731
1732 assert_eq!(TRANSACTION_BYTE_FEE, Balance::from(1 * GIGAWEI));
1734 assert_eq!(
1735 get!(pallet_transaction_payment, OperationalFeeMultiplier, u8),
1736 5_u8
1737 );
1738 assert_eq!(STORAGE_BYTE_FEE, Balance::from(100 * MICROUNIT));
1739
1740 assert_eq!(
1742 get!(pallet_identity, BasicDeposit, u128),
1743 Balance::from(1 * UNIT + 25800 * MICROUNIT)
1744 );
1745 assert_eq!(
1746 get!(pallet_identity, ByteDeposit, u128),
1747 Balance::from(100 * MICROUNIT)
1748 );
1749 assert_eq!(
1750 get!(pallet_identity, SubAccountDeposit, u128),
1751 Balance::from(1 * UNIT + 5300 * MICROUNIT)
1752 );
1753
1754 assert_eq!(
1756 get!(pallet_parachain_staking, MinCandidateStk, u128),
1757 Balance::from(500 * UNIT)
1758 );
1759 assert_eq!(
1760 get!(pallet_parachain_staking, MinDelegation, u128),
1761 Balance::from(1 * UNIT)
1762 );
1763
1764 assert_eq!(
1766 get!(pallet_crowdloan_rewards, MinimumReward, u128),
1767 Balance::from(0u128)
1768 );
1769
1770 assert_eq!(
1772 get!(pallet_author_mapping, DepositAmount, u128),
1773 Balance::from(100 * UNIT)
1774 );
1775
1776 assert_eq!(
1778 get!(pallet_proxy, ProxyDepositBase, u128),
1779 Balance::from(1 * UNIT + 800 * MICROUNIT)
1780 );
1781 assert_eq!(
1782 get!(pallet_proxy, ProxyDepositFactor, u128),
1783 Balance::from(2100 * MICROUNIT)
1784 );
1785 assert_eq!(
1786 get!(pallet_proxy, AnnouncementDepositBase, u128),
1787 Balance::from(1 * UNIT + 800 * MICROUNIT)
1788 );
1789 assert_eq!(
1790 get!(pallet_proxy, AnnouncementDepositFactor, u128),
1791 Balance::from(5600 * MICROUNIT)
1792 );
1793 }
1794
1795 #[test]
1796 fn max_offline_rounds_lower_or_eq_than_reward_payment_delay() {
1797 assert!(
1798 get!(pallet_parachain_staking, MaxOfflineRounds, u32)
1799 <= get!(pallet_parachain_staking, RewardPaymentDelay, u32)
1800 );
1801 }
1802
1803 #[test]
1804 fn updating_maximum_delegators_per_candidate_requires_configuring_required_migration() {
1808 assert_eq!(
1809 get!(pallet_parachain_staking, MaxTopDelegationsPerCandidate, u32),
1810 300
1811 );
1812 assert_eq!(
1813 get!(
1814 pallet_parachain_staking,
1815 MaxBottomDelegationsPerCandidate,
1816 u32
1817 ),
1818 50
1819 );
1820 }
1821
1822 #[test]
1823 fn test_proxy_type_can_be_decoded_from_valid_values() {
1824 let test_cases = vec![
1825 (0u8, ProxyType::Any),
1827 (1, ProxyType::NonTransfer),
1828 (2, ProxyType::Governance),
1829 (3, ProxyType::Staking),
1830 (4, ProxyType::CancelProxy),
1831 (5, ProxyType::Balances),
1832 (6, ProxyType::AuthorMapping),
1833 (7, ProxyType::IdentityJudgement),
1834 ];
1835
1836 for (input, expected) in test_cases {
1837 let actual = ProxyType::decode(&mut input.to_le_bytes().as_slice());
1838 assert_eq!(
1839 Ok(expected),
1840 actual,
1841 "failed decoding ProxyType for value '{}'",
1842 input
1843 );
1844 }
1845 }
1846
1847 #[test]
1848 fn configured_base_extrinsic_weight_is_evm_compatible() {
1849 let min_ethereum_transaction_weight = WeightPerGas::get() * 21_000;
1850 let base_extrinsic = <Runtime as frame_system::Config>::BlockWeights::get()
1851 .get(frame_support::dispatch::DispatchClass::Normal)
1852 .base_extrinsic;
1853 assert!(base_extrinsic.ref_time() <= min_ethereum_transaction_weight.ref_time());
1854 }
1855
1856 #[test]
1857 fn test_storage_growth_ratio_is_correct() {
1858 let expected_storage_growth_ratio = BlockGasLimit::get()
1859 .low_u64()
1860 .saturating_div(BLOCK_STORAGE_LIMIT);
1861 let actual_storage_growth_ratio =
1862 <Runtime as pallet_evm::Config>::GasLimitStorageGrowthRatio::get();
1863 assert_eq!(
1864 expected_storage_growth_ratio, actual_storage_growth_ratio,
1865 "Storage growth ratio is not correct"
1866 );
1867 }
1868}