diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock
index b94ad7964fac60ed8381ea061d7cfb4dd992144f..99a3c52ced0235ad75b54b7f2bc4db0f1d033ef1 100644
--- a/polkadot/Cargo.lock
+++ b/polkadot/Cargo.lock
@@ -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",
diff --git a/polkadot/network/src/protocol/tests.rs b/polkadot/network/src/protocol/tests.rs
index cefc8f126f03bdaff2801d16af0323d6008405f3..eaa18962be1b38210fe23bb9c77344ad480962cc 100644
--- a/polkadot/network/src/protocol/tests.rs
+++ b/polkadot/network/src/protocol/tests.rs
@@ -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 {
diff --git a/polkadot/parachain/src/primitives.rs b/polkadot/parachain/src/primitives.rs
index ff32cc6395b349c1cdd8d7ed4caf41d3b7e5a934..54c6907f4201f7b1ad2e2ba0fa13e50460c79215 100644
--- a/polkadot/parachain/src/primitives.rs
+++ b/polkadot/parachain/src/primitives.rs
@@ -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.
diff --git a/polkadot/primitives/src/parachain.rs b/polkadot/primitives/src/parachain.rs
index 187d06e3376144eddef60b4a28ca5472ee43c941..295e4a73c25a11b275785b9653194863a48a7dc9 100644
--- a/polkadot/primitives/src/parachain.rs
+++ b/polkadot/primitives/src/parachain.rs
@@ -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>>;
diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml
index 8fe805e89b0826fe0d6d6bb47c3286079a76bd93..26ef1f78c90f7d00f870f192484e669ca53cc0a1 100644
--- a/polkadot/runtime/common/Cargo.toml
+++ b/polkadot/runtime/common/Cargo.toml
@@ -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",
diff --git a/polkadot/runtime/common/src/crowdfund.rs b/polkadot/runtime/common/src/crowdfund.rs
index 2e728d46e6895c802b6b97c277a343c0b2db7953..99d671b76bd816de08e535250e3e714115cf70d9 100644
--- a/polkadot/runtime/common/src/crowdfund.rs
+++ b/polkadot/runtime/common/src/crowdfund.rs
@@ -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!
diff --git a/polkadot/runtime/common/src/parachains.rs b/polkadot/runtime/common/src/parachains.rs
index 3661c224c3f86594cc138652933c18d6f1675c19..23345b20d723100c27b79e3506b61c21ff8d77a1 100644
--- a/polkadot/runtime/common/src/parachains.rs
+++ b/polkadot/runtime/common/src/parachains.rs
@@ -46,7 +46,7 @@ use primitives::{
 		UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData,
 		CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt,
 		LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID,
-		ValidatorSignature, SigningContext,
+		ValidatorSignature, SigningContext, HeadData, ValidationCode,
 	},
 };
 use frame_support::{
@@ -443,14 +443,14 @@ decl_storage! {
 		/// All authorities' keys at the moment.
 		pub Authorities get(fn authorities): Vec<ValidatorId>;
 		/// The active code of a currently-registered parachain.
-		pub Code get(fn parachain_code): map hasher(twox_64_concat) ParaId => Option<Vec<u8>>;
+		pub Code get(fn parachain_code): map hasher(twox_64_concat) ParaId => Option<ValidationCode>;
 		/// Past code of parachains. The parachains themselves may not be registered anymore,
 		/// but we also keep their code on-chain for the same amount of time as outdated code
 		/// to assist with availability.
 		PastCodeMeta get(fn past_code_meta): map hasher(twox_64_concat) ParaId => ParaPastCodeMeta<T::BlockNumber>;
 		/// Actual past code, indicated by the parachain and the block number at which it
 		/// became outdated.
-		PastCode: map hasher(twox_64_concat) (ParaId, T::BlockNumber) => Option<Vec<u8>>;
+		PastCode: map hasher(twox_64_concat) (ParaId, T::BlockNumber) => Option<ValidationCode>;
 		/// Past code pruning, in order of priority.
 		PastCodePruning get(fn past_code_pruning_tasks): Vec<(ParaId, T::BlockNumber)>;
 		// The block number at which the planned code change is expected for a para.
@@ -458,10 +458,10 @@ decl_storage! {
 		// in the context of a relay chain block with a number >= `expected_at`.
 		FutureCodeUpgrades get(fn code_upgrade_schedule): map hasher(twox_64_concat) ParaId => Option<T::BlockNumber>;
 		// The actual future code of a para.
-		FutureCode: map hasher(twox_64_concat) ParaId => Vec<u8>;
+		FutureCode: map hasher(twox_64_concat) ParaId => ValidationCode;
 
 		/// The heads of the parachains registered at present.
-		pub Heads get(fn parachain_head): map hasher(twox_64_concat) ParaId => Option<Vec<u8>>;
+		pub Heads get(fn parachain_head): map hasher(twox_64_concat) ParaId => Option<HeadData>;
 		/// Messages ready to be dispatched onto the relay chain. It is subject to
 		/// `MAX_MESSAGE_COUNT` and `WATERMARK_MESSAGE_SIZE`.
 		pub RelayDispatchQueue: map hasher(twox_64_concat) ParaId => Vec<UpwardMessage>;
@@ -681,8 +681,8 @@ impl<T: Trait> Module<T> {
 	/// Initialize the state of a new parachain/parathread.
 	pub fn initialize_para(
 		id: ParaId,
-		code: Vec<u8>,
-		initial_head_data: Vec<u8>,
+		code: ValidationCode,
+		initial_head_data: HeadData,
 	) {
 		<Code>::insert(id, code);
 		<Heads>::insert(id, initial_head_data);
@@ -714,7 +714,7 @@ impl<T: Trait> Module<T> {
 	// `at` for para-triggered replacement is the block number of the relay-chain
 	// block in whose context the parablock was executed
 	// (i.e. number of `relay_parent` in the receipt)
-	fn note_past_code(id: ParaId, at: T::BlockNumber, old_code: Vec<u8>) {
+	fn note_past_code(id: ParaId, at: T::BlockNumber, old_code: ValidationCode) {
 		<Self as Store>::PastCodeMeta::mutate(&id, |past_meta| {
 			past_meta.note_replacement(at);
 		});
@@ -766,7 +766,7 @@ impl<T: Trait> Module<T> {
 	}
 
 	// Performs a code upgrade of a parachain.
-	fn do_code_upgrade(id: ParaId, at: T::BlockNumber, new_code: &[u8]) {
+	fn do_code_upgrade(id: ParaId, at: T::BlockNumber, new_code: &ValidationCode) {
 		let old_code = Self::parachain_code(&id).unwrap_or_default();
 		Code::insert(&id, new_code);
 
@@ -852,7 +852,7 @@ impl<T: Trait> Module<T> {
 
 		for head in heads.iter() {
 			let id = head.parachain_index();
-			Heads::insert(id, &head.candidate.head_data.0);
+			Heads::insert(id, &head.candidate.head_data);
 
 			// Queue up upwards messages (from parachains to relay chain).
 			Self::queue_upward_messages(
@@ -1052,7 +1052,7 @@ impl<T: Trait> Module<T> {
 		})();
 
 		Self::parachain_head(id).map(|parent_head| LocalValidationData {
-			parent_head: primitives::parachain::HeadData(parent_head),
+			parent_head,
 			balance: T::ParachainCurrency::free_balance(*id),
 			code_upgrade_allowed,
 		})
@@ -1070,7 +1070,7 @@ impl<T: Trait> Module<T> {
 	}
 
 	/// Fetch the code used for verifying a parachain at a particular height.
-	pub fn parachain_code_at(id: &ParaId, at: T::BlockNumber) -> Option<Vec<u8>> {
+	pub fn parachain_code_at(id: &ParaId, at: T::BlockNumber) -> Option<ValidationCode> {
 		// note - we don't check that the parachain is currently registered
 		// as this might be a deregistered parachain whose old code should still
 		// stick around on-chain for some time.
@@ -1249,7 +1249,7 @@ impl<T: Trait> Module<T> {
 					Error::<T>::DisallowedCodeUpgrade,
 				);
 				ensure!(
-					schedule.max_code_size >= new_code.len() as u32,
+					schedule.max_code_size >= new_code.0.len() as u32,
 					Error::<T>::ValidationCodeTooLarge,
 				);
 
@@ -1529,7 +1529,7 @@ mod tests {
 	use primitives::{
 		parachain::{
 			CandidateReceipt, ValidityAttestation, ValidatorId, Info as ParaInfo,
-			Scheduling, CandidateCommitments, HeadData,
+			Scheduling, CandidateCommitments,
 		},
 		BlockNumber,
 		Header,
@@ -1819,7 +1819,7 @@ mod tests {
 	type Registrar = registrar::Module<Test>;
 	type Historical = session::historical::Module<Test>;
 
-	fn new_test_ext(parachains: Vec<(ParaId, Vec<u8>, Vec<u8>)>) -> TestExternalities {
+	fn new_test_ext(parachains: Vec<(ParaId, ValidationCode, HeadData)>) -> TestExternalities {
 		use staking::StakerStatus;
 		use babe::AuthorityId as BabeAuthorityId;
 
@@ -1911,12 +1911,12 @@ mod tests {
 	// creates a template candidate which pins to correct relay-chain state.
 	fn raw_candidate(para_id: ParaId) -> CandidateReceipt {
 		let mut head_data = Parachains::parachain_head(&para_id).unwrap();
-		head_data.extend(para_id.encode());
+		head_data.0.extend(para_id.encode());
 
 		CandidateReceipt {
 			parachain_index: para_id,
 			relay_parent: System::parent_hash(),
-			head_data: HeadData(head_data),
+			head_data,
 			collator: Default::default(),
 			signature: Default::default(),
 			pov_block_hash: Default::default(),
@@ -2069,9 +2069,9 @@ mod tests {
 	#[test]
 	fn check_dispatch_upward_works() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
-			(2u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
+			(2u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			init_block();
@@ -2161,7 +2161,7 @@ mod tests {
 	#[test]
 	fn check_queue_upward_messages_works() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			run_to_block(2);
@@ -2189,7 +2189,7 @@ mod tests {
 	#[test]
 	fn check_queue_full_upward_messages_fails() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			run_to_block(2);
@@ -2225,7 +2225,7 @@ mod tests {
 	#[test]
 	fn check_queued_too_many_upward_messages_fails() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			run_to_block(2);
@@ -2247,7 +2247,7 @@ mod tests {
 	#[test]
 	fn check_queued_total_oversize_upward_messages_fails() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			run_to_block(2);
@@ -2268,7 +2268,7 @@ mod tests {
 	#[test]
 	fn check_queued_pre_jumbo_upward_messages_fails() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			run_to_block(2);
@@ -2289,7 +2289,7 @@ mod tests {
 	#[test]
 	fn check_queued_post_jumbo_upward_messages_fails() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
 		];
 		new_test_ext(parachains.clone()).execute_with(|| {
 			run_to_block(2);
@@ -2311,8 +2311,8 @@ mod tests {
 	fn upward_queuing_works() {
 		// That the list of egress queue roots is in ascending order by `ParaId`.
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
@@ -2341,39 +2341,45 @@ mod tests {
 	#[test]
 	fn active_parachains_should_work() {
 		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.clone()).execute_with(|| {
 			run_to_block(2);
 			assert_eq!(Parachains::active_parachains(), vec![(5u32.into(), None), (100u32.into(), None)]);
-			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()));
 		});
 	}
 
 	#[test]
 	fn register_deregister() {
 		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.clone()).execute_with(|| {
 			run_to_block(2);
 			assert_eq!(Parachains::active_parachains(), vec![(5u32.into(), None), (100u32.into(), None)]);
 
-			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()));
 
-			assert_ok!(Registrar::register_para(Origin::ROOT, 99u32.into(), ParaInfo{scheduling: Scheduling::Always}, vec![7,8,9], vec![1, 1, 1]));
+			assert_ok!(Registrar::register_para(
+				Origin::ROOT,
+				99u32.into(),
+				ParaInfo{scheduling: Scheduling::Always},
+				vec![7,8,9].into(),
+				vec![1, 1, 1].into(),
+			));
 			assert_ok!(Parachains::set_heads(Origin::NONE, vec![]));
 
 			run_to_block(3);
 
 			assert_eq!(Parachains::active_parachains(), vec![(5u32.into(), None), (99u32.into(), None), (100u32.into(), None)]);
-			assert_eq!(Parachains::parachain_code(&ParaId::from(99u32)), Some(vec![7,8,9]));
+			assert_eq!(Parachains::parachain_code(&ParaId::from(99u32)), Some(vec![7,8,9].into()));
 
 			assert_ok!(Registrar::deregister_para(Origin::ROOT, 5u32.into()));
 			assert_ok!(Parachains::set_heads(Origin::NONE, vec![]));
@@ -2389,8 +2395,8 @@ mod tests {
 	#[test]
 	fn duty_roster_works() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
@@ -2425,8 +2431,8 @@ mod tests {
 	#[test]
 	fn unattested_candidate_is_rejected() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
@@ -2439,8 +2445,8 @@ mod tests {
 	#[test]
 	fn attested_candidates_accepted_in_order() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
@@ -2463,16 +2469,16 @@ mod tests {
 				Origin::NONE,
 			));
 
-			assert_eq!(Heads::get(&ParaId::from(0)).map(HeadData), Some(candidate_a.candidate.head_data));
-			assert_eq!(Heads::get(&ParaId::from(1)).map(HeadData), Some(candidate_b.candidate.head_data));
+			assert_eq!(Heads::get(&ParaId::from(0)), Some(candidate_a.candidate.head_data));
+			assert_eq!(Heads::get(&ParaId::from(1)), Some(candidate_b.candidate.head_data));
 		});
 	}
 
 	#[test]
 	fn duplicate_vote_is_rejected() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
@@ -2495,8 +2501,8 @@ mod tests {
 	#[test]
 	fn validators_not_from_group_is_rejected() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
@@ -2587,14 +2593,14 @@ mod tests {
 	#[test]
 	fn para_past_code_pruning_in_initialize() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
 			let id = ParaId::from(0u32);
 			let at_block: BlockNumber = 10;
-			<Parachains as Store>::PastCode::insert(&(id, at_block), vec![1, 2, 3]);
+			<Parachains as Store>::PastCode::insert(&(id, at_block), &ValidationCode(vec![1, 2, 3]));
 			<Parachains as Store>::PastCodePruning::put(&vec![(id, at_block)]);
 
 			{
@@ -2604,10 +2610,10 @@ mod tests {
 			}
 
 			let pruned_at: BlockNumber = at_block + SlashPeriod::get() + 1;
-			assert_eq!(<Parachains as Store>::PastCode::get(&(id, at_block)), Some(vec![1, 2, 3]));
+			assert_eq!(<Parachains as Store>::PastCode::get(&(id, at_block)), Some(vec![1, 2, 3].into()));
 
 			run_to_block(pruned_at - 1);
-			assert_eq!(<Parachains as Store>::PastCode::get(&(id, at_block)), Some(vec![1, 2, 3]));
+			assert_eq!(<Parachains as Store>::PastCode::get(&(id, at_block)), Some(vec![1, 2, 3].into()));
 			assert_eq!(Parachains::past_code_meta(&id).most_recent_change(), Some(at_block));
 
 			run_to_block(pruned_at);
@@ -2619,16 +2625,16 @@ mod tests {
 	#[test]
 	fn note_past_code_sets_up_pruning_correctly() {
 		let parachains = vec![
-			(0u32.into(), vec![], vec![]),
-			(1u32.into(), vec![], vec![]),
+			(0u32.into(), vec![].into(), vec![].into()),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
 			let id_a = ParaId::from(0u32);
 			let id_b = ParaId::from(1u32);
 
-			Parachains::note_past_code(id_a, 10, vec![1, 2, 3]);
-			Parachains::note_past_code(id_b, 20, vec![4, 5, 6]);
+			Parachains::note_past_code(id_a, 10, vec![1, 2, 3].into());
+			Parachains::note_past_code(id_b, 20, vec![4, 5, 6].into());
 
 			assert_eq!(Parachains::past_code_pruning_tasks(), vec![(id_a, 10), (id_b, 20)]);
 			assert_eq!(
@@ -2651,16 +2657,16 @@ mod tests {
 	#[test]
 	fn code_upgrade_applied_after_delay() {
 		let parachains = vec![
-			(0u32.into(), vec![1, 2, 3], vec![]),
+			(0u32.into(), vec![1, 2, 3].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
 			let para_id = ParaId::from(0);
-			let new_code = vec![4, 5, 6];
+			let new_code = ValidationCode(vec![4, 5, 6]);
 
 			run_to_block(2);
 			assert_eq!(Parachains::active_parachains().len(), 1);
-			assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3]));
+			assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3].into()));
 
 			let applied_after ={
 				let raw_candidate = raw_candidate(para_id);
@@ -2681,7 +2687,7 @@ mod tests {
 				assert!(Parachains::past_code_meta(&para_id).most_recent_change().is_none());
 				assert_eq!(Parachains::code_upgrade_schedule(&para_id), Some(applied_after));
 				assert_eq!(<Parachains as Store>::FutureCode::get(&para_id), new_code);
-				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3]));
+				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3].into()));
 
 				applied_after
 			};
@@ -2705,7 +2711,7 @@ mod tests {
 				assert!(Parachains::past_code_meta(&para_id).most_recent_change().is_none());
 				assert_eq!(Parachains::code_upgrade_schedule(&para_id), Some(applied_after));
 				assert_eq!(<Parachains as Store>::FutureCode::get(&para_id), new_code);
-				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3]));
+				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3].into()));
 			}
 
 			run_to_block(applied_after + 1);
@@ -2730,10 +2736,10 @@ mod tests {
 				);
 				assert_eq!(
 					<Parachains as Store>::PastCode::get(&(para_id, applied_after)),
-					Some(vec![1, 2, 3,]),
+					Some(vec![1, 2, 3,].into()),
 				);
 				assert!(Parachains::code_upgrade_schedule(&para_id).is_none());
-				assert!(<Parachains as Store>::FutureCode::get(&para_id).is_empty());
+				assert!(<Parachains as Store>::FutureCode::get(&para_id).0.is_empty());
 				assert_eq!(Parachains::parachain_code(&para_id), Some(new_code));
 			}
 		});
@@ -2742,16 +2748,16 @@ mod tests {
 	#[test]
 	fn code_upgrade_applied_after_delay_even_when_late() {
 		let parachains = vec![
-			(0u32.into(), vec![1, 2, 3], vec![]),
+			(0u32.into(), vec![1, 2, 3].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
 			let para_id = ParaId::from(0);
-			let new_code = vec![4, 5, 6];
+			let new_code = ValidationCode(vec![4, 5, 6]);
 
 			run_to_block(2);
 			assert_eq!(Parachains::active_parachains().len(), 1);
-			assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3]));
+			assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3].into()));
 
 			let applied_after ={
 				let raw_candidate = raw_candidate(para_id);
@@ -2772,7 +2778,7 @@ mod tests {
 				assert!(Parachains::past_code_meta(&para_id).most_recent_change().is_none());
 				assert_eq!(Parachains::code_upgrade_schedule(&para_id), Some(applied_after));
 				assert_eq!(<Parachains as Store>::FutureCode::get(&para_id), new_code);
-				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3]));
+				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3].into()));
 
 				applied_after
 			};
@@ -2797,10 +2803,10 @@ mod tests {
 				);
 				assert_eq!(
 					<Parachains as Store>::PastCode::get(&(para_id, applied_after + 4)),
-					Some(vec![1, 2, 3,]),
+					Some(vec![1, 2, 3,].into()),
 				);
 				assert!(Parachains::code_upgrade_schedule(&para_id).is_none());
-				assert!(<Parachains as Store>::FutureCode::get(&para_id).is_empty());
+				assert!(<Parachains as Store>::FutureCode::get(&para_id).0.is_empty());
 				assert_eq!(Parachains::parachain_code(&para_id), Some(new_code));
 			}
 		});
@@ -2809,12 +2815,12 @@ mod tests {
 	#[test]
 	fn submit_code_change_when_not_allowed_is_err() {
 		let parachains = vec![
-			(0u32.into(), vec![1, 2, 3], vec![]),
+			(0u32.into(), vec![1, 2, 3].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
 			let para_id = ParaId::from(0);
-			let new_code = vec![4, 5, 6];
+			let new_code = ValidationCode(vec![4, 5, 6]);
 
 			run_to_block(2);
 
@@ -2838,7 +2844,7 @@ mod tests {
 				let raw_candidate = raw_candidate(para_id);
 				assert!(raw_candidate.local_validation.code_upgrade_allowed.is_none());
 				let mut candidate_a = make_blank_attested(raw_candidate);
-				candidate_a.candidate.commitments.new_validation_code = Some(vec![1, 2, 3]);
+				candidate_a.candidate.commitments.new_validation_code = Some(vec![1, 2, 3].into());
 
 				make_attestations(&mut candidate_a);
 
@@ -2856,12 +2862,12 @@ mod tests {
 	#[test]
 	fn full_parachain_cleanup_storage() {
 		let parachains = vec![
-			(0u32.into(), vec![1, 2, 3], vec![]),
+			(0u32.into(), vec![1, 2, 3].into(), vec![].into()),
 		];
 
 		new_test_ext(parachains.clone()).execute_with(|| {
 			let para_id = ParaId::from(0);
-			let new_code = vec![4, 5, 6];
+			let new_code = ValidationCode(vec![4, 5, 6]);
 
 			run_to_block(2);
 			{
@@ -2883,7 +2889,7 @@ mod tests {
 				assert!(Parachains::past_code_meta(&para_id).most_recent_change().is_none());
 				assert_eq!(Parachains::code_upgrade_schedule(&para_id), Some(applied_after));
 				assert_eq!(<Parachains as Store>::FutureCode::get(&para_id), new_code);
-				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3]));
+				assert_eq!(Parachains::parachain_code(&para_id), Some(vec![1, 2, 3].into()));
 
 				assert!(Parachains::past_code_pruning_tasks().is_empty());
 			};
@@ -2893,13 +2899,13 @@ mod tests {
 			// cleaning up the parachain should place the current parachain code
 			// into the past code buffer & schedule cleanup.
 			assert_eq!(Parachains::past_code_meta(&para_id).most_recent_change(), Some(2));
-			assert_eq!(<Parachains as Store>::PastCode::get(&(para_id, 2)), Some(vec![1, 2, 3]));
+			assert_eq!(<Parachains as Store>::PastCode::get(&(para_id, 2)), Some(vec![1, 2, 3].into()));
 			assert_eq!(Parachains::past_code_pruning_tasks(), vec![(para_id, 2)]);
 
 			// any future upgrades haven't been used to validate yet, so those
 			// are cleaned up immediately.
 			assert!(Parachains::code_upgrade_schedule(&para_id).is_none());
-			assert!(<Parachains as Store>::FutureCode::get(&para_id).is_empty());
+			assert!(<Parachains as Store>::FutureCode::get(&para_id).0.is_empty());
 			assert!(Parachains::parachain_code(&para_id).is_none());
 
 			let cleaned_up_at = 2 + SlashPeriod::get() + 1;
@@ -2915,7 +2921,7 @@ mod tests {
 	#[test]
 	fn double_vote_candidate_and_valid_works() {
 		let parachains = vec![
-			(1u32.into(), vec![], vec![]),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		let extract_key = |public: ValidatorId| {
@@ -3013,7 +3019,7 @@ mod tests {
 	#[test]
 	fn double_vote_candidate_and_invalid_works() {
 		let parachains = vec![
-			(1u32.into(), vec![], vec![]),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		let extract_key = |public: ValidatorId| {
@@ -3110,7 +3116,7 @@ mod tests {
 	#[test]
 	fn double_vote_valid_and_invalid_works() {
 		let parachains = vec![
-			(1u32.into(), vec![], vec![]),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		let extract_key = |public: ValidatorId| {
@@ -3207,7 +3213,7 @@ mod tests {
 	#[test]
 	fn double_vote_submit_twice_works() {
 		let parachains = vec![
-			(1u32.into(), vec![], vec![]),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		let extract_key = |public: ValidatorId| {
@@ -3313,7 +3319,7 @@ mod tests {
 	#[test]
 	fn double_vote_submit_invalid_works() {
 		let parachains = vec![
-			(1u32.into(), vec![], vec![]),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		let extract_key = |public: ValidatorId| {
@@ -3372,7 +3378,7 @@ mod tests {
 	#[test]
 	fn double_vote_proof_session_mismatch_fails() {
 		let parachains = vec![
-			(1u32.into(), vec![], vec![]),
+			(1u32.into(), vec![].into(), vec![].into()),
 		];
 
 		let extract_key = |public: ValidatorId| {
diff --git a/polkadot/runtime/common/src/registrar.rs b/polkadot/runtime/common/src/registrar.rs
index 39281eaac52a82a4a9723289ef7c609230d8eed6..39a78e57f4a8e681bea848bc853013095256959f 100644
--- a/polkadot/runtime/common/src/registrar.rs
+++ b/polkadot/runtime/common/src/registrar.rs
@@ -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));
diff --git a/polkadot/runtime/common/src/slots.rs b/polkadot/runtime/common/src/slots.rs
index f54364a426c8744168a7fc10fa8f23a08e0a8a21..811857ed664f1ef799105eaf24011ed4714ea7fc 100644
--- a/polkadot/runtime/common/src/slots.rs
+++ b/polkadot/runtime/common/src/slots.rs
@@ -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};
 use crate::registrar::{Registrar, swap_ordered_existence};
@@ -113,9 +113,9 @@ pub enum IncomingParachain<AccountId, Hash> {
 	/// The code size must be included so that checks against a maximum code size
 	/// can be done. If the size of the preimage of the code hash does not match
 	/// the given code size, it will not be possible to register the parachain.
-	Fixed { code_hash: Hash, code_size: u32, initial_head_data: Vec<u8> },
+	Fixed { code_hash: Hash, code_size: u32, initial_head_data: HeadData },
 	/// Deploy information fully set; so we store the code and head data.
-	Deploy { code: Vec<u8>, initial_head_data: Vec<u8> },
+	Deploy { code: ValidationCode, initial_head_data: HeadData },
 }
 
 type LeasePeriodOf<T> = <T as system::Trait>::BlockNumber;
@@ -413,7 +413,7 @@ decl_module! {
 			#[compact] para_id: ParaId,
 			code_hash: T::Hash,
 			code_size: u32,
-			initial_head_data: Vec<u8>
+			initial_head_data: HeadData,
 		) {
 			let who = ensure_signed(origin)?;
 			let (starts, details) = <Onboarding<T>>::get(&para_id)
@@ -425,7 +425,7 @@ decl_module! {
 			}
 
 			ensure!(
-				T::Parachains::head_data_size_allowed(initial_head_data.len() as _),
+				T::Parachains::head_data_size_allowed(initial_head_data.0.len() as _),
 				Error::<T>::HeadDataTooLarge,
 			);
 			ensure!(
@@ -450,12 +450,16 @@ decl_module! {
 		/// - `para_id` is the parachain ID whose code will be elaborated.
 		/// - `code` is the preimage of the registered `code_hash` of `para_id`.
 		#[weight = SimpleDispatchInfo::FixedNormal(5_000_000)]
-		pub fn elaborate_deploy_data(_origin, #[compact] para_id: ParaId, code: Vec<u8>) -> DispatchResult {
+		pub fn elaborate_deploy_data(
+			_origin,
+			#[compact] para_id: ParaId,
+			code: ValidationCode,
+		) -> DispatchResult {
 			let (starts, details) = <Onboarding<T>>::get(&para_id)
 				.ok_or(Error::<T>::ParaNotOnboarding)?;
 			if let IncomingParachain::Fixed{code_hash, code_size, initial_head_data} = details {
-				ensure!(code.len() as u32 == code_size, Error::<T>::InvalidCode);
-				ensure!(<T as system::Trait>::Hashing::hash(&code) == code_hash, Error::<T>::InvalidCode);
+				ensure!(code.0.len() as u32 == code_size, Error::<T>::InvalidCode);
+				ensure!(<T as system::Trait>::Hashing::hash(&code.0) == code_hash, Error::<T>::InvalidCode);
 
 				if starts > Self::lease_period_index() {
 					// Hasn't yet begun. Replace the on-boarding entry with the new information.
@@ -941,7 +945,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;
@@ -971,8 +975,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()) {
@@ -997,7 +1001,7 @@ mod tests {
 		PARACHAIN_COUNT.with(|p| *p.borrow_mut() = 0);
 	}
 
-	fn with_parachains<T>(f: impl FnOnce(&HashMap<u32, (Vec<u8>, Vec<u8>)>) -> T) -> T {
+	fn with_parachains<T>(f: impl FnOnce(&HashMap<u32, (ValidationCode, HeadData)>) -> T) -> T {
 		PARACHAINS.with(|p| f(&*p.borrow()))
 	}
 
@@ -1186,13 +1190,13 @@ mod tests {
 
 			run_to_block(9);
 			let h = BlakeTwo256::hash(&[42u8][..]);
-			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![69]));
-			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42]));
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![69].into()));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42].into()));
 
 			run_to_block(10);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 1);
-				assert_eq!(p[&0], (vec![42], vec![69]));
+				assert_eq!(p[&0], (vec![42].into(), vec![69].into()));
 			});
 		});
 	}
@@ -1211,11 +1215,11 @@ mod tests {
 
 			run_to_block(11);
 			let h = BlakeTwo256::hash(&[42u8][..]);
-			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![69]));
-			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42]));
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![69].into()));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42].into()));
 			with_parachains(|p| {
 				assert_eq!(p.len(), 1);
-				assert_eq!(p[&0], (vec![42], vec![69]));
+				assert_eq!(p[&0], (vec![42].into(), vec![69].into()));
 			});
 		});
 	}
@@ -1321,33 +1325,33 @@ mod tests {
 
 			for &(para, sub, acc) in &[(0, 0, 1), (1, 0, 2), (2, 0, 3), (3, 1, 4), (4, 1, 5)] {
 				let h = BlakeTwo256::hash(&[acc][..]);
-				assert_ok!(Slots::fix_deploy_data(Origin::signed(acc as _), sub, para.into(), h, 1, vec![acc]));
-				assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), para.into(), vec![acc]));
+				assert_ok!(Slots::fix_deploy_data(Origin::signed(acc as _), sub, para.into(), h, 1, vec![acc].into()));
+				assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), para.into(), vec![acc].into()));
 			}
 
 			run_to_block(10);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 2);
-				assert_eq!(p[&0], (vec![1], vec![1]));
-				assert_eq!(p[&3], (vec![4], vec![4]));
+				assert_eq!(p[&0], (vec![1].into(), vec![1].into()));
+				assert_eq!(p[&3], (vec![4].into(), vec![4].into()));
 			});
 			run_to_block(20);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 2);
-				assert_eq!(p[&1], (vec![2], vec![2]));
-				assert_eq!(p[&3], (vec![4], vec![4]));
+				assert_eq!(p[&1], (vec![2].into(), vec![2].into()));
+				assert_eq!(p[&3], (vec![4].into(), vec![4].into()));
 			});
 			run_to_block(30);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 2);
-				assert_eq!(p[&1], (vec![2], vec![2]));
-				assert_eq!(p[&4], (vec![5], vec![5]));
+				assert_eq!(p[&1], (vec![2].into(), vec![2].into()));
+				assert_eq!(p[&4], (vec![5].into(), vec![5].into()));
 			});
 			run_to_block(40);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 2);
-				assert_eq!(p[&2], (vec![3], vec![3]));
-				assert_eq!(p[&4], (vec![5], vec![5]));
+				assert_eq!(p[&2], (vec![3].into(), vec![3].into()));
+				assert_eq!(p[&4], (vec![5].into(), vec![5].into()));
 			});
 			run_to_block(50);
 			with_parachains(|p| {
@@ -1368,21 +1372,21 @@ mod tests {
 
 			run_to_block(10);
 			let h = BlakeTwo256::hash(&[1u8][..]);
-			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![1]));
-			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1]));
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![1].into()));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1].into()));
 
 			assert_ok!(Slots::new_auction(Origin::ROOT, 5, 2));
 			assert_ok!(Slots::bid_renew(Origin::signed(ParaId::from(0).into_account()), 2, 2, 2, 1));
 
 			with_parachains(|p| {
 				assert_eq!(p.len(), 1);
-				assert_eq!(p[&0], (vec![1], vec![1]));
+				assert_eq!(p[&0], (vec![1].into(), vec![1].into()));
 			});
 
 			run_to_block(20);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 1);
-				assert_eq!(p[&0], (vec![1], vec![1]));
+				assert_eq!(p[&0], (vec![1].into(), vec![1].into()));
 			});
 			assert_ok!(Slots::new_auction(Origin::ROOT, 5, 2));
 			assert_ok!(Balances::transfer(Origin::signed(1), ParaId::from(0).into_account(), 1));
@@ -1391,7 +1395,7 @@ mod tests {
 			run_to_block(30);
 			with_parachains(|p| {
 				assert_eq!(p.len(), 1);
-				assert_eq!(p[&0], (vec![1], vec![1]));
+				assert_eq!(p[&0], (vec![1].into(), vec![1].into()));
 			});
 
 			run_to_block(40);
@@ -1413,8 +1417,8 @@ mod tests {
 
 			run_to_block(10);
 			let h = BlakeTwo256::hash(&[1u8][..]);
-			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![1]));
-			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1]));
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![1].into()));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1].into()));
 
 			assert_ok!(Slots::new_auction(Origin::ROOT, 5, 2));
 			assert_ok!(Slots::bid_renew(Origin::signed(ParaId::from(0).into_account()), 2, 2, 2, 3));
@@ -1619,7 +1623,7 @@ mod tests {
 			let h = BlakeTwo256::hash(&code[..]);
 			assert_eq!(
 				Slots::fix_deploy_data(
-					Origin::signed(1), 0, 0.into(), h, code.len() as _, vec![1],
+					Origin::signed(1), 0, 0.into(), h, code.len() as _, vec![1].into(),
 				),
 				Err(Error::<Test>::CodeTooLarge.into()),
 			);
@@ -1639,7 +1643,7 @@ mod tests {
 			run_to_block(10);
 
 			let code = vec![0u8; MAX_CODE_SIZE as _];
-			let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _];
+			let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _].into();
 			let h = BlakeTwo256::hash(&code[..]);
 			assert_ok!(Slots::fix_deploy_data(
 				Origin::signed(1), 0, 0.into(), h, code.len() as _, head_data,
@@ -1660,7 +1664,7 @@ mod tests {
 			run_to_block(10);
 
 			let code = vec![0u8; MAX_CODE_SIZE as _];
-			let head_data = vec![1u8; (MAX_HEAD_DATA_SIZE + 1) as _];
+			let head_data = vec![1u8; (MAX_HEAD_DATA_SIZE + 1) as _].into();
 			let h = BlakeTwo256::hash(&code[..]);
 			assert_eq!(
 				Slots::fix_deploy_data(
@@ -1684,12 +1688,12 @@ mod tests {
 			run_to_block(10);
 
 			let code = vec![0u8; MAX_CODE_SIZE as _];
-			let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _];
+			let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _].into();
 			let h = BlakeTwo256::hash(&code[..]);
 			assert_ok!(Slots::fix_deploy_data(
 				Origin::signed(1), 0, 0.into(), h, (code.len() - 1) as _, head_data,
 			));
-			assert!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), code).is_err());
+			assert!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), code.into()).is_err());
 		});
 	}
 }
diff --git a/polkadot/runtime/kusama/Cargo.toml b/polkadot/runtime/kusama/Cargo.toml
index c7d796eec693ed659feeb406f31c15d89370ed78..566ba0b62f591921c5cd6e2724326a1ff4c95423 100644
--- a/polkadot/runtime/kusama/Cargo.toml
+++ b/polkadot/runtime/kusama/Cargo.toml
@@ -64,7 +64,6 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch =
 
 runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false }
 primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false }
-polkadot-parachain = { path = "../../parachain", default-features = false }
 
 [dev-dependencies]
 hex-literal = "0.2.1"
@@ -91,7 +90,6 @@ std = [
 	"codec/std",
 	"inherents/std",
 	"sp-core/std",
-	"polkadot-parachain/std",
 	"sp-api/std",
 	"tx-pool-api/std",
 	"block-builder-api/std",
diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs
index 70e4205cf632a41faab5f6733ba91b9c6c37a91b..d5e28b9c2d59b93433297aa8c375058ebe82cd6a 100644
--- a/polkadot/runtime/kusama/src/lib.rs
+++ b/polkadot/runtime/kusama/src/lib.rs
@@ -846,7 +846,7 @@ sp_api::impl_runtime_apis! {
 		fn local_validation_data(id: parachain::Id) -> Option<parachain::LocalValidationData> {
 			Parachains::current_local_validation_data(&id)
 		}
-		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
+		fn parachain_code(id: parachain::Id) -> Option<parachain::ValidationCode> {
 			Parachains::parachain_code(&id)
 		}
 		fn get_heads(extrinsics: Vec<<Block as BlockT>::Extrinsic>)
diff --git a/polkadot/runtime/polkadot/Cargo.toml b/polkadot/runtime/polkadot/Cargo.toml
index 305eae524fa0cf793760f366944f67c0b4447725..22fb630c10c1895a3e40afcbc2a7bdf4f2cbfab7 100644
--- a/polkadot/runtime/polkadot/Cargo.toml
+++ b/polkadot/runtime/polkadot/Cargo.toml
@@ -61,7 +61,6 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch =
 
 runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false }
 primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false }
-polkadot-parachain = { path = "../../parachain", default-features = false }
 
 [dev-dependencies]
 hex-literal = "0.2.1"
@@ -88,7 +87,6 @@ std = [
 	"codec/std",
 	"inherents/std",
 	"sp-core/std",
-	"polkadot-parachain/std",
 	"sp-api/std",
 	"tx-pool-api/std",
 	"block-builder-api/std",
diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs
index b05d4b8824544ea1b6b559438f3afb44d5410040..f4076147375aa02c7057edec3c9387d0452af807 100644
--- a/polkadot/runtime/polkadot/src/lib.rs
+++ b/polkadot/runtime/polkadot/src/lib.rs
@@ -764,7 +764,7 @@ sp_api::impl_runtime_apis! {
 		fn local_validation_data(id: parachain::Id) -> Option<parachain::LocalValidationData> {
 			Parachains::current_local_validation_data(&id)
 		}
-		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
+		fn parachain_code(id: parachain::Id) -> Option<parachain::ValidationCode> {
 			Parachains::parachain_code(&id)
 		}
 		fn get_heads(extrinsics: Vec<<Block as BlockT>::Extrinsic>)
diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs
index 960adaa1948e39007c15f1fdc4d29329a5ce2d57..e86bb7df8b8d326f5c6356302e5e689cd1b85b8d 100644
--- a/polkadot/runtime/test-runtime/src/lib.rs
+++ b/polkadot/runtime/test-runtime/src/lib.rs
@@ -549,7 +549,7 @@ sp_api::impl_runtime_apis! {
 		fn local_validation_data(id: parachain::Id) -> Option<parachain::LocalValidationData> {
 			Parachains::current_local_validation_data(&id)
 		}
-		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
+		fn parachain_code(id: parachain::Id) -> Option<parachain::ValidationCode> {
 			Parachains::parachain_code(&id)
 		}
 		fn get_heads(extrinsics: Vec<<Block as BlockT>::Extrinsic>)
diff --git a/polkadot/validation/src/pipeline.rs b/polkadot/validation/src/pipeline.rs
index 408d330928e976af05ba9e0656a9ef2371e1ac1c..a6df1001b94b6612eca93d9f9007e0ec62d56387 100644
--- a/polkadot/validation/src/pipeline.rs
+++ b/polkadot/validation/src/pipeline.rs
@@ -24,7 +24,7 @@ use polkadot_erasure_coding as erasure;
 use polkadot_primitives::parachain::{
 	CollationInfo, PoVBlock, LocalValidationData, GlobalValidationSchedule, OmittedValidationData,
 	AvailableData, FeeSchedule, CandidateCommitments, ErasureChunk, ParachainHost,
-	Id as ParaId, AbridgedCandidateReceipt
+	Id as ParaId, AbridgedCandidateReceipt, ValidationCode,
 };
 use polkadot_primitives::{Block, BlockId, Balance, Hash};
 use parachain::{
@@ -230,7 +230,7 @@ pub fn validate<'a>(
 	pov_block: &'a PoVBlock,
 	local_validation: &'a LocalValidationData,
 	global_validation: &'a GlobalValidationSchedule,
-	validation_code: &[u8],
+	validation_code: &ValidationCode,
 ) -> Result<ValidatedCandidate<'a>, Error> {
 	if collation.head_data.0.len() > global_validation.max_head_data_size as _ {
 		return Err(Error::HeadDataTooLarge(
@@ -260,7 +260,7 @@ pub fn validate<'a>(
 
 	let ext = Externalities::new(local_validation.balance, fee_schedule);
 	match wasm_executor::validate_candidate(
-		&validation_code,
+		&validation_code.0,
 		params,
 		ext.clone(),
 		execution_mode,
@@ -291,7 +291,7 @@ pub fn validate<'a>(
 
 /// Extracts validation parameters from a Polkadot runtime API for a specific parachain.
 pub fn validation_params<P>(api: &P, relay_parent: Hash, para_id: ParaId)
-	-> Result<(LocalValidationData, GlobalValidationSchedule, Vec<u8>), Error>
+	-> Result<(LocalValidationData, GlobalValidationSchedule, ValidationCode), Error>
 where
 	P: ProvideRuntimeApi<Block>,
 	P::Api: ParachainHost<Block, Error = sp_blockchain::Error>,
diff --git a/polkadot/validation/src/validation_service/mod.rs b/polkadot/validation/src/validation_service/mod.rs
index 3c8d1857350e4ddd712669a2c36eccf07a62ba48..9bd9dd7242e60eb8d324394992e94b67c25a5737 100644
--- a/polkadot/validation/src/validation_service/mod.rs
+++ b/polkadot/validation/src/validation_service/mod.rs
@@ -536,7 +536,7 @@ mod tests {
 	use polkadot_primitives::parachain::{
 		PoVBlock, AbridgedCandidateReceipt, ErasureChunk, ValidatorIndex,
 		CollationInfo, DutyRoster, GlobalValidationSchedule, LocalValidationData,
-		Retriable, CollatorId, BlockData, Chain, AvailableData, SigningContext,
+		Retriable, CollatorId, BlockData, Chain, AvailableData, SigningContext, ValidationCode,
 	};
 	use runtime_primitives::traits::Block as BlockT;
 	use std::pin::Pin;
@@ -686,7 +686,7 @@ mod tests {
 			fn active_parachains() -> Vec<(ParaId, Option<(CollatorId, Retriable)>)> { vec![(ParaId::from(1), None)] }
 			fn global_validation_schedule() -> GlobalValidationSchedule { Default::default() }
 			fn local_validation_data(_: ParaId) -> Option<LocalValidationData> { None }
-			fn parachain_code(_: ParaId) -> Option<Vec<u8>> { None }
+			fn parachain_code(_: ParaId) -> Option<ValidationCode> { None }
 			fn get_heads(_: Vec<<Block as BlockT>::Extrinsic>) -> Option<Vec<AbridgedCandidateReceipt>> {
 				None
 			}