diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index b73491c32d..62c9ec75f6 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -94,7 +94,7 @@ type WinnersData = Vec<(::AccountId, ParaId, Balan decl_storage! { trait Store for Module as Auctions { /// Number of auctions started so far. - pub AuctionCounter: AuctionIndex; + pub AuctionCounter get(fn auction_counter): AuctionIndex; /// Information relating to the current auction, if there is one. /// @@ -504,11 +504,9 @@ impl Module { let auction_counter = AuctionCounter::get(); Self::deposit_event(RawEvent::WinningOffset(auction_counter, offset)); let res = Winning::::get(offset).unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); - let mut i = T::BlockNumber::zero(); - while i < ending_period { - Winning::::remove(i); - i += One::one(); - } + // This `remove_all` statement should remove at most `EndingPeriod` / `SampleLength` items, + // which should be bounded and sensibly configured in the runtime. + Winning::::remove_all(); AuctionInfo::::kill(); return Some((res, lease_period_index)) } @@ -1517,6 +1515,7 @@ mod benchmarking { } // Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for auction end. + // Entire winner map should be full and removed at the end of the benchmark. on_initialize { // Create a new auction let duration: T::BlockNumber = 99u32.into(); @@ -1530,6 +1529,12 @@ mod benchmarking { assert!(winner.is_some()); } + let winning_data = Winning::::get(T::BlockNumber::from(0u32)).unwrap(); + // Make winning map full + for i in 0u32 .. (T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + Winning::::insert(T::BlockNumber::from(i), winning_data.clone()); + } + // Move ahead to the block we want to initialize frame_system::Pallet::::set_block_number(duration + now + T::EndingPeriod::get()); @@ -1546,6 +1551,7 @@ mod benchmarking { } verify { let auction_index = AuctionCounter::get(); assert_last_event::(RawEvent::AuctionClosed(auction_index).into()); + assert!(Winning::::iter().count().is_zero()); } // Worst case: 10 bidders taking all wining spots, and winning data is full. @@ -1564,7 +1570,7 @@ mod benchmarking { } // Make winning map full - for i in 0u32 .. T::EndingPeriod::get().saturated_into() { + for i in 0u32 .. (T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { Winning::::insert(T::BlockNumber::from(i), winning_data.clone()); } assert!(AuctionInfo::::get().is_some()); diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index 8c320d64b1..a4b455bf40 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -216,7 +216,6 @@ parameter_types! { pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); pub const SubmissionDeposit: Balance = 100; pub const MinContribution: Balance = 1; - pub const RetirementPeriod: BlockNumber = 10; pub const RemoveKeysLimit: u32 = 100; pub const MaxMemoLength: u8 = 32; } diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index d17e3f4f35..2456c8bf0e 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm. +//! The Kusama runtime. This can be compiled with `#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. @@ -32,7 +32,8 @@ use primitives::v1::{ InboundDownwardMessage, InboundHrmpMessage, SessionInfo, }; use runtime_common::{ - claims, SlowAdjustingFeeUpdate, CurrencyToVote, paras_registrar, xcm_sender, slots, impls::DealWithFees, + claims, paras_registrar, xcm_sender, slots, auctions, crowdloan, + SlowAdjustingFeeUpdate, CurrencyToVote, impls::DealWithFees, BlockHashCount, RocksDbWeight, BlockWeights, BlockLength, OffchainSolutionWeightLimit, OffchainSolutionLengthLimit, ToAuthor, }; @@ -426,8 +427,9 @@ impl pallet_staking::EraPayout for EraPayout { _total_issuance: Balance, era_duration_millis: u64, ) -> (Balance, Balance) { - // TODO: #2999 Update with Auctions logic when auctions pallet added. - const AUCTIONED_SLOTS: u64 = 0; + // TODO: #3011 Update with proper auctioned slots tracking. + // This should be fine for the first year of parachains. + let auctioned_slots: u64 = auctions::Pallet::::auction_counter().into(); const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10); const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; @@ -436,7 +438,7 @@ impl pallet_staking::EraPayout for EraPayout { Gilt::issuance().non_gilt, MAX_ANNUAL_INFLATION, Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), - AUCTIONED_SLOTS, + auctioned_slots, ) } } @@ -1106,6 +1108,52 @@ impl slots::Config for Runtime { type WeightInfo = weights::runtime_common_slots::WeightInfo; } +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + pub const SubmissionDeposit: Balance = 3 * GRAND; // ~ 10 KSM + pub const MinContribution: Balance = 3_000 * CENTS; // ~ .1 KSM + pub const RemoveKeysLimit: u32 = 1000; + // Allow 32 bytes for an additional memo to a crowdloan. + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Runtime { + type Event = Event; + type PalletId = CrowdloanId; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = weights::runtime_common_crowdloan::WeightInfo; +} + +parameter_types! { + // The average auction is 7 days long, so this will be 70% for ending period. + // 5 Days = 72000 Blocks @ 6 sec per block + pub const EndingPeriod: BlockNumber = 5 * DAYS; + // ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples + pub const SampleLength: BlockNumber = 2 * MINUTES; +} + +type AuctionInitiate = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective> +>; + +impl auctions::Config for Runtime { + type Event = Event; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type InitiateOrigin = AuctionInitiate; + type WeightInfo = weights::runtime_common_auctions::WeightInfo; +} + parameter_types! { /// The location of the KSM token, from the context of this chain. Since this token is native to this /// chain, we make it synonymous with it and thus it is the `Null` location, which means "equivalent to @@ -1389,6 +1437,8 @@ construct_runtime! { // Parachain Onboarding Pallets. Start indices at 70 to leave room. Registrar: paras_registrar::{Pallet, Call, Storage, Event} = 70, Slots: slots::{Pallet, Call, Storage, Event} = 71, + Auctions: auctions::{Pallet, Call, Storage, Event} = 72, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, // Pallet for sending XCM. XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event} = 99, @@ -1811,6 +1861,8 @@ sp_api::impl_runtime_apis! { // Polkadot // NOTE: Make sure to prefix these `runtime_common::` so that path resolves correctly // in the generated file. + add_benchmark!(params, batches, runtime_common::auctions, Auctions); + add_benchmark!(params, batches, runtime_common::crowdloan, Crowdloan); add_benchmark!(params, batches, runtime_common::claims, Claims); add_benchmark!(params, batches, runtime_common::slots, Slots); add_benchmark!(params, batches, runtime_common::paras_registrar, Registrar); @@ -1844,103 +1896,3 @@ sp_api::impl_runtime_apis! { } } } - -#[cfg(test)] -mod test_fees { - use super::*; - use frame_support::weights::WeightToFeePolynomial; - use frame_support::storage::StorageValue; - use sp_runtime::FixedPointNumber; - use frame_support::weights::GetDispatchInfo; - use parity_scale_codec::Encode; - use pallet_transaction_payment::Multiplier; - use separator::Separatable; - - #[test] - fn payout_weight_portion() { - use pallet_staking::WeightInfo; - let payout_weight = - ::WeightInfo::payout_stakers_alive_staked( - MaxNominatorRewardedPerValidator::get(), - ) as f64; - let block_weight = BlockWeights::get().max_block as f64; - - println!( - "a full payout takes {:.2} of the block weight [{} / {}]", - payout_weight / block_weight, - payout_weight, - block_weight - ); - assert!(payout_weight * 2f64 < block_weight); - } - - #[test] - #[ignore] - fn block_cost() { - let max_block_weight = BlockWeights::get().max_block; - let raw_fee = WeightToFee::calc(&max_block_weight); - - println!( - "Full Block weight == {} // WeightToFee(full_block) == {} plank", - max_block_weight, - raw_fee.separated_string(), - ); - } - - #[test] - #[ignore] - fn transfer_cost_min_multiplier() { - let min_multiplier = runtime_common::MinimumMultiplier::get(); - let call = >::transfer_keep_alive(Default::default(), Default::default()); - let info = call.get_dispatch_info(); - // convert to outer call. - let call = Call::Balances(call); - let len = call.using_encoded(|e| e.len()) as u32; - - let mut ext = sp_io::TestExternalities::new_empty(); - let mut test_with_multiplier = |m| { - ext.execute_with(|| { - pallet_transaction_payment::NextFeeMultiplier::put(m); - let fee = TransactionPayment::compute_fee(len, &info, 0); - println!( - "weight = {:?} // multiplier = {:?} // full transfer fee = {:?}", - info.weight.separated_string(), - pallet_transaction_payment::NextFeeMultiplier::get(), - fee.separated_string(), - ); - }); - }; - - test_with_multiplier(min_multiplier); - test_with_multiplier(Multiplier::saturating_from_rational(1, 1u128)); - test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000u128)); - test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000_000u128)); - test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000_000_000u128)); - } - - #[test] - fn nominator_limit() { - use pallet_election_provider_multi_phase::WeightInfo; - // starting point of the nominators. - let all_voters: u32 = 10_000; - - // assuming we want around 5k candidates and 1k active validators. - let all_targets: u32 = 5_000; - let desired: u32 = 1_000; - let weight_with = |active| { - ::WeightInfo::submit_unsigned( - all_voters.max(active), - all_targets, - active, - desired, - ) - }; - - let mut active = 1; - while weight_with(active) <= OffchainSolutionWeightLimit::get() || active == all_voters { - active += 1; - } - - println!("can support {} nominators to yield a weight of {}", active, weight_with(active)); - } -} diff --git a/polkadot/runtime/kusama/src/tests.rs b/polkadot/runtime/kusama/src/tests.rs index 153ad3c8da..f48a8aeb09 100644 --- a/polkadot/runtime/kusama/src/tests.rs +++ b/polkadot/runtime/kusama/src/tests.rs @@ -17,6 +17,120 @@ //! Tests for the Kusama Runtime Configuration use crate::*; +use frame_support::weights::WeightToFeePolynomial; +use frame_support::storage::StorageValue; +use sp_runtime::FixedPointNumber; +use frame_support::weights::GetDispatchInfo; +use parity_scale_codec::Encode; +use pallet_transaction_payment::Multiplier; +use separator::Separatable; + +#[test] +fn remove_keys_weight_is_sensible() { + use runtime_common::crowdloan::WeightInfo; + let max_weight = ::WeightInfo::refund(RemoveKeysLimit::get()); + // Max remove keys limit should be no more than half the total block weight. + assert!(max_weight * 2 < BlockWeights::get().max_block); +} + +#[test] +fn sample_size_is_sensible() { + use runtime_common::auctions::WeightInfo; + // Need to clean up all samples at the end of an auction. + let samples: BlockNumber = EndingPeriod::get() / SampleLength::get(); + let max_weight: Weight = RocksDbWeight::get().reads_writes(samples.into(), samples.into()); + // Max sample cleanup should be no more than half the total block weight. + assert!(max_weight * 2 < BlockWeights::get().max_block); + assert!(::WeightInfo::on_initialize() * 2 < BlockWeights::get().max_block); +} + +#[test] +fn payout_weight_portion() { + use pallet_staking::WeightInfo; + let payout_weight = + ::WeightInfo::payout_stakers_alive_staked( + MaxNominatorRewardedPerValidator::get(), + ) as f64; + let block_weight = BlockWeights::get().max_block as f64; + + println!( + "a full payout takes {:.2} of the block weight [{} / {}]", + payout_weight / block_weight, + payout_weight, + block_weight + ); + assert!(payout_weight * 2f64 < block_weight); +} + +#[test] +#[ignore] +fn block_cost() { + let max_block_weight = BlockWeights::get().max_block; + let raw_fee = WeightToFee::calc(&max_block_weight); + + println!( + "Full Block weight == {} // WeightToFee(full_block) == {} plank", + max_block_weight, + raw_fee.separated_string(), + ); +} + +#[test] +#[ignore] +fn transfer_cost_min_multiplier() { + let min_multiplier = runtime_common::MinimumMultiplier::get(); + let call = >::transfer_keep_alive(Default::default(), Default::default()); + let info = call.get_dispatch_info(); + // convert to outer call. + let call = Call::Balances(call); + let len = call.using_encoded(|e| e.len()) as u32; + + let mut ext = sp_io::TestExternalities::new_empty(); + let mut test_with_multiplier = |m| { + ext.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::put(m); + let fee = TransactionPayment::compute_fee(len, &info, 0); + println!( + "weight = {:?} // multiplier = {:?} // full transfer fee = {:?}", + info.weight.separated_string(), + pallet_transaction_payment::NextFeeMultiplier::get(), + fee.separated_string(), + ); + }); + }; + + test_with_multiplier(min_multiplier); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000_000u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000_000_000u128)); +} + +#[test] +fn nominator_limit() { + use pallet_election_provider_multi_phase::WeightInfo; + // starting point of the nominators. + let all_voters: u32 = 10_000; + + // assuming we want around 5k candidates and 1k active validators. + let all_targets: u32 = 5_000; + let desired: u32 = 1_000; + let weight_with = |active| { + ::WeightInfo::submit_unsigned( + all_voters.max(active), + all_targets, + active, + desired, + ) + }; + + let mut active = 1; + while weight_with(active) <= OffchainSolutionWeightLimit::get() || active == all_voters { + active += 1; + } + + println!("can support {} nominators to yield a weight of {}", active, weight_with(active)); +} #[test] fn compute_inflation_should_give_sensible_results() { diff --git a/polkadot/runtime/kusama/src/weights/mod.rs b/polkadot/runtime/kusama/src/weights/mod.rs index 9faf641e22..a83b57bfcd 100644 --- a/polkadot/runtime/kusama/src/weights/mod.rs +++ b/polkadot/runtime/kusama/src/weights/mod.rs @@ -37,6 +37,8 @@ pub mod pallet_tips; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_vesting; +pub mod runtime_common_auctions; pub mod runtime_common_claims; +pub mod runtime_common_crowdloan; pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs b/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs new file mode 100644 index 0000000000..2d302eb4cb --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs @@ -0,0 +1,66 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . +//! Autogenerated weights for runtime_common::auctions +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-05-11, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::auctions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_auctions.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for runtime_common::auctions. +pub struct WeightInfo(PhantomData); +impl runtime_common::auctions::WeightInfo for WeightInfo { + fn new_auction() -> Weight { + (25_733_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn bid() -> Weight { + (148_934_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn on_initialize() -> Weight { + (23_611_972_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3688 as Weight)) + .saturating_add(T::DbWeight::get().writes(3683 as Weight)) + } + fn cancel_auction() -> Weight { + (4_932_138_000 as Weight) + .saturating_add(T::DbWeight::get().reads(73 as Weight)) + .saturating_add(T::DbWeight::get().writes(3673 as Weight)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs new file mode 100644 index 0000000000..55362f7a0c --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs @@ -0,0 +1,99 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . +//! Autogenerated weights for runtime_common::crowdloan +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-05-09, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::crowdloan +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_crowdloan.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for runtime_common::crowdloan. +pub struct WeightInfo(PhantomData); +impl runtime_common::crowdloan::WeightInfo for WeightInfo { + fn create() -> Weight { + (83_361_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn contribute() -> Weight { + (563_730_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn withdraw() -> Weight { + (119_245_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn refund(k: u32, ) -> Weight { + (97_502_000 as Weight) + // Standard Error: 37_000 + .saturating_add((46_561_000 as Weight).saturating_mul(k as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(k as Weight))) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(k as Weight))) + } + fn dissolve() -> Weight { + (68_741_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn edit() -> Weight { + (41_924_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn add_memo() -> Weight { + (62_266_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn poke() -> Weight { + (48_087_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn on_initialize(n: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 19_000 + .saturating_add((117_928_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().reads((5 as Weight).saturating_mul(n as Weight))) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(n as Weight))) + } +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 1965d4006e..1e5bfa765a 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -831,7 +831,6 @@ parameter_types! { pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); pub const SubmissionDeposit: Balance = 100 * DOLLARS; pub const MinContribution: Balance = 1 * DOLLARS; - pub const RetirementPeriod: BlockNumber = 6 * HOURS; pub const RemoveKeysLimit: u32 = 500; // Allow 32 bytes for an additional memo to a crowdloan. pub const MaxMemoLength: u8 = 32; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 05cad15a5e..15528e324e 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -31,7 +31,7 @@ use primitives::v1::{ InboundDownwardMessage, InboundHrmpMessage, SessionInfo, }; use runtime_common::{ - paras_sudo_wrapper, paras_registrar, xcm_sender, slots, + paras_sudo_wrapper, paras_registrar, xcm_sender, slots, crowdloan, auctions, SlowAdjustingFeeUpdate, CurrencyToVote, impls::ToAuthor, BlockHashCount, BlockWeights, BlockLength, RocksDbWeight, @@ -80,7 +80,7 @@ use sp_version::NativeVersion; use sp_core::OpaqueMetadata; use sp_staking::SessionIndex; use frame_support::{ - parameter_types, construct_runtime, RuntimeDebug, + parameter_types, construct_runtime, RuntimeDebug, PalletId, traits::{KeyOwnerProofSystem, Filter, InstanceFilter, All}, weights::Weight, }; @@ -106,6 +106,9 @@ use constants::{time::*, currency::*, fee::*}; // Weights used in the runtime mod weights; +#[cfg(test)] +mod tests; + // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); @@ -792,6 +795,46 @@ impl slots::Config for Runtime { type WeightInfo = weights::runtime_common_slots::WeightInfo; } +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + pub const SubmissionDeposit: Balance = 100 * 100 * CENTS; + pub const MinContribution: Balance = 100 * CENTS; + pub const RemoveKeysLimit: u32 = 500; + // Allow 32 bytes for an additional memo to a crowdloan. + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Runtime { + type Event = Event; + type PalletId = CrowdloanId; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = weights::runtime_common_crowdloan::WeightInfo; +} + +parameter_types! { + // The average auction is 7 days long, so this will be 70% for ending period. + // 5 Days = 72000 Blocks @ 6 sec per block + pub const EndingPeriod: BlockNumber = 5 * DAYS; + // ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples + pub const SampleLength: BlockNumber = 2 * MINUTES; +} + +impl auctions::Config for Runtime { + type Event = Event; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type InitiateOrigin = EnsureRoot; + type WeightInfo = weights::runtime_common_auctions::WeightInfo; +} + parameter_types! { pub const WndLocation: MultiLocation = MultiLocation::Null; pub const Ancestry: MultiLocation = MultiLocation::Null; @@ -999,6 +1042,8 @@ construct_runtime! { Registrar: paras_registrar::{Pallet, Call, Storage, Event} = 60, Slots: slots::{Pallet, Call, Storage, Event} = 61, ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 62, + Auctions: auctions::{Pallet, Call, Storage, Event} = 63, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 64, // Pallet for sending XCM. XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event} = 99, @@ -1422,8 +1467,10 @@ sp_api::impl_runtime_apis! { // Polkadot // NOTE: Make sure to prefix these `runtime_common::` so that path resolves correctly // in the generated file. - add_benchmark!(params, batches, runtime_common::slots, Slots); + add_benchmark!(params, batches, runtime_common::auctions, Auctions); + add_benchmark!(params, batches, runtime_common::crowdloan, Crowdloan); add_benchmark!(params, batches, runtime_common::paras_registrar, Registrar); + add_benchmark!(params, batches, runtime_common::slots, Slots); // Substrate add_benchmark!(params, batches, pallet_balances, Balances); add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase); diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs new file mode 100644 index 0000000000..54d49d1c84 --- /dev/null +++ b/polkadot/runtime/westend/src/tests.rs @@ -0,0 +1,38 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Tests for the Westend Runtime Configuration + +use crate::*; + +#[test] +fn remove_keys_weight_is_sensible() { + use runtime_common::crowdloan::WeightInfo; + let max_weight = ::WeightInfo::refund(RemoveKeysLimit::get()); + // Max remove keys limit should be no more than half the total block weight. + assert!(max_weight * 2 < BlockWeights::get().max_block); +} + +#[test] +fn sample_size_is_sensible() { + use runtime_common::auctions::WeightInfo; + // Need to clean up all samples at the end of an auction. + let samples: BlockNumber = EndingPeriod::get() / SampleLength::get(); + let max_weight: Weight = RocksDbWeight::get().reads_writes(samples.into(), samples.into()); + // Max sample cleanup should be no more than half the total block weight. + assert!(max_weight * 2 < BlockWeights::get().max_block); + assert!(::WeightInfo::on_initialize() * 2 < BlockWeights::get().max_block); +} diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index fc5606ea37..0dc5bddb0c 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -29,5 +29,7 @@ pub mod pallet_staking; pub mod pallet_timestamp; pub mod pallet_utility; pub mod pallet_vesting; +pub mod runtime_common_auctions; +pub mod runtime_common_crowdloan; pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; diff --git a/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs b/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs new file mode 100644 index 0000000000..e044c58c58 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs @@ -0,0 +1,66 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . +//! Autogenerated weights for runtime_common::auctions +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-05-11, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::auctions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_common_auctions.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for runtime_common::auctions. +pub struct WeightInfo(PhantomData); +impl runtime_common::auctions::WeightInfo for WeightInfo { + fn new_auction() -> Weight { + (24_066_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn bid() -> Weight { + (145_175_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn on_initialize() -> Weight { + (23_489_581_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3688 as Weight)) + .saturating_add(T::DbWeight::get().writes(3683 as Weight)) + } + fn cancel_auction() -> Weight { + (4_854_267_000 as Weight) + .saturating_add(T::DbWeight::get().reads(73 as Weight)) + .saturating_add(T::DbWeight::get().writes(3673 as Weight)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs new file mode 100644 index 0000000000..20134ef6b5 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs @@ -0,0 +1,99 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . +//! Autogenerated weights for runtime_common::crowdloan +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-05-09, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::crowdloan +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_common_crowdloan.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for runtime_common::crowdloan. +pub struct WeightInfo(PhantomData); +impl runtime_common::crowdloan::WeightInfo for WeightInfo { + fn create() -> Weight { + (82_505_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn contribute() -> Weight { + (457_621_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn withdraw() -> Weight { + (117_405_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn refund(k: u32, ) -> Weight { + (83_536_000 as Weight) + // Standard Error: 35_000 + .saturating_add((45_810_000 as Weight).saturating_mul(k as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(k as Weight))) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(k as Weight))) + } + fn dissolve() -> Weight { + (70_190_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn edit() -> Weight { + (43_505_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn add_memo() -> Weight { + (60_686_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn poke() -> Weight { + (46_891_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn on_initialize(n: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 19_000 + .saturating_add((118_943_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().reads((5 as Weight).saturating_mul(n as Weight))) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(n as Weight))) + } +}