#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::vec::Vec;
use cumulus_pallet_parachain_system as parachain_system;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
pub use pallet::*;
use polkadot_primitives::PersistedValidationData;
#[frame_support::pallet]
pub mod pallet {
use super::*;
#[pallet::config]
pub trait Config:
frame_system::Config + parachain_system::Config + pallet_sudo::Config
{
type RuntimeEvent: From<Event> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
#[pallet::pallet]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);
#[pallet::storage]
pub(super) type PendingCustomValidationHeadData<T: Config> =
StorageValue<_, Vec<u8>, OptionQuery>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event {
CustomValidationHeadDataStored,
CustomValidationHeadDataApplied,
}
#[pallet::error]
pub enum Error<T> {
NoCustomHeadData,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight({0})]
pub fn schedule_migration(
origin: OriginFor<T>,
code: Vec<u8>,
head_data: Vec<u8>,
) -> DispatchResult {
ensure_root(origin)?;
parachain_system::Pallet::<T>::schedule_code_upgrade(code)?;
Self::store_pending_custom_validation_head_data(head_data);
Ok(())
}
}
impl<T: Config> Pallet<T> {
fn store_pending_custom_validation_head_data(head_data: Vec<u8>) {
PendingCustomValidationHeadData::<T>::put(head_data);
Self::deposit_event(Event::CustomValidationHeadDataStored);
}
fn set_pending_custom_validation_head_data() {
if let Some(head_data) = <PendingCustomValidationHeadData<T>>::take() {
parachain_system::Pallet::<T>::set_custom_validation_head_data(head_data);
Self::deposit_event(Event::CustomValidationHeadDataApplied);
}
}
}
impl<T: Config> parachain_system::OnSystemEvent for Pallet<T> {
fn on_validation_data(_data: &PersistedValidationData) {}
fn on_validation_code_applied() {
crate::Pallet::<T>::set_pending_custom_validation_head_data();
}
}
}