Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
17 changes: 17 additions & 0 deletions cumulus/pallets/parachain-system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,23 @@ impl<T: Config> UpwardMessageSender for Pallet<T> {
fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
Self::send_upward_message(message)
}

fn can_send_upward_message(message: &UpwardMessage) -> Result<(), MessageSendError> {
#[cfg(not(feature = "runtime-benchmarks"))]
let max_upward_message_size = HostConfiguration::<T>::get()
.map(|cfg| cfg.max_upward_message_size)
.ok_or(MessageSendError::Other)?;
// for benchmarks, if host cfg is not set, we assume no limit on the size.
#[cfg(feature = "runtime-benchmarks")]
let max_upward_message_size = HostConfiguration::<T>::get()
.map(|cfg| cfg.max_upward_message_size)
.unwrap_or_else(sp_runtime::traits::Bounded::max_value);
if message.len() > max_upward_message_size as usize {
Err(MessageSendError::TooBig)
} else {
Ok(())
}
}
}

impl<T: Config> InspectMessageQueues for Pallet<T> {
Expand Down
30 changes: 29 additions & 1 deletion cumulus/pallets/parachain-system/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ fn aborted_upgrade() {
}

#[test]
fn checks_size() {
fn checks_code_size() {
BlockTests::new()
.with_relay_sproof_builder(|_, _, builder| {
builder.host_config.max_code_size = 8;
Expand Down Expand Up @@ -706,6 +706,34 @@ fn send_upward_message_relay_bottleneck() {
);
}

#[test]
fn send_upwards_message_checks_size_on_validate() {
BlockTests::new()
.with_relay_sproof_builder(|_, _, sproof| {
sproof.host_config.max_upward_message_size = 128;
})
.add(1, || {
assert_eq!(
ParachainSystem::can_send_upward_message(vec![0u8; 129].as_ref()),
Err(MessageSendError::TooBig)
);
});
}

#[test]
fn send_upward_message_check_size() {
BlockTests::new()
.with_relay_sproof_builder(|_, _, sproof| {
sproof.host_config.max_upward_message_size = 128;
})
.add(1, || {
assert_eq!(
ParachainSystem::send_upward_message(vec![0u8; 129]),
Err(MessageSendError::TooBig)
);
});
}

#[test]
fn send_hrmp_message_buffer_channel_close() {
BlockTests::new()
Expand Down
12 changes: 10 additions & 2 deletions cumulus/primitives/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,20 @@ pub trait UpwardMessageSender {
/// Send the given UMP message; return the expected number of blocks before the message will
/// be dispatched or an error if the message cannot be sent.
/// return the hash of the message sent
fn send_upward_message(msg: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError>;
fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError>;

/// Pre-check the given UMP message.
fn can_send_upward_message(message: &UpwardMessage) -> Result<(), MessageSendError>;
}

impl UpwardMessageSender for () {
fn send_upward_message(_msg: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
fn send_upward_message(_message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
Err(MessageSendError::NoChannel)
}

fn can_send_upward_message(_message: &UpwardMessage) -> Result<(), MessageSendError> {
Err(MessageSendError::Other)
}
}

/// The status of a channel.
Expand Down
20 changes: 16 additions & 4 deletions cumulus/primitives/utility/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ where
.map_err(|()| SendError::ExceedsMaxMessageSize)?;
let data = versioned_xcm.encode();

// Pre-check with our message sender if everything else is okay.
T::can_send_upward_message(&data).map_err(Self::map_upward_sender_err)?;

Ok((data, price))
} else {
// Anything else is unhandled. This includes a message that is not meant for us.
Expand All @@ -87,12 +90,17 @@ where
}

fn deliver(data: Vec<u8>) -> Result<XcmHash, SendError> {
let (_, hash) = T::send_upward_message(data).map_err(|e| match e {
let (_, hash) = T::send_upward_message(data).map_err(Self::map_upward_sender_err)?;
Ok(hash)
}
}

impl<T, W, P> ParentAsUmp<T, W, P> {
fn map_upward_sender_err(message_send_error: MessageSendError) -> SendError {
match message_send_error {
MessageSendError::TooBig => SendError::ExceedsMaxMessageSize,
e => SendError::Transport(e.into()),
})?;

Ok(hash)
}
}
}

Expand Down Expand Up @@ -602,6 +610,10 @@ mod test_xcm_router {
fn send_upward_message(_: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
Err(MessageSendError::Other)
}

fn can_send_upward_message(_: &UpwardMessage) -> Result<(), MessageSendError> {
Err(MessageSendError::Other)
}
}

#[test]
Expand Down
14 changes: 14 additions & 0 deletions prdoc/pr_8409.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: check XCM size in VMP routing
doc:
- audience: Runtime Dev
description: |-
This PR adds the ability for a UMP (para -> relay), when using `UpwardMessageSender` to also
check the size of the message within validate. This is exposed into the existing `validate` of
`ParentAsUmp`.
crates:
- name: cumulus-pallet-parachain-system
bump: minor
- name: cumulus-primitives-core
bump: minor
- name: cumulus-primitives-utility
bump: minor
Loading