diff --git a/evm-template/node/src/service.rs b/evm-template/node/src/service.rs index c175db8..490c2cb 100644 --- a/evm-template/node/src/service.rs +++ b/evm-template/node/src/service.rs @@ -21,8 +21,9 @@ use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; // Local Runtime Types use parachain_template_runtime::{ + apis::RuntimeApi, + configs::TransactionConverter, opaque::{Block, Hash}, - RuntimeApi, TransactionConverter, }; use sc_client_api::Backend; use sc_consensus::ImportQueue; @@ -48,7 +49,7 @@ impl sc_executor::NativeExecutionDispatch for ParachainNativeExecutor { type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; fn dispatch(method: &str, data: &[u8]) -> Option> { - parachain_template_runtime::api::dispatch(method, data) + parachain_template_runtime::apis::api::dispatch(method, data) } fn native_version() -> sc_executor::NativeVersion { @@ -503,7 +504,6 @@ fn start_consensus( // NOTE: because we use Aura here explicitly, we can use // `CollatorSybilResistance::Resistant` when starting the network. - #[cfg(not(feature = "async-backing"))] let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; diff --git a/evm-template/runtime/src/apis.rs b/evm-template/runtime/src/apis.rs new file mode 100644 index 0000000..df3dc62 --- /dev/null +++ b/evm-template/runtime/src/apis.rs @@ -0,0 +1,471 @@ +use frame_support::{ + genesis_builder_helper::{build_config, create_default_config}, + traits::OnFinalize, + weights::Weight, +}; +use pallet_ethereum::{ + Call::transact, Transaction as EthereumTransaction, TransactionAction, TransactionData, + TransactionStatus, +}; +use pallet_evm::{Account as EVMAccount, FeeCalculator, Runner}; +use sp_api::impl_runtime_apis; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160, H256, U256}; +use sp_runtime::{ + traits::{Block as BlockT, Get, UniqueSaturatedInto}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, Permill, +}; +use sp_std::prelude::Vec; +use sp_version::RuntimeVersion; + +#[cfg(not(feature = "async-backing"))] +use crate::Aura; +#[cfg(feature = "async-backing")] +use crate::{constants::SLOT_DURATION, types::ConsensusHook}; +use crate::{ + constants::VERSION, + types::{AccountId, Balance, Block, Executive, Nonce}, + Ethereum, InherentDataExt, ParachainSystem, Runtime, RuntimeCall, RuntimeGenesisConfig, + SessionKeys, System, TransactionPayment, UncheckedExtrinsic, +}; + +impl_runtime_apis! { + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + #[cfg(feature = "async-backing")] + return sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION); + #[cfg(not(feature = "async-backing"))] + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + pallet_aura::Authorities::::get().into_inner() + } + } + + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl fp_rpc::EthereumRuntimeRPCApi for Runtime { + fn chain_id() -> u64 { + ::ChainId::get() + } + + fn account_basic(address: H160) -> EVMAccount { + let (account, _) = pallet_evm::Pallet::::account_basic(&address); + account + } + + fn gas_price() -> U256 { + let (gas_price, _) = ::FeeCalculator::min_gas_price(); + gas_price + } + + fn account_code_at(address: H160) -> Vec { + pallet_evm::AccountCodes::::get(address) + } + + fn author() -> H160 { + >::find_author() + } + + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + pallet_evm::AccountStorages::::get(address, H256::from_slice(&tmp[..])) + } + + fn call( + from: H160, + to: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let gas_limit = gas_limit.min(u64::MAX.into()); + let transaction_data = TransactionData::new( + TransactionAction::Call(to), + data.clone(), + nonce.unwrap_or_default(), + gas_limit, + None, + max_fee_per_gas, + max_priority_fee_per_gas, + value, + Some(::ChainId::get()), + access_list.clone().unwrap_or_default(), + ); + let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); + + ::Runner::call( + from, + to, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + false, + true, + weight_limit, + proof_size_base_cost, + config.as_ref().unwrap_or(::config()), + ).map_err(|err| err.error.into()) + } + + fn create( + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let transaction_data = TransactionData::new( + TransactionAction::Create, + data.clone(), + nonce.unwrap_or_default(), + gas_limit, + None, + max_fee_per_gas, + max_priority_fee_per_gas, + value, + Some(::ChainId::get()), + access_list.clone().unwrap_or_default(), + ); + let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); + + ::Runner::create( + from, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + false, + true, + weight_limit, + proof_size_base_cost, + config.as_ref().unwrap_or(::config()), + ).map_err(|err| err.error.into()) + } + + fn current_transaction_statuses() -> Option> { + pallet_ethereum::CurrentTransactionStatuses::::get() + } + + fn current_block() -> Option { + pallet_ethereum::CurrentBlock::::get() + } + + fn current_receipts() -> Option> { + pallet_ethereum::CurrentReceipts::::get() + } + + fn current_all() -> ( + Option, + Option>, + Option> + ) { + ( + pallet_ethereum::CurrentBlock::::get(), + pallet_ethereum::CurrentReceipts::::get(), + pallet_ethereum::CurrentTransactionStatuses::::get() + ) + } + + fn extrinsic_filter( + xts: Vec<::Extrinsic>, + ) -> Vec { + xts.into_iter().filter_map(|xt| match xt.0.function { + RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), + _ => None + }).collect::>() + } + + fn elasticity() -> Option { + Some(pallet_base_fee::Elasticity::::get()) + } + + fn gas_limit_multiplier_support() {} + + fn pending_block( + xts: Vec<::Extrinsic>, + ) -> (Option, Option>) { + for ext in xts.into_iter() { + let _ = Executive::apply_extrinsic(ext); + } + + Ethereum::on_finalize(System::block_number() + 1); + + ( + pallet_ethereum::CurrentBlock::::get(), + pallet_ethereum::CurrentTransactionStatuses::::get() + ) + } + } + + impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { + fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } + } + + + + impl cumulus_primitives_core::CollectCollationInfo for Runtime { + fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info(header) + } + } + + #[cfg(feature = "async-backing")] + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot + ) -> bool { + ConsensusHook::can_build_upon(included_hash, slot) + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + use super::configs::RuntimeBlockWeights; + + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, RuntimeBlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + use frame_system_benchmarking::Pallet as SystemBench; + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + + use super::*; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; + use frame_system_benchmarking::Pallet as SystemBench; + + use super::*; + + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } + + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + impl cumulus_pallet_session_benchmarking::Config for Runtime {} + + use frame_support::traits::WhitelistedStorageKeys; + let whitelist = AllPalletsWithSystem::whitelisted_storage_keys(); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + add_benchmarks!(params, batches); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } + + impl sp_genesis_builder::GenesisBuilder for Runtime { + fn create_default_config() -> Vec { + create_default_config::() + } + + fn build_config(config: Vec) -> sp_genesis_builder::Result { + build_config::(config) + } + } +} diff --git a/evm-template/runtime/src/benchmark.rs b/evm-template/runtime/src/benchmark.rs new file mode 100644 index 0000000..59d1822 --- /dev/null +++ b/evm-template/runtime/src/benchmark.rs @@ -0,0 +1,11 @@ +frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_assets, Assets] + [pallet_balances, Balances] + [pallet_session, SessionBench::] + [pallet_timestamp, Timestamp] + [pallet_message_queue, MessageQueue] + [pallet_sudo, Sudo] + [pallet_collator_selection, CollatorSelection] + [cumulus_pallet_xcmp_queue, XcmpQueue] +); diff --git a/evm-template/runtime/src/governance/mod.rs b/evm-template/runtime/src/configs/governance/mod.rs similarity index 83% rename from evm-template/runtime/src/governance/mod.rs rename to evm-template/runtime/src/configs/governance/mod.rs index cb7d758..743c325 100644 --- a/evm-template/runtime/src/governance/mod.rs +++ b/evm-template/runtime/src/configs/governance/mod.rs @@ -1,19 +1,23 @@ //! OpenGov governance config pub mod origins; -pub use origins::{ - pallet_custom_origins, ReferendumCanceller, ReferendumKiller, Spender, Treasurer, - WhitelistedCaller, -}; +pub use origins::{Spender, WhitelistedCaller}; mod tracks; -use frame_support::traits::EitherOf; -use frame_system::EnsureRootWithSuccess; +use frame_support::{ + parameter_types, + traits::{ConstU32, EitherOf}, +}; +use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned}; -use super::*; use crate::{ - constants::currency::{CENTS, GRAND}, - Balance, + constants::{ + currency::{CENTS, GRAND}, + DAYS, + }, + types::{AccountId, Balance, BlockNumber}, + Balances, Preimage, Referenda, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, + Treasury, }; parameter_types! { diff --git a/generic-template/runtime/src/governance/origins.rs b/evm-template/runtime/src/configs/governance/origins.rs similarity index 98% rename from generic-template/runtime/src/governance/origins.rs rename to evm-template/runtime/src/configs/governance/origins.rs index 1ea9c48..03b878c 100644 --- a/generic-template/runtime/src/governance/origins.rs +++ b/evm-template/runtime/src/configs/governance/origins.rs @@ -6,7 +6,7 @@ pub use pallet_custom_origins::*; pub mod pallet_custom_origins { use frame_support::pallet_prelude::*; - use crate::governance::{Balance, CENTS, GRAND}; + use crate::configs::governance::{Balance, CENTS, GRAND}; #[pallet::config] pub trait Config: frame_system::Config {} diff --git a/evm-template/runtime/src/governance/tracks.rs b/evm-template/runtime/src/configs/governance/tracks.rs similarity index 99% rename from evm-template/runtime/src/governance/tracks.rs rename to evm-template/runtime/src/configs/governance/tracks.rs index 5038407..3ec4b6e 100644 --- a/evm-template/runtime/src/governance/tracks.rs +++ b/evm-template/runtime/src/configs/governance/tracks.rs @@ -1,6 +1,7 @@ //! Track configurations for governance. use super::*; +use crate::constants::MINUTES; const fn percent(x: i32) -> sp_arithmetic::FixedI64 { sp_arithmetic::FixedI64::from_rational(x as u128, 100) diff --git a/evm-template/runtime/src/configs/mod.rs b/evm-template/runtime/src/configs/mod.rs new file mode 100644 index 0000000..82f54f5 --- /dev/null +++ b/evm-template/runtime/src/configs/mod.rs @@ -0,0 +1,706 @@ +pub mod governance; +pub mod xcm_config; + +#[cfg(feature = "async-backing")] +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; +#[cfg(not(feature = "async-backing"))] +use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; +use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; +use frame_support::{ + derive_impl, + dispatch::DispatchClass, + parameter_types, + traits::{ + AsEnsureOriginWithArg, ConstU32, ConstU64, Contains, EitherOfDiverse, FindAuthor, + InstanceFilter, TransformOrigin, + }, + weights::{ConstantMultiplier, Weight}, + PalletId, +}; +use frame_system::{ + limits::{BlockLength, BlockWeights}, + EnsureRoot, EnsureSigned, +}; +pub use governance::origins::pallet_custom_origins; +use governance::{origins::Treasurer, TreasurySpender}; +use pallet_ethereum::PostLogContent; +use pallet_evm::{EVMCurrencyAdapter, EnsureAccountId20, IdentityAddressMapping}; +use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use polkadot_runtime_common::{ + impls::{LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter}, + xcm_sender::NoPriceForMessageDelivery, + BlockHashCount, SlowAdjustingFeeUpdate, +}; +use scale_info::TypeInfo; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{H160, U256}; +use sp_runtime::{ + traits::{AccountIdLookup, BlakeTwo256, IdentityLookup}, + ConsensusEngineId, Perbill, Permill, RuntimeDebug, +}; +use sp_std::marker::PhantomData; +use sp_version::RuntimeVersion; +// XCM Imports +use xcm::{ + latest::{prelude::BodyId, InteriorLocation, Junction::PalletInstance}, + VersionedLocation, +}; +use xcm_builder::PayOverXcm; +#[cfg(not(feature = "runtime-benchmarks"))] +use xcm_builder::ProcessXcmMessage; +use xcm_config::XcmOriginToTransactDispatchOrigin; + +use crate::{ + constants::{ + currency::{deposit, CENTS, EXISTENTIAL_DEPOSIT, MICROCENTS, MILLICENTS}, + AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, MAX_BLOCK_LENGTH, + MAX_POV_SIZE, NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION, WEIGHT_PER_GAS, + }, + opaque, + types::{ + AccountId, Balance, Block, BlockNumber, CollatorSelectionUpdateOrigin, ConsensusHook, Hash, + Nonce, + }, + weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}, + Aura, Balances, BaseFee, CollatorSelection, EVMChainId, MessageQueue, OriginCaller, PalletInfo, + ParachainSystem, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeFreezeReason, + RuntimeHoldReason, RuntimeOrigin, RuntimeTask, Session, SessionKeys, System, Timestamp, + Treasury, UncheckedExtrinsic, WeightToFee, XcmpQueue, +}; + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + + // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. + // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the + // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize + // the lazy contract deletion. + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + pub const SS58Prefix: u16 = 42; +} + +pub struct NormalFilter; +impl Contains for NormalFilter { + fn contains(c: &RuntimeCall) -> bool { + match c { + // We filter anonymous proxy as they make "reserve" inconsistent + // See: https://github.com/paritytech/substrate/blob/37cca710eed3dadd4ed5364c7686608f5175cce1/frame/proxy/src/lib.rs#L270 + RuntimeCall::Proxy(method) => !matches!( + method, + pallet_proxy::Call::create_pure { .. } | pallet_proxy::Call::kill_pure { .. } + ), + _ => true, + } + } +} + +/// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from +/// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), +/// but overridden as needed. +#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = NormalFilter; + /// The block type. + type Block = Block; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The lookup mechanism to get account ID from whatever is passed in + /// dispatchers. + type Lookup = AccountIdLookup; + /// The maximum number of consumers allowed on a single account. + type MaxConsumers = ConstU32<16>; + /// The index type for storing how many extrinsics an account has signed. + type Nonce = Nonce; + /// The action to take on a Runtime Upgrade + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// Converts a module to an index of this module in the runtime. + type PalletInfo = PalletInfo; + /// The aggregated dispatch type that is available for extrinsics. + type RuntimeCall = RuntimeCall; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + /// The ubiquitous origin type. + type RuntimeOrigin = RuntimeOrigin; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Runtime version. + type Version = Version; +} + +parameter_types! { + pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) * + RuntimeBlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Runtime { + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type MaximumWeight = MaximumSchedulerWeight; + type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; + type Preimages = Preimage; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; +} + +parameter_types! { + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); + pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); +} + +impl pallet_preimage::Config for Runtime { + type Consideration = frame_support::traits::fungible::HoldConsideration< + AccountId, + Balances, + PreimageHoldReason, + frame_support::traits::LinearStoragePrice< + PreimageBaseDeposit, + PreimageByteDeposit, + Balance, + >, + >; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_preimage::weights::SubstrateWeight; +} + +impl pallet_timestamp::Config for Runtime { + #[cfg(feature = "experimental")] + type MinimumPeriod = ConstU64<0>; + #[cfg(not(feature = "experimental"))] + type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = Aura; + type WeightInfo = pallet_timestamp::weights::SubstrateWeight; +} + +impl pallet_authorship::Config for Runtime { + type EventHandler = (CollatorSelection,); + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; +} + +parameter_types! { + pub const MaxProxies: u32 = 32; + pub const MaxPending: u32 = 32; + pub const ProxyDepositBase: Balance = deposit(1, 40); + pub const AnnouncementDepositBase: Balance = deposit(1, 48); + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); +} + +/// The type used to represent the kinds of proxying allowed. +/// If you are adding new pallets, consider adding new ProxyType variant +#[derive( + Copy, + Clone, + Decode, + Default, + Encode, + Eq, + MaxEncodedLen, + Ord, + PartialEq, + PartialOrd, + RuntimeDebug, + TypeInfo, +)] +pub enum ProxyType { + /// Allows to proxy all calls + #[default] + Any, + /// Allows all non-transfer calls + NonTransfer, + /// Allows to finish the proxy + CancelProxy, + /// Allows to operate with collators list (invulnerables, candidates, etc.) + Collator, +} + +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances { .. }), + ProxyType::CancelProxy => matches!( + c, + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) + | RuntimeCall::Multisig { .. } + ), + ProxyType::Collator => { + matches!(c, RuntimeCall::CollatorSelection { .. } | RuntimeCall::Multisig { .. }) + } + } + } +} + +impl pallet_proxy::Config for Runtime { + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; + type CallHasher = BlakeTwo256; + type Currency = Balances; + type MaxPending = MaxPending; + type MaxProxies = MaxProxies; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type ProxyType = ProxyType; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_proxy::weights::SubstrateWeight; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxFreezes: u32 = 0; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type AccountStore = System; + /// The type for recording an account's balance. + type Balance = Balance; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type FreezeIdentifier = (); + type MaxFreezes = MaxFreezes; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + type RuntimeFreezeReason = RuntimeFreezeReason; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +parameter_types! { + pub const AssetDeposit: Balance = 10 * CENTS; + pub const AssetAccountDeposit: Balance = deposit(1, 16); + pub const ApprovalDeposit: Balance = MILLICENTS; + pub const StringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = deposit(1, 68); + pub const MetadataDepositPerByte: Balance = deposit(0, 1); + pub const RemoveItemsLimit: u32 = 1000; +} + +impl pallet_assets::Config for Runtime { + type ApprovalDeposit = ApprovalDeposit; + type AssetAccountDeposit = AssetAccountDeposit; + type AssetDeposit = AssetDeposit; + type AssetId = u32; + type AssetIdParameter = parity_scale_codec::Compact; + type Balance = Balance; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + type CallbackHandle = (); + type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type Extra = (); + type ForceOrigin = EnsureRoot; + type Freezer = (); + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type RemoveItemsLimit = RemoveItemsLimit; + type RuntimeEvent = RuntimeEvent; + type StringLimit = StringLimit; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +parameter_types! { + /// Relay Chain `TransactionByteFee` / 10 + pub const TransactionByteFee: Balance = 10 * MICROCENTS; + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type LengthToFee = ConstantMultiplier; + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type RuntimeEvent = RuntimeEvent; + type WeightToFee = WeightToFee; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_sudo::weights::SubstrateWeight; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + #[cfg(not(feature = "async-backing"))] + type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; + #[cfg(feature = "async-backing")] + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; + type OnSystemEvent = (); + type OutboundXcmpMessageSource = XcmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type RuntimeEvent = RuntimeEvent; + type SelfParaId = parachain_info::Pallet; + type WeightInfo = cumulus_pallet_parachain_system::weights::SubstrateWeight; + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +parameter_types! { + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + pub const HeapSize: u32 = 64 * 1024; + pub const MaxStale: u32 = 8; +} + +impl pallet_message_queue::Config for Runtime { + type HeapSize = HeapSize; + type IdleMaxServiceWeight = MessageQueueServiceWeight; + type MaxStale = MaxStale; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< + cumulus_primitives_core::AggregateMessageOrigin, + >; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = ProcessXcmMessage< + AggregateMessageOrigin, + xcm_executor::XcmExecutor, + RuntimeCall, + >; + // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: + type QueueChangeHandler = NarrowOriginToSibling; + type QueuePausedQuery = NarrowOriginToSibling; + type RuntimeEvent = RuntimeEvent; + type ServiceWeight = MessageQueueServiceWeight; + type Size = u32; + type WeightInfo = pallet_message_queue::weights::SubstrateWeight; +} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +parameter_types! { + pub const MaxInboundSuspended: u32 = 1000; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type ChannelInfo = ParachainSystem; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; + type MaxInboundSuspended = MaxInboundSuspended; + type PriceForSiblingDelivery = NoPriceForMessageDelivery; + type RuntimeEvent = RuntimeEvent; + type VersionWrapper = (); + type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight; + // Enqueue XCMP messages from siblings for later processing. + type XcmpQueue = TransformOrigin; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u16 = 100; +} + +impl pallet_multisig::Config for Runtime { + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_multisig::weights::SubstrateWeight; +} + +parameter_types! { + pub const Period: u32 = 6 * HOURS; + pub const Offset: u32 = 0; +} + +impl pallet_session::Config for Runtime { + type Keys = SessionKeys; + type NextSessionRotation = pallet_session::PeriodicSessions; + type RuntimeEvent = RuntimeEvent; + // Essentially just Aura, but let's be pedantic. + type SessionHandler = ::KeyTypeIdProviders; + type SessionManager = CollatorSelection; + type ShouldEndSession = pallet_session::PeriodicSessions; + type ValidatorId = ::AccountId; + // we don't have stash and controller, thus we don't need the convert as well. + type ValidatorIdOf = pallet_collator_selection::IdentityCollator; + type WeightInfo = pallet_session::weights::SubstrateWeight; +} + +#[cfg(not(feature = "async-backing"))] +parameter_types! { + pub const AllowMultipleBlocksPerSlot: bool = false; + pub const MaxAuthorities: u32 = 100_000; +} + +#[cfg(feature = "async-backing")] +parameter_types! { + pub const AllowMultipleBlocksPerSlot: bool = true; + pub const MaxAuthorities: u32 = 100_000; +} + +impl pallet_aura::Config for Runtime { + type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot; + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; + #[cfg(feature = "async-backing")] + type SlotDuration = ConstU64; + #[cfg(not(feature = "async-backing"))] + type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; +} + +parameter_types! { + pub const PotId: PalletId = PalletId(*b"PotStake"); + pub const SessionLength: BlockNumber = 6 * HOURS; + // StakingAdmin pluralistic body. + pub const StakingAdminBodyId: BodyId = BodyId::Defense; +} + +parameter_types! { + pub const MaxCandidates: u32 = 100; + pub const MaxInvulnerables: u32 = 20; + pub const MinEligibleCollators: u32 = 4; +} + +impl pallet_collator_selection::Config for Runtime { + type Currency = Balances; + // should be a multiple of session or things will get inconsistent + type KickThreshold = Period; + type MaxCandidates = MaxCandidates; + type MaxInvulnerables = MaxInvulnerables; + type MinEligibleCollators = MinEligibleCollators; + type PotId = PotId; + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = CollatorSelectionUpdateOrigin; + type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_collator_selection::IdentityCollator; + type ValidatorRegistration = Session; + type WeightInfo = pallet_collator_selection::weights::SubstrateWeight; +} + +impl pallet_utility::Config for Runtime { + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_utility::weights::SubstrateWeight; +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 2000; // * CENTS + pub const ProposalBondMaximum: Balance = 1;// * GRAND; + pub const SpendPeriod: BlockNumber = 6 * DAYS; + pub const Burn: Permill = Permill::from_perthousand(2); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; + // The asset's interior location for the paying account. This is the Treasury + // pallet instance (which sits at index 13). + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(13).into(); + pub const MaxApprovals: u32 = 100; +} + +parameter_types! { + pub TreasuryAccount: AccountId = Treasury::account_id(); +} + +impl pallet_treasury::Config for Runtime { + type ApproveOrigin = EitherOfDiverse, Treasurer>; + type AssetKind = VersionedLocatableAsset; + type BalanceConverter = frame_support::traits::tokens::UnityAssetBalanceConversion; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments; + type Beneficiary = VersionedLocation; + type BeneficiaryLookup = IdentityLookup; + type Burn = (); + type BurnDestination = (); + type Currency = Balances; + type MaxApprovals = MaxApprovals; + type OnSlash = Treasury; + type PalletId = TreasuryPalletId; + type Paymaster = PayOverXcm< + TreasuryInteriorLocation, + xcm_config::XcmRouter, + crate::PolkadotXcm, + ConstU32<{ 6 * HOURS }>, + Self::Beneficiary, + Self::AssetKind, + LocatableAssetConverter, + VersionedLocationConverter, + >; + type PayoutPeriod = PayoutSpendPeriod; + type ProposalBond = ProposalBond; + type ProposalBondMaximum = ProposalBondMaximum; + type ProposalBondMinimum = ProposalBondMinimum; + type RejectOrigin = EitherOfDiverse, Treasurer>; + type RuntimeEvent = RuntimeEvent; + type SpendFunds = (); + type SpendOrigin = TreasurySpender; + type SpendPeriod = SpendPeriod; + type WeightInfo = pallet_treasury::weights::SubstrateWeight; +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for Runtime { + type ExtraDataLength = ConstU32<30>; + type PostLogContent = PostBlockAndTxnHashes; + type RuntimeEvent = RuntimeEvent; + type StateRoot = pallet_ethereum::IntermediateStateRoot; +} + +parameter_types! { + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); + pub GasLimitPovSizeRatio: u64 = BlockGasLimit::get().as_u64().saturating_div(MAX_POV_SIZE); + pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); + pub SuicideQuickClearLimit: u32 = 0; +} + +impl pallet_evm::Config for Runtime { + type AddressMapping = IdentityAddressMapping; + type BlockGasLimit = BlockGasLimit; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAccountId20; + type ChainId = EVMChainId; + type Currency = Balances; + type FeeCalculator = BaseFee; + type FindAuthor = FindAuthorSession; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type OnChargeTransaction = EVMCurrencyAdapter; + type OnCreate = (); + // FIXME: Will be implemented in #11 + type PrecompilesType = (); + // FIXME: Will be implemented in #11 + type PrecompilesValue = (); + type Runner = pallet_evm::runner::stack::Runner; + type RuntimeEvent = RuntimeEvent; + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type Timestamp = Timestamp; + // FIXME: run the benchmarks + type WeightInfo = pallet_evm::weights::SubstrateWeight; + type WeightPerGas = WeightPerGas; + type WithdrawOrigin = EnsureAccountId20; +} + +impl pallet_evm_chain_id::Config for Runtime {} + +parameter_types! { + /// Starting value for base fee. Set at the same value as in Ethereum. + pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000); + /// Default elasticity rate. Set at the same value as in Ethereum. + pub DefaultElasticity: Permill = Permill::from_parts(125_000); +} + +/// The thresholds based on which the base fee will change. +pub struct BaseFeeThreshold; +impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold { + fn lower() -> Permill { + Permill::zero() + } + + fn ideal() -> Permill { + Permill::from_parts(500_000) + } + + fn upper() -> Permill { + Permill::from_parts(1_000_000) + } +} +impl pallet_base_fee::Config for Runtime { + type DefaultBaseFeePerGas = DefaultBaseFeePerGas; + type DefaultElasticity = DefaultElasticity; + type RuntimeEvent = RuntimeEvent; + type Threshold = BaseFeeThreshold; +} + +pub struct FindAuthorSession(PhantomData); +impl> FindAuthor for FindAuthorSession { + fn find_author<'a, I>(digests: I) -> Option + where + I: 'a + IntoIterator, + { + if let Some(author_index) = F::find_author(digests) { + let account_id: AccountId = Session::validators()[author_index as usize]; + return Some(H160::from(account_id)); + } + None + } +} + +#[derive(Clone)] +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } +} diff --git a/evm-template/runtime/src/xcm_config.rs b/evm-template/runtime/src/configs/xcm_config.rs similarity index 97% rename from evm-template/runtime/src/xcm_config.rs rename to evm-template/runtime/src/configs/xcm_config.rs index 61335a7..2363591 100644 --- a/evm-template/runtime/src/xcm_config.rs +++ b/evm-template/runtime/src/configs/xcm_config.rs @@ -17,9 +17,13 @@ use xcm_builder::{ }; use xcm_executor::XcmExecutor; -use super::{ - AccountId, AllPalletsWithSystem, Assets, Balance, Balances, ParachainInfo, ParachainSystem, - PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, +use crate::{ + configs::{ + Balances, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, + XcmpQueue, + }, + types::{AccountId, Balance}, + AllPalletsWithSystem, Assets, ParachainInfo, PolkadotXcm, }; parameter_types! { diff --git a/evm-template/runtime/src/constants.rs b/evm-template/runtime/src/constants.rs index d522a24..e7808b8 100644 --- a/evm-template/runtime/src/constants.rs +++ b/evm-template/runtime/src/constants.rs @@ -1,5 +1,11 @@ +use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}; +use sp_runtime::{create_runtime_str, Perbill}; +use sp_version::RuntimeVersion; + +use crate::{apis, types::BlockNumber}; + pub mod currency { - use crate::Balance; + use crate::types::Balance; pub const MICROCENTS: Balance = 1_000_000; pub const MILLICENTS: Balance = 1_000_000_000; @@ -13,3 +19,85 @@ pub mod currency { items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS } } + +pub const P_FACTOR: u128 = 10; +pub const Q_FACTOR: u128 = 100; +pub const POLY_DEGREE: u8 = 1; + +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("template-parachain"), + impl_name: create_runtime_str!("template-parachain"), + authoring_version: 1, + spec_version: 1, + impl_version: 0, + apis: apis::RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, +}; + +/// This determines the average expected block time that we are targeting. +/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. +/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked +/// up by `pallet_aura` to implement `fn slot_duration()`. +/// +/// Change this to adjust the block time. +#[cfg(feature = "async-backing")] +pub const MILLISECS_PER_BLOCK: u64 = 6000; +#[cfg(not(feature = "async-backing"))] +pub const MILLISECS_PER_BLOCK: u64 = 12000; + +// NOTE: Currently it is not possible to change the slot duration after the +// chain has started. Attempting to do so will brick block production. +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +// Time is measured by number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +/// We assume that ~5% of the block weight is consumed by `on_initialize` +/// handlers. This is used to limit the maximal weight of a single extrinsic. +pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); + +/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be +/// used by `Operational` extrinsics. +pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); + +pub const WEIGHT_MILLISECS_PER_BLOCK: u64 = 2000; + +/// We allow for 0.5 of a second of compute with a 12 second average block time. +pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + #[cfg(feature = "async-backing")] + WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), + #[cfg(not(feature = "async-backing"))] + WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), + cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, +); + +/// Maximum number of blocks simultaneously accepted by the Runtime, not yet +/// included into the relay chain. +#[cfg(feature = "async-backing")] +pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; +#[cfg(not(feature = "async-backing"))] +pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; +/// How many parachain blocks are processed by the relay chain per parent. +/// Limits the number of blocks authored per slot. +pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; +/// Relay chain slot duration, in milliseconds. +pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000; +/// Maximum length for a block. +pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; + +pub const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +/// Current approximation of the gas/s consumption considering +/// EVM execution over compiled WASM (on 4.4Ghz CPU). +/// Given the 500ms Weight, from which 75% only are used for transactions, +/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. +/// With the async backing enabled the gas limit will rise 4 times because of execution time. +pub const GAS_PER_SECOND: u64 = 40_000_000; + +/// Approximate ratio of the amount of Weight per Gas. +/// u64 works for approximations because Weight is a very small unit compared to gas. +pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND; diff --git a/evm-template/runtime/src/lib.rs b/evm-template/runtime/src/lib.rs index 488f51f..743dcd8 100644 --- a/evm-template/runtime/src/lib.rs +++ b/evm-template/runtime/src/lib.rs @@ -6,140 +6,42 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +pub mod apis; +pub mod configs; pub mod constants; -pub mod governance; +mod types; mod weights; -pub mod xcm_config; -#[cfg(feature = "async-backing")] -use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; -#[cfg(not(feature = "async-backing"))] -use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; -use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; -use fp_account::EthereumSignature; use frame_support::{ - construct_runtime, derive_impl, - dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, - parameter_types, - traits::{ - AsEnsureOriginWithArg, ConstU32, ConstU64, Contains, EitherOfDiverse, FindAuthor, - InstanceFilter, OnFinalize, TransformOrigin, - }, - weights::{ - constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient, - WeightToFeeCoefficients, WeightToFeePolynomial, - }, - PalletId, + construct_runtime, + weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial}, }; -use frame_system::{ - limits::{BlockLength, BlockWeights}, - EnsureRoot, EnsureSigned, -}; -use governance::{ - origins::{pallet_custom_origins, Treasurer}, - TreasurySpender, -}; -use pallet_ethereum::{ - Call::transact, PostLogContent, Transaction as EthereumTransaction, TransactionAction, - TransactionData, TransactionStatus, -}; -use pallet_evm::{ - Account as EVMAccount, EVMCurrencyAdapter, EnsureAccountId20, FeeCalculator, - IdentityAddressMapping, Runner, -}; -use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; -use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use polkadot_runtime_common::{ - impls::{LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter}, - xcm_sender::NoPriceForMessageDelivery, - BlockHashCount, SlowAdjustingFeeUpdate, -}; -use scale_info::TypeInfo; use smallvec::smallvec; -use sp_api::impl_runtime_apis; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160, H256, U256}; +use sp_core::H160; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, Get, - IdentifyAccount, IdentityLookup, PostDispatchInfoOf, UniqueSaturatedInto, Verify, - }, - transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, - ApplyExtrinsicResult, ConsensusEngineId, RuntimeDebug, + impl_opaque_keys, + traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf}, + transaction_validity::{TransactionValidity, TransactionValidityError}, }; pub use sp_runtime::{MultiAddress, Perbill, Permill}; -use sp_std::{marker::PhantomData, prelude::*}; +use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -// XCM Imports -use xcm::{ - latest::{prelude::BodyId, InteriorLocation, Junction::PalletInstance}, - VersionedLocation, -}; -use xcm_builder::PayOverXcm; -#[cfg(not(feature = "runtime-benchmarks"))] -use xcm_builder::ProcessXcmMessage; use crate::{ - constants::currency::{deposit, CENTS, EXISTENTIAL_DEPOSIT, MICROCENTS, MILLICENTS}, - weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}, - xcm_config::{RelayLocation, XcmOriginToTransactDispatchOrigin}, + configs::pallet_custom_origins, + constants::{currency::MILLICENTS, POLY_DEGREE, P_FACTOR, Q_FACTOR}, + weights::ExtrinsicBaseWeight, +}; +pub use crate::{ + configs::RuntimeBlockWeights, + types::{ + AccountId, Balance, Block, BlockNumber, Executive, Nonce, Signature, UncheckedExtrinsic, + }, }; - -/// Ethereum Signature -pub type Signature = EthereumSignature; - -/// AccountId20 because 20 bytes long like H160 Ethereum Addresses -pub type AccountId = <::Signer as IdentifyAccount>::AccountId; - -/// Balance of an account. -pub type Balance = u128; - -/// Index of a transaction in the chain. -pub type Nonce = u32; - -/// A hash of some data used by the chain. -pub type Hash = sp_core::H256; - -/// An index to a block. -pub type BlockNumber = u32; - -/// The address format for describing accounts. -pub type Address = MultiAddress; - -/// Block header type as expected by this runtime. -pub type Header = generic::Header; - -/// Block type as expected by this runtime. -pub type Block = generic::Block; - -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; - -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; - -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); - -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = - fp_self_contained::UncheckedExtrinsic; impl fp_self_contained::SelfContainedCall for RuntimeCall { type SignedInfo = H160; @@ -197,15 +99,6 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { } } -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, ->; - /// Handles converting a weight scalar to a fee value, based on the scale and /// granularity of the node's balance type. /// @@ -220,10 +113,6 @@ pub type Executive = frame_executive::Executive< /// charged. pub struct WeightToFee; -pub const P_FACTOR: u128 = 10; -pub const Q_FACTOR: u128 = 100; -pub const POLY_DEGREE: u8 = 1; - impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; @@ -270,741 +159,15 @@ impl_opaque_keys! { } } -#[sp_version::runtime_version] -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("template-parachain"), - impl_name: create_runtime_str!("template-parachain"), - authoring_version: 1, - spec_version: 1, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 1, -}; - -/// This determines the average expected block time that we are targeting. -/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. -/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked -/// up by `pallet_aura` to implement `fn slot_duration()`. -/// -/// Change this to adjust the block time. -#[cfg(feature = "async-backing")] -pub const MILLISECS_PER_BLOCK: u64 = 6000; -#[cfg(not(feature = "async-backing"))] -pub const MILLISECS_PER_BLOCK: u64 = 12000; - -// NOTE: Currently it is not possible to change the slot duration after the -// chain has started. Attempting to do so will brick block production. -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -// Time is measured by number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -/// We assume that ~5% of the block weight is consumed by `on_initialize` -/// handlers. This is used to limit the maximal weight of a single extrinsic. -pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); - -/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be -/// used by `Operational` extrinsics. -pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); - -pub const WEIGHT_MILLISECS_PER_BLOCK: u64 = 2000; - -/// We allow for 0.5 of a second of compute with a 12 second average block time. -pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( - #[cfg(feature = "async-backing")] - WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), - #[cfg(not(feature = "async-backing"))] - WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), - cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, -); - -/// Maximum number of blocks simultaneously accepted by the Runtime, not yet -/// included into the relay chain. -#[cfg(feature = "async-backing")] -pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; -#[cfg(not(feature = "async-backing"))] -pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; -/// How many parachain blocks are processed by the relay chain per parent. -/// Limits the number of blocks authored per slot. -pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; -/// Relay chain slot duration, in milliseconds. -pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000; -/// Maximum length for a block. -pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; - /// The version information used to identify this runtime when compiled /// natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { + use crate::constants::VERSION; + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -parameter_types! { - pub const Version: RuntimeVersion = VERSION; - - // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. - // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the - // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize - // the lazy contract deletion. - pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); - pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() - .base_block(BlockExecutionWeight::get()) - .for_class(DispatchClass::all(), |weights| { - weights.base_extrinsic = ExtrinsicBaseWeight::get(); - }) - .for_class(DispatchClass::Normal, |weights| { - weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); - }) - .for_class(DispatchClass::Operational, |weights| { - weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); - // Operational transactions have some extra reserved space, so that they - // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. - weights.reserved = Some( - MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT - ); - }) - .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) - .build_or_panic(); - pub const SS58Prefix: u16 = 42; -} - -pub struct NormalFilter; -impl Contains for NormalFilter { - fn contains(c: &RuntimeCall) -> bool { - match c { - // We filter anonymous proxy as they make "reserve" inconsistent - // See: https://github.com/paritytech/substrate/blob/37cca710eed3dadd4ed5364c7686608f5175cce1/frame/proxy/src/lib.rs#L270 - RuntimeCall::Proxy(method) => !matches!( - method, - pallet_proxy::Call::create_pure { .. } | pallet_proxy::Call::kill_pure { .. } - ), - _ => true, - } - } -} - -/// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from -/// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), -/// but overridden as needed. -#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] -impl frame_system::Config for Runtime { - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = NormalFilter; - /// The block type. - type Block = Block; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// The maximum length of a block (in bytes). - type BlockLength = RuntimeBlockLength; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The lookup mechanism to get account ID from whatever is passed in - /// dispatchers. - type Lookup = AccountIdLookup; - /// The maximum number of consumers allowed on a single account. - type MaxConsumers = ConstU32<16>; - /// The index type for storing how many extrinsics an account has signed. - type Nonce = Nonce; - /// The action to take on a Runtime Upgrade - type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - /// Converts a module to an index of this module in the runtime. - type PalletInfo = PalletInfo; - /// The aggregated dispatch type that is available for extrinsics. - type RuntimeCall = RuntimeCall; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - /// The ubiquitous origin type. - type RuntimeOrigin = RuntimeOrigin; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// Runtime version. - type Version = Version; -} - -parameter_types! { - pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) * - RuntimeBlockWeights::get().max_block; - pub const MaxScheduledPerBlock: u32 = 50; - pub const NoPreimagePostponement: Option = Some(10); -} - -impl pallet_scheduler::Config for Runtime { - type MaxScheduledPerBlock = MaxScheduledPerBlock; - type MaximumWeight = MaximumSchedulerWeight; - type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; - type PalletsOrigin = OriginCaller; - type Preimages = Preimage; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type ScheduleOrigin = EnsureRoot; - type WeightInfo = pallet_scheduler::weights::SubstrateWeight; -} - -parameter_types! { - pub const PreimageBaseDeposit: Balance = deposit(2, 64); - pub const PreimageByteDeposit: Balance = deposit(0, 1); - pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); -} - -impl pallet_preimage::Config for Runtime { - type Consideration = frame_support::traits::fungible::HoldConsideration< - AccountId, - Balances, - PreimageHoldReason, - frame_support::traits::LinearStoragePrice< - PreimageBaseDeposit, - PreimageByteDeposit, - Balance, - >, - >; - type Currency = Balances; - type ManagerOrigin = EnsureRoot; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_preimage::weights::SubstrateWeight; -} - -impl pallet_timestamp::Config for Runtime { - #[cfg(feature = "experimental")] - type MinimumPeriod = ConstU64<0>; - #[cfg(not(feature = "experimental"))] - type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = Aura; - type WeightInfo = pallet_timestamp::weights::SubstrateWeight; -} - -impl pallet_authorship::Config for Runtime { - type EventHandler = (CollatorSelection,); - type FindAuthor = pallet_session::FindAccountFromAuthorIndex; -} - -parameter_types! { - pub const MaxProxies: u32 = 32; - pub const MaxPending: u32 = 32; - pub const ProxyDepositBase: Balance = deposit(1, 40); - pub const AnnouncementDepositBase: Balance = deposit(1, 48); - pub const ProxyDepositFactor: Balance = deposit(0, 33); - pub const AnnouncementDepositFactor: Balance = deposit(0, 66); -} - -/// The type used to represent the kinds of proxying allowed. -/// If you are adding new pallets, consider adding new ProxyType variant -#[derive( - Copy, - Clone, - Decode, - Default, - Encode, - Eq, - MaxEncodedLen, - Ord, - PartialEq, - PartialOrd, - RuntimeDebug, - TypeInfo, -)] -pub enum ProxyType { - /// Allows to proxy all calls - #[default] - Any, - /// Allows all non-transfer calls - NonTransfer, - /// Allows to finish the proxy - CancelProxy, - /// Allows to operate with collators list (invulnerables, candidates, etc.) - Collator, -} - -impl InstanceFilter for ProxyType { - fn filter(&self, c: &RuntimeCall) -> bool { - match self { - ProxyType::Any => true, - ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances { .. }), - ProxyType::CancelProxy => matches!( - c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) - | RuntimeCall::Multisig { .. } - ), - ProxyType::Collator => { - matches!(c, RuntimeCall::CollatorSelection { .. } | RuntimeCall::Multisig { .. }) - } - } - } -} - -impl pallet_proxy::Config for Runtime { - type AnnouncementDepositBase = AnnouncementDepositBase; - type AnnouncementDepositFactor = AnnouncementDepositFactor; - type CallHasher = BlakeTwo256; - type Currency = Balances; - type MaxPending = MaxPending; - type MaxProxies = MaxProxies; - type ProxyDepositBase = ProxyDepositBase; - type ProxyDepositFactor = ProxyDepositFactor; - type ProxyType = ProxyType; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_proxy::weights::SubstrateWeight; -} - -parameter_types! { - pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; - pub const MaxFreezes: u32 = 0; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type AccountStore = System; - /// The type for recording an account's balance. - type Balance = Balance; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type FreezeIdentifier = (); - type MaxFreezes = MaxFreezes; - type MaxLocks = MaxLocks; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - type RuntimeFreezeReason = RuntimeFreezeReason; - type RuntimeHoldReason = RuntimeHoldReason; - type WeightInfo = pallet_balances::weights::SubstrateWeight; -} - -parameter_types! { - pub const AssetDeposit: Balance = 10 * CENTS; - pub const AssetAccountDeposit: Balance = deposit(1, 16); - pub const ApprovalDeposit: Balance = MILLICENTS; - pub const StringLimit: u32 = 50; - pub const MetadataDepositBase: Balance = deposit(1, 68); - pub const MetadataDepositPerByte: Balance = deposit(0, 1); - pub const RemoveItemsLimit: u32 = 1000; -} - -impl pallet_assets::Config for Runtime { - type ApprovalDeposit = ApprovalDeposit; - type AssetAccountDeposit = AssetAccountDeposit; - type AssetDeposit = AssetDeposit; - type AssetId = u32; - type AssetIdParameter = parity_scale_codec::Compact; - type Balance = Balance; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); - type CallbackHandle = (); - type CreateOrigin = AsEnsureOriginWithArg>; - type Currency = Balances; - type Extra = (); - type ForceOrigin = EnsureRoot; - type Freezer = (); - type MetadataDepositBase = MetadataDepositBase; - type MetadataDepositPerByte = MetadataDepositPerByte; - type RemoveItemsLimit = RemoveItemsLimit; - type RuntimeEvent = RuntimeEvent; - type StringLimit = StringLimit; - type WeightInfo = pallet_assets::weights::SubstrateWeight; -} - -parameter_types! { - /// Relay Chain `TransactionByteFee` / 10 - pub const TransactionByteFee: Balance = 10 * MICROCENTS; - pub const OperationalFeeMultiplier: u8 = 5; -} - -impl pallet_transaction_payment::Config for Runtime { - type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type LengthToFee = ConstantMultiplier; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type OperationalFeeMultiplier = OperationalFeeMultiplier; - type RuntimeEvent = RuntimeEvent; - type WeightToFee = WeightToFee; -} - -impl pallet_sudo::Config for Runtime { - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_sudo::weights::SubstrateWeight; -} - -parameter_types! { - pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); - pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); - pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; -} - -type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< - Runtime, - RELAY_CHAIN_SLOT_DURATION_MILLIS, - BLOCK_PROCESSING_VELOCITY, - UNINCLUDED_SEGMENT_CAPACITY, ->; - -impl cumulus_pallet_parachain_system::Config for Runtime { - #[cfg(not(feature = "async-backing"))] - type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; - #[cfg(feature = "async-backing")] - type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; - type ConsensusHook = ConsensusHook; - type DmpQueue = frame_support::traits::EnqueueWithOrigin; - type OnSystemEvent = (); - type OutboundXcmpMessageSource = XcmpQueue; - type ReservedDmpWeight = ReservedDmpWeight; - type ReservedXcmpWeight = ReservedXcmpWeight; - type RuntimeEvent = RuntimeEvent; - type SelfParaId = parachain_info::Pallet; - type WeightInfo = cumulus_pallet_parachain_system::weights::SubstrateWeight; - type XcmpMessageHandler = XcmpQueue; -} - -impl parachain_info::Config for Runtime {} - -parameter_types! { - pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; - pub const HeapSize: u32 = 64 * 1024; - pub const MaxStale: u32 = 8; -} - -impl pallet_message_queue::Config for Runtime { - type HeapSize = HeapSize; - type IdleMaxServiceWeight = MessageQueueServiceWeight; - type MaxStale = MaxStale; - #[cfg(feature = "runtime-benchmarks")] - type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< - cumulus_primitives_core::AggregateMessageOrigin, - >; - #[cfg(not(feature = "runtime-benchmarks"))] - type MessageProcessor = ProcessXcmMessage< - AggregateMessageOrigin, - xcm_executor::XcmExecutor, - RuntimeCall, - >; - // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: - type QueueChangeHandler = NarrowOriginToSibling; - type QueuePausedQuery = NarrowOriginToSibling; - type RuntimeEvent = RuntimeEvent; - type ServiceWeight = MessageQueueServiceWeight; - type Size = u32; - type WeightInfo = pallet_message_queue::weights::SubstrateWeight; -} - -impl cumulus_pallet_aura_ext::Config for Runtime {} - -parameter_types! { - pub const MaxInboundSuspended: u32 = 1000; -} - -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type ChannelInfo = ParachainSystem; - type ControllerOrigin = EnsureRoot; - type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; - type MaxInboundSuspended = MaxInboundSuspended; - type PriceForSiblingDelivery = NoPriceForMessageDelivery; - type RuntimeEvent = RuntimeEvent; - type VersionWrapper = (); - type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight; - // Enqueue XCMP messages from siblings for later processing. - type XcmpQueue = TransformOrigin; -} - -parameter_types! { - // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. - pub const DepositBase: Balance = deposit(1, 88); - // Additional storage item size of 32 bytes. - pub const DepositFactor: Balance = deposit(0, 32); - pub const MaxSignatories: u16 = 100; -} - -impl pallet_multisig::Config for Runtime { - type Currency = Balances; - type DepositBase = DepositBase; - type DepositFactor = DepositFactor; - type MaxSignatories = MaxSignatories; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_multisig::weights::SubstrateWeight; -} - -parameter_types! { - pub const Period: u32 = 6 * HOURS; - pub const Offset: u32 = 0; -} - -impl pallet_session::Config for Runtime { - type Keys = SessionKeys; - type NextSessionRotation = pallet_session::PeriodicSessions; - type RuntimeEvent = RuntimeEvent; - // Essentially just Aura, but let's be pedantic. - type SessionHandler = ::KeyTypeIdProviders; - type SessionManager = CollatorSelection; - type ShouldEndSession = pallet_session::PeriodicSessions; - type ValidatorId = ::AccountId; - // we don't have stash and controller, thus we don't need the convert as well. - type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type WeightInfo = pallet_session::weights::SubstrateWeight; -} - -#[cfg(not(feature = "async-backing"))] -parameter_types! { - pub const AllowMultipleBlocksPerSlot: bool = false; - pub const MaxAuthorities: u32 = 100_000; -} - -#[cfg(feature = "async-backing")] -parameter_types! { - pub const AllowMultipleBlocksPerSlot: bool = true; - pub const MaxAuthorities: u32 = 100_000; -} - -impl pallet_aura::Config for Runtime { - type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot; - type AuthorityId = AuraId; - type DisabledValidators = (); - type MaxAuthorities = MaxAuthorities; - #[cfg(feature = "async-backing")] - type SlotDuration = ConstU64; - #[cfg(not(feature = "async-backing"))] - type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; -} - -parameter_types! { - pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const SessionLength: BlockNumber = 6 * HOURS; - // StakingAdmin pluralistic body. - pub const StakingAdminBodyId: BodyId = BodyId::Defense; -} - -/// We allow root and the StakingAdmin to execute privileged collator selection -/// operations. -pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< - EnsureRoot, - EnsureXcm>, ->; - -parameter_types! { - pub const MaxCandidates: u32 = 100; - pub const MaxInvulnerables: u32 = 20; - pub const MinEligibleCollators: u32 = 4; -} - -impl pallet_collator_selection::Config for Runtime { - type Currency = Balances; - // should be a multiple of session or things will get inconsistent - type KickThreshold = Period; - type MaxCandidates = MaxCandidates; - type MaxInvulnerables = MaxInvulnerables; - type MinEligibleCollators = MinEligibleCollators; - type PotId = PotId; - type RuntimeEvent = RuntimeEvent; - type UpdateOrigin = CollatorSelectionUpdateOrigin; - type ValidatorId = ::AccountId; - type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type ValidatorRegistration = Session; - type WeightInfo = pallet_collator_selection::weights::SubstrateWeight; -} - -impl pallet_utility::Config for Runtime { - type PalletsOrigin = OriginCaller; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_utility::weights::SubstrateWeight; -} - -parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const ProposalBondMinimum: Balance = 2000; // * CENTS - pub const ProposalBondMaximum: Balance = 1;// * GRAND; - pub const SpendPeriod: BlockNumber = 6 * DAYS; - pub const Burn: Permill = Permill::from_perthousand(2); - pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); - pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; - // The asset's interior location for the paying account. This is the Treasury - // pallet instance (which sits at index 13). - pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(13).into(); - pub const MaxApprovals: u32 = 100; -} - -parameter_types! { - pub TreasuryAccount: AccountId = Treasury::account_id(); -} - -impl pallet_treasury::Config for Runtime { - type ApproveOrigin = EitherOfDiverse, Treasurer>; - type AssetKind = VersionedLocatableAsset; - type BalanceConverter = frame_support::traits::tokens::UnityAssetBalanceConversion; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments; - type Beneficiary = VersionedLocation; - type BeneficiaryLookup = IdentityLookup; - type Burn = (); - type BurnDestination = (); - type Currency = Balances; - type MaxApprovals = MaxApprovals; - type OnSlash = Treasury; - type PalletId = TreasuryPalletId; - type Paymaster = PayOverXcm< - TreasuryInteriorLocation, - crate::xcm_config::XcmRouter, - crate::PolkadotXcm, - ConstU32<{ 6 * HOURS }>, - Self::Beneficiary, - Self::AssetKind, - LocatableAssetConverter, - VersionedLocationConverter, - >; - type PayoutPeriod = PayoutSpendPeriod; - type ProposalBond = ProposalBond; - type ProposalBondMaximum = ProposalBondMaximum; - type ProposalBondMinimum = ProposalBondMinimum; - type RejectOrigin = EitherOfDiverse, Treasurer>; - type RuntimeEvent = RuntimeEvent; - type SpendFunds = (); - type SpendOrigin = TreasurySpender; - type SpendPeriod = SpendPeriod; - type WeightInfo = pallet_treasury::weights::SubstrateWeight; -} - -parameter_types! { - pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; -} - -impl pallet_ethereum::Config for Runtime { - type ExtraDataLength = ConstU32<30>; - type PostLogContent = PostBlockAndTxnHashes; - type RuntimeEvent = RuntimeEvent; - type StateRoot = pallet_ethereum::IntermediateStateRoot; -} - -const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; - -/// Current approximation of the gas/s consumption considering -/// EVM execution over compiled WASM (on 4.4Ghz CPU). -/// Given the 500ms Weight, from which 75% only are used for transactions, -/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. -/// With the async backing enabled the gas limit will rise 4 times because of execution time. -pub const GAS_PER_SECOND: u64 = 40_000_000; - -/// Approximate ratio of the amount of Weight per Gas. -/// u64 works for approximations because Weight is a very small unit compared to gas. -pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND; - -parameter_types! { - pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); - pub GasLimitPovSizeRatio: u64 = BlockGasLimit::get().as_u64().saturating_div(MAX_POV_SIZE); - pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); - pub SuicideQuickClearLimit: u32 = 0; -} - -impl pallet_evm::Config for Runtime { - type AddressMapping = IdentityAddressMapping; - type BlockGasLimit = BlockGasLimit; - type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; - type CallOrigin = EnsureAccountId20; - type ChainId = EVMChainId; - type Currency = Balances; - type FeeCalculator = BaseFee; - type FindAuthor = FindAuthorSession; - type GasLimitPovSizeRatio = GasLimitPovSizeRatio; - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type OnChargeTransaction = EVMCurrencyAdapter; - type OnCreate = (); - // FIXME: Will be implemented in #11 - type PrecompilesType = (); - // FIXME: Will be implemented in #11 - type PrecompilesValue = (); - type Runner = pallet_evm::runner::stack::Runner; - type RuntimeEvent = RuntimeEvent; - type SuicideQuickClearLimit = SuicideQuickClearLimit; - type Timestamp = Timestamp; - // FIXME: run the benchmarks - type WeightInfo = pallet_evm::weights::SubstrateWeight; - type WeightPerGas = WeightPerGas; - type WithdrawOrigin = EnsureAccountId20; -} - -impl pallet_evm_chain_id::Config for Runtime {} - -parameter_types! { - /// Starting value for base fee. Set at the same value as in Ethereum. - pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000); - /// Default elasticity rate. Set at the same value as in Ethereum. - pub DefaultElasticity: Permill = Permill::from_parts(125_000); -} - -/// The thresholds based on which the base fee will change. -pub struct BaseFeeThreshold; -impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold { - fn lower() -> Permill { - Permill::zero() - } - - fn ideal() -> Permill { - Permill::from_parts(500_000) - } - - fn upper() -> Permill { - Permill::from_parts(1_000_000) - } -} -impl pallet_base_fee::Config for Runtime { - type DefaultBaseFeePerGas = DefaultBaseFeePerGas; - type DefaultElasticity = DefaultElasticity; - type RuntimeEvent = RuntimeEvent; - type Threshold = BaseFeeThreshold; -} - -pub struct FindAuthorSession(PhantomData); -impl> FindAuthor for FindAuthorSession { - fn find_author<'a, I>(digests: I) -> Option - where - I: 'a + IntoIterator, - { - if let Some(author_index) = F::find_author(digests) { - let account_id: AccountId = Session::validators()[author_index as usize]; - return Some(H160::from(account_id)); - } - None - } -} - -#[derive(Clone)] -pub struct TransactionConverter; - -impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { - UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } -} - -impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction( - &self, - transaction: pallet_ethereum::Transaction, - ) -> opaque::UncheckedExtrinsic { - let extrinsic = UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ); - let encoded = extrinsic.encode(); - opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) - .expect("Encoded extrinsic is always valid") - } -} - // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( @@ -1055,480 +218,10 @@ construct_runtime!( } ); -#[cfg(feature = "runtime-benchmarks")] -mod benches { - frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_assets, Assets] - [pallet_balances, Balances] - [pallet_session, SessionBench::] - [pallet_timestamp, Timestamp] - [pallet_message_queue, MessageQueue] - [pallet_sudo, Sudo] - [pallet_collator_selection, CollatorSelection] - [cumulus_pallet_xcmp_queue, XcmpQueue] - ); -} - -impl_runtime_apis! { - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> sp_consensus_aura::SlotDuration { - #[cfg(feature = "async-backing")] - return sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION); - #[cfg(not(feature = "async-backing"))] - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) - } - - fn authorities() -> Vec { - pallet_aura::Authorities::::get().into_inner() - } - } - - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - - fn metadata_at_version(version: u32) -> Option { - Runtime::metadata_at_version(version) - } - - fn metadata_versions() -> sp_std::vec::Vec { - Runtime::metadata_versions() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Nonce { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi - for Runtime - { - fn query_call_info( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::RuntimeDispatchInfo { - TransactionPayment::query_call_info(call, len) - } - fn query_call_fee_details( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_call_fee_details(call, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl fp_rpc::EthereumRuntimeRPCApi for Runtime { - fn chain_id() -> u64 { - ::ChainId::get() - } - - fn account_basic(address: H160) -> EVMAccount { - let (account, _) = pallet_evm::Pallet::::account_basic(&address); - account - } - - fn gas_price() -> U256 { - let (gas_price, _) = ::FeeCalculator::min_gas_price(); - gas_price - } - - fn account_code_at(address: H160) -> Vec { - pallet_evm::AccountCodes::::get(address) - } - - fn author() -> H160 { - >::find_author() - } - - fn storage_at(address: H160, index: U256) -> H256 { - let mut tmp = [0u8; 32]; - index.to_big_endian(&mut tmp); - pallet_evm::AccountStorages::::get(address, H256::from_slice(&tmp[..])) - } - - fn call( - from: H160, - to: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - - let gas_limit = gas_limit.min(u64::MAX.into()); - let transaction_data = TransactionData::new( - TransactionAction::Call(to), - data.clone(), - nonce.unwrap_or_default(), - gas_limit, - None, - max_fee_per_gas, - max_priority_fee_per_gas, - value, - Some(::ChainId::get()), - access_list.clone().unwrap_or_default(), - ); - let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); - - ::Runner::call( - from, - to, - data, - value, - gas_limit.unique_saturated_into(), - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - false, - true, - weight_limit, - proof_size_base_cost, - config.as_ref().unwrap_or(::config()), - ).map_err(|err| err.error.into()) - } - - fn create( - from: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - - let transaction_data = TransactionData::new( - TransactionAction::Create, - data.clone(), - nonce.unwrap_or_default(), - gas_limit, - None, - max_fee_per_gas, - max_priority_fee_per_gas, - value, - Some(::ChainId::get()), - access_list.clone().unwrap_or_default(), - ); - let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); - - ::Runner::create( - from, - data, - value, - gas_limit.unique_saturated_into(), - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - false, - true, - weight_limit, - proof_size_base_cost, - config.as_ref().unwrap_or(::config()), - ).map_err(|err| err.error.into()) - } - - fn current_transaction_statuses() -> Option> { - pallet_ethereum::CurrentTransactionStatuses::::get() - } - - fn current_block() -> Option { - pallet_ethereum::CurrentBlock::::get() - } - - fn current_receipts() -> Option> { - pallet_ethereum::CurrentReceipts::::get() - } - - fn current_all() -> ( - Option, - Option>, - Option> - ) { - ( - pallet_ethereum::CurrentBlock::::get(), - pallet_ethereum::CurrentReceipts::::get(), - pallet_ethereum::CurrentTransactionStatuses::::get() - ) - } - - fn extrinsic_filter( - xts: Vec<::Extrinsic>, - ) -> Vec { - xts.into_iter().filter_map(|xt| match xt.0.function { - RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), - _ => None - }).collect::>() - } - - fn elasticity() -> Option { - Some(pallet_base_fee::Elasticity::::get()) - } - - fn gas_limit_multiplier_support() {} - - fn pending_block( - xts: Vec<::Extrinsic>, - ) -> (Option, Option>) { - for ext in xts.into_iter() { - let _ = Executive::apply_extrinsic(ext); - } - - Ethereum::on_finalize(System::block_number() + 1); - - ( - pallet_ethereum::CurrentBlock::::get(), - pallet_ethereum::CurrentTransactionStatuses::::get() - ) - } - } - - impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { - fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { - UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } - } - - - - impl cumulus_primitives_core::CollectCollationInfo for Runtime { - fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { - ParachainSystem::collect_collation_info(header) - } - } - - #[cfg(feature = "async-backing")] - impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { - fn can_build_upon( - included_hash: ::Hash, - slot: cumulus_primitives_aura::Slot - ) -> bool { - ConsensusHook::can_build_upon(included_hash, slot) - } - } - - #[cfg(feature = "try-runtime")] - impl frame_try_runtime::TryRuntime for Runtime { - fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { - let weight = Executive::try_runtime_upgrade(checks).unwrap(); - (weight, RuntimeBlockWeights::get().max_block) - } - - fn execute_block( - block: Block, - state_root_check: bool, - signature_check: bool, - select: frame_try_runtime::TryStateSelect, - ) -> Weight { - // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to - // have a backtrace here. - Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use cumulus_pallet_session_benchmarking::Pallet as SessionBench; - - let mut list = Vec::::new(); - list_benchmarks!(list, extra); - - let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; - - use frame_system_benchmarking::Pallet as SystemBench; - impl frame_system_benchmarking::Config for Runtime { - fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { - ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); - Ok(()) - } - - fn verify_set_code() { - System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); - } - } - - use cumulus_pallet_session_benchmarking::Pallet as SessionBench; - impl cumulus_pallet_session_benchmarking::Config for Runtime {} - - use frame_support::traits::WhitelistedStorageKeys; - let whitelist = AllPalletsWithSystem::whitelisted_storage_keys(); - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - add_benchmarks!(params, batches); - - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok(batches) - } - } - - impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() - } - - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) - } - } -} - cumulus_pallet_parachain_system::register_validate_block! { Runtime = Runtime, BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, } -// tests -#[cfg(test)] -mod tests { - use super::*; - - // RUNTIME_API_VERSIONS constant is generated by a macro and is private. - #[test] - fn check_version() { - assert_eq!( - VERSION, - RuntimeVersion { - spec_name: create_runtime_str!("template-parachain"), - impl_name: create_runtime_str!("template-parachain"), - authoring_version: 1, - spec_version: 1, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 1, - } - ); - } -} +#[cfg(feature = "runtime-benchmarks")] +mod benchmark; diff --git a/evm-template/runtime/src/types.rs b/evm-template/runtime/src/types.rs new file mode 100644 index 0000000..6f96ceb --- /dev/null +++ b/evm-template/runtime/src/types.rs @@ -0,0 +1,84 @@ +use fp_account::EthereumSignature; +use frame_support::traits::EitherOfDiverse; +use frame_system::EnsureRoot; +use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; +use sp_runtime::{ + generic, + traits::{BlakeTwo256, IdentifyAccount, Verify}, + MultiAddress, +}; + +pub use crate::{ + configs::{xcm_config::RelayLocation, StakingAdminBodyId}, + constants::{ + BLOCK_PROCESSING_VELOCITY, RELAY_CHAIN_SLOT_DURATION_MILLIS, UNINCLUDED_SEGMENT_CAPACITY, + }, + AllPalletsWithSystem, Runtime, RuntimeCall, +}; + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + fp_self_contained::UncheckedExtrinsic; + +/// Ethereum Signature +pub type Signature = EthereumSignature; + +/// AccountId20 because 20 bytes long like H160 Ethereum Addresses +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; + +/// Balance of an account. +pub type Balance = u128; + +/// Index of a transaction in the chain. +pub type Nonce = u32; + +/// A hash of some data used by the chain. +pub type Hash = sp_core::H256; + +/// An index to a block. +pub type BlockNumber = u32; + +/// The address format for describing accounts. +pub type Address = MultiAddress; + +/// Block header type as expected by this runtime. +pub type Header = generic::Header; + +/// Block type as expected by this runtime. +pub type Block = generic::Block; + +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); + +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, +>; + +/// Configures the number of blocks that can be created without submission of validity proof to the relay chain +pub type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + RELAY_CHAIN_SLOT_DURATION_MILLIS, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; + +/// We allow root and the StakingAdmin to execute privileged collator selection +/// operations. +pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< + EnsureRoot, + EnsureXcm>, +>; diff --git a/evm-template/runtime/tests/constants_test.rs b/evm-template/runtime/tests/constants_test.rs index b09ddb2..ae344f9 100644 --- a/evm-template/runtime/tests/constants_test.rs +++ b/evm-template/runtime/tests/constants_test.rs @@ -20,9 +20,33 @@ mod constant_tests { mod runtime_tests { use frame_support::{pallet_prelude::Weight, traits::TypedGet, PalletId}; - use parachain_template_runtime::{constants::currency::*, *}; + use parachain_template_runtime::{ + configs::*, + constants::{currency::*, *}, + *, + }; + use sp_runtime::create_runtime_str; + use sp_version::RuntimeVersion; use xcm::latest::prelude::BodyId; + // RUNTIME_API_VERSIONS constant is generated by a macro and is private. + #[test] + fn check_version() { + assert_eq!( + VERSION, + RuntimeVersion { + spec_name: create_runtime_str!("template-parachain"), + impl_name: create_runtime_str!("template-parachain"), + authoring_version: 1, + spec_version: 1, + impl_version: 0, + apis: parachain_template_runtime::apis::RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, + } + ); + } + #[test] fn weight_to_fee_constants() { assert_eq!(P_FACTOR, 10); @@ -199,7 +223,7 @@ mod runtime_tests { mod xcm_tests { use frame_support::weights::Weight; - use parachain_template_runtime::xcm_config::*; + use parachain_template_runtime::configs::xcm_config::*; #[test] fn xcm_executor_constants() { diff --git a/evm-template/template-fuzzer/src/main.rs b/evm-template/template-fuzzer/src/main.rs index 67eb598..1703b06 100644 --- a/evm-template/template-fuzzer/src/main.rs +++ b/evm-template/template-fuzzer/src/main.rs @@ -8,8 +8,9 @@ use frame_support::{ weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, }; use parachain_template_runtime::{ - AccountId, AllPalletsWithSystem, Balance, Balances, BlockNumber, EVMChainIdConfig, Executive, - Runtime, RuntimeCall, RuntimeOrigin, SudoConfig, UncheckedExtrinsic, SLOT_DURATION, + constants::SLOT_DURATION, AccountId, AllPalletsWithSystem, Balance, Balances, BlockNumber, + EVMChainIdConfig, Executive, Runtime, RuntimeCall, RuntimeOrigin, SudoConfig, + UncheckedExtrinsic, }; use sp_consensus_aura::AURA_ENGINE_ID; use sp_runtime::{ diff --git a/generic-template/node/src/service.rs b/generic-template/node/src/service.rs index 8e28cc0..898b282 100644 --- a/generic-template/node/src/service.rs +++ b/generic-template/node/src/service.rs @@ -21,8 +21,8 @@ use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; // Local Runtime Types use parachain_template_runtime::{ + apis::RuntimeApi, opaque::{Block, Hash}, - RuntimeApi, }; use sc_client_api::Backend; use sc_consensus::ImportQueue; @@ -368,7 +368,6 @@ fn start_consensus( // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` // when starting the network. - #[cfg(not(feature = "async-backing"))] let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; diff --git a/generic-template/runtime/src/apis.rs b/generic-template/runtime/src/apis.rs new file mode 100644 index 0000000..5875ba3 --- /dev/null +++ b/generic-template/runtime/src/apis.rs @@ -0,0 +1,327 @@ +use frame_support::{ + genesis_builder_helper::{build_config, create_default_config}, + weights::Weight, +}; +use sp_api::impl_runtime_apis; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; +use sp_runtime::{ + traits::Block as BlockT, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, +}; +use sp_std::prelude::Vec; +use sp_version::RuntimeVersion; + +#[cfg(not(feature = "async-backing"))] +use crate::Aura; +#[cfg(feature = "async-backing")] +use crate::{constants::SLOT_DURATION, types::ConsensusHook}; +use crate::{ + constants::VERSION, + types::{AccountId, Balance, Block, Executive, Nonce}, + InherentDataExt, ParachainSystem, Runtime, RuntimeCall, RuntimeGenesisConfig, SessionKeys, + System, TransactionPayment, +}; + +impl_runtime_apis! { + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + #[cfg(feature = "async-backing")] + return sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION); + #[cfg(not(feature = "async-backing"))] + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + pallet_aura::Authorities::::get().into_inner() + } + } + + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl cumulus_primitives_core::CollectCollationInfo for Runtime { + fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info(header) + } + } + + #[cfg(feature = "async-backing")] + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot + ) -> bool { + ConsensusHook::can_build_upon(included_hash, slot) + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + use super::configs::RuntimeBlockWeights; + + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, RuntimeBlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + use frame_system_benchmarking::Pallet as SystemBench; + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + + use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; + + use super::*; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; + use frame_support::parameter_types; + use cumulus_primitives_core::ParaId; + use frame_system_benchmarking::Pallet as SystemBench; + + use super::{*, types::*, configs::*, constants::currency::CENTS}; + + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } + + parameter_types! { + pub const RandomParaId: ParaId = ParaId::new(43211234); + pub ExistentialDepositAsset: Option = Some(( + RelayLocation::get(), + ExistentialDeposit::get() + ).into()); + /// The base fee for the message delivery fees. Kusama is based for the reference. + pub const ToParentBaseDeliveryFee: u128 = CENTS.saturating_mul(3); + } + pub type PriceForParentDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice< + FeeAssetId, + ToParentBaseDeliveryFee, + TransactionByteFee, + ParachainSystem, + >; + use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; + use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen}; + impl pallet_xcm::benchmarking::Config for Runtime { + type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< + xcm_config::XcmConfig, + ExistentialDepositAsset, + PriceForParentDelivery, + >; + + fn reachable_dest() -> Option { + Some(Parent.into()) + } + + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { + None + } + + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { + Some(( + Asset { + fun: Fungible(ExistentialDeposit::get()), + id: AssetId(Parent.into()) + }.into(), + ParentThen(Parachain(RandomParaId::get().into()).into()).into(), + )) + } + + fn set_up_complex_asset_transfer( + ) -> Option<(AssetList, u32, Location, Box)> { + None + } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } + } + + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + impl cumulus_pallet_session_benchmarking::Config for Runtime {} + + use frame_support::traits::WhitelistedStorageKeys; + let whitelist = AllPalletsWithSystem::whitelisted_storage_keys(); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + add_benchmarks!(params, batches); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } + + impl sp_genesis_builder::GenesisBuilder for Runtime { + fn create_default_config() -> Vec { + create_default_config::() + } + + fn build_config(config: Vec) -> sp_genesis_builder::Result { + build_config::(config) + } + } +} diff --git a/generic-template/runtime/src/benchmark.rs b/generic-template/runtime/src/benchmark.rs new file mode 100644 index 0000000..32b055a --- /dev/null +++ b/generic-template/runtime/src/benchmark.rs @@ -0,0 +1,16 @@ +frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_assets, Assets] + [pallet_balances, Balances] + [pallet_session, SessionBench::] + [pallet_timestamp, Timestamp] + [pallet_message_queue, MessageQueue] + [pallet_sudo, Sudo] + [pallet_collator_selection, CollatorSelection] + [cumulus_pallet_xcmp_queue, XcmpQueue] + [cumulus_pallet_parachain_system, ParachainSystem] + [pallet_proxy, Proxy] + [pallet_utility, Utility] + [pallet_multisig, Multisig] + [pallet_xcm, PalletXcmExtrinsicsBenchmark::] +); diff --git a/generic-template/runtime/src/governance/mod.rs b/generic-template/runtime/src/configs/governance/mod.rs similarity index 83% rename from generic-template/runtime/src/governance/mod.rs rename to generic-template/runtime/src/configs/governance/mod.rs index cb7d758..743c325 100644 --- a/generic-template/runtime/src/governance/mod.rs +++ b/generic-template/runtime/src/configs/governance/mod.rs @@ -1,19 +1,23 @@ //! OpenGov governance config pub mod origins; -pub use origins::{ - pallet_custom_origins, ReferendumCanceller, ReferendumKiller, Spender, Treasurer, - WhitelistedCaller, -}; +pub use origins::{Spender, WhitelistedCaller}; mod tracks; -use frame_support::traits::EitherOf; -use frame_system::EnsureRootWithSuccess; +use frame_support::{ + parameter_types, + traits::{ConstU32, EitherOf}, +}; +use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned}; -use super::*; use crate::{ - constants::currency::{CENTS, GRAND}, - Balance, + constants::{ + currency::{CENTS, GRAND}, + DAYS, + }, + types::{AccountId, Balance, BlockNumber}, + Balances, Preimage, Referenda, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, + Treasury, }; parameter_types! { diff --git a/evm-template/runtime/src/governance/origins.rs b/generic-template/runtime/src/configs/governance/origins.rs similarity index 98% rename from evm-template/runtime/src/governance/origins.rs rename to generic-template/runtime/src/configs/governance/origins.rs index 1ea9c48..03b878c 100644 --- a/evm-template/runtime/src/governance/origins.rs +++ b/generic-template/runtime/src/configs/governance/origins.rs @@ -6,7 +6,7 @@ pub use pallet_custom_origins::*; pub mod pallet_custom_origins { use frame_support::pallet_prelude::*; - use crate::governance::{Balance, CENTS, GRAND}; + use crate::configs::governance::{Balance, CENTS, GRAND}; #[pallet::config] pub trait Config: frame_system::Config {} diff --git a/generic-template/runtime/src/governance/tracks.rs b/generic-template/runtime/src/configs/governance/tracks.rs similarity index 99% rename from generic-template/runtime/src/governance/tracks.rs rename to generic-template/runtime/src/configs/governance/tracks.rs index 5038407..3ec4b6e 100644 --- a/generic-template/runtime/src/governance/tracks.rs +++ b/generic-template/runtime/src/configs/governance/tracks.rs @@ -1,6 +1,7 @@ //! Track configurations for governance. use super::*; +use crate::constants::MINUTES; const fn percent(x: i32) -> sp_arithmetic::FixedI64 { sp_arithmetic::FixedI64::from_rational(x as u128, 100) diff --git a/generic-template/runtime/src/configs/mod.rs b/generic-template/runtime/src/configs/mod.rs new file mode 100644 index 0000000..1b56647 --- /dev/null +++ b/generic-template/runtime/src/configs/mod.rs @@ -0,0 +1,589 @@ +pub mod governance; +pub mod xcm_config; + +#[cfg(feature = "async-backing")] +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; +#[cfg(not(feature = "async-backing"))] +use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; +use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; +use frame_support::{ + derive_impl, + dispatch::DispatchClass, + parameter_types, + traits::{ + AsEnsureOriginWithArg, ConstU32, ConstU64, Contains, EitherOfDiverse, InstanceFilter, + TransformOrigin, + }, + weights::{ConstantMultiplier, Weight}, + PalletId, +}; +use frame_system::{ + limits::{BlockLength, BlockWeights}, + EnsureRoot, EnsureSigned, +}; +pub use governance::origins::pallet_custom_origins; +use governance::{origins::Treasurer, TreasurySpender}; +use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use polkadot_runtime_common::{ + impls::{LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter}, + BlockHashCount, SlowAdjustingFeeUpdate, +}; +use scale_info::TypeInfo; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_runtime::{ + traits::{AccountIdLookup, BlakeTwo256, IdentityLookup}, + Perbill, Permill, RuntimeDebug, +}; +use sp_version::RuntimeVersion; +use xcm::{ + latest::{ + prelude::{AssetId, BodyId}, + InteriorLocation, + Junction::PalletInstance, + }, + VersionedLocation, +}; +use xcm_builder::PayOverXcm; +#[cfg(not(feature = "runtime-benchmarks"))] +use xcm_builder::ProcessXcmMessage; +use xcm_config::{RelayLocation, XcmOriginToTransactDispatchOrigin}; + +use crate::{ + constants::{ + currency::{deposit, CENTS, EXISTENTIAL_DEPOSIT, MICROCENTS}, + AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, MAX_BLOCK_LENGTH, + NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION, + }, + types::{ + AccountId, Balance, Block, BlockNumber, CollatorSelectionUpdateOrigin, ConsensusHook, Hash, + Nonce, PriceForSiblingParachainDelivery, + }, + weights, + weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}, + Aura, Balances, CollatorSelection, MessageQueue, OriginCaller, PalletInfo, ParachainSystem, + Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason, + RuntimeOrigin, RuntimeTask, Session, SessionKeys, System, Treasury, WeightToFee, XcmpQueue, +}; + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + + // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. + // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the + // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize + // the lazy contract deletion. + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + // generic substrate prefix. For more info, see: [Polkadot Accounts In-Depth](https://wiki.polkadot.network/docs/learn-account-advanced#:~:text=The%20address%20format%20used%20in,belonging%20to%20a%20specific%20network) + pub const SS58Prefix: u16 = 42; +} + +pub struct NormalFilter; +impl Contains for NormalFilter { + fn contains(c: &RuntimeCall) -> bool { + match c { + // We filter anonymous proxy as they make "reserve" inconsistent + // See: https://github.com/paritytech/polkadot-sdk/blob/v1.9.0-rc2/substrate/frame/proxy/src/lib.rs#L260 + RuntimeCall::Proxy(method) => !matches!( + method, + pallet_proxy::Call::create_pure { .. } + | pallet_proxy::Call::kill_pure { .. } + | pallet_proxy::Call::remove_proxies { .. } + ), + _ => true, + } + } +} + +/// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from +/// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), +/// but overridden as needed. +#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = NormalFilter; + /// The block type. + type Block = Block; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The lookup mechanism to get account ID from whatever is passed in + /// dispatchers. + type Lookup = AccountIdLookup; + /// The maximum number of consumers allowed on a single account. + type MaxConsumers = ConstU32<16>; + /// The index type for storing how many extrinsics an account has signed. + type Nonce = Nonce; + /// The action to take on a Runtime Upgrade + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// Converts a module to an index of this module in the runtime. + type PalletInfo = PalletInfo; + /// The aggregated dispatch type that is available for extrinsics. + type RuntimeCall = RuntimeCall; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + /// The ubiquitous origin type. + type RuntimeOrigin = RuntimeOrigin; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Runtime version. + type Version = Version; +} + +parameter_types! { + pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) * + RuntimeBlockWeights::get().max_block; + pub const MaxScheduledRuntimeCallsPerBlock: u32 = 50; +} + +impl pallet_scheduler::Config for Runtime { + type MaxScheduledPerBlock = MaxScheduledRuntimeCallsPerBlock; + type MaximumWeight = MaximumSchedulerWeight; + type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; + type Preimages = Preimage; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; +} + +parameter_types! { + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); + pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); +} + +impl pallet_preimage::Config for Runtime { + type Consideration = frame_support::traits::fungible::HoldConsideration< + AccountId, + Balances, + PreimageHoldReason, + frame_support::traits::LinearStoragePrice< + PreimageBaseDeposit, + PreimageByteDeposit, + Balance, + >, + >; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_preimage::weights::SubstrateWeight; +} + +impl pallet_timestamp::Config for Runtime { + #[cfg(feature = "experimental")] + type MinimumPeriod = ConstU64<0>; + #[cfg(not(feature = "experimental"))] + type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = Aura; + type WeightInfo = weights::pallet_timestamp::WeightInfo; +} + +impl pallet_authorship::Config for Runtime { + type EventHandler = (CollatorSelection,); + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; +} + +parameter_types! { + pub const MaxProxies: u32 = 32; + pub const MaxPending: u32 = 32; + pub const ProxyDepositBase: Balance = deposit(1, 40); + pub const AnnouncementDepositBase: Balance = deposit(1, 48); + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); +} + +/// The type used to represent the kinds of proxying allowed. +/// If you are adding new pallets, consider adding new ProxyType variant +#[derive( + Copy, + Clone, + Decode, + Default, + Encode, + Eq, + MaxEncodedLen, + Ord, + PartialEq, + PartialOrd, + RuntimeDebug, + TypeInfo, +)] +pub enum ProxyType { + /// Allows to proxy all calls + #[default] + Any, + /// Allows all non-transfer calls + NonTransfer, + /// Allows to finish the proxy + CancelProxy, + /// Allows to operate with collators list (invulnerables, candidates, etc.) + Collator, +} + +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances { .. }), + ProxyType::CancelProxy => matches!( + c, + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) + | RuntimeCall::Multisig { .. } + ), + ProxyType::Collator => { + matches!(c, RuntimeCall::CollatorSelection { .. } | RuntimeCall::Multisig { .. }) + } + } + } +} + +impl pallet_proxy::Config for Runtime { + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; + type CallHasher = BlakeTwo256; + type Currency = Balances; + type MaxPending = MaxPending; + type MaxProxies = MaxProxies; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type ProxyType = ProxyType; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_proxy::WeightInfo; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxFreezes: u32 = 0; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type AccountStore = System; + /// The type for recording an account's balance. + type Balance = Balance; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type FreezeIdentifier = (); + type MaxFreezes = MaxFreezes; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + type RuntimeFreezeReason = RuntimeFreezeReason; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = weights::pallet_balances::WeightInfo; +} + +parameter_types! { + pub const AssetDeposit: Balance = 10 * CENTS; + pub const AssetAccountDeposit: Balance = deposit(1, 16); + pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const StringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = deposit(1, 68); + pub const MetadataDepositPerByte: Balance = deposit(0, 1); + pub const RemoveItemsLimit: u32 = 1000; +} + +impl pallet_assets::Config for Runtime { + type ApprovalDeposit = ApprovalDeposit; + type AssetAccountDeposit = AssetAccountDeposit; + type AssetDeposit = AssetDeposit; + type AssetId = u32; + type AssetIdParameter = parity_scale_codec::Compact; + type Balance = Balance; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + type CallbackHandle = (); + type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type Extra = (); + type ForceOrigin = EnsureRoot; + type Freezer = (); + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type RemoveItemsLimit = RemoveItemsLimit; + type RuntimeEvent = RuntimeEvent; + type StringLimit = StringLimit; + type WeightInfo = weights::pallet_assets::WeightInfo; +} + +parameter_types! { + /// Relay Chain `TransactionByteFee` / 10 + pub const TransactionByteFee: Balance = 10 * MICROCENTS; + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type LengthToFee = ConstantMultiplier; + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type RuntimeEvent = RuntimeEvent; + type WeightToFee = WeightToFee; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_sudo::WeightInfo; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + #[cfg(not(feature = "async-backing"))] + type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; + #[cfg(feature = "async-backing")] + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; + type OnSystemEvent = (); + type OutboundXcmpMessageSource = XcmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type RuntimeEvent = RuntimeEvent; + type SelfParaId = parachain_info::Pallet; + type WeightInfo = weights::cumulus_pallet_parachain_system::WeightInfo; + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +parameter_types! { + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + pub const HeapSize: u32 = 64 * 1024; + pub const MaxStale: u32 = 8; +} + +impl pallet_message_queue::Config for Runtime { + type HeapSize = HeapSize; + type IdleMaxServiceWeight = MessageQueueServiceWeight; + type MaxStale = MaxStale; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< + cumulus_primitives_core::AggregateMessageOrigin, + >; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = ProcessXcmMessage< + AggregateMessageOrigin, + xcm_executor::XcmExecutor, + RuntimeCall, + >; + // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: + type QueueChangeHandler = NarrowOriginToSibling; + type QueuePausedQuery = NarrowOriginToSibling; + type RuntimeEvent = RuntimeEvent; + type ServiceWeight = MessageQueueServiceWeight; + type Size = u32; + type WeightInfo = weights::pallet_message_queue::WeightInfo; +} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +parameter_types! { + pub const MaxInboundSuspended: u32 = 1000; + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); + /// The base fee for the message delivery fees. Kusama is based for the reference. + pub const ToSiblingBaseDeliveryFee: u128 = CENTS.saturating_mul(3); +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type ChannelInfo = ParachainSystem; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; + type MaxInboundSuspended = MaxInboundSuspended; + type PriceForSiblingDelivery = PriceForSiblingParachainDelivery; + type RuntimeEvent = RuntimeEvent; + type VersionWrapper = (); + type WeightInfo = weights::cumulus_pallet_xcmp_queue::WeightInfo; + // Enqueue XCMP messages from siblings for later processing. + type XcmpQueue = TransformOrigin; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u16 = 100; +} + +impl pallet_multisig::Config for Runtime { + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_multisig::WeightInfo; +} + +parameter_types! { + // pallet_session ends the session after a fixed period of blocks. + // The first session will have length of Offset, + // and the following sessions will have length of Period. + // This may prove nonsensical if Offset >= Period. + pub const Period: u32 = 6 * HOURS; + pub const Offset: u32 = 0; +} + +impl pallet_session::Config for Runtime { + type Keys = SessionKeys; + type NextSessionRotation = pallet_session::PeriodicSessions; + type RuntimeEvent = RuntimeEvent; + // Essentially just Aura, but let's be pedantic. + type SessionHandler = ::KeyTypeIdProviders; + type SessionManager = CollatorSelection; + type ShouldEndSession = pallet_session::PeriodicSessions; + type ValidatorId = ::AccountId; + // we don't have stash and controller, thus we don't need the convert as well. + type ValidatorIdOf = pallet_collator_selection::IdentityCollator; + type WeightInfo = weights::pallet_session::WeightInfo; +} + +#[cfg(not(feature = "async-backing"))] +parameter_types! { + pub const AllowMultipleBlocksPerSlot: bool = false; + pub const MaxAuthorities: u32 = 100_000; +} + +#[cfg(feature = "async-backing")] +parameter_types! { + pub const AllowMultipleBlocksPerSlot: bool = true; + pub const MaxAuthorities: u32 = 100_000; +} + +impl pallet_aura::Config for Runtime { + type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot; + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; + type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; +} + +parameter_types! { + pub const PotId: PalletId = PalletId(*b"PotStake"); + pub const SessionLength: BlockNumber = 6 * HOURS; + // StakingAdmin pluralistic body. + pub const StakingAdminBodyId: BodyId = BodyId::Defense; + pub const MaxCandidates: u32 = 100; + pub const MaxInvulnerables: u32 = 20; + pub const MinEligibleCollators: u32 = 4; +} + +impl pallet_collator_selection::Config for Runtime { + type Currency = Balances; + // should be a multiple of session or things will get inconsistent + type KickThreshold = Period; + type MaxCandidates = MaxCandidates; + type MaxInvulnerables = MaxInvulnerables; + type MinEligibleCollators = MinEligibleCollators; + type PotId = PotId; + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = CollatorSelectionUpdateOrigin; + type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_collator_selection::IdentityCollator; + type ValidatorRegistration = Session; + type WeightInfo = weights::pallet_collator_selection::WeightInfo; +} + +impl pallet_utility::Config for Runtime { + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_utility::WeightInfo; +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 2000; // * CENTS + pub const ProposalBondMaximum: Balance = 1;// * GRAND; + pub const SpendPeriod: BlockNumber = 6 * DAYS; + pub const Burn: Permill = Permill::from_perthousand(2); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; + // The asset's interior location for the paying account. This is the Treasury + // pallet instance (which sits at index 13). + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(13).into(); + pub const MaxApprovals: u32 = 100; + pub TreasuryAccount: AccountId = Treasury::account_id(); +} + +impl pallet_treasury::Config for Runtime { + type ApproveOrigin = EitherOfDiverse, Treasurer>; + type AssetKind = VersionedLocatableAsset; + type BalanceConverter = frame_support::traits::tokens::UnityAssetBalanceConversion; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments; + type Beneficiary = VersionedLocation; + type BeneficiaryLookup = IdentityLookup; + type Burn = (); + type BurnDestination = (); + type Currency = Balances; + type MaxApprovals = MaxApprovals; + type OnSlash = Treasury; + type PalletId = TreasuryPalletId; + type Paymaster = PayOverXcm< + TreasuryInteriorLocation, + xcm_config::XcmRouter, + crate::PolkadotXcm, + ConstU32<{ 6 * HOURS }>, + Self::Beneficiary, + Self::AssetKind, + LocatableAssetConverter, + VersionedLocationConverter, + >; + type PayoutPeriod = PayoutSpendPeriod; + type ProposalBond = ProposalBond; + type ProposalBondMaximum = ProposalBondMaximum; + type ProposalBondMinimum = ProposalBondMinimum; + type RejectOrigin = EitherOfDiverse, Treasurer>; + type RuntimeEvent = RuntimeEvent; + type SpendFunds = (); + type SpendOrigin = TreasurySpender; + type SpendPeriod = SpendPeriod; + type WeightInfo = pallet_treasury::weights::SubstrateWeight; +} diff --git a/generic-template/runtime/src/xcm_config.rs b/generic-template/runtime/src/configs/xcm_config.rs similarity index 97% rename from generic-template/runtime/src/xcm_config.rs rename to generic-template/runtime/src/configs/xcm_config.rs index 13f0128..c0a082d 100644 --- a/generic-template/runtime/src/xcm_config.rs +++ b/generic-template/runtime/src/configs/xcm_config.rs @@ -22,10 +22,13 @@ use xcm_builder::{ }; use xcm_executor::XcmExecutor; -use super::{ - weights, AccountId, AllPalletsWithSystem, Assets, Balance, Balances, ParachainInfo, - ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, - XcmpQueue, +use crate::{ + configs::{ + weights, Balances, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + WeightToFee, XcmpQueue, + }, + types::{AccountId, Balance}, + AllPalletsWithSystem, Assets, ParachainInfo, PolkadotXcm, }; parameter_types! { diff --git a/generic-template/runtime/src/constants.rs b/generic-template/runtime/src/constants.rs index 97386ce..4541343 100644 --- a/generic-template/runtime/src/constants.rs +++ b/generic-template/runtime/src/constants.rs @@ -1,5 +1,11 @@ +use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}; +use sp_runtime::{create_runtime_str, Perbill}; +use sp_version::RuntimeVersion; + +use crate::{apis, types::BlockNumber}; + pub mod currency { - use crate::Balance; + use crate::types::Balance; pub const MICROCENTS: Balance = 1_000_000; pub const MILLICENTS: Balance = 1_000_000_000; @@ -13,3 +19,70 @@ pub mod currency { items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS } } + +pub const P_FACTOR: u128 = 10; +pub const Q_FACTOR: u128 = 100; +pub const POLY_DEGREE: u8 = 1; + +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("template-parachain"), + impl_name: create_runtime_str!("template-parachain"), + authoring_version: 1, + spec_version: 1, + impl_version: 0, + apis: apis::RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, +}; + +/// This determines the average expected block time that we are targeting. +/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. +/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked +/// up by `pallet_aura` to implement `fn slot_duration()`. +/// +/// Change this to adjust the block time. +#[cfg(feature = "async-backing")] +pub const MILLISECS_PER_BLOCK: u64 = 6000; +#[cfg(not(feature = "async-backing"))] +pub const MILLISECS_PER_BLOCK: u64 = 12000; + +// NOTE: Currently it is not possible to change the slot duration after the +// chain has started. Attempting to do so will brick block production. +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +// Time is measured by number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +/// We assume that ~5% of the block weight is consumed by `on_initialize` +/// handlers. This is used to limit the maximal weight of a single extrinsic. +pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); + +/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be +/// used by `Operational` extrinsics. +pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); + +/// We allow for 0.5 of a second of compute with a 12 second average block time. +pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + #[cfg(feature = "async-backing")] + WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), + #[cfg(not(feature = "async-backing"))] + WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), + cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, +); + +/// Maximum number of blocks simultaneously accepted by the Runtime, not yet +/// included into the relay chain. +#[cfg(feature = "async-backing")] +pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; +#[cfg(not(feature = "async-backing"))] +pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; +/// How many parachain blocks are processed by the relay chain per parent. +/// Limits the number of blocks authored per slot. +pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; +/// Relay chain slot duration, in milliseconds. +pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000; +/// Maximum length for a block. +pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; diff --git a/generic-template/runtime/src/lib.rs b/generic-template/runtime/src/lib.rs index edb45d3..f33895d 100644 --- a/generic-template/runtime/src/lib.rs +++ b/generic-template/runtime/src/lib.rs @@ -6,145 +6,37 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +pub mod apis; +pub mod configs; pub mod constants; -pub mod governance; +mod types; mod weights; -pub mod xcm_config; -#[cfg(feature = "async-backing")] -use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; -#[cfg(not(feature = "async-backing"))] -use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; -use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ - construct_runtime, derive_impl, - dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, - parameter_types, - traits::{ - AsEnsureOriginWithArg, ConstU32, ConstU64, Contains, EitherOfDiverse, InstanceFilter, - TransformOrigin, - }, - weights::{ - constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient, - WeightToFeeCoefficients, WeightToFeePolynomial, - }, - PalletId, + construct_runtime, + weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial}, }; -use frame_system::{ - limits::{BlockLength, BlockWeights}, - EnsureRoot, EnsureSigned, -}; -use governance::{ - origins::{pallet_custom_origins, Treasurer}, - TreasurySpender, -}; -use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; -use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -// Polkadot imports -use polkadot_runtime_common::{ - impls::{LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter}, - BlockHashCount, SlowAdjustingFeeUpdate, -}; -use scale_info::TypeInfo; use smallvec::smallvec; -use sp_api::impl_runtime_apis; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; +use sp_runtime::impl_opaque_keys; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, IdentityLookup, Verify, - }, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiSignature, RuntimeDebug, -}; pub use sp_runtime::{MultiAddress, Perbill, Permill}; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -// XCM Imports -use xcm::{ - latest::{ - prelude::{AssetId, BodyId}, - InteriorLocation, - Junction::PalletInstance, - }, - VersionedLocation, -}; -use xcm_builder::PayOverXcm; -#[cfg(not(feature = "runtime-benchmarks"))] -use xcm_builder::ProcessXcmMessage; use crate::{ - constants::currency::{deposit, CENTS, EXISTENTIAL_DEPOSIT, MICROCENTS, MILLICENTS}, - weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}, - xcm_config::{RelayLocation, XcmOriginToTransactDispatchOrigin}, + configs::pallet_custom_origins, + constants::{currency::MILLICENTS, POLY_DEGREE, P_FACTOR, Q_FACTOR}, + weights::ExtrinsicBaseWeight, +}; +pub use crate::{ + configs::RuntimeBlockWeights, + types::{ + AccountId, Balance, Block, BlockNumber, Executive, Nonce, Signature, UncheckedExtrinsic, + }, }; - -/// Alias to 512-bit hash when used in the context of a transaction signature on -/// the chain. -pub type Signature = MultiSignature; - -/// Some way of identifying an account on the chain. We intentionally make it -/// equivalent to the public key of our transaction signing scheme. -pub type AccountId = <::Signer as IdentifyAccount>::AccountId; - -/// Balance of an account. -pub type Balance = u128; - -/// Index of a transaction in the chain. -pub type Nonce = u32; - -/// A hash of some data used by the chain. -pub type Hash = sp_core::H256; - -/// An index to a block. -pub type BlockNumber = u32; - -/// The address format for describing accounts. -pub type Address = MultiAddress; - -/// Block header type as expected by this runtime. -pub type Header = generic::Header; - -/// Block type as expected by this runtime. -pub type Block = generic::Block; - -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; - -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; - -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); - -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; - -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, ->; /// Handles converting a weight scalar to a fee value, based on the scale and /// granularity of the node's balance type. @@ -160,10 +52,6 @@ pub type Executive = frame_executive::Executive< /// charged. pub struct WeightToFee; -pub const P_FACTOR: u128 = 10; -pub const Q_FACTOR: u128 = 100; -pub const POLY_DEGREE: u8 = 1; - impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; @@ -210,619 +98,15 @@ impl_opaque_keys! { } } -#[sp_version::runtime_version] -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("template-parachain"), - impl_name: create_runtime_str!("template-parachain"), - authoring_version: 1, - spec_version: 1, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 1, -}; - -/// This determines the average expected block time that we are targeting. -/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. -/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked -/// up by `pallet_aura` to implement `fn slot_duration()`. -/// -/// Change this to adjust the block time. -#[cfg(feature = "async-backing")] -pub const MILLISECS_PER_BLOCK: u64 = 6000; -#[cfg(not(feature = "async-backing"))] -pub const MILLISECS_PER_BLOCK: u64 = 12000; - -// NOTE: Currently it is not possible to change the slot duration after the -// chain has started. Attempting to do so will brick block production. -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -// Time is measured by number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -/// We assume that ~5% of the block weight is consumed by `on_initialize` -/// handlers. This is used to limit the maximal weight of a single extrinsic. -pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); - -/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be -/// used by `Operational` extrinsics. -pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); - -/// We allow for 0.5 of a second of compute with a 12 second average block time. -pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( - #[cfg(feature = "async-backing")] - WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), - #[cfg(not(feature = "async-backing"))] - WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), - cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, -); - -/// Maximum number of blocks simultaneously accepted by the Runtime, not yet -/// included into the relay chain. -#[cfg(feature = "async-backing")] -pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; -#[cfg(not(feature = "async-backing"))] -pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; -/// How many parachain blocks are processed by the relay chain per parent. -/// Limits the number of blocks authored per slot. -pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; -/// Relay chain slot duration, in milliseconds. -pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000; -/// Maximum length for a block. -pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; - /// The version information used to identify this runtime when compiled /// natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { + use crate::constants::VERSION; + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -parameter_types! { - pub const Version: RuntimeVersion = VERSION; - - // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. - // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the - // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize - // the lazy contract deletion. - pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); - pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() - .base_block(BlockExecutionWeight::get()) - .for_class(DispatchClass::all(), |weights| { - weights.base_extrinsic = ExtrinsicBaseWeight::get(); - }) - .for_class(DispatchClass::Normal, |weights| { - weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); - }) - .for_class(DispatchClass::Operational, |weights| { - weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); - // Operational transactions have some extra reserved space, so that they - // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. - weights.reserved = Some( - MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT - ); - }) - .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) - .build_or_panic(); - // generic substrate prefix. For more info, see: [Polkadot Accounts In-Depth](https://wiki.polkadot.network/docs/learn-account-advanced#:~:text=The%20address%20format%20used%20in,belonging%20to%20a%20specific%20network) - pub const SS58Prefix: u16 = 42; -} - -pub struct NormalFilter; -impl Contains for NormalFilter { - fn contains(c: &RuntimeCall) -> bool { - match c { - // We filter anonymous proxy as they make "reserve" inconsistent - // See: https://github.com/paritytech/polkadot-sdk/blob/v1.9.0-rc2/substrate/frame/proxy/src/lib.rs#L260 - RuntimeCall::Proxy(method) => !matches!( - method, - pallet_proxy::Call::create_pure { .. } - | pallet_proxy::Call::kill_pure { .. } - | pallet_proxy::Call::remove_proxies { .. } - ), - _ => true, - } - } -} - -/// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from -/// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), -/// but overridden as needed. -#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] -impl frame_system::Config for Runtime { - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = NormalFilter; - /// The block type. - type Block = Block; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// The maximum length of a block (in bytes). - type BlockLength = RuntimeBlockLength; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The lookup mechanism to get account ID from whatever is passed in - /// dispatchers. - type Lookup = AccountIdLookup; - /// The maximum number of consumers allowed on a single account. - type MaxConsumers = ConstU32<16>; - /// The index type for storing how many extrinsics an account has signed. - type Nonce = Nonce; - /// The action to take on a Runtime Upgrade - type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - /// Converts a module to an index of this module in the runtime. - type PalletInfo = PalletInfo; - /// The aggregated dispatch type that is available for extrinsics. - type RuntimeCall = RuntimeCall; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - /// The ubiquitous origin type. - type RuntimeOrigin = RuntimeOrigin; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// Runtime version. - type Version = Version; -} - -parameter_types! { - pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) * - RuntimeBlockWeights::get().max_block; - pub const MaxScheduledRuntimeCallsPerBlock: u32 = 50; -} - -impl pallet_scheduler::Config for Runtime { - type MaxScheduledPerBlock = MaxScheduledRuntimeCallsPerBlock; - type MaximumWeight = MaximumSchedulerWeight; - type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; - type PalletsOrigin = OriginCaller; - type Preimages = Preimage; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type ScheduleOrigin = EnsureRoot; - type WeightInfo = pallet_scheduler::weights::SubstrateWeight; -} - -parameter_types! { - pub const PreimageBaseDeposit: Balance = deposit(2, 64); - pub const PreimageByteDeposit: Balance = deposit(0, 1); - pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); -} - -impl pallet_preimage::Config for Runtime { - type Consideration = frame_support::traits::fungible::HoldConsideration< - AccountId, - Balances, - PreimageHoldReason, - frame_support::traits::LinearStoragePrice< - PreimageBaseDeposit, - PreimageByteDeposit, - Balance, - >, - >; - type Currency = Balances; - type ManagerOrigin = EnsureRoot; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_preimage::weights::SubstrateWeight; -} - -impl pallet_timestamp::Config for Runtime { - #[cfg(feature = "experimental")] - type MinimumPeriod = ConstU64<0>; - #[cfg(not(feature = "experimental"))] - type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = Aura; - type WeightInfo = weights::pallet_timestamp::WeightInfo; -} - -impl pallet_authorship::Config for Runtime { - type EventHandler = (CollatorSelection,); - type FindAuthor = pallet_session::FindAccountFromAuthorIndex; -} - -parameter_types! { - pub const MaxProxies: u32 = 32; - pub const MaxPending: u32 = 32; - pub const ProxyDepositBase: Balance = deposit(1, 40); - pub const AnnouncementDepositBase: Balance = deposit(1, 48); - pub const ProxyDepositFactor: Balance = deposit(0, 33); - pub const AnnouncementDepositFactor: Balance = deposit(0, 66); -} - -/// The type used to represent the kinds of proxying allowed. -/// If you are adding new pallets, consider adding new ProxyType variant -#[derive( - Copy, - Clone, - Decode, - Default, - Encode, - Eq, - MaxEncodedLen, - Ord, - PartialEq, - PartialOrd, - RuntimeDebug, - TypeInfo, -)] -pub enum ProxyType { - /// Allows to proxy all calls - #[default] - Any, - /// Allows all non-transfer calls - NonTransfer, - /// Allows to finish the proxy - CancelProxy, - /// Allows to operate with collators list (invulnerables, candidates, etc.) - Collator, -} - -impl InstanceFilter for ProxyType { - fn filter(&self, c: &RuntimeCall) -> bool { - match self { - ProxyType::Any => true, - ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances { .. }), - ProxyType::CancelProxy => matches!( - c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) - | RuntimeCall::Multisig { .. } - ), - ProxyType::Collator => { - matches!(c, RuntimeCall::CollatorSelection { .. } | RuntimeCall::Multisig { .. }) - } - } - } -} - -impl pallet_proxy::Config for Runtime { - type AnnouncementDepositBase = AnnouncementDepositBase; - type AnnouncementDepositFactor = AnnouncementDepositFactor; - type CallHasher = BlakeTwo256; - type Currency = Balances; - type MaxPending = MaxPending; - type MaxProxies = MaxProxies; - type ProxyDepositBase = ProxyDepositBase; - type ProxyDepositFactor = ProxyDepositFactor; - type ProxyType = ProxyType; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = weights::pallet_proxy::WeightInfo; -} - -parameter_types! { - pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; - pub const MaxFreezes: u32 = 0; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type AccountStore = System; - /// The type for recording an account's balance. - type Balance = Balance; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type FreezeIdentifier = (); - type MaxFreezes = MaxFreezes; - type MaxLocks = MaxLocks; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - type RuntimeFreezeReason = RuntimeFreezeReason; - type RuntimeHoldReason = RuntimeHoldReason; - type WeightInfo = weights::pallet_balances::WeightInfo; -} - -parameter_types! { - pub const AssetDeposit: Balance = 10 * CENTS; - pub const AssetAccountDeposit: Balance = deposit(1, 16); - pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT; - pub const StringLimit: u32 = 50; - pub const MetadataDepositBase: Balance = deposit(1, 68); - pub const MetadataDepositPerByte: Balance = deposit(0, 1); - pub const RemoveItemsLimit: u32 = 1000; -} - -impl pallet_assets::Config for Runtime { - type ApprovalDeposit = ApprovalDeposit; - type AssetAccountDeposit = AssetAccountDeposit; - type AssetDeposit = AssetDeposit; - type AssetId = u32; - type AssetIdParameter = parity_scale_codec::Compact; - type Balance = Balance; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); - type CallbackHandle = (); - type CreateOrigin = AsEnsureOriginWithArg>; - type Currency = Balances; - type Extra = (); - type ForceOrigin = EnsureRoot; - type Freezer = (); - type MetadataDepositBase = MetadataDepositBase; - type MetadataDepositPerByte = MetadataDepositPerByte; - type RemoveItemsLimit = RemoveItemsLimit; - type RuntimeEvent = RuntimeEvent; - type StringLimit = StringLimit; - type WeightInfo = weights::pallet_assets::WeightInfo; -} - -parameter_types! { - /// Relay Chain `TransactionByteFee` / 10 - pub const TransactionByteFee: Balance = 10 * MICROCENTS; - pub const OperationalFeeMultiplier: u8 = 5; -} - -impl pallet_transaction_payment::Config for Runtime { - type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type LengthToFee = ConstantMultiplier; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type OperationalFeeMultiplier = OperationalFeeMultiplier; - type RuntimeEvent = RuntimeEvent; - type WeightToFee = WeightToFee; -} - -impl pallet_sudo::Config for Runtime { - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = weights::pallet_sudo::WeightInfo; -} - -parameter_types! { - pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); - pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); - pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; -} - -type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< - Runtime, - RELAY_CHAIN_SLOT_DURATION_MILLIS, - BLOCK_PROCESSING_VELOCITY, - UNINCLUDED_SEGMENT_CAPACITY, ->; - -impl cumulus_pallet_parachain_system::Config for Runtime { - #[cfg(not(feature = "async-backing"))] - type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; - #[cfg(feature = "async-backing")] - type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; - type ConsensusHook = ConsensusHook; - type DmpQueue = frame_support::traits::EnqueueWithOrigin; - type OnSystemEvent = (); - type OutboundXcmpMessageSource = XcmpQueue; - type ReservedDmpWeight = ReservedDmpWeight; - type ReservedXcmpWeight = ReservedXcmpWeight; - type RuntimeEvent = RuntimeEvent; - type SelfParaId = parachain_info::Pallet; - type WeightInfo = weights::cumulus_pallet_parachain_system::WeightInfo; - type XcmpMessageHandler = XcmpQueue; -} - -impl parachain_info::Config for Runtime {} - -parameter_types! { - pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; - pub const HeapSize: u32 = 64 * 1024; - pub const MaxStale: u32 = 8; -} - -impl pallet_message_queue::Config for Runtime { - type HeapSize = HeapSize; - type IdleMaxServiceWeight = MessageQueueServiceWeight; - type MaxStale = MaxStale; - #[cfg(feature = "runtime-benchmarks")] - type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< - cumulus_primitives_core::AggregateMessageOrigin, - >; - #[cfg(not(feature = "runtime-benchmarks"))] - type MessageProcessor = ProcessXcmMessage< - AggregateMessageOrigin, - xcm_executor::XcmExecutor, - RuntimeCall, - >; - // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: - type QueueChangeHandler = NarrowOriginToSibling; - type QueuePausedQuery = NarrowOriginToSibling; - type RuntimeEvent = RuntimeEvent; - type ServiceWeight = MessageQueueServiceWeight; - type Size = u32; - type WeightInfo = weights::pallet_message_queue::WeightInfo; -} - -impl cumulus_pallet_aura_ext::Config for Runtime {} - -parameter_types! { - pub const MaxInboundSuspended: u32 = 1000; - /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); - /// The base fee for the message delivery fees. Kusama is based for the reference. - pub const ToSiblingBaseDeliveryFee: u128 = CENTS.saturating_mul(3); -} - -pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice< - FeeAssetId, - ToSiblingBaseDeliveryFee, - TransactionByteFee, - XcmpQueue, ->; - -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type ChannelInfo = ParachainSystem; - type ControllerOrigin = EnsureRoot; - type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; - type MaxInboundSuspended = MaxInboundSuspended; - type PriceForSiblingDelivery = PriceForSiblingParachainDelivery; - type RuntimeEvent = RuntimeEvent; - type VersionWrapper = (); - type WeightInfo = weights::cumulus_pallet_xcmp_queue::WeightInfo; - // Enqueue XCMP messages from siblings for later processing. - type XcmpQueue = TransformOrigin; -} - -parameter_types! { - // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. - pub const DepositBase: Balance = deposit(1, 88); - // Additional storage item size of 32 bytes. - pub const DepositFactor: Balance = deposit(0, 32); - pub const MaxSignatories: u16 = 100; -} - -impl pallet_multisig::Config for Runtime { - type Currency = Balances; - type DepositBase = DepositBase; - type DepositFactor = DepositFactor; - type MaxSignatories = MaxSignatories; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = weights::pallet_multisig::WeightInfo; -} - -parameter_types! { - // pallet_session ends the session after a fixed period of blocks. - // The first session will have length of Offset, - // and the following sessions will have length of Period. - // This may prove nonsensical if Offset >= Period. - pub const Period: u32 = 6 * HOURS; - pub const Offset: u32 = 0; -} - -impl pallet_session::Config for Runtime { - type Keys = SessionKeys; - type NextSessionRotation = pallet_session::PeriodicSessions; - type RuntimeEvent = RuntimeEvent; - // Essentially just Aura, but let's be pedantic. - type SessionHandler = ::KeyTypeIdProviders; - type SessionManager = CollatorSelection; - type ShouldEndSession = pallet_session::PeriodicSessions; - type ValidatorId = ::AccountId; - // we don't have stash and controller, thus we don't need the convert as well. - type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type WeightInfo = weights::pallet_session::WeightInfo; -} - -#[cfg(not(feature = "async-backing"))] -parameter_types! { - pub const AllowMultipleBlocksPerSlot: bool = false; - pub const MaxAuthorities: u32 = 100_000; -} - -#[cfg(feature = "async-backing")] -parameter_types! { - pub const AllowMultipleBlocksPerSlot: bool = true; - pub const MaxAuthorities: u32 = 100_000; -} - -impl pallet_aura::Config for Runtime { - type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot; - type AuthorityId = AuraId; - type DisabledValidators = (); - type MaxAuthorities = MaxAuthorities; - type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; -} - -parameter_types! { - pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const SessionLength: BlockNumber = 6 * HOURS; - // StakingAdmin pluralistic body. - pub const StakingAdminBodyId: BodyId = BodyId::Defense; - pub const MaxCandidates: u32 = 100; - pub const MaxInvulnerables: u32 = 20; - pub const MinEligibleCollators: u32 = 4; -} - -/// We allow root and the StakingAdmin to execute privileged collator selection -/// operations. -pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< - EnsureRoot, - EnsureXcm>, ->; - -impl pallet_collator_selection::Config for Runtime { - type Currency = Balances; - // should be a multiple of session or things will get inconsistent - type KickThreshold = Period; - type MaxCandidates = MaxCandidates; - type MaxInvulnerables = MaxInvulnerables; - type MinEligibleCollators = MinEligibleCollators; - type PotId = PotId; - type RuntimeEvent = RuntimeEvent; - type UpdateOrigin = CollatorSelectionUpdateOrigin; - type ValidatorId = ::AccountId; - type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type ValidatorRegistration = Session; - type WeightInfo = weights::pallet_collator_selection::WeightInfo; -} - -impl pallet_utility::Config for Runtime { - type PalletsOrigin = OriginCaller; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type WeightInfo = weights::pallet_utility::WeightInfo; -} - -parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const ProposalBondMinimum: Balance = 2000; // * CENTS - pub const ProposalBondMaximum: Balance = 1;// * GRAND; - pub const SpendPeriod: BlockNumber = 6 * DAYS; - pub const Burn: Permill = Permill::from_perthousand(2); - pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); - pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; - // The asset's interior location for the paying account. This is the Treasury - // pallet instance (which sits at index 13). - pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(13).into(); - pub const MaxApprovals: u32 = 100; - pub TreasuryAccount: AccountId = Treasury::account_id(); -} - -impl pallet_treasury::Config for Runtime { - type ApproveOrigin = EitherOfDiverse, Treasurer>; - type AssetKind = VersionedLocatableAsset; - type BalanceConverter = frame_support::traits::tokens::UnityAssetBalanceConversion; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments; - type Beneficiary = VersionedLocation; - type BeneficiaryLookup = IdentityLookup; - type Burn = (); - type BurnDestination = (); - type Currency = Balances; - type MaxApprovals = MaxApprovals; - type OnSlash = Treasury; - type PalletId = TreasuryPalletId; - type Paymaster = PayOverXcm< - TreasuryInteriorLocation, - crate::xcm_config::XcmRouter, - crate::PolkadotXcm, - ConstU32<{ 6 * HOURS }>, - Self::Beneficiary, - Self::AssetKind, - LocatableAssetConverter, - VersionedLocationConverter, - >; - type PayoutPeriod = PayoutSpendPeriod; - type ProposalBond = ProposalBond; - type ProposalBondMaximum = ProposalBondMaximum; - type ProposalBondMinimum = ProposalBondMinimum; - type RejectOrigin = EitherOfDiverse, Treasurer>; - type RuntimeEvent = RuntimeEvent; - type SpendFunds = (); - type SpendOrigin = TreasurySpender; - type SpendPeriod = SpendPeriod; - type WeightInfo = pallet_treasury::weights::SubstrateWeight; -} - // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( @@ -867,345 +151,10 @@ construct_runtime!( } ); -#[cfg(feature = "runtime-benchmarks")] -mod benches { - frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_assets, Assets] - [pallet_balances, Balances] - [pallet_session, SessionBench::] - [pallet_timestamp, Timestamp] - [pallet_message_queue, MessageQueue] - [pallet_sudo, Sudo] - [pallet_collator_selection, CollatorSelection] - [cumulus_pallet_xcmp_queue, XcmpQueue] - [cumulus_pallet_parachain_system, ParachainSystem] - [pallet_proxy, Proxy] - [pallet_utility, Utility] - [pallet_multisig, Multisig] - [pallet_xcm, PalletXcmExtrinsicsBenchmark::] - ); -} - -impl_runtime_apis! { - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> sp_consensus_aura::SlotDuration { - #[cfg(feature = "async-backing")] - return sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION); - #[cfg(not(feature = "async-backing"))] - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) - } - - fn authorities() -> Vec { - pallet_aura::Authorities::::get().into_inner() - } - } - - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - - fn metadata_at_version(version: u32) -> Option { - Runtime::metadata_at_version(version) - } - - fn metadata_versions() -> sp_std::vec::Vec { - Runtime::metadata_versions() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Nonce { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi - for Runtime - { - fn query_call_info( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::RuntimeDispatchInfo { - TransactionPayment::query_call_info(call, len) - } - fn query_call_fee_details( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_call_fee_details(call, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl cumulus_primitives_core::CollectCollationInfo for Runtime { - fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { - ParachainSystem::collect_collation_info(header) - } - } - - #[cfg(feature = "async-backing")] - impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { - fn can_build_upon( - included_hash: ::Hash, - slot: cumulus_primitives_aura::Slot - ) -> bool { - ConsensusHook::can_build_upon(included_hash, slot) - } - } - - #[cfg(feature = "try-runtime")] - impl frame_try_runtime::TryRuntime for Runtime { - fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { - let weight = Executive::try_runtime_upgrade(checks).unwrap(); - (weight, RuntimeBlockWeights::get().max_block) - } - - fn execute_block( - block: Block, - state_root_check: bool, - signature_check: bool, - select: frame_try_runtime::TryStateSelect, - ) -> Weight { - // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to - // have a backtrace here. - Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use cumulus_pallet_session_benchmarking::Pallet as SessionBench; - - use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; - - let mut list = Vec::::new(); - list_benchmarks!(list, extra); - - let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; - - use frame_system_benchmarking::Pallet as SystemBench; - impl frame_system_benchmarking::Config for Runtime { - fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { - ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); - Ok(()) - } - - fn verify_set_code() { - System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); - } - } - - parameter_types! { - pub const RandomParaId: ParaId = ParaId::new(43211234); - pub ExistentialDepositAsset: Option = Some(( - RelayLocation::get(), - ExistentialDeposit::get() - ).into()); - /// The base fee for the message delivery fees. Kusama is based for the reference. - pub const ToParentBaseDeliveryFee: u128 = CENTS.saturating_mul(3); - } - pub type PriceForParentDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice< - FeeAssetId, - ToParentBaseDeliveryFee, - TransactionByteFee, - ParachainSystem, - >; - use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; - use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen}; - impl pallet_xcm::benchmarking::Config for Runtime { - type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< - xcm_config::XcmConfig, - ExistentialDepositAsset, - PriceForParentDelivery, - >; - - fn reachable_dest() -> Option { - Some(Parent.into()) - } - - fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { - None - } - - fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { - Some(( - Asset { - fun: Fungible(ExistentialDeposit::get()), - id: AssetId(Parent.into()) - }.into(), - ParentThen(Parachain(RandomParaId::get().into()).into()).into(), - )) - } - - fn set_up_complex_asset_transfer( - ) -> Option<(AssetList, u32, Location, Box)> { - None - } - - fn get_asset() -> Asset { - Asset { - id: AssetId(Location::parent()), - fun: Fungible(ExistentialDeposit::get()), - } - } - } - - use cumulus_pallet_session_benchmarking::Pallet as SessionBench; - impl cumulus_pallet_session_benchmarking::Config for Runtime {} - - use frame_support::traits::WhitelistedStorageKeys; - let whitelist = AllPalletsWithSystem::whitelisted_storage_keys(); - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - add_benchmarks!(params, batches); - - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok(batches) - } - } - - impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() - } - - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) - } - } -} - cumulus_pallet_parachain_system::register_validate_block! { Runtime = Runtime, BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, } -// tests -#[cfg(test)] -mod tests { - use super::*; - - // RUNTIME_API_VERSIONS constant is generated by a macro and is private. - #[test] - fn check_version() { - assert_eq!( - VERSION, - RuntimeVersion { - spec_name: create_runtime_str!("template-parachain"), - impl_name: create_runtime_str!("template-parachain"), - authoring_version: 1, - spec_version: 1, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 1, - } - ); - } -} +#[cfg(feature = "runtime-benchmarks")] +mod benchmark; diff --git a/generic-template/runtime/src/types.rs b/generic-template/runtime/src/types.rs new file mode 100644 index 0000000..34c6bdc --- /dev/null +++ b/generic-template/runtime/src/types.rs @@ -0,0 +1,95 @@ +use frame_support::traits::EitherOfDiverse; +use frame_system::EnsureRoot; +use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; +use sp_runtime::{ + generic, + traits::{BlakeTwo256, IdentifyAccount, Verify}, + MultiAddress, MultiSignature, +}; + +pub use crate::{ + configs::{ + xcm_config::RelayLocation, FeeAssetId, StakingAdminBodyId, ToSiblingBaseDeliveryFee, + TransactionByteFee, + }, + constants::{ + BLOCK_PROCESSING_VELOCITY, RELAY_CHAIN_SLOT_DURATION_MILLIS, UNINCLUDED_SEGMENT_CAPACITY, + }, + AllPalletsWithSystem, Runtime, RuntimeCall, XcmpQueue, +}; + +/// Alias to 512-bit hash when used in the context of a transaction signature on +/// the chain. +pub type Signature = MultiSignature; + +/// Some way of identifying an account on the chain. We intentionally make it +/// equivalent to the public key of our transaction signing scheme. +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; + +/// Balance of an account. +pub type Balance = u128; + +/// Index of a transaction in the chain. +pub type Nonce = u32; + +/// A hash of some data used by the chain. +pub type Hash = sp_core::H256; + +/// An index to a block. +pub type BlockNumber = u32; + +/// The address format for describing accounts. +pub type Address = MultiAddress; + +/// Block header type as expected by this runtime. +pub type Header = generic::Header; + +/// Block type as expected by this runtime. +pub type Block = generic::Block; + +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; + +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, +>; + +pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice< + FeeAssetId, + ToSiblingBaseDeliveryFee, + TransactionByteFee, + XcmpQueue, +>; + +/// We allow root and the StakingAdmin to execute privileged collator selection +/// operations. +pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< + EnsureRoot, + EnsureXcm>, +>; + +/// Configures the number of blocks that can be created without submission of validity proof to the relay chain +pub type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + RELAY_CHAIN_SLOT_DURATION_MILLIS, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; diff --git a/generic-template/runtime/tests/constants_test.rs b/generic-template/runtime/tests/constants_test.rs index 03ed89f..64ffd87 100644 --- a/generic-template/runtime/tests/constants_test.rs +++ b/generic-template/runtime/tests/constants_test.rs @@ -20,9 +20,32 @@ mod constant_tests { mod runtime_tests { use frame_support::{pallet_prelude::Weight, traits::TypedGet, PalletId}; - use parachain_template_runtime::{constants::currency::*, *}; + use parachain_template_runtime::{ + configs::*, + constants::{currency::*, *}, + *, + }; + use sp_runtime::create_runtime_str; + use sp_version::RuntimeVersion; use xcm::latest::prelude::BodyId; + #[test] + fn check_runtime_api_version() { + assert_eq!( + VERSION, + RuntimeVersion { + spec_name: create_runtime_str!("template-parachain"), + impl_name: create_runtime_str!("template-parachain"), + authoring_version: 1, + spec_version: 1, + impl_version: 0, + apis: parachain_template_runtime::apis::RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, + } + ); + } + #[test] fn weight_to_fee_constants() { assert_eq!(P_FACTOR, 10); @@ -199,7 +222,7 @@ mod runtime_tests { mod xcm_tests { use frame_support::weights::Weight; - use parachain_template_runtime::xcm_config::*; + use parachain_template_runtime::configs::xcm_config::*; #[test] fn xcm_executor_constants() { diff --git a/generic-template/template-fuzzer/src/main.rs b/generic-template/template-fuzzer/src/main.rs index 230e669..d734b9c 100644 --- a/generic-template/template-fuzzer/src/main.rs +++ b/generic-template/template-fuzzer/src/main.rs @@ -8,8 +8,8 @@ use frame_support::{ weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, }; use parachain_template_runtime::{ - AllPalletsWithSystem, Balance, Balances, BlockNumber, Executive, Runtime, RuntimeCall, - RuntimeOrigin, SudoConfig, UncheckedExtrinsic, SLOT_DURATION, + constants::SLOT_DURATION, AllPalletsWithSystem, Balance, Balances, BlockNumber, Executive, + Runtime, RuntimeCall, RuntimeOrigin, SudoConfig, UncheckedExtrinsic, }; use parachains_common::AccountId; use sp_consensus_aura::AURA_ENGINE_ID;