cumulus_pallet_xcmp_queue/migration/
v5.rs1use crate::*;
20use alloc::vec::Vec;
21use cumulus_primitives_core::ListChannelInfos;
22use frame_support::{pallet_prelude::*, traits::UncheckedOnRuntimeUpgrade};
23
24pub trait V5Config: Config {
26 type ChannelList: ListChannelInfos;
28}
29
30pub type MigrateV4ToV5<T> = frame_support::migrations::VersionedMigration<
35 4,
36 5,
37 unversioned::UncheckedMigrateV4ToV5<T>,
38 Pallet<T>,
39 <T as frame_system::Config>::DbWeight,
40>;
41
42mod v4 {
44 use super::*;
45
46 #[frame_support::storage_alias]
47 pub(super) type OutboundXcmpStatus<T: Config> =
48 StorageValue<Pallet<T>, Vec<OutboundChannelDetails>, ValueQuery>;
49
50 #[frame_support::storage_alias]
51 pub(super) type OutboundXcmpMessages<T: Config> = StorageDoubleMap<
52 Pallet<T>,
53 Blake2_128Concat,
54 ParaId,
55 Twox64Concat,
56 u16,
57 Vec<u8>,
58 ValueQuery,
59 >;
60
61 #[frame_support::storage_alias]
62 pub(super) type SignalMessages<T: Config> =
63 StorageMap<Pallet<T>, Blake2_128Concat, ParaId, Vec<u8>, ValueQuery>;
64}
65
66mod unversioned {
68 pub struct UncheckedMigrateV4ToV5<T: super::V5Config>(core::marker::PhantomData<T>);
70}
71
72impl<T: V5Config> UncheckedOnRuntimeUpgrade for unversioned::UncheckedMigrateV4ToV5<T> {
73 fn on_runtime_upgrade() -> frame_support::weights::Weight {
74 Default::default()
75 }
76
77 #[cfg(feature = "try-runtime")]
78 fn post_upgrade(_: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
79 ensure!(
81 v4::OutboundXcmpStatus::<T>::get().len() as u32 <= T::MaxActiveOutboundChannels::get(),
82 "Too many outbound channels. Close some channels or increase `MaxActiveOutboundChannels`."
83 );
84
85 ensure!(T::MaxPageSize::get() >= 16, "Sanity check failed: MaxPageSize too small");
86
87 let max_msg_len = T::MaxPageSize::get() - XcmpMessageFormat::max_encoded_len() as u32;
89 for channel in T::ChannelList::outgoing_channels() {
90 let info = T::ChannelInfo::get_channel_info(channel)
91 .expect("All listed channels must provide info");
92
93 if info.max_message_size > max_msg_len {
94 tracing::error!(
95 target: "runtime::xcmp-queue-migration::v5",
96 channel_max=%info.max_message_size,
97 max_page_size=%max_msg_len,
98 "Max message size for channel is too large. This means that the V5 \
99 migration can be front-run and an attacker could place a large message just right \
100 before the migration to make other messages un-decodable. Please either increase \
101 `MaxPageSize` or decrease the `max_message_size` for this channel."
102 );
103 return Err("Migration can be front-run".into());
104 }
105 }
106
107 Ok(())
108 }
109}