diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 55fa4cd4aa779..68d4eeeb7ad3a 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -128,7 +128,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); /// Assume 10% of weight for average on_initialize calls. - pub const MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() + pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get(); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 67e988f496c29..1637ca57062a6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -40,7 +40,7 @@ pub use node_primitives::{AccountId, Signature}; use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; use sp_runtime::{ - Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, + Permill, Perbill, Perquintill, Percent, PerThing, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str, ModuleId, }; use sp_runtime::curve::PiecewiseLinear; @@ -65,11 +65,11 @@ use static_assertions::const_assert; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -pub use pallet_timestamp::Call as TimestampCall; +#[cfg(any(feature = "std", test))] pub use pallet_balances::Call as BalancesCall; +#[cfg(any(feature = "std", test))] pub use frame_system::Call as SystemCall; -pub use pallet_contracts::Gas; -pub use frame_support::StorageValue; +#[cfg(any(feature = "std", test))] pub use pallet_staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. @@ -126,18 +126,22 @@ impl OnUnbalanced for DealWithFees { } } +const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_percent(10); parameter_types! { pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); /// Assume 10% of weight for average on_initialize calls. - pub const MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() - .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get(); + pub MaximumExtrinsicWeight: Weight = + AvailableBlockRatio::get().saturating_sub(AVERAGE_ON_INITIALIZE_WEIGHT) + * MaximumBlockWeight::get(); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; } +const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct()); + impl frame_system::Trait for Runtime { type Origin = Origin; type Call = Call; @@ -183,7 +187,7 @@ impl pallet_utility::Trait for Runtime { } parameter_types! { - pub const MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); } impl pallet_scheduler::Trait for Runtime { @@ -229,10 +233,16 @@ impl pallet_balances::Trait for Runtime { parameter_types! { pub const TransactionByteFee: Balance = 10 * MILLICENTS; - // for a sane configuration, this should always be less than `AvailableBlockRatio`. pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); } +// for a sane configuration, this should always be less than `AvailableBlockRatio`. +const_assert!( + TargetBlockFullness::get().deconstruct() < + (AvailableBlockRatio::get().deconstruct() as ::Inner) + * (::ACCURACY / ::ACCURACY as ::Inner) +); + impl pallet_transaction_payment::Trait for Runtime { type Currency = Balances; type OnTransactionPayment = DealWithFees; @@ -399,17 +409,17 @@ impl pallet_collective::Trait for Runtime { type MaxProposals = CouncilMaxProposals; } -const DESIRED_MEMBERS: u32 = 13; parameter_types! { pub const CandidacyBond: Balance = 10 * DOLLARS; pub const VotingBond: Balance = 1 * DOLLARS; pub const TermDuration: BlockNumber = 7 * DAYS; - pub const DesiredMembers: u32 = DESIRED_MEMBERS; + pub const DesiredMembers: u32 = 13; pub const DesiredRunnersUp: u32 = 7; pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect"; } + // Make sure that there are no more than `MAX_MEMBERS` members elected via phragmen. -const_assert!(DESIRED_MEMBERS <= pallet_collective::MAX_MEMBERS); +const_assert!(DesiredMembers::get() <= pallet_collective::MAX_MEMBERS); impl pallet_elections_phragmen::Trait for Runtime { type ModuleId = ElectionsPhragmenModuleId; @@ -586,7 +596,7 @@ impl pallet_im_online::Trait for Runtime { } parameter_types! { - pub const OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl pallet_offences::Trait for Runtime { diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index d9c7e24709ff8..2bbae96cf4332 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -23,7 +23,7 @@ use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, WASM_BINARY, - AccountId, + AccountId, StakerStatus, }; use node_runtime::constants::currency::*; use sp_core::ChangesTrieConfiguration; @@ -87,9 +87,9 @@ pub fn config_endowed( }), pallet_staking: Some(StakingConfig { stakers: vec![ - (dave(), alice(), 111 * DOLLARS, pallet_staking::StakerStatus::Validator), - (eve(), bob(), 100 * DOLLARS, pallet_staking::StakerStatus::Validator), - (ferdie(), charlie(), 100 * DOLLARS, pallet_staking::StakerStatus::Validator) + (dave(), alice(), 111 * DOLLARS, StakerStatus::Validator), + (eve(), bob(), 100 * DOLLARS, StakerStatus::Validator), + (ferdie(), charlie(), 100 * DOLLARS, StakerStatus::Validator) ], validator_count: 3, minimum_validator_count: 0, diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index c567aec0b6a0c..103ac6a84b6b8 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -110,7 +110,7 @@ impl frame_system::Trait for Test { type OnKilledAccount = (); } parameter_types! { - pub const MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); } impl pallet_scheduler::Trait for Test { type Event = Event; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index e429212cef622..08329fbb70b59 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -232,7 +232,7 @@ impl staking::Trait for Test { } parameter_types! { - pub const OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl offences::Trait for Test { diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 15b46fc19484b..28263a5292cb5 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -187,7 +187,7 @@ impl pallet_im_online::Trait for Test { } parameter_types! { - pub const OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl pallet_offences::Trait for Test { diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index b3f35e01711e9..30d2409a00194 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -122,7 +122,7 @@ impl frame_system::Trait for Runtime { } parameter_types! { - pub const OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl Trait for Runtime { diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 4fefe12a8e529..687fe46d16a67 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -515,7 +515,7 @@ mod tests { type Event = (); } parameter_types! { - pub const MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); } impl Trait for Test { type Event = (); diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 68d56ee955a48..471dd72a748df 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -84,27 +84,62 @@ pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; #[derive(Debug)] pub enum Never {} -/// Macro for easily creating a new implementation of the `Get` trait. Use similarly to -/// how you would declare a `const`: +/// Macro for easily creating a new implementation of the `Get` trait. If `const` token is used, the +/// rhs of the expression must be `const`-only, and get is implemented as `const`: /// -/// ```no_compile +/// ``` +/// # use frame_support::traits::Get; +/// # use frame_support::parameter_types; +/// // This function cannot be used in a const context. +/// fn non_const_expression() -> u64 { 99 } +/// +/// const FIXED_VALUE: u64 = 10; /// parameter_types! { -/// pub const Argument: u64 = 42; +/// pub const Argument: u64 = 42 + FIXED_VALUE; +/// pub OtherArgument: u64 = non_const_expression(); /// } +/// /// trait Config { /// type Parameter: Get; +/// type OtherParameter: Get; /// } +/// /// struct Runtime; /// impl Config for Runtime { /// type Parameter = Argument; +/// type OtherParameter = OtherArgument; /// } /// ``` +/// +/// Invalid example: +/// +/// ```compile_fail +/// # use frame_support::traits::Get; +/// # use frame_support::parameter_types; +/// // This function cannot be used in a const context. +/// fn non_const_expression() -> u64 { 99 } +/// +/// parameter_types! { +/// pub const Argument: u64 = non_const_expression(); +/// } +/// ``` + #[macro_export] macro_rules! parameter_types { ( $( #[ $attr:meta ] )* $vis:vis const $name:ident: $type:ty = $value:expr; $( $rest:tt )* + ) => ( + $( #[ $attr ] )* + $vis struct $name; + $crate::parameter_types!{IMPL_CONST $name , $type , $value} + $crate::parameter_types!{ $( $rest )* } + ); + ( + $( #[ $attr:meta ] )* + $vis:vis $name:ident: $type:ty = $value:expr; + $( $rest:tt )* ) => ( $( #[ $attr ] )* $vis struct $name; @@ -112,6 +147,18 @@ macro_rules! parameter_types { $crate::parameter_types!{ $( $rest )* } ); () => (); + (IMPL_CONST $name:ident , $type:ty , $value:expr) => { + impl $name { + pub const fn get() -> $type { + $value + } + } + impl> $crate::traits::Get for $name { + fn get() -> I { + I::from($value) + } + } + }; (IMPL $name:ident , $type:ty , $value:expr) => { impl $name { pub fn get() -> $type { diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 4fa826ce89893..8360f6c4cb46e 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1877,7 +1877,7 @@ pub(crate) mod tests { pub const MaximumExtrinsicWeight: Weight = 768; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 1024; - pub const Version: RuntimeVersion = RuntimeVersion { + pub Version: RuntimeVersion = RuntimeVersion { spec_name: sp_version::create_runtime_str!("test"), impl_name: sp_version::create_runtime_str!("system-test"), authoring_version: 1, diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index b50b35f7af374..cf5aa6e4cb7aa 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -383,7 +383,6 @@ macro_rules! implement_per_thing { impl $name { /// From an explicitly defined number of parts per maximum of the type. /// - /// This can be called at compile time. // needed only for peru16. Since peru16 is the only type in which $max == // $type::max_value(), rustc is being a smart-a** here by warning that the comparison // is not needed. @@ -399,9 +398,9 @@ macro_rules! implement_per_thing { Self(([x, 100][(x > 100) as usize] as $upper_type * $max as $upper_type / 100) as $type) } - /// See [`PerThing::one`]. - pub fn one() -> Self { - ::one() + /// See [`PerThing::one`] + pub const fn one() -> Self { + Self::from_parts($max) } /// See [`PerThing::is_one`]. @@ -410,8 +409,8 @@ macro_rules! implement_per_thing { } /// See [`PerThing::zero`]. - pub fn zero() -> Self { - ::zero() + pub const fn zero() -> Self { + Self::from_parts(0) } /// See [`PerThing::is_zero`]. @@ -420,8 +419,8 @@ macro_rules! implement_per_thing { } /// See [`PerThing::deconstruct`]. - pub fn deconstruct(self) -> $type { - PerThing::deconstruct(self) + pub const fn deconstruct(self) -> $type { + self.0 } /// See [`PerThing::square`]. @@ -1130,6 +1129,18 @@ macro_rules! implement_per_thing { 1, ); } + + #[test] + #[allow(unused)] + fn const_fns_work() { + const C1: $name = $name::from_percent(50); + const C2: $name = $name::one(); + const C3: $name = $name::zero(); + const C4: $name = $name::from_parts(1); + + // deconstruct is also const, hence it can be called in const rhs. + const C5: bool = C1.deconstruct() == 0; + } } }; }