mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 17:31:03 +00:00
Use a BoundedVec in ValidationResult (#6603)
* Use a `BoundedVec` in `ValidationResult` > Use a `BoundedVec` for `upward_messages` and `horizontal_messages` in order to > limit the number of individual messages/memory allocations right at decoding > time. The reason for this is that the `ValidationResult` may contain a code > upgrade (including a full PVF binary), so the total size limit can't be set > too low and this limit will still allow several millions of upward messages, > which will (due to the memory allocator overhead) already have a > non-negligible memory footprint in decoded form. * List all fields when hashing so we don't miss one * Define types for `BoundedVec`s of messages * Fix test compile errors * Depend on `bounded-collections` 0.1.4 (fixes allocation issue) * Fix compilation issue * Derive `Hash` instead of manual `impl` * Avoid use of unwrap
This commit is contained in:
@@ -45,6 +45,7 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
rand_chacha = { version = "0.3.1", default-features = false }
|
||||
static_assertions = { version = "1.1.0", optional = true }
|
||||
polkadot-parachain = { path = "../../parachain", default-features = false }
|
||||
polkadot-runtime-metrics = { path = "../metrics", default-features = false}
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -292,8 +292,8 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
||||
availability_votes,
|
||||
);
|
||||
let commitments = CandidateCommitments::<u32> {
|
||||
upward_messages: vec![],
|
||||
horizontal_messages: vec![],
|
||||
upward_messages: Default::default(),
|
||||
horizontal_messages: Default::default(),
|
||||
new_validation_code: None,
|
||||
head_data: Self::mock_head_data(),
|
||||
processed_downward_messages: 0,
|
||||
@@ -535,8 +535,8 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
||||
validation_code_hash,
|
||||
},
|
||||
commitments: CandidateCommitments::<u32> {
|
||||
upward_messages: Vec::new(),
|
||||
horizontal_messages: Vec::new(),
|
||||
upward_messages: Default::default(),
|
||||
horizontal_messages: Default::default(),
|
||||
new_validation_code: includes_code_upgrade
|
||||
.map(|v| ValidationCode(vec![42u8; v as usize])),
|
||||
head_data,
|
||||
|
||||
@@ -22,6 +22,7 @@ use crate::shared;
|
||||
use frame_support::{pallet_prelude::*, weights::constants::WEIGHT_REF_TIME_PER_MILLIS};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use polkadot_parachain::primitives::{MAX_HORIZONTAL_MESSAGE_NUM, MAX_UPWARD_MESSAGE_NUM};
|
||||
use primitives::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE};
|
||||
use sp_runtime::traits::Zero;
|
||||
use sp_std::prelude::*;
|
||||
@@ -322,8 +323,12 @@ pub enum InconsistentError<BlockNumber> {
|
||||
},
|
||||
/// `validation_upgrade_delay` is less than or equal 1.
|
||||
ValidationUpgradeDelayIsTooLow { validation_upgrade_delay: BlockNumber },
|
||||
/// Maximum UMP message size (`MAX_UPWARD_MESSAGE_SIZE_BOUND`) exceeded.
|
||||
/// Maximum UMP message size ([`MAX_UPWARD_MESSAGE_SIZE_BOUND`]) exceeded.
|
||||
MaxUpwardMessageSizeExceeded { max_message_size: u32 },
|
||||
/// Maximum HRMP message num ([`MAX_HORIZONTAL_MESSAGE_NUM`]) exceeded.
|
||||
MaxHorizontalMessageNumExceeded { max_message_num: u32 },
|
||||
/// Maximum UMP message num ([`MAX_UPWARD_MESSAGE_NUM`]) exceeded.
|
||||
MaxUpwardMessageNumExceeded { max_message_num: u32 },
|
||||
/// Maximum number of HRMP outbound channels exceeded.
|
||||
MaxHrmpOutboundChannelsExceeded,
|
||||
/// Maximum number of HRMP inbound channels exceeded.
|
||||
@@ -396,6 +401,18 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
if self.hrmp_max_message_num_per_candidate > MAX_HORIZONTAL_MESSAGE_NUM {
|
||||
return Err(MaxHorizontalMessageNumExceeded {
|
||||
max_message_num: self.hrmp_max_message_num_per_candidate,
|
||||
})
|
||||
}
|
||||
|
||||
if self.max_upward_message_num_per_candidate > MAX_UPWARD_MESSAGE_NUM {
|
||||
return Err(MaxUpwardMessageNumExceeded {
|
||||
max_message_num: self.max_upward_message_num_per_candidate,
|
||||
})
|
||||
}
|
||||
|
||||
if self.hrmp_max_parachain_outbound_channels > crate::hrmp::HRMP_MAX_OUTBOUND_CHANNELS_BOUND
|
||||
{
|
||||
return Err(MaxHrmpOutboundChannelsExceeded)
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::{
|
||||
use frame_support::{pallet_prelude::*, traits::ReservableCurrency};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use polkadot_parachain::primitives::HorizontalMessages;
|
||||
use primitives::{
|
||||
Balance, Hash, HrmpChannelId, Id as ParaId, InboundHrmpMessage, OutboundHrmpMessage,
|
||||
SessionIndex,
|
||||
@@ -1057,10 +1058,7 @@ impl<T: Config> Pallet<T> {
|
||||
/// 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: Vec<OutboundHrmpMessage<ParaId>>,
|
||||
) -> Weight {
|
||||
pub(crate) fn queue_outbound_hrmp(sender: ParaId, out_hrmp_msgs: HorizontalMessages) -> Weight {
|
||||
let mut weight = Weight::zero();
|
||||
let now = <frame_system::Pallet<T>>::block_number();
|
||||
|
||||
|
||||
@@ -278,8 +278,10 @@ fn send_recv_messages() {
|
||||
// A sends a message to B
|
||||
run_to_block(6, Some(vec![6]));
|
||||
assert!(channel_exists(para_a, para_b));
|
||||
let msgs =
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: b"this is an emergency".to_vec() }];
|
||||
let msgs: HorizontalMessages =
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: b"this is an emergency".to_vec() }]
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let config = Configuration::config();
|
||||
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
||||
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs);
|
||||
@@ -313,13 +315,17 @@ fn hrmp_mqc_head_fixture() {
|
||||
run_to_block(3, Some(vec![3]));
|
||||
let _ = Hrmp::queue_outbound_hrmp(
|
||||
para_a,
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }],
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
run_to_block(4, None);
|
||||
let _ = Hrmp::queue_outbound_hrmp(
|
||||
para_a,
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }],
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -381,7 +387,10 @@ fn check_sent_messages() {
|
||||
run_to_block(6, Some(vec![6]));
|
||||
assert!(Paras::is_valid_para(para_a));
|
||||
|
||||
let msgs = vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }];
|
||||
let msgs: HorizontalMessages =
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }]
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let config = Configuration::config();
|
||||
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
||||
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs.clone());
|
||||
|
||||
@@ -20,6 +20,7 @@ use crate::{
|
||||
};
|
||||
use frame_support::{pallet_prelude::*, traits::EnsureOrigin};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use polkadot_parachain::primitives::UpwardMessages;
|
||||
use primitives::{Id as ParaId, UpwardMessage};
|
||||
use sp_std::{collections::btree_map::BTreeMap, fmt, marker::PhantomData, mem, prelude::*};
|
||||
use xcm::latest::Outcome;
|
||||
@@ -28,7 +29,7 @@ pub use pallet::*;
|
||||
|
||||
/// Maximum value that `config.max_upward_message_size` can be set to
|
||||
///
|
||||
/// This is used for benchmarking sanely bounding relevant storate items. It is expected from the `configurations`
|
||||
/// This is used for benchmarking sanely bounding relevant storage items. It is expected from the `configurations`
|
||||
/// pallet to check these values before setting.
|
||||
pub const MAX_UPWARD_MESSAGE_SIZE_BOUND: u32 = 50 * 1024;
|
||||
/// Maximum amount of overweight messages that can exist in the queue at any given time.
|
||||
@@ -470,10 +471,7 @@ impl<T: Config> Pallet<T> {
|
||||
}
|
||||
|
||||
/// Enqueues `upward_messages` from a `para`'s accepted candidate block.
|
||||
pub(crate) fn receive_upward_messages(
|
||||
para: ParaId,
|
||||
upward_messages: Vec<UpwardMessage>,
|
||||
) -> Weight {
|
||||
pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: UpwardMessages) -> Weight {
|
||||
let mut weight = Weight::zero();
|
||||
|
||||
if !upward_messages.is_empty() {
|
||||
|
||||
@@ -32,7 +32,7 @@ fn queue_upward_msg<T: Config>(
|
||||
msg: UpwardMessage,
|
||||
) {
|
||||
let len = msg.len() as u32;
|
||||
let msgs = vec![msg];
|
||||
let msgs: UpwardMessages = vec![msg].try_into().unwrap();
|
||||
Ump::<T>::check_upward_messages(host_conf, para, &msgs).unwrap();
|
||||
let _ = Ump::<T>::receive_upward_messages(para, msgs);
|
||||
assert_last_event_type::<T>(Event::UpwardMessagesReceived(para, 1, len).into());
|
||||
|
||||
@@ -72,7 +72,7 @@ fn default_genesis_config() -> MockGenesisConfig {
|
||||
}
|
||||
|
||||
fn queue_upward_msg(para: ParaId, msg: UpwardMessage) {
|
||||
let msgs = vec![msg];
|
||||
let msgs: UpwardMessages = vec![msg].try_into().unwrap();
|
||||
assert!(Ump::check_upward_messages(&Configuration::config(), para, &msgs).is_ok());
|
||||
let _ = Ump::receive_upward_messages(para, msgs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user