diff --git a/parachain/Cargo.toml b/parachain/Cargo.toml index 85948c302244..a0104dc6f803 100644 --- a/parachain/Cargo.toml +++ b/parachain/Cargo.toml @@ -18,6 +18,7 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "cumulus-bra lazy_static = { version = "1.4.0", optional = true } parking_lot = { version = "0.10.0", optional = true } log = { version = "0.4.8", optional = true } +polkadot-primitives = { path = "../primitives", default-features = false } [target.'cfg(not(target_os = "unknown"))'.dependencies] shared_memory = { version = "0.10.0", optional = true } @@ -44,4 +45,5 @@ std = [ "sp-externalities", "sc-executor", "sp-io", + "polkadot-primitives/std", ] diff --git a/parachain/src/lib.rs b/parachain/src/lib.rs index d1324140d78f..5367a01c0a1c 100644 --- a/parachain/src/lib.rs +++ b/parachain/src/lib.rs @@ -50,12 +50,21 @@ mod wasm_api; use rstd::vec::Vec; -use codec::{Encode, Decode, CompactAs}; -use sp_core::{RuntimeDebug, TypeId}; +use codec::{Encode, Decode}; #[cfg(all(not(feature = "std"), feature = "wasm-api"))] pub use wasm_api::*; +#[deprecated(note="moved to primitives package")] +pub use polkadot_primitives::{BlockNumber, parachain::{ + AccountIdConversion, + Id, + IncomingMessage, + LOWEST_USER_ID, + ParachainDispatchOrigin, + UpwardMessage, +}}; + /// Validation parameters for evaluating the parachain validity function. // TODO: balance downloads (https://github.com/paritytech/polkadot/issues/220) #[derive(PartialEq, Eq, Decode)] @@ -65,6 +74,8 @@ pub struct ValidationParams { pub block_data: Vec, /// Previous head-data. pub parent_head: Vec, + /// Number of the current relay chain block. + pub current_relay_block: BlockNumber, } /// The result of parachain validation. @@ -75,152 +86,3 @@ pub struct ValidationResult { /// New head data that should be included in the relay chain state. pub head_data: Vec, } - -/// Unique identifier of a parachain. -#[derive( - Clone, CompactAs, Copy, Decode, Default, Encode, Eq, - Hash, Ord, PartialEq, PartialOrd, RuntimeDebug, -)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize, derive_more::Display))] -pub struct Id(u32); - -impl TypeId for Id { - const TYPE_ID: [u8; 4] = *b"para"; -} - -/// Type for determining the active set of parachains. -pub trait ActiveThreads { - /// Return the current ordered set of `Id`s of active parathreads. - fn active_threads() -> Vec; -} - -impl From for u32 { - fn from(x: Id) -> Self { x.0 } -} - -impl From for Id { - fn from(x: u32) -> Self { Id(x) } -} - -const USER_INDEX_START: u32 = 1000; - -/// The ID of the first user (non-system) parachain. -pub const LOWEST_USER_ID: Id = Id(USER_INDEX_START); - -impl Id { - /// Create an `Id`. - pub const fn new(id: u32) -> Self { - Self(id) - } - - /// Returns `true` if this parachain runs with system-level privileges. - pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START } -} - -impl rstd::ops::Add for Id { - type Output = Self; - - fn add(self, other: u32) -> Self { - Self(self.0 + other) - } -} - -// TODO: Remove all of this, move sp-runtime::AccountIdConversion to own crate and and use that. -// #360 -struct TrailingZeroInput<'a>(&'a [u8]); -impl<'a> codec::Input for TrailingZeroInput<'a> { - fn remaining_len(&mut self) -> Result, codec::Error> { - Ok(None) - } - - fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> { - let len = into.len().min(self.0.len()); - into[..len].copy_from_slice(&self.0[..len]); - for i in &mut into[len..] { - *i = 0; - } - self.0 = &self.0[len..]; - Ok(()) - } -} - -/// This type can be converted into and possibly from an AccountId (which itself is generic). -pub trait AccountIdConversion: Sized { - /// Convert into an account ID. This is infallible. - fn into_account(&self) -> AccountId; - - /// Try to convert an account ID into this type. Might not succeed. - fn try_from_account(a: &AccountId) -> Option; -} - -/// Format is b"para" ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing -/// zeroes to fill AccountId. -impl AccountIdConversion for Id { - fn into_account(&self) -> T { - (b"para", self).using_encoded(|b| - T::decode(&mut TrailingZeroInput(b)) - ).unwrap_or_default() - } - - fn try_from_account(x: &T) -> Option { - x.using_encoded(|d| { - if &d[0..4] != b"para" { return None } - let mut cursor = &d[4..]; - let result = Decode::decode(&mut cursor).ok()?; - if cursor.iter().all(|x| *x == 0) { - Some(result) - } else { - None - } - }) - } -} - -/// Which origin a parachain's message to the relay chain should be dispatched from. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] -#[repr(u8)] -pub enum ParachainDispatchOrigin { - /// As a simple `Origin::Signed`, using `ParaId::account_id` as its value. This is good when - /// interacting with standard modules such as `balances`. - Signed, - /// As the special `Origin::Parachain(ParaId)`. This is good when interacting with parachain- - /// aware modules which need to succinctly verify that the origin is a parachain. - Parachain, - /// As the simple, superuser `Origin::Root`. This can only be done on specially permissioned - /// parachains. - Root, -} - -impl rstd::convert::TryFrom for ParachainDispatchOrigin { - type Error = (); - fn try_from(x: u8) -> core::result::Result { - const SIGNED: u8 = ParachainDispatchOrigin::Signed as u8; - const PARACHAIN: u8 = ParachainDispatchOrigin::Parachain as u8; - Ok(match x { - SIGNED => ParachainDispatchOrigin::Signed, - PARACHAIN => ParachainDispatchOrigin::Parachain, - _ => return Err(()), - }) - } -} - -/// A message from a parachain to its Relay Chain. -#[derive(Clone, PartialEq, Eq, Encode, Decode, sp_runtime_interface::pass_by::PassByCodec)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct UpwardMessage { - /// The origin for the message to be sent from. - pub origin: ParachainDispatchOrigin, - /// The message data. - pub data: Vec, -} - -/// An incoming message. -#[derive(PartialEq, Eq, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Encode))] -pub struct IncomingMessage { - /// The source parachain. - pub source: Id, - /// The data of the message. - pub data: Vec, -} diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 98861c5afc0b..db9beee34309 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -11,13 +11,13 @@ primitives = { package = "sp-core", git = "https://github.com/paritytech/substra inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } sp-api = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } +sp-runtime-interface = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } sp-version = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } runtime_primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } -polkadot-parachain = { path = "../parachain", default-features = false } trie = { package = "sp-trie", git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } bitvec = { version = "0.15.2", default-features = false, features = ["alloc"] } -babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "cumulus-branch", default-features = false } +derive_more = { version = "0.99.2" } [dev-dependencies] sp-serializer = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" } @@ -31,11 +31,10 @@ std = [ "inherents/std", "trie/std", "sp-api/std", + "sp-runtime-interface/std", "rstd/std", "sp-version/std", "runtime_primitives/std", "serde", - "polkadot-parachain/std", "bitvec/std", - "babe/std" ] diff --git a/primitives/src/parachain.rs b/primitives/src/parachain.rs index 045f99d62319..faa9f083bbe4 100644 --- a/primitives/src/parachain.rs +++ b/primitives/src/parachain.rs @@ -18,7 +18,7 @@ use rstd::prelude::*; use rstd::cmp::Ordering; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Encode, Decode, CompactAs}; use bitvec::vec::BitVec; use super::{Hash, Balance}; @@ -27,17 +27,13 @@ use serde::{Serialize, Deserialize}; #[cfg(feature = "std")] use primitives::bytes; -use primitives::RuntimeDebug; +use primitives::{RuntimeDebug, TypeId}; use inherents::InherentIdentifier; use application_crypto::KeyTypeId; #[cfg(feature = "std")] use trie::TrieConfiguration; -pub use polkadot_parachain::{ - Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage, -}; - /// The key type ID for a collator key. pub const COLLATOR_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"coll"); @@ -465,6 +461,157 @@ pub mod id { pub const PARACHAIN_HOST: ApiId = *b"parahost"; } +/// Unique identifier of a parachain. +#[derive( + Clone, CompactAs, Copy, Decode, Default, Encode, Eq, + Hash, Ord, PartialEq, PartialOrd, RuntimeDebug, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize, derive_more::Display))] +pub struct Id(u32); + +impl TypeId for Id { + const TYPE_ID: [u8; 4] = *b"para"; +} + +const USER_INDEX_START: u32 = 1000; + +/// The ID of the first user (non-system) parachain. +pub const LOWEST_USER_ID: Id = Id(USER_INDEX_START); + +impl Id { + /// Create an `Id`. + pub const fn new(id: u32) -> Self { + Self(id) + } + + /// Returns `true` if this parachain runs with system-level privileges. + pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START } +} + +impl rstd::ops::Add for Id { + type Output = Self; + + fn add(self, other: u32) -> Self { + Self(self.0 + other) + } +} + +/// Type for determining the active set of parachains. +pub trait ActiveThreads { + /// Return the current ordered set of `Id`s of active parathreads. + fn active_threads() -> Vec; +} + +impl From for u32 { + fn from(x: Id) -> Self { x.0 } +} + +impl From for Id { + fn from(x: u32) -> Self { Id(x) } +} + +// TODO: Remove all of this, move sp-runtime::AccountIdConversion to own crate and and use that. +// #360 +struct TrailingZeroInput<'a>(&'a [u8]); +impl<'a> parity_scale_codec::Input for TrailingZeroInput<'a> { + fn remaining_len(&mut self) -> Result, parity_scale_codec::Error> { + Ok(None) + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), parity_scale_codec::Error> { + let len = into.len().min(self.0.len()); + into[..len].copy_from_slice(&self.0[..len]); + for i in &mut into[len..] { + *i = 0; + } + self.0 = &self.0[len..]; + Ok(()) + } +} + +/// This type can be converted into and possibly from an AccountId (which itself is generic). +pub trait AccountIdConversion: Sized { + /// Convert into an account ID. This is infallible. + fn into_account(&self) -> AccountId; + + /// Try to convert an account ID into this type. Might not succeed. + fn try_from_account(a: &AccountId) -> Option; +} + +/// Format is b"para" ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing +/// zeroes to fill AccountId. +impl AccountIdConversion for Id { + fn into_account(&self) -> T { + (b"para", self).using_encoded(|b| + T::decode(&mut TrailingZeroInput(b)) + ).unwrap_or_default() + } + + fn try_from_account(x: &T) -> Option { + x.using_encoded(|d| { + if &d[0..4] != b"para" { return None } + let mut cursor = &d[4..]; + let result = Decode::decode(&mut cursor).ok()?; + if cursor.iter().all(|x| *x == 0) { + Some(result) + } else { + None + } + }) + } +} + + +/// Which origin a parachain's message to the relay chain should be dispatched from. +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +#[repr(u8)] +pub enum ParachainDispatchOrigin { + /// As a simple `Origin::Signed`, using `ParaId::account_id` as its value. This is good when + /// interacting with standard modules such as `balances`. + Signed, + /// As the special `Origin::Parachain(ParaId)`. This is good when interacting with parachain- + /// aware modules which need to succinctly verify that the origin is a parachain. + Parachain, + /// As the simple, superuser `Origin::Root`. This can only be done on specially permissioned + /// parachains. + Root, +} + +impl rstd::convert::TryFrom for ParachainDispatchOrigin { + type Error = (); + fn try_from(x: u8) -> core::result::Result { + const SIGNED: u8 = ParachainDispatchOrigin::Signed as u8; + const PARACHAIN: u8 = ParachainDispatchOrigin::Parachain as u8; + Ok(match x { + SIGNED => ParachainDispatchOrigin::Signed, + PARACHAIN => ParachainDispatchOrigin::Parachain, + _ => return Err(()), + }) + } +} + +/// A message from a parachain to its Relay Chain. +#[derive(Clone, PartialEq, Eq, Encode, Decode, sp_runtime_interface::pass_by::PassByCodec)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct UpwardMessage { + /// The origin for the message to be sent from. + pub origin: ParachainDispatchOrigin, + /// The message data. + pub data: Vec, +} + +/// An incoming message. +#[derive(PartialEq, Eq, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Encode))] +pub struct IncomingMessage { + /// The source parachain. + pub source: Id, + /// The data of the message. + pub data: Vec, +} + + #[cfg(test)] mod tests { use super::*;