Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cumulus/pallets/xcmp-queue/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ xcm-executor = { workspace = true }
# Cumulus
cumulus-primitives-core = { workspace = true }

# Optional import for weight accuracy testing
approx = { optional = true, workspace = true }
# Optional import for benchmarking
bounded-collections = { workspace = true }
frame-benchmarking = { optional = true, workspace = true }
Expand All @@ -53,6 +55,7 @@ cumulus-pallet-parachain-system = { workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"approx/std",
"bounded-collections/std",
"bp-xcm-bridge-hub-router?/std",
"codec/std",
Expand Down
49 changes: 47 additions & 2 deletions cumulus/pallets/xcmp-queue/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

//! Benchmarking setup for cumulus-pallet-xcmp-queue

use crate::*;
use crate::{weights_ext::get_average_page_pos, *};

use alloc::vec;
use codec::DecodeAll;
Expand Down Expand Up @@ -107,6 +107,40 @@ mod benchmarks {
}
}

/// Add an XCMP message of 0 bytes to the message queue at the provided position
/// on an existing page.
#[benchmark]
fn enqueue_empty_xcmp_message_at(
n: Linear<0, { crate::MaxXcmpMessageLenOf::<T>::get() - 10 }>,
) {
#[cfg(test)]
{
mock::EnqueuedMessages::set(vec![]);
}

assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
0.into(),
&[BoundedVec::try_from(vec![0; n as usize]).unwrap()],
&mut WeightMeter::new()
));

#[cfg(not(test))]
let fp_before = T::XcmpQueue::footprint(0.into());
#[block]
{
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
0.into(),
&[Default::default()],
&mut WeightMeter::new()
));
}
#[cfg(not(test))]
{
let fp_after = T::XcmpQueue::footprint(0.into());
assert_eq!(fp_after.ready_pages, fp_before.ready_pages);
}
}

/// Add `n` pages to the message queue.
///
/// We add one page by enqueueing a maximal size message which fills it.
Expand Down Expand Up @@ -157,6 +191,17 @@ mod benchmarks {
});
}

assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
0.into(),
&[BoundedVec::try_from(vec![
0;
get_average_page_pos(MaxXcmpMessageLenOf::<T>::get())
as usize
])
.unwrap()],
&mut WeightMeter::new()
));

let mut msgs = vec![];
for _i in 0..1000 {
msgs.push(BoundedVec::try_from(vec![0; 3]).unwrap());
Expand All @@ -175,7 +220,7 @@ mod benchmarks {
#[cfg(not(test))]
{
let fp_after = T::XcmpQueue::footprint(0.into());
assert_eq!(fp_after.ready_pages, fp_before.ready_pages + 1);
assert_eq!(fp_after.ready_pages, fp_before.ready_pages);
}
}

Expand Down
36 changes: 8 additions & 28 deletions cumulus/pallets/xcmp-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ pub mod weights;
pub mod weights_ext;

pub use weights::WeightInfo;
#[cfg(feature = "std")]
pub use weights_ext::check_weight_info_ext_accuracy;
pub use weights_ext::WeightInfoExt;

extern crate alloc;
Expand All @@ -68,8 +66,8 @@ use cumulus_primitives_core::{
use frame_support::{
defensive, defensive_assert,
traits::{
BatchFootprint, Defensive, EnqueueMessage, EnsureOrigin, Get, QueueFootprint,
QueueFootprintQuery, QueuePausedQuery,
Defensive, EnqueueMessage, EnsureOrigin, Get, QueueFootprint, QueueFootprintQuery,
QueuePausedQuery,
},
weights::{Weight, WeightMeter},
BoundedVec,
Expand All @@ -79,7 +77,7 @@ use polkadot_runtime_common::xcm_sender::PriceForMessageDelivery;
use polkadot_runtime_parachains::{FeeTracker, GetMinFeeFactor};
use scale_info::TypeInfo;
use sp_core::MAX_POSSIBLE_ALLOCATION;
use sp_runtime::{FixedU128, RuntimeDebug, WeakBoundedVec};
use sp_runtime::{FixedU128, RuntimeDebug, SaturatedConversion, WeakBoundedVec};
use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm, WrapVersion, MAX_XCM_DECODE_DEPTH};
use xcm_builder::InspectMessageQueues;
use xcm_executor::traits::ConvertOrigin;
Expand Down Expand Up @@ -643,39 +641,21 @@ impl<T: Config> Pallet<T> {
drop_threshold,
);

// `batches_footprints[n]` contains the footprint of the batch `xcms[0..n]`,
// so as `n` increases `batches_footprints[n]` contains the footprint of a bigger batch.
let best_batch_idx = batches_footprints.binary_search_by(|batch_info| {
let best_batch_footprint = batches_footprints.search_best_by(|batch_info| {
let required_weight = T::WeightInfo::enqueue_xcmp_messages(
batch_info.new_pages_count,
batch_info.msgs_count,
batch_info.size_in_bytes,
batches_footprints.first_page_pos.saturated_into(),
batch_info,
);

match meter.can_consume(required_weight) {
true => core::cmp::Ordering::Less,
false => core::cmp::Ordering::Greater,
}
});
let best_batch_idx = match best_batch_idx {
Ok(last_ok_idx) => {
// We should never reach this branch since we never return `Ordering::Equal`.
defensive!("Unexpected best_batch_idx found: Ok({})", last_ok_idx);
Some(last_ok_idx)
},
Err(first_err_idx) => first_err_idx.checked_sub(1),
};
let best_batch_footprint = match best_batch_idx {
Some(best_batch_idx) => batches_footprints.get(best_batch_idx).ok_or_else(|| {
defensive!("Invalid best_batch_idx: {}", best_batch_idx);
})?,
None => &BatchFootprint { msgs_count: 0, size_in_bytes: 0, new_pages_count: 0 },
};

meter.consume(T::WeightInfo::enqueue_xcmp_messages(
best_batch_footprint.new_pages_count,
best_batch_footprint.msgs_count,
best_batch_footprint.size_in_bytes,
batches_footprints.first_page_pos.saturated_into(),
best_batch_footprint,
));
T::XcmpQueue::enqueue_messages(
xcms.iter()
Expand Down
18 changes: 5 additions & 13 deletions cumulus/pallets/xcmp-queue/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use cumulus_pallet_parachain_system::AnyRelayNumber;
use cumulus_primitives_core::{ChannelInfo, IsSystem, ParaId};
use frame_support::{
derive_impl, parameter_types,
traits::{ConstU32, Everything, OriginTrait},
traits::{BatchesFootprints, ConstU32, Everything, OriginTrait},
BoundedSlice,
};
use frame_system::EnsureRoot;
Expand Down Expand Up @@ -193,24 +193,16 @@ impl<T: OnQueueChanged<ParaId>> QueueFootprintQuery<ParaId> for EnqueueToLocalSt
origin: ParaId,
msgs: impl Iterator<Item = BoundedSlice<'a, u8, Self::MaxMessageLen>>,
total_pages_limit: u32,
) -> Vec<BatchFootprint> {
) -> BatchesFootprints {
// Let's consider that we add one message per page
let footprint = Self::footprint(origin);
let mut batches_footprints = vec![];
let mut new_pages_count = 0;
let mut total_size = 0;
let mut batches_footprints = BatchesFootprints::default();
for (idx, msg) in msgs.enumerate() {
new_pages_count += 1;
if footprint.pages + new_pages_count > total_pages_limit {
if footprint.pages + idx as u32 + 1 > total_pages_limit {
break;
}

total_size += msg.len();
batches_footprints.push(BatchFootprint {
msgs_count: idx + 1,
size_in_bytes: total_size,
new_pages_count,
})
batches_footprints.push(msg.into(), true);
}
batches_footprints
}
Expand Down
12 changes: 8 additions & 4 deletions cumulus/pallets/xcmp-queue/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use XcmpMessageFormat::*;
use codec::Input;
use cumulus_primitives_core::{ParaId, XcmpMessageHandler};
use frame_support::{
assert_err, assert_noop, assert_ok, assert_storage_noop, hypothetically, traits::Hooks,
assert_err, assert_noop, assert_ok, assert_storage_noop, hypothetically,
traits::{BatchFootprint, Hooks},
StorageNoopGuard,
};
use mock::{new_test_ext, ParachainSystem, RuntimeOrigin as Origin, Test, XcmpQueue};
Expand Down Expand Up @@ -210,9 +211,12 @@ fn xcm_enqueueing_starts_dropping_on_out_of_weight() {

total_size += xcm.len();
let required_weight = <<Test as Config>::WeightInfo>::enqueue_xcmp_messages(
idx as u32 + 1,
idx + 1,
total_size,
0,
&BatchFootprint {
msgs_count: idx + 1,
size_in_bytes: total_size,
new_pages_count: idx as u32 + 1,
},
);

let mut weight_meter = WeightMeter::with_limit(required_weight);
Expand Down
Loading
Loading