diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index bf663b4cfcea..903c8dd1af29 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -17,9 +17,7 @@ libc = { workspace = true } nix = { features = ["resource", "sched"], workspace = true } thiserror = { workspace = true } -codec = { features = [ - "derive", -], workspace = true } +codec = { features = ["derive"], workspace = true } polkadot-parachain-primitives = { workspace = true, default-features = true } polkadot-primitives = { workspace = true, default-features = true } diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 59afff359d08..65e56881c315 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -68,6 +68,21 @@ fn account(name: &'static str, index: u32, seed: u32) -> Acco .expect("infinite input; no invalid input; qed") } +pub fn generate_validator_pairs( + validator_count: u32, +) -> Vec<(T::AccountId, ValidatorId)> { + (0..validator_count) + .map(|i| { + let public = ValidatorId::generate_pair(None); + + // The account Id is not actually used anywhere, just necessary to fulfill the + // expected type of the `validators` param of `test_trigger_on_new_session`. + let account: T::AccountId = account("validator", i, i); + (account, public) + }) + .collect() +} + /// Create a 32 byte slice based on the given number. fn byte32_slice_from(n: u32) -> [u8; 32] { let mut slice = [0u8; 32]; @@ -423,20 +438,6 @@ impl BenchBuilder { } } - /// Generate validator key pairs and account ids. - fn generate_validator_pairs(validator_count: u32) -> Vec<(T::AccountId, ValidatorId)> { - (0..validator_count) - .map(|i| { - let public = ValidatorId::generate_pair(None); - - // The account Id is not actually used anywhere, just necessary to fulfill the - // expected type of the `validators` param of `test_trigger_on_new_session`. - let account: T::AccountId = account("validator", i, i); - (account, public) - }) - .collect() - } - fn signing_context(&self) -> SigningContext { SigningContext { parent_hash: Self::header(self.block_number).hash(), @@ -800,7 +801,7 @@ impl BenchBuilder { c.scheduler_params.num_cores = used_cores as u32; }); - let validator_ids = Self::generate_validator_pairs(self.max_validators()); + let validator_ids = generate_validator_pairs::(self.max_validators()); let target_session = SessionIndex::from(self.target_session); let builder = self.setup_session(target_session, validator_ids, used_cores, extra_cores); diff --git a/polkadot/runtime/parachains/src/dmp.rs b/polkadot/runtime/parachains/src/dmp.rs index 54e112d1b8b4..03580e11b8e9 100644 --- a/polkadot/runtime/parachains/src/dmp.rs +++ b/polkadot/runtime/parachains/src/dmp.rs @@ -287,7 +287,7 @@ impl Pallet { } /// Prunes the specified number of messages from the downward message queue of the given para. - pub(crate) fn prune_dmq(para: ParaId, processed_downward_messages: u32) -> Weight { + pub(crate) fn prune_dmq(para: ParaId, processed_downward_messages: u32) { let q_len = DownwardMessageQueues::::mutate(para, |q| { let processed_downward_messages = processed_downward_messages as usize; if processed_downward_messages > q.len() { @@ -306,7 +306,6 @@ impl Pallet { if q_len <= (threshold as usize) { Self::decrease_fee_factor(para); } - T::DbWeight::get().reads_writes(1, 1) } /// Returns the Head of Message Queue Chain for the given para or `None` if there is none diff --git a/polkadot/runtime/parachains/src/hrmp.rs b/polkadot/runtime/parachains/src/hrmp.rs index 8b01a755c3c7..b149404b41b8 100644 --- a/polkadot/runtime/parachains/src/hrmp.rs +++ b/polkadot/runtime/parachains/src/hrmp.rs @@ -1305,9 +1305,7 @@ impl Pallet { remaining } - pub(crate) fn prune_hrmp(recipient: ParaId, new_hrmp_watermark: BlockNumberFor) -> Weight { - let mut weight = Weight::zero(); - + pub(crate) fn prune_hrmp(recipient: ParaId, new_hrmp_watermark: BlockNumberFor) { // sift through the incoming messages digest to collect the paras that sent at least one // message to this parachain between the old and new watermarks. let senders = HrmpChannelDigests::::mutate(&recipient, |digest| { @@ -1323,7 +1321,6 @@ impl Pallet { *digest = leftover; senders }); - weight += T::DbWeight::get().reads_writes(1, 1); // having all senders we can trivially find out the channels which we need to prune. let channels_to_prune = @@ -1356,21 +1353,13 @@ impl Pallet { channel.total_size -= pruned_size as u32; } }); - - weight += T::DbWeight::get().reads_writes(2, 2); } HrmpWatermarks::::insert(&recipient, new_hrmp_watermark); - weight += T::DbWeight::get().reads_writes(0, 1); - - weight } /// Process the outbound HRMP messages by putting them into the appropriate recipient queues. - /// - /// Returns the amount of weight consumed. - pub(crate) fn queue_outbound_hrmp(sender: ParaId, out_hrmp_msgs: HorizontalMessages) -> Weight { - let mut weight = Weight::zero(); + pub(crate) fn queue_outbound_hrmp(sender: ParaId, out_hrmp_msgs: HorizontalMessages) { let now = frame_system::Pallet::::block_number(); for out_msg in out_hrmp_msgs { @@ -1426,11 +1415,7 @@ impl Pallet { recipient_digest.push((now, vec![sender])); } HrmpChannelDigests::::insert(&channel_id.recipient, recipient_digest); - - weight += T::DbWeight::get().reads_writes(2, 2); } - - weight } /// Initiate opening a channel from a parachain to a given recipient with given channel diff --git a/polkadot/runtime/parachains/src/inclusion/benchmarking.rs b/polkadot/runtime/parachains/src/inclusion/benchmarking.rs index 169e858deda8..978ef718ea40 100644 --- a/polkadot/runtime/parachains/src/inclusion/benchmarking.rs +++ b/polkadot/runtime/parachains/src/inclusion/benchmarking.rs @@ -15,23 +15,134 @@ // along with Polkadot. If not, see . use super::*; +use crate::{ + builder::generate_validator_pairs, + configuration, + hrmp::{HrmpChannel, HrmpChannels}, + initializer, HeadData, ValidationCode, +}; +use bitvec::{bitvec, prelude::Lsb0}; use frame_benchmarking::benchmarks; use pallet_message_queue as mq; +use polkadot_primitives::{ + CandidateCommitments, CollatorId, CollatorSignature, CommittedCandidateReceipt, HrmpChannelId, + OutboundHrmpMessage, SessionIndex, +}; +use sp_core::sr25519; + +fn create_candidate_commitments( + para_id: ParaId, + head_data: HeadData, + max_msg_len: usize, + ump_msg_count: u32, + hrmp_msg_count: u32, + code_upgrade: bool, +) -> CandidateCommitments { + let upward_messages = { + let unbounded = create_messages(max_msg_len, ump_msg_count as _); + BoundedVec::truncate_from(unbounded) + }; + + let horizontal_messages = { + let unbounded = create_messages(max_msg_len, hrmp_msg_count as _); + + for n in 0..unbounded.len() { + let channel_id = HrmpChannelId { sender: para_id, recipient: para_id + n as u32 + 1 }; + HrmpChannels::::insert( + &channel_id, + HrmpChannel { + sender_deposit: 42, + recipient_deposit: 42, + max_capacity: 10_000_000, + max_total_size: 1_000_000_000, + max_message_size: 10_000_000, + msg_count: 0, + total_size: 0, + mqc_head: None, + }, + ); + } + + let unbounded = unbounded + .into_iter() + .enumerate() + .map(|(n, data)| OutboundHrmpMessage { recipient: para_id + n as u32 + 1, data }) + .collect(); + BoundedVec::truncate_from(unbounded) + }; + + let new_validation_code = code_upgrade.then_some(ValidationCode(vec![42u8; 1024])); + + CandidateCommitments:: { + upward_messages, + horizontal_messages, + new_validation_code, + head_data, + processed_downward_messages: 0, + hrmp_watermark: 10, + } +} + +fn create_messages(msg_len: usize, n_msgs: usize) -> Vec> { + let best_number = 73_u8; // Chuck Norris of numbers + vec![vec![best_number; msg_len]; n_msgs] +} benchmarks! { where_clause { where - T: mq::Config, + T: mq::Config + configuration::Config + initializer::Config, } - receive_upward_messages { - let i in 1 .. 1000; + enact_candidate { + let u in 1 .. 32; + let h in 1 .. 32; + let c in 0 .. 1; + + let para = 42_u32.into(); // not especially important. let max_len = mq::MaxMessageLenOf::::get() as usize; - let para = 42u32.into(); // not especially important. - let upward_messages = vec![vec![0; max_len]; i as usize]; + + let config = configuration::ActiveConfig::::get(); + let n_validators = config.max_validators.unwrap_or(500); + let validators = generate_validator_pairs::(n_validators); + + let session = SessionIndex::from(0u32); + initializer::Pallet::::test_trigger_on_new_session( + false, + session, + validators.iter().map(|(a, v)| (a, v.clone())), + None, + ); + let backing_group_size = config.scheduler_params.max_validators_per_core.unwrap_or(5); + let head_data = HeadData(vec![0xFF; 1024]); + + let relay_parent_number = BlockNumberFor::::from(10u32); + let commitments = create_candidate_commitments::(para, head_data, max_len, u, h, c != 0); + let backers = bitvec![u8, Lsb0; 1; backing_group_size as usize]; + let availability_votes = bitvec![u8, Lsb0; 1; n_validators as usize]; + let core_index = CoreIndex::from(0); + let backing_group = GroupIndex::from(0); + + let descriptor = CandidateDescriptor:: { + para_id: para, + relay_parent: Default::default(), + collator: CollatorId::from(sr25519::Public::from_raw([42u8; 32])), + persisted_validation_data_hash: Default::default(), + pov_hash: Default::default(), + erasure_root: Default::default(), + signature: CollatorSignature::from(sr25519::Signature::from_raw([42u8; 64])), + para_head: Default::default(), + validation_code_hash: ValidationCode(vec![1, 2, 3]).hash(), + }; + + let receipt = CommittedCandidateReceipt:: { + descriptor, + commitments, + }; + Pallet::::receive_upward_messages(para, vec![vec![0; max_len]; 1].as_slice()); - }: { Pallet::::receive_upward_messages(para, upward_messages.as_slice()) } + } : { Pallet::::enact_candidate(relay_parent_number, receipt, backers, availability_votes, core_index, backing_group) } impl_benchmark_test_suite!( Pallet, diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 115eee975530..fbf13339dfca 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -65,18 +65,23 @@ mod benchmarking; pub mod migration; pub trait WeightInfo { - fn receive_upward_messages(i: u32) -> Weight; + /// Weight for `enact_candidate` extrinsic given the number of sent messages + /// (ump, hrmp) and whether there is a new code for a runtime upgrade. + /// + /// NOTE: due to a shortcoming of the current benchmarking framework, + /// we use `u32` for the code upgrade, even though it is a `bool`. + fn enact_candidate(u: u32, h: u32, c: u32) -> Weight; } pub struct TestWeightInfo; impl WeightInfo for TestWeightInfo { - fn receive_upward_messages(_: u32) -> Weight { - Weight::MAX + fn enact_candidate(_u: u32, _h: u32, _c: u32) -> Weight { + Weight::zero() } } impl WeightInfo for () { - fn receive_upward_messages(_: u32) -> Weight { + fn enact_candidate(_u: u32, _h: u32, _c: u32) -> Weight { Weight::zero() } } @@ -507,7 +512,7 @@ impl Pallet { pub(crate) fn update_pending_availability_and_get_freed_cores( validators: &[ValidatorId], signed_bitfields: SignedAvailabilityBitfields, - ) -> Vec<(CoreIndex, CandidateHash)> { + ) -> (Weight, Vec<(CoreIndex, CandidateHash)>) { let threshold = availability_threshold(validators.len()); let mut votes_per_core: BTreeMap> = BTreeMap::new(); @@ -528,6 +533,7 @@ impl Pallet { } let mut freed_cores = vec![]; + let mut weight = Weight::zero(); let pending_paraids: Vec<_> = PendingAvailability::::iter_keys().collect(); for paraid in pending_paraids { @@ -581,7 +587,17 @@ impl Pallet { descriptor: candidate.descriptor, commitments: candidate.commitments, }; - let _weight = Self::enact_candidate( + + let has_runtime_upgrade = + receipt.commitments.new_validation_code.as_ref().map_or(0, |_| 1); + let u = receipt.commitments.upward_messages.len() as u32; + let h = receipt.commitments.horizontal_messages.len() as u32; + let enact_weight = ::WeightInfo::enact_candidate( + u, + h, + has_runtime_upgrade, + ); + Self::enact_candidate( candidate.relay_parent_number, receipt, candidate.backers, @@ -589,13 +605,14 @@ impl Pallet { candidate.core, candidate.backing_group, ); + weight.saturating_accrue(enact_weight); } } } }); } - freed_cores + (weight, freed_cores) } /// Process candidates that have been backed. Provide a set of @@ -842,7 +859,7 @@ impl Pallet { availability_votes: BitVec, core_index: CoreIndex, backing_group: GroupIndex, - ) -> Weight { + ) { let plain = receipt.to_plain(); let commitments = receipt.commitments; let config = configuration::ActiveConfig::::get(); @@ -863,38 +880,36 @@ impl Pallet { .map(|(i, _)| ValidatorIndex(i as _)), ); - // initial weight is config read. - let mut weight = T::DbWeight::get().reads_writes(1, 0); if let Some(new_code) = commitments.new_validation_code { // Block number of candidate's inclusion. let now = frame_system::Pallet::::block_number(); - weight.saturating_add(paras::Pallet::::schedule_code_upgrade( + paras::Pallet::::schedule_code_upgrade( receipt.descriptor.para_id, new_code, now, &config, UpgradeStrategy::SetGoAheadSignal, - )); + ); } // enact the messaging facet of the candidate. - weight.saturating_accrue(dmp::Pallet::::prune_dmq( + dmp::Pallet::::prune_dmq( receipt.descriptor.para_id, commitments.processed_downward_messages, - )); - weight.saturating_accrue(Self::receive_upward_messages( + ); + Self::receive_upward_messages( receipt.descriptor.para_id, commitments.upward_messages.as_slice(), - )); - weight.saturating_accrue(hrmp::Pallet::::prune_hrmp( + ); + hrmp::Pallet::::prune_hrmp( receipt.descriptor.para_id, BlockNumberFor::::from(commitments.hrmp_watermark), - )); - weight.saturating_accrue(hrmp::Pallet::::queue_outbound_hrmp( + ); + hrmp::Pallet::::queue_outbound_hrmp( receipt.descriptor.para_id, commitments.horizontal_messages, - )); + ); Self::deposit_event(Event::::CandidateIncluded( plain, @@ -903,11 +918,11 @@ impl Pallet { backing_group, )); - weight.saturating_add(paras::Pallet::::note_new_head( + paras::Pallet::::note_new_head( receipt.descriptor.para_id, commitments.head_data, relay_parent_number, - )) + ); } pub(crate) fn relay_dispatch_queue_size(para_id: ParaId) -> (u32, u32) { @@ -972,7 +987,7 @@ impl Pallet { /// This function is infallible since the candidate was already accepted and we therefore need /// to deal with the messages as given. Messages that are too long will be ignored since such /// candidates should have already been rejected in [`Self::check_upward_messages`]. - pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: &[Vec]) -> Weight { + pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: &[Vec]) { let bounded = upward_messages .iter() .filter_map(|d| { @@ -991,19 +1006,17 @@ impl Pallet { pub(crate) fn receive_bounded_upward_messages( para: ParaId, messages: Vec>>, - ) -> Weight { + ) { let count = messages.len() as u32; if count == 0 { - return Weight::zero() + return } T::MessageQueue::enqueue_messages( messages.into_iter(), AggregateMessageOrigin::Ump(UmpQueueId::Para(para)), ); - let weight = ::WeightInfo::receive_upward_messages(count); Self::deposit_event(Event::UpwardMessagesReceived { from: para, count }); - weight } /// Cleans up all timed out candidates as well as their descendant candidates. diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index 3ead456cde5a..95fd66bf8e4f 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -366,10 +366,11 @@ pub(crate) fn process_bitfields( ) -> Vec<(CoreIndex, CandidateHash)> { let validators = shared::ActiveValidatorKeys::::get(); - ParaInclusion::update_pending_availability_and_get_freed_cores( + let (_weight, bitfields) = ParaInclusion::update_pending_availability_and_get_freed_cores( &validators[..], signed_bitfields, - ) + ); + bitfields } #[test] diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index fbe9ebf809b3..75c9e3a5c9b9 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -449,8 +449,16 @@ impl SendXcm for DummyXcmSender { } } +pub struct InclusionWeightInfo; + +impl crate::inclusion::WeightInfo for InclusionWeightInfo { + fn enact_candidate(_u: u32, _h: u32, _c: u32) -> Weight { + Weight::from_parts(1024 * 1024, 0) + } +} + impl crate::inclusion::Config for Test { - type WeightInfo = (); + type WeightInfo = InclusionWeightInfo; type RuntimeEvent = RuntimeEvent; type DisputesHandler = Disputes; type RewardValidators = TestRewardValidators; diff --git a/polkadot/runtime/parachains/src/paras/mod.rs b/polkadot/runtime/parachains/src/paras/mod.rs index a4c404de2a65..5048656e6363 100644 --- a/polkadot/runtime/parachains/src/paras/mod.rs +++ b/polkadot/runtime/parachains/src/paras/mod.rs @@ -1956,14 +1956,12 @@ impl Pallet { inclusion_block_number: BlockNumberFor, cfg: &configuration::HostConfiguration>, upgrade_strategy: UpgradeStrategy, - ) -> Weight { - let mut weight = T::DbWeight::get().reads(1); - + ) { // Should be prevented by checks in `schedule_code_upgrade_external` let new_code_len = new_code.0.len(); if new_code_len < MIN_CODE_SIZE as usize || new_code_len > cfg.max_code_size as usize { log::warn!(target: LOG_TARGET, "attempted to schedule an upgrade with invalid new validation code",); - return weight + return } // Enacting this should be prevented by the `can_upgrade_validation_code` @@ -1977,7 +1975,7 @@ impl Pallet { // NOTE: we cannot set `UpgradeGoAheadSignal` signal here since this will be reset by // the following call `note_new_head` log::warn!(target: LOG_TARGET, "ended up scheduling an upgrade while one is pending",); - return weight + return } let code_hash = new_code.hash(); @@ -1986,7 +1984,6 @@ impl Pallet { // process right away. // // We do not want to allow this since it will mess with the code reference counting. - weight += T::DbWeight::get().reads(1); if CurrentCodeHash::::get(&id) == Some(code_hash) { // NOTE: we cannot set `UpgradeGoAheadSignal` signal here since this will be reset by // the following call `note_new_head` @@ -1994,15 +1991,13 @@ impl Pallet { target: LOG_TARGET, "para tried to upgrade to the same code. Abort the upgrade", ); - return weight + return } // This is the start of the upgrade process. Prevent any further attempts at upgrading. - weight += T::DbWeight::get().writes(2); FutureCodeHash::::insert(&id, &code_hash); UpgradeRestrictionSignal::::insert(&id, UpgradeRestriction::Present); - weight += T::DbWeight::get().reads_writes(1, 1); let next_possible_upgrade_at = inclusion_block_number + cfg.validation_upgrade_cooldown; UpgradeCooldowns::::mutate(|upgrade_cooldowns| { let insert_idx = upgrade_cooldowns @@ -2011,14 +2006,12 @@ impl Pallet { upgrade_cooldowns.insert(insert_idx, (id, next_possible_upgrade_at)); }); - weight += Self::kick_off_pvf_check( + Self::kick_off_pvf_check( PvfCheckCause::Upgrade { id, included_at: inclusion_block_number, upgrade_strategy }, code_hash, new_code, cfg, ); - - weight } /// Makes sure that the given code hash has passed pre-checking. @@ -2108,11 +2101,11 @@ impl Pallet { id: ParaId, new_head: HeadData, execution_context: BlockNumberFor, - ) -> Weight { + ) { Heads::::insert(&id, &new_head); MostRecentContext::::insert(&id, execution_context); - let weight = if let Some(expected_at) = FutureCodeUpgrades::::get(&id) { + if let Some(expected_at) = FutureCodeUpgrades::::get(&id) { if expected_at <= execution_context { FutureCodeUpgrades::::remove(&id); UpgradeGoAheadSignal::::remove(&id); @@ -2122,14 +2115,10 @@ impl Pallet { new_code_hash } else { log::error!(target: LOG_TARGET, "Missing future code hash for {:?}", &id); - return T::DbWeight::get().reads_writes(3, 1 + 3) + return }; - let weight = Self::set_current_code(id, new_code_hash, expected_at); - - weight + T::DbWeight::get().reads_writes(3, 3) - } else { - T::DbWeight::get().reads_writes(1, 1 + 0) + Self::set_current_code(id, new_code_hash, expected_at); } } else { // This means there is no upgrade scheduled. @@ -2137,10 +2126,9 @@ impl Pallet { // In case the upgrade was aborted by the relay-chain we should reset // the `Abort` signal. UpgradeGoAheadSignal::::remove(&id); - T::DbWeight::get().reads_writes(1, 2) }; - weight.saturating_add(T::OnNewHead::on_new_head(id, &new_head)) + T::OnNewHead::on_new_head(id, &new_head); } /// Set the current code for the given parachain. diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 9d27e86ef901..bd8d08a842c3 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -347,12 +347,12 @@ impl Pallet { let bitfields_weight = signed_bitfields_weight::(&bitfields); let disputes_weight = multi_dispute_statement_sets_weight::(&disputes); - // Weight before filtering/sanitization - let all_weight_before = candidates_weight + bitfields_weight + disputes_weight; + // Weight before filtering/sanitization except for enacting the candidates + let weight_before_filtering = candidates_weight + bitfields_weight + disputes_weight; - METRICS.on_before_filter(all_weight_before.ref_time()); - log::debug!(target: LOG_TARGET, "Size before filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_before.proof_size(), candidates_weight.proof_size() + bitfields_weight.proof_size(), disputes_weight.proof_size()); - log::debug!(target: LOG_TARGET, "Time weight before filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_before.ref_time(), candidates_weight.ref_time() + bitfields_weight.ref_time(), disputes_weight.ref_time()); + METRICS.on_before_filter(weight_before_filtering.ref_time()); + log::debug!(target: LOG_TARGET, "Size before filter: {}, candidates + bitfields: {}, disputes: {}", weight_before_filtering.proof_size(), candidates_weight.proof_size() + bitfields_weight.proof_size(), disputes_weight.proof_size()); + log::debug!(target: LOG_TARGET, "Time weight before filter: {}, candidates + bitfields: {}, disputes: {}", weight_before_filtering.ref_time(), candidates_weight.ref_time() + bitfields_weight.ref_time(), disputes_weight.ref_time()); let current_session = shared::CurrentSessionIndex::::get(); let expected_bits = scheduler::AvailabilityCores::::get().len(); @@ -409,7 +409,7 @@ impl Pallet { max_block_weight, ); - let all_weight_after = if context == ProcessInherentDataContext::ProvideInherent { + let mut all_weight_after = if context == ProcessInherentDataContext::ProvideInherent { // Assure the maximum block weight is adhered, by limiting bitfields and backed // candidates. Dispute statement sets were already limited before. let non_disputes_weight = apply_weight_limit::( @@ -424,11 +424,11 @@ impl Pallet { METRICS.on_after_filter(all_weight_after.ref_time()); log::debug!( - target: LOG_TARGET, - "[process_inherent_data] after filter: bitfields.len(): {}, backed_candidates.len(): {}, checked_disputes_sets.len() {}", - bitfields.len(), - backed_candidates.len(), - checked_disputes_sets.len() + target: LOG_TARGET, + "[process_inherent_data] after filter: bitfields.len(): {}, backed_candidates.len(): {}, checked_disputes_sets.len() {}", + bitfields.len(), + backed_candidates.len(), + checked_disputes_sets.len() ); log::debug!(target: LOG_TARGET, "Size after filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_after.proof_size(), non_disputes_weight.proof_size(), checked_disputes_sets_consumed_weight.proof_size()); log::debug!(target: LOG_TARGET, "Time weight after filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_after.ref_time(), non_disputes_weight.ref_time(), checked_disputes_sets_consumed_weight.ref_time()); @@ -440,17 +440,20 @@ impl Pallet { } else { // This check is performed in the context of block execution. Ensures inherent weight // invariants guaranteed by `create_inherent_data` for block authorship. - if all_weight_before.any_gt(max_block_weight) { + if weight_before_filtering.any_gt(max_block_weight) { log::error!( "Overweight para inherent data reached the runtime {:?}: {} > {}", parent_hash, - all_weight_before, + weight_before_filtering, max_block_weight ); } - ensure!(all_weight_before.all_lte(max_block_weight), Error::::InherentOverweight); - all_weight_before + ensure!( + weight_before_filtering.all_lte(max_block_weight), + Error::::InherentOverweight + ); + weight_before_filtering }; // Note that `process_checked_multi_dispute_data` will iterate and import each @@ -529,11 +532,32 @@ impl Pallet { // Process new availability bitfields, yielding any availability cores whose // work has now concluded. - let freed_concluded = + let (enact_weight, freed_concluded) = inclusion::Pallet::::update_pending_availability_and_get_freed_cores( &validator_public[..], bitfields.clone(), ); + all_weight_after.saturating_accrue(enact_weight); + log::debug!( + target: LOG_TARGET, + "Enacting weight: {}, all weight: {}", + enact_weight.ref_time(), + all_weight_after.ref_time(), + ); + + // It's possible that that after the enacting the candidates, the total weight + // goes over the limit, however, we can't do anything about it at this point. + // By using the `Mandatory` weight, we ensure the block is still accepted, + // but no other (user) transactions can be included. + if all_weight_after.any_gt(max_block_weight) { + log::warn!( + target: LOG_TARGET, + "Overweight para inherent data after enacting the candidates {:?}: {} > {}", + parent_hash, + all_weight_after, + max_block_weight, + ); + } // Inform the disputes module of all included candidates. for (_, candidate_hash) in &freed_concluded { diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 59fbb0948373..ad89e68e9059 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -943,6 +943,65 @@ mod enter { }); } + // Ensure that even if the block is over weight due to candidates enactment, + // we still can import it. + #[test] + fn overweight_candidates_enactment_is_fine() { + sp_tracing::try_init_simple(); + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + use crate::inclusion::WeightInfo as _; + + let mut backed_and_concluding = BTreeMap::new(); + // The number of candidates is chosen to go over the weight limit + // of the mock runtime together with the `enact_candidate`s weight. + let num_candidates = 5u32; + let max_weight = ::BlockWeights::get().max_block; + assert!(::WeightInfo::enact_candidate(0, 0, 0) + .saturating_mul(u64::from(num_candidates)) + .any_gt(max_weight)); + + for i in 0..num_candidates { + backed_and_concluding.insert(i, 2); + } + + let num_validators_per_core: u32 = 5; + let num_backed = backed_and_concluding.len(); + let bitfields_len = num_validators_per_core as usize * num_backed; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], + backed_and_concluding, + num_validators_per_core, + code_upgrade: None, + fill_claimqueue: true, + elastic_paras: BTreeMap::new(), + unavailable_cores: vec![], + }); + + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + assert_eq!(expected_para_inherent_data.bitfields.len(), bitfields_len); + assert_eq!(expected_para_inherent_data.backed_candidates.len(), num_backed); + assert_eq!(expected_para_inherent_data.disputes.len(), 0); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + assert!(limit_inherent_data == expected_para_inherent_data); + + assert_ok!(Pallet::::enter( + frame_system::RawOrigin::None.into(), + limit_inherent_data, + )); + }); + } + fn max_block_weight_proof_size_adjusted() -> Weight { let raw_weight = ::BlockWeights::get().max_block; let block_length = ::BlockLength::get(); diff --git a/polkadot/runtime/parachains/src/paras_inherent/weights.rs b/polkadot/runtime/parachains/src/paras_inherent/weights.rs index 3e84c132aa24..81c926a90e0b 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/weights.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/weights.rs @@ -19,6 +19,7 @@ //! the relay chain, but we do care about the size of the block, by putting the tx in the //! proof_size we can use the already existing weight limiting code to limit the used size as well. +use crate::{configuration, inclusion}; use codec::{Encode, WrapperTypeEncode}; use polkadot_primitives::{ CheckedMultiDisputeStatementSet, MultiDisputeStatementSet, UncheckedSignedAvailabilityBitfield, @@ -96,6 +97,7 @@ pub fn paras_inherent_total_weight( backed_candidates_weight::(backed_candidates) .saturating_add(signed_bitfields_weight::(bitfields)) .saturating_add(multi_dispute_statement_sets_weight::(disputes)) + .saturating_add(enact_candidates_max_weight::(bitfields)) } pub fn multi_dispute_statement_sets_weight( @@ -156,6 +158,27 @@ pub fn signed_bitfield_weight(bitfield: &UncheckedSignedAvailabilityB ) } +/// Worst case scenario is all candidates have been enacted +/// and process a maximum number of messages. +pub fn enact_candidates_max_weight( + bitfields: &UncheckedSignedAvailabilityBitfields, +) -> Weight { + let config = configuration::ActiveConfig::::get(); + let max_ump_msgs = config.max_upward_message_num_per_candidate; + let max_hrmp_msgs = config.hrmp_max_message_num_per_candidate; + // No bitfields - no enacted candidates + let bitfield_size = bitfields.first().map(|b| b.unchecked_payload().0.len()).unwrap_or(0); + set_proof_size_to_tx_size( + <::WeightInfo as inclusion::WeightInfo>::enact_candidate( + max_ump_msgs, + max_hrmp_msgs, + 1, // runtime upgrade + ) + .saturating_mul(bitfield_size as u64), + bitfields, + ) +} + pub fn backed_candidate_weight( candidate: &BackedCandidate, ) -> Weight { diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_inclusion.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_inclusion.rs index da1b7a0dad9a..4c6ce8835573 100644 --- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_inclusion.rs +++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_inclusion.rs @@ -14,27 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Autogenerated weights for `runtime_parachains::inclusion` +//! Autogenerated weights for `polkadot_runtime_parachains::inclusion` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --pallet=runtime_parachains::inclusion // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_parachains_inclusion.rs +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=polkadot_runtime_parachains::inclusion +// --chain=rococo-dev +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -44,31 +45,79 @@ use frame_support::{traits::Get, weights::Weight}; use core::marker::PhantomData; -/// Weight functions for `runtime_parachains::inclusion`. +/// Weight functions for `polkadot_runtime_parachains::inclusion`. pub struct WeightInfo(PhantomData); impl polkadot_runtime_parachains::inclusion::WeightInfo for WeightInfo { - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:999) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// The range of component `i` is `[1, 1000]`. - fn receive_upward_messages(i: u32, ) -> Weight { + /// Storage: `Paras::FutureCodeHash` (r:1 w:1) + /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeCooldowns` (r:1 w:1) + /// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:1 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:32) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: `Hrmp::HrmpChannelDigests` (r:33 w:33) + /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:32 w:32) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelContents` (r:32 w:32) + /// Proof: `Hrmp::HrmpChannelContents` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) + /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeRestrictionSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// The range of component `u` is `[1, 32]`. + /// The range of component `h` is `[1, 32]`. + /// The range of component `c` is `[0, 1]`. + fn enact_candidate(u: u32, h: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `33280` - // Estimated: `36283` - // Minimum execution time: 71_094_000 picoseconds. - Weight::from_parts(71_436_000, 0) - .saturating_add(Weight::from_parts(0, 36283)) - // Standard Error: 22_149 - .saturating_add(Weight::from_parts(51_495_472, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + // Measured: `33353 + c * (16114 ±0) + h * (75 ±0)` + // Estimated: `36818 + c * (26467 ±0) + h * (2551 ±0)` + // Minimum execution time: 4_829_551_000 picoseconds. + Weight::from_parts(1_892_697_027, 0) + .saturating_add(Weight::from_parts(0, 36818)) + // Standard Error: 793_993 + .saturating_add(Weight::from_parts(126_698_671, 0).saturating_mul(u.into())) + // Standard Error: 793_993 + .saturating_add(Weight::from_parts(144_116_038, 0).saturating_mul(h.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(h.into()))) + .saturating_add(T::DbWeight::get().reads((8_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(10)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(h.into()))) + .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 26467).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(h.into())) } } diff --git a/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_inclusion.rs b/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_inclusion.rs index 25909beb6a07..36a4c5c24c9a 100644 --- a/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_inclusion.rs +++ b/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_inclusion.rs @@ -14,30 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Autogenerated weights for `runtime_parachains::inclusion` +//! Autogenerated weights for `polkadot_runtime_parachains::inclusion` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=westend-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=runtime_parachains::inclusion // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/westend/src/weights/runtime_parachains_inclusion.rs +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=polkadot_runtime_parachains::inclusion +// --chain=westend-dev +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/westend/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,29 +45,87 @@ use frame_support::{traits::Get, weights::Weight}; use core::marker::PhantomData; -/// Weight functions for `runtime_parachains::inclusion`. +/// Weight functions for `polkadot_runtime_parachains::inclusion`. pub struct WeightInfo(PhantomData); impl polkadot_runtime_parachains::inclusion::WeightInfo for WeightInfo { - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:999) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) - /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// The range of component `i` is `[1, 1000]`. - fn receive_upward_messages(i: u32, ) -> Weight { + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaSessionInfo::AccountKeys` (r:1 w:0) + /// Proof: `ParaSessionInfo::AccountKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::Validators` (r:1 w:0) + /// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Staking::ActiveEra` (r:1 w:0) + /// Proof: `Staking::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasRewardPoints` (r:1 w:1) + /// Proof: `Staking::ErasRewardPoints` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeHash` (r:1 w:1) + /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeCooldowns` (r:1 w:1) + /// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:1 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:32) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(131122), added: 133597, mode: `MaxEncodedLen`) + /// Storage: `Hrmp::HrmpChannelDigests` (r:33 w:33) + /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:32 w:32) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelContents` (r:32 w:32) + /// Proof: `Hrmp::HrmpChannelContents` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) + /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeRestrictionSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// The range of component `u` is `[1, 32]`. + /// The range of component `h` is `[1, 32]`. + /// The range of component `c` is `[0, 1]`. + fn enact_candidate(u: u32, h: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `131297` - // Estimated: `134587` - // Minimum execution time: 209_898_000 picoseconds. - Weight::from_parts(210_955_000, 0) - .saturating_add(Weight::from_parts(0, 134587)) - // Standard Error: 97_069 - .saturating_add(Weight::from_parts(207_030_437, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + // Measured: `132737 + c * (15992 ±0) + h * (75 ±0)` + // Estimated: `136202 + c * (76098 ±0) + h * (2551 ±0)` + // Minimum execution time: 18_868_930_000 picoseconds. + Weight::from_parts(6_899_601_016, 0) + .saturating_add(Weight::from_parts(0, 136202)) + // Standard Error: 1_952_665 + .saturating_add(Weight::from_parts(467_810_135, 0).saturating_mul(u.into())) + // Standard Error: 1_952_665 + .saturating_add(Weight::from_parts(551_226_340, 0).saturating_mul(h.into())) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(h.into()))) + .saturating_add(T::DbWeight::get().reads((8_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(h.into()))) + .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 76098).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(h.into())) } } diff --git a/prdoc/pr_5270.prdoc b/prdoc/pr_5270.prdoc new file mode 100644 index 000000000000..e6d7142cabd0 --- /dev/null +++ b/prdoc/pr_5270.prdoc @@ -0,0 +1,20 @@ +title: "Inclusion: account for enact_candidate weight" + +doc: + - audience: Runtime Dev + description: | + We are now properly accounting for the `enact_candidate`s weight in + processing of a relay chain block inherent. This may result in some + of the user relay chain transactions not being included in the block if + it's really heavy. This should be fine though as we are moving towards + the minimal relay chain. + +crates: +- name: polkadot-runtime-parachains + bump: major +- name: westend-runtime + bump: patch +- name: rococo-runtime + bump: patch +- name: polkadot-node-core-pvf-common + bump: none