Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Update some types and interfaces to match the spec #24

Merged
merged 2 commits into from
Dec 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 21 additions & 29 deletions primitives/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,34 @@

//! Block and header type definitions.

use bytes;
use hash::H256;
use parachain;

/// Hash used to refer to a block hash.
pub type HeaderHash = H256;

/// Execution log (event)
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Log(#[serde(with="bytes")] pub Vec<u8>);

/// A relay chain block header.
///
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#header
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Header {
/// Block parent's hash.
pub parent_hash: HeaderHash,
/// State root after this transition.
pub state_root: H256,
/// Unix time at which this header was produced.
pub timestamp: u64,
/// Block number.
pub number: u64,
/// State root after this transition.
pub state_root: H256,
/// Parachain activity bitfield
pub parachain_activity: parachain::Activity,
/// Logs (generated by execution)
pub logs: Vec<Log>,
}

/// A relay chain block body.
Expand All @@ -46,7 +55,7 @@ pub struct Header {
#[serde(deny_unknown_fields)]
pub struct Body {
/// Parachain proposal blocks.
pub para_blocks: Vec<parachain::Proposal>,
pub candidates: Vec<parachain::Candidate>,
}

#[cfg(test)]
Expand All @@ -58,34 +67,17 @@ mod tests {
fn test_header_serialization() {
assert_eq!(ser::to_string_pretty(&Header {
parent_hash: 5.into(),
state_root: 3.into(),
timestamp: 10,
number: 67,
state_root: 3.into(),
parachain_activity: parachain::Activity(vec![0]),
logs: vec![Log(vec![1])],
}), r#"{
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
"number": 67,
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
"timestamp": 10,
"number": 67
}"#);
}

#[test]
fn test_body_serialization() {
assert_eq!(ser::to_string_pretty(&Body {
para_blocks: vec![
parachain::Proposal {
parachain: 5.into(),
header: parachain::Header(vec![1, 2, 3, 4]),
proof_hash: 5.into(),
}
],
}), r#"{
"paraBlocks": [
{
"parachain": 5,
"header": "0x01020304",
"proofHash": "0x0000000000000000000000000000000000000000000000000000000000000005"
}
"parachainActivity": "0x00",
"logs": [
"0x01"
]
}"#);
}
Expand Down
2 changes: 2 additions & 0 deletions primitives/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ impl_hash!(H160, 20);
impl_serde!(H160, 20);
impl_hash!(H256, 32);
impl_serde!(H256, 32);
impl_hash!(H520, 65);
impl_serde!(H520, 65);

#[cfg(test)]
mod tests {
Expand Down
3 changes: 3 additions & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub mod validator;

/// Alias to 160-bit hash when used in the context of an account address.
pub type Address = hash::H160;
/// Alias to 520-bit hash when used in the context of a signature.
pub type Signature = hash::H520;

pub use self::hash::{H160, H256};
pub use self::uint::{U256, U512};

Expand Down
105 changes: 59 additions & 46 deletions primitives/src/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,72 +30,85 @@ impl From<u64> for Id {
fn from(x: u64) -> Self { Id(x) }
}

/// A parachain block proposal.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
/// Candidate parachain block.
///
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#candidate-para-chain-block
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Proposal {
pub struct Candidate {
/// The ID of the parachain this is a proposal for.
pub parachain: Id,
/// Parachain block header bytes.
pub header: Header,
/// Hash of data necessary to prove validity of the header.
pub proof_hash: ProofHash,
pub parachain_index: Id,
/// Collator's signature
pub collator_signature: ::Signature,
/// Unprocessed ingress queue.
///
/// Ordered by parachain ID and block number.
pub unprocessed_ingress: Vec<(u64, Vec<Message>)>,
/// Block data
pub block: BlockData,
}

/// Parachain header raw bytes wrapper type.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Header(#[serde(with="bytes")] pub Vec<u8>);
/// Parachain ingress queue message.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Message(#[serde(with="bytes")] pub Vec<u8>);

/// Hash used to refer to proof of block header.
pub type ProofHash = ::hash::H256;
/// Parachain block data.
///
/// contains everything required to validate para-block, may contain block and witness data
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct BlockData(#[serde(with="bytes")] pub Vec<u8>);

/// Raw proof data.
/// Parachain header raw bytes wrapper type.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct RawProof(#[serde(with="bytes")] pub Vec<u8>);

impl RawProof {
/// Compute and store the hash of the proof.
pub fn into_proof(self) -> Proof {
let hash = ::hash(&self.0);
Proof(self, hash)
}
}
pub struct Header(#[serde(with="bytes")] pub Vec<u8>);

/// Parachain proof data.
/// Parachain head data included in the chain.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Proof(RawProof, ProofHash);

impl Proof {
/// Get raw proof data.
pub fn raw(&self) -> &RawProof { &self.0 }

/// Get hash of proof data.
pub fn hash(&self) -> &ProofHash { &self.1 }

/// Decompose the proof back into raw data and hash.
pub fn into_inner(self) -> (RawProof, ProofHash) {
(self.0, self.1)
}
}
pub struct HeadData(#[serde(with="bytes")] pub Vec<u8>);

/// Parachain validation code.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ValidationCode(#[serde(with="bytes")] pub Vec<u8>);

/// Activitiy bit field
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Activity(#[serde(with="bytes")] pub Vec<u8>);

#[cfg(test)]
mod tests {
use super::*;
use polkadot_serializer as ser;

#[test]
fn test_proof_serialization() {
assert_eq!(
ser::to_string_pretty(&Proof(RawProof(vec![1,2,3]), 5.into())),
r#"[
"0x010203",
"0x0000000000000000000000000000000000000000000000000000000000000005"
]"#
)
fn test_candidate() {
assert_eq!(ser::to_string_pretty(&Candidate {
parachain_index: 5.into(),
collator_signature: 10.into(),
unprocessed_ingress: vec![
(1, vec![Message(vec![2])]),
(2, vec![Message(vec![2]), Message(vec![3])]),
],
block: BlockData(vec![1, 2, 3]),
}), r#"{
"parachainIndex": 5,
"collatorSignature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a",
"unprocessedIngress": [
[
1,
[
"0x02"
]
],
[
2,
[
"0x02",
"0x03"
]
]
],
"block": "0x010203"
}"#);
}
}
84 changes: 35 additions & 49 deletions primitives/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,31 @@
//! Validator primitives.

use bytes;
use parachain;

/// Parachain incoming messages.
/// Parachain outgoing message.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IngressPosts(#[serde(with="bytes")] pub Vec<u8>);
pub struct EgressPost(#[serde(with="bytes")] pub Vec<u8>);

/// Parachain incoming messages delta.
/// Balance upload.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IngressPostsDelta(#[serde(with="bytes")] pub Vec<u8>);
pub struct BalanceUpload(#[serde(with="bytes")] pub Vec<u8>);

/// Parachain outgoing messages.
/// Balance download.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct EgressPosts(#[serde(with="bytes")] pub Vec<u8>);
pub struct BalanceDownload(#[serde(with="bytes")] pub Vec<u8>);

/// Validity result of particular proof and ingress queue.
/// The result of parachain validation.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag="type", content="data")]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub enum ProofValidity {
/// The proof is invalid.
Invalid,
/// The proof is processed and new egress queue is created.
/// Also includes current ingress queue delta.
Valid(IngressPostsDelta, EgressPosts),
}

impl ProofValidity {
/// The proof is valid.
pub fn is_valid(&self) -> bool {
match *self {
ProofValidity::Invalid => false,
ProofValidity::Valid(..) => true,
}
}
}

impl From<Option<(IngressPostsDelta, EgressPosts)>> for ProofValidity {
fn from(posts: Option<(IngressPostsDelta, EgressPosts)>) -> Self {
match posts {
Some((delta, posts)) => ProofValidity::Valid(delta, posts),
None => ProofValidity::Invalid,
}
}
pub struct ValidationResult {
/// New head data that should be included in the relay chain state.
pub head_data: parachain::HeadData,
/// Outgoing messages (a vec for each parachain).
pub egress_queues: Vec<Vec<EgressPost>>,
/// Balance uploads
pub balance_uploads: Vec<BalanceUpload>,
}

// TODO [ToDr] This shouldn't be here!
Expand All @@ -73,10 +55,13 @@ pub trait Validator {
/// In case of success produces egress posts.
fn validate(
&self,
messages: &IngressPosts,
proof: &::parachain::Proof,
code: &[u8],
) -> Result<ProofValidity, Self::Error>;
// TODO [ToDr] actually consolidate
consolidated_ingress: &[(u64, Vec<parachain::Message>)],
balance_downloads: &[BalanceDownload],
block_data: &parachain::BlockData,
previous_head_data: &parachain::HeadData,
) -> Result<ValidationResult, Self::Error>;
}

#[cfg(test)]
Expand All @@ -85,19 +70,20 @@ mod tests {
use polkadot_serializer as ser;

#[test]
fn test_proof_validity_serialization() {
assert_eq!(
ser::to_string_pretty(&ProofValidity::Invalid),
r#"{
"type": "invalid"
}"#);
assert_eq!(
ser::to_string_pretty(&ProofValidity::Valid(IngressPostsDelta(vec![1]), EgressPosts(vec![1, 2, 3]))),
r#"{
"type": "valid",
"data": [
"0x01",
"0x010203"
fn test_validation_result() {
assert_eq!(ser::to_string_pretty(&ValidationResult {
head_data: parachain::HeadData(vec![1]),
egress_queues: vec![vec![EgressPost(vec![1])]],
balance_uploads: vec![BalanceUpload(vec![2])],
}), r#"{
"headData": "0x01",
"egressQueues": [
[
"0x01"
]
],
"balanceUploads": [
"0x02"
]
}"#);
}
Expand Down
6 changes: 4 additions & 2 deletions rpc/src/chain/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use primitives::parachain;
use super::*;

use test_helpers::Blockchain;
Expand All @@ -26,9 +27,10 @@ fn should_return_header() {
ChainApi::header(&state, 0.into()),
Ok(Some(ref x)) if x == &block::Header {
parent_hash: 0.into(),
state_root: 0.into(),
timestamp: 0,
number: 0,
state_root: 0.into(),
parachain_activity: parachain::Activity(vec![0]),
logs: vec![],
}
);

Expand Down
Loading