Unverified Commit 20dd6228 authored by asynchronous rob's avatar asynchronous rob Committed by GitHub
Browse files

Use strong types in runtime for parachain heads and validation code (#964)

* use stronger types for HeadData and ValidationCode in runtime

* fix weird debug compile error

* fix runtime build

* update invocations invalidation.rs

* fix tests
parent 90e9898d
Pipeline #87534 passed with stages
in 23 minutes and 54 seconds
......@@ -2290,7 +2290,6 @@ dependencies = [
"pallet-utility",
"pallet-vesting",
"parity-scale-codec",
"polkadot-parachain",
"polkadot-primitives",
"polkadot-runtime-common",
"rustc-hex",
......@@ -4276,7 +4275,6 @@ dependencies = [
"pallet-treasury",
"pallet-vesting",
"parity-scale-codec",
"polkadot-parachain",
"polkadot-primitives",
"polkadot-runtime-common",
"rustc-hex",
......@@ -4326,7 +4324,6 @@ dependencies = [
"pallet-treasury",
"pallet-vesting",
"parity-scale-codec",
"polkadot-parachain",
"polkadot-primitives",
"rustc-hex",
"serde",
......
......@@ -22,7 +22,7 @@ use polkadot_primitives::parachain::{
Id as ParaId, Chain, DutyRoster, ParachainHost, ValidatorId,
Retriable, CollatorId, AbridgedCandidateReceipt,
GlobalValidationSchedule, LocalValidationData, ErasureChunk, SigningContext,
PoVBlock, BlockData,
PoVBlock, BlockData, ValidationCode,
};
use polkadot_validation::{SharedTable, TableRouter};
......@@ -163,8 +163,8 @@ sp_api::mock_impl_runtime_apis! {
self.data.lock().active_parachains.clone()
}
fn parachain_code(_: ParaId) -> Option<Vec<u8>> {
Some(Vec::new())
fn parachain_code(_: ParaId) -> Option<ValidationCode> {
Some(ValidationCode(Vec::new()))
}
fn global_validation_schedule() -> GlobalValidationSchedule {
......
......@@ -33,15 +33,27 @@ use sp_core::bytes;
pub type RelayChainBlockNumber = u32;
/// Parachain head data included in the chain.
#[derive(PartialEq, Eq, Clone, PartialOrd, Ord, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Default))]
#[derive(PartialEq, Eq, Clone, PartialOrd, Ord, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Default))]
pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl From<Vec<u8>> for HeadData {
fn from(head: Vec<u8>) -> Self {
HeadData(head)
}
}
/// Parachain validation code.
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ValidationCode(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl From<Vec<u8>> for ValidationCode {
fn from(code: Vec<u8>) -> Self {
ValidationCode(code)
}
}
/// Parachain block data.
///
/// Contains everything required to validate para-block, may contain block and witness data.
......
......@@ -214,7 +214,7 @@ pub struct CandidateCommitments {
/// The root of a block's erasure encoding Merkle tree.
pub erasure_root: Hash,
/// New validation code.
pub new_validation_code: Option<Vec<u8>>,
pub new_validation_code: Option<ValidationCode>,
}
/// Get a collator signature payload on a relay-parent, block-data combo.
......@@ -672,7 +672,7 @@ sp_api::decl_runtime_apis! {
/// Get the local validation data for a particular parachain.
fn local_validation_data(id: Id) -> Option<LocalValidationData>;
/// Get the given parachain's head code blob.
fn parachain_code(id: Id) -> Option<Vec<u8>>;
fn parachain_code(id: Id) -> Option<ValidationCode>;
/// Extract the abridged head that was set in the extrinsics.
fn get_heads(extrinsics: Vec<<Block as BlockT>::Extrinsic>)
-> Option<Vec<AbridgedCandidateReceipt>>;
......
......@@ -32,7 +32,6 @@ offences = { package = "pallet-offences", git = "https://github.com/paritytech/s
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false }
polkadot-parachain = { path = "../../parachain", default-features = false }
libsecp256k1 = { version = "0.3.2", default-features = false, optional = true }
[dev-dependencies]
......@@ -57,7 +56,6 @@ std = [
"codec/std",
"inherents/std",
"sp-core/std",
"polkadot-parachain/std",
"sp-api/std",
"sp-std/std",
"sp-io/std",
......
......@@ -80,7 +80,7 @@ use crate::slots;
use codec::{Encode, Decode};
use sp_std::vec::Vec;
use sp_core::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX;
use primitives::parachain::Id as ParaId;
use primitives::parachain::{Id as ParaId, HeadData};
const MODULE_ID: ModuleId = ModuleId(*b"py/cfund");
......@@ -124,7 +124,7 @@ pub enum LastContribution<BlockNumber> {
struct DeployData<Hash> {
code_hash: Hash,
code_size: u32,
initial_head_data: Vec<u8>,
initial_head_data: HeadData,
}
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
......@@ -358,7 +358,7 @@ decl_module! {
#[compact] index: FundIndex,
code_hash: T::Hash,
code_size: u32,
initial_head_data: Vec<u8>
initial_head_data: HeadData,
) {
let who = ensure_signed(origin)?;
......@@ -582,7 +582,7 @@ mod tests {
};
use frame_support::traits::Contains;
use sp_core::H256;
use primitives::parachain::{Info as ParaInfo, Id as ParaId, Scheduling};
use primitives::parachain::{Info as ParaInfo, Id as ParaId, Scheduling, ValidationCode};
// The testing primitives are very useful for avoiding having to work with signatures
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
use sp_runtime::{
......@@ -675,7 +675,7 @@ mod tests {
thread_local! {
pub static PARACHAIN_COUNT: RefCell<u32> = RefCell::new(0);
pub static PARACHAINS:
RefCell<HashMap<u32, (Vec<u8>, Vec<u8>)>> = RefCell::new(HashMap::new());
RefCell<HashMap<u32, (ValidationCode, HeadData)>> = RefCell::new(HashMap::new());
}
const MAX_CODE_SIZE: u32 = 100;
......@@ -705,8 +705,8 @@ mod tests {
fn register_para(
id: ParaId,
_info: ParaInfo,
code: Vec<u8>,
initial_head_data: Vec<u8>
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult {
PARACHAINS.with(|p| {
if p.borrow().contains_key(&id.into()) {
......@@ -919,7 +919,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into()
));
let fund = Crowdfund::funds(0).unwrap();
......@@ -930,7 +930,7 @@ mod tests {
Some(DeployData {
code_hash: <Test as system::Trait>::Hash::default(),
code_size: 0,
initial_head_data: vec![0],
initial_head_data: vec![0].into(),
}),
);
});
......@@ -949,7 +949,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]),
vec![0].into()),
Error::<Test>::InvalidOrigin
);
......@@ -959,7 +959,7 @@ mod tests {
1,
<Test as system::Trait>::Hash::default(),
0,
vec![0]),
vec![0].into()),
Error::<Test>::InvalidFundIndex
);
......@@ -969,7 +969,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
assert_noop!(Crowdfund::fix_deploy_data(
......@@ -977,7 +977,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![1]),
vec![1].into()),
Error::<Test>::ExistingDeployData
);
});
......@@ -997,7 +997,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
// Fund crowdfund
......@@ -1043,7 +1043,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
// Cannot onboard fund with incorrect parachain id
......@@ -1071,7 +1071,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
// Fund crowdfund
......@@ -1114,7 +1114,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
// Fund crowdfund
......@@ -1256,7 +1256,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
assert_ok!(Crowdfund::onboard(Origin::signed(1), 0, 0.into()));
......@@ -1285,7 +1285,7 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
// Move to the end of auction...
run_to_block(12);
......@@ -1324,14 +1324,14 @@ mod tests {
0,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
assert_ok!(Crowdfund::fix_deploy_data(
Origin::signed(2),
1,
<Test as system::Trait>::Hash::default(),
0,
vec![0]
vec![0].into(),
));
// End the current auction, fund 0 wins!
......
This diff is collapsed.
......@@ -36,7 +36,7 @@ use frame_support::{
use system::{self, ensure_root, ensure_signed};
use primitives::parachain::{
Id as ParaId, CollatorId, Scheduling, LOWEST_USER_ID, SwapAux, Info as ParaInfo, ActiveParas,
Retriable
Retriable, ValidationCode, HeadData,
};
use crate::parachains;
use sp_runtime::transaction_validity::InvalidTransaction;
......@@ -65,8 +65,8 @@ pub trait Registrar<AccountId> {
fn register_para(
id: ParaId,
info: ParaInfo,
code: Vec<u8>,
initial_head_data: Vec<u8>,
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult;
/// Deregister a parachain with given `id`. If `id` is not currently registered, an error is returned.
......@@ -93,8 +93,8 @@ impl<T: Trait> Registrar<T::AccountId> for Module<T> {
fn register_para(
id: ParaId,
info: ParaInfo,
code: Vec<u8>,
initial_head_data: Vec<u8>,
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult {
ensure!(!Paras::contains_key(id), Error::<T>::ParaAlreadyExists);
if let Scheduling::Always = info.scheduling {
......@@ -196,7 +196,7 @@ decl_storage! {
Debtors: map hasher(twox_64_concat) ParaId => T::AccountId;
}
add_extra_genesis {
config(parachains): Vec<(ParaId, Vec<u8>, Vec<u8>)>;
config(parachains): Vec<(ParaId, ValidationCode, HeadData)>;
config(_phdata): PhantomData<T>;
build(build::<T>);
}
......@@ -268,19 +268,19 @@ decl_module! {
pub fn register_para(origin,
#[compact] id: ParaId,
info: ParaInfo,
code: Vec<u8>,
initial_head_data: Vec<u8>,
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(
<Self as Registrar<T::AccountId>>::code_size_allowed(code.len() as _),
<Self as Registrar<T::AccountId>>::code_size_allowed(code.0.len() as _),
Error::<T>::CodeTooLarge,
);
ensure!(
<Self as Registrar<T::AccountId>>::head_data_size_allowed(
initial_head_data.len() as _
initial_head_data.0.len() as _
),
Error::<T>::HeadDataTooLarge,
);
......@@ -316,8 +316,8 @@ decl_module! {
/// action.
#[weight = SimpleDispatchInfo::default()]
fn register_parathread(origin,
code: Vec<u8>,
initial_head_data: Vec<u8>,
code: ValidationCode,
initial_head_data: HeadData,
) {
let who = ensure_signed(origin)?;
......@@ -328,13 +328,13 @@ decl_module! {
};
ensure!(
<Self as Registrar<T::AccountId>>::code_size_allowed(code.len() as _),
<Self as Registrar<T::AccountId>>::code_size_allowed(code.0.len() as _),
Error::<T>::CodeTooLarge,
);
ensure!(
<Self as Registrar<T::AccountId>>::head_data_size_allowed(
initial_head_data.len() as _
initial_head_data.0.len() as _
),
Error::<T>::HeadDataTooLarge,
);
......@@ -632,7 +632,7 @@ impl<T: Trait + Send + Sync> SignedExtension for LimitParathreadCommits<T> where
// ensure that this is a live bid (i.e. that the thread's chain head matches)
let e = TransactionValidityError::from(InvalidTransaction::Custom(ValidityError::InvalidId as u8));
let head = <parachains::Module<T>>::parachain_head(id).ok_or(e)?;
let actual = T::Hashing::hash(&head);
let actual = T::Hashing::hash(&head.0);
ensure!(&actual == hash, InvalidTransaction::Stale);
// updated the selected threads.
......@@ -895,7 +895,7 @@ mod tests {
Sr25519Keyring::Two,
];
fn new_test_ext(parachains: Vec<(ParaId, Vec<u8>, Vec<u8>)>) -> TestExternalities {
fn new_test_ext(parachains: Vec<(ParaId, ValidationCode, HeadData)>) -> TestExternalities {
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap();
let authority_keys = [
......@@ -1031,8 +1031,8 @@ mod tests {
#[test]
fn genesis_registration_works() {
let parachains = vec![
(5u32.into(), vec![1,2,3], vec![1]),
(100u32.into(), vec![4,5,6], vec![2,]),
(5u32.into(), vec![1,2,3].into(), vec![1].into()),
(100u32.into(), vec![4,5,6].into(), vec![2,].into()),
];
new_test_ext(parachains).execute_with(|| {
......@@ -1048,8 +1048,8 @@ mod tests {
Registrar::paras(&ParaId::from(100u32)),
Some(ParaInfo { scheduling: Scheduling::Always }),
);
assert_eq!(Parachains::parachain_code(&ParaId::from(5u32)), Some(vec![1, 2, 3]));
assert_eq!(Parachains::parachain_code(&ParaId::from(100u32)), Some(vec![4, 5, 6]));
assert_eq!(Parachains::parachain_code(&ParaId::from(5u32)), Some(vec![1, 2, 3].into()));
assert_eq!(Parachains::parachain_code(&ParaId::from(100u32)), Some(vec![4, 5, 6].into()));
});
}
......@@ -1064,8 +1064,8 @@ mod tests {
// Register a new parathread
assert_ok!(Registrar::register_parathread(
Origin::signed(1u64),
vec![1; 3],
vec![1; 3],
vec![1; 3].into(),
vec![1; 3].into(),
));
// Lease out a new parachain
......@@ -1079,8 +1079,8 @@ mod tests {
run_to_block(10);
let h = BlakeTwo256::hash(&[2u8; 3]);
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, user_id(1), h, 3, vec![2; 3]));
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), user_id(1), vec![2; 3]));
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, user_id(1), h, 3, vec![2; 3].into()));
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), user_id(1), vec![2; 3].into()));
assert_ok!(Slots::set_offboarding(Origin::signed(user_id(1).into_account()), 1));
run_to_block(11);
......@@ -1100,10 +1100,10 @@ mod tests {
assert_eq!(Slots::managed_ids(), vec![user_id(1)]);
assert_eq!(Slots::deposits(user_id(1)), vec![1; 3]);
assert_eq!(Slots::offboarding(user_id(1)), 1);
assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![1u8; 3]));
assert_eq!(Parachains::parachain_head(&user_id(0)), Some(vec![1u8; 3]));
assert_eq!(Parachains::parachain_code(&user_id(1)), Some(vec![2u8; 3]));
assert_eq!(Parachains::parachain_head(&user_id(1)), Some(vec![2u8; 3]));
assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![1u8; 3].into()));
assert_eq!(Parachains::parachain_head(&user_id(0)), Some(vec![1u8; 3].into()));
assert_eq!(Parachains::parachain_code(&user_id(1)), Some(vec![2u8; 3].into()));
assert_eq!(Parachains::parachain_head(&user_id(1)), Some(vec![2u8; 3].into()));
// Intention to swap is added
assert_eq!(PendingSwap::get(user_id(0)), Some(user_id(1)));
......@@ -1116,10 +1116,10 @@ mod tests {
assert_eq!(Slots::managed_ids(), vec![user_id(0)]);
assert_eq!(Slots::deposits(user_id(0)), vec![1; 3]);
assert_eq!(Slots::offboarding(user_id(0)), 1);
assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![1u8; 3]));
assert_eq!(Parachains::parachain_head(&user_id(0)), Some(vec![1u8; 3]));
assert_eq!(Parachains::parachain_code(&user_id(1)), Some(vec![2u8; 3]));
assert_eq!(Parachains::parachain_head(&user_id(1)), Some(vec![2u8; 3]));
assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![1u8; 3].into()));
assert_eq!(Parachains::parachain_head(&user_id(0)), Some(vec![1u8; 3].into()));
assert_eq!(Parachains::parachain_code(&user_id(1)), Some(vec![2u8; 3].into()));
assert_eq!(Parachains::parachain_head(&user_id(1)), Some(vec![2u8; 3].into()));
// Intention to swap is no longer present
assert_eq!(PendingSwap::get(user_id(0)), None);
......@@ -1146,8 +1146,8 @@ mod tests {
// User 1 register a new parathread
assert_ok!(Registrar::register_parathread(
Origin::signed(1),
vec![1; 3],
vec![1; 3],
vec![1; 3].into(),
vec![1; 3].into(),
));
// User 2 leases out a new parachain
......@@ -1175,7 +1175,7 @@ mod tests {
#[test]
fn register_deregister_chains_works() {
let parachains = vec![
(1u32.into(), vec![1; 3], vec![1; 3]),
(1u32.into(), vec![1; 3].into(), vec![1; 3].into()),
];
new_test_ext(parachains).execute_with(|| {
......@@ -1188,23 +1188,23 @@ mod tests {
Registrar::paras(&ParaId::from(1u32)),
Some(ParaInfo { scheduling: Scheduling::Always })
);
assert_eq!(Parachains::parachain_code(&ParaId::from(1u32)), Some(vec![1; 3]));
assert_eq!(Parachains::parachain_code(&ParaId::from(1u32)), Some(vec![1; 3].into()));
// Register a new parachain
assert_ok!(Registrar::register_para(
Origin::ROOT,
2u32.into(),
ParaInfo { scheduling: Scheduling::Always },
vec![2; 3],
vec![2; 3],
vec![2; 3].into(),
vec![2; 3].into(),
));
let orig_bal = Balances::free_balance(&3u64);
// Register a new parathread
assert_ok!(Registrar::register_parathread(
Origin::signed(3u64),
vec![3; 3],
vec![3; 3],
vec![3; 3].into(),
vec![3; 3].into(),
));
// deposit should be taken (reserved)
assert_eq!(Balances::free_balance(3u64) + ParathreadDeposit::get(), orig_bal);
......@@ -1222,8 +1222,8 @@ mod tests {
Registrar::paras(&user_id(0)),
Some(ParaInfo { scheduling: Scheduling::Dynamic })
);
assert_eq!(Parachains::parachain_code(&ParaId::from(2u32)), Some(vec![2; 3]));
assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![3; 3]));
assert_eq!(Parachains::parachain_code(&ParaId::from(2u32)), Some(vec![2; 3].into()));
assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![3; 3].into()));
assert_ok!(Registrar::deregister_para(Origin::ROOT, 2u32.into()));
assert_ok!(Registrar::deregister_parathread(
......@@ -1253,8 +1253,8 @@ mod tests {
// Register a new parathread
assert_ok!(Registrar::register_parathread(
Origin::signed(3u64),
vec![3; 3],
vec![3; 3],
vec![3; 3].into(),
vec![3; 3].into(),
));
run_to_block(3);
......@@ -1285,7 +1285,7 @@ mod tests {
run_to_block(2);
// Register some parathreads.
assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![3; 3], vec![3; 3]));
assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![3; 3].into(), vec![3; 3].into()));
run_to_block(3);
// transaction submitted to get parathread progressed.
......@@ -1300,7 +1300,7 @@ mod tests {
run_to_block(5);
assert_eq!(Registrar::active_paras(), vec![]); // should not be scheduled.
assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![4; 3], vec![4; 3]));
assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![4; 3].into(), vec![4; 3].into()));
run_to_block(6);
// transaction submitted to get parathread progressed.
......@@ -1328,9 +1328,9 @@ mod tests {
run_to_block(2);
// Register some parathreads.
assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![3; 3], vec![3; 3]));
assert_ok!(Registrar::register_parathread(Origin::signed(4), vec![4; 3], vec![4; 3]));
assert_ok!(Registrar::register_parathread(Origin::signed(5), vec![5; 3], vec![5; 3]));
assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![3; 3].into(), vec![3; 3].into()));
assert_ok!(Registrar::register_parathread(Origin::signed(4), vec![4; 3].into(), vec![4; 3].into()));
assert_ok!(Registrar::register_parathread(Origin::signed(5), vec![5; 3].into(), vec![5; 3].into()));
run_to_block(3);
......@@ -1406,7 +1406,7 @@ mod tests {
new_test_ext(vec![]).execute_with(|| {
run_to_block(2);
let o = Origin::signed(0);
assert_ok!(Registrar::register_parathread(o, vec![7, 8, 9], vec![1, 1, 1]));
assert_ok!(Registrar::register_parathread(o, vec![7, 8, 9].into(), vec![1, 1, 1].into()));
run_to_block(3);
assert_eq!(
......@@ -1461,7 +1461,7 @@ mod tests {
// Register 5 parathreads
for x in 0..5 {
let o = Origin::signed(x as u64);
assert_ok!(Registrar::register_parathread(o, vec![x; 3], vec![x; 3]));
assert_ok!(Registrar::register_parathread(o, vec![x; 3].into(), vec![x; 3].into()));
}
run_to_block(3);
......@@ -1537,8 +1537,8 @@ mod tests {
let bad_code_size = <Test as parachains::Trait>::MaxCodeSize::get() + 1;
let bad_head_size = <Test as parachains::Trait>::MaxHeadDataSize::get() + 1;
let code = vec![1u8; bad_code_size as _];
let head_data = vec![2u8; bad_head_size as _];
let code = vec![1u8; bad_code_size as _].into();
let head_data = vec![2u8; bad_head_size as _].into();
assert!(!<Registrar as super::Registrar<u64>>::code_size_allowed(bad_code_size));
assert!(!<Registrar as super::Registrar<u64>>::head_data_size_allowed(bad_head_size));
......
......@@ -29,7 +29,7 @@ use frame_support::{
weights::{SimpleDispatchInfo, WeighData, Weight},
};
use primitives::parachain::{
SwapAux, PARACHAIN_INFO, Id as ParaId
SwapAux, PARACHAIN_INFO, Id as ParaId, ValidationCode, HeadData,
};
use system::{ensure_signed, ensure_root};