use crate::*;
use alloc::vec::Vec;
use cumulus_primitives_core::ListChannelInfos;
use frame_support::{pallet_prelude::*, traits::UncheckedOnRuntimeUpgrade};
pub trait V5Config: Config {
type ChannelList: ListChannelInfos;
}
pub type MigrateV4ToV5<T> = frame_support::migrations::VersionedMigration<
4,
5,
unversioned::UncheckedMigrateV4ToV5<T>,
Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;
mod v4 {
use super::*;
#[frame_support::storage_alias]
pub(super) type OutboundXcmpStatus<T: Config> =
StorageValue<Pallet<T>, Vec<OutboundChannelDetails>, ValueQuery>;
#[frame_support::storage_alias]
pub(super) type OutboundXcmpMessages<T: Config> = StorageDoubleMap<
Pallet<T>,
Blake2_128Concat,
ParaId,
Twox64Concat,
u16,
Vec<u8>,
ValueQuery,
>;
#[frame_support::storage_alias]
pub(super) type SignalMessages<T: Config> =
StorageMap<Pallet<T>, Blake2_128Concat, ParaId, Vec<u8>, ValueQuery>;
}
mod unversioned {
pub struct UncheckedMigrateV4ToV5<T: super::V5Config>(core::marker::PhantomData<T>);
}
impl<T: V5Config> UncheckedOnRuntimeUpgrade for unversioned::UncheckedMigrateV4ToV5<T> {
fn on_runtime_upgrade() -> frame_support::weights::Weight {
Default::default()
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
ensure!(
v4::OutboundXcmpStatus::<T>::get().len() as u32 <= T::MaxActiveOutboundChannels::get(),
"Too many outbound channels. Close some channels or increase `MaxActiveOutboundChannels`."
);
ensure!(T::MaxPageSize::get() >= 16, "Sanity check failed: MaxPageSize too small");
let max_msg_len = T::MaxPageSize::get() - XcmpMessageFormat::max_encoded_len() as u32;
for channel in T::ChannelList::outgoing_channels() {
let info = T::ChannelInfo::get_channel_info(channel)
.expect("All listed channels must provide info");
if info.max_message_size > max_msg_len {
log::error!(
"Max message size for channel is too large. This means that the V5 \
migration can be front-run and an attacker could place a large message just right \
before the migration to make other messages un-decodable. Please either increase \
`MaxPageSize` or decrease the `max_message_size` for this channel. Channel max: {}, \
MaxPageSize: {}",
info.max_message_size,
max_msg_len
);
return Err("Migration can be front-run".into());
}
}
Ok(())
}
}