Initial validator trait. (#14)

* Initial validator trait.

* Add missing docs warning.

* Fix formatting.

* Fix validator output and serialization.

* Get rid of redundant ValidationCode type.
This commit is contained in:
Tomasz Drwięga
2017-11-12 16:48:35 +01:00
committed by Robert Habermeier
parent 9d083be47a
commit e9177294f6
12 changed files with 520 additions and 52 deletions
+87 -8
View File
@@ -1,11 +1,3 @@
[root]
name = "polkadot-serializer"
version = "0.1.0"
dependencies = [
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aho-corasick"
version = "0.6.3"
@@ -30,6 +22,29 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "0.7.0"
@@ -45,6 +60,16 @@ name = "byteorder"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
version = "2.27.1"
@@ -65,6 +90,15 @@ name = "crunchy"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "dbghelp-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "difference"
version = "1.0.0"
@@ -84,6 +118,14 @@ dependencies = [
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "error-chain"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fixed-hash"
version = "0.1.0"
@@ -179,9 +221,28 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uint 0.1.0 (git+https://github.com/paritytech/primitives.git)",
]
[[package]]
name = "polkadot-serializer"
version = "0.1.0"
dependencies = [
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "polkadot-validator"
version = "0.1.0"
dependencies = [
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-primitives 0.1.0",
"polkadot-serializer 0.1.0",
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pretty_assertions"
version = "0.4.0"
@@ -235,6 +296,11 @@ name = "regex-syntax"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-demangle"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-hex"
version = "1.0.0"
@@ -346,6 +412,11 @@ dependencies = [
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tiny-keccak"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "uint"
version = "0.1.0"
@@ -408,14 +479,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
"checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983"
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "<none>"
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
@@ -433,6 +510,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
"checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
@@ -447,6 +525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"
"checksum uint 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "<none>"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
+3 -2
View File
@@ -4,10 +4,11 @@ version = "0.1.0"
authors = ["Parity Team <admin@parity.io>"]
[dependencies]
polkadot-cli = { path = "cli" }
polkadot-cli = { path = "cli", version = "0.1" }
[workspace]
members = [
"primitives",
"serializer"
"serializer",
"validator",
]
+2 -1
View File
@@ -4,11 +4,12 @@ version = "0.1.0"
authors = ["Parity Team <admin@parity.io>"]
[dependencies]
crunchy = "0.1.5"
crunchy = "0.1"
fixed-hash = { git = "https://github.com/paritytech/primitives.git" }
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"
tiny-keccak = "1.3"
uint = { git = "https://github.com/paritytech/primitives.git" }
[dev-dependencies]
+14 -40
View File
@@ -16,50 +16,23 @@
//! Block and header type definitions.
use bytes;
use hash::H256;
use parachain;
/// Hash used to refer to a block hash.
pub type HeaderHash = H256;
/// Hash used to refer to proof of block header.
pub type ProofHash = H256;
/// Unique identifier of a parachain.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)]
pub struct ParachainId(u64);
impl From<ParachainId> for u64 {
fn from(x: ParachainId) -> Self { x.0 }
}
impl From<u64> for ParachainId {
fn from(x: u64) -> Self { ParachainId(x) }
}
/// A wrapper type for parachain block header raw bytes.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ParachainBlockHeader(#[serde(with="bytes")] pub Vec<u8>);
/// A parachain block proposal.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ParachainProposal {
/// The ID of the parachain this is a proposal for.
pub parachain: ParachainId,
/// Parachain block header bytes.
pub header: ParachainBlockHeader,
/// Hash of data necessary to prove validity of the header.
pub proof_hash: ProofHash,
}
/// A relay chain block header.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Header {
/// Block parent's hash.
pub parent_hash: HeaderHash,
#[serde(rename="parentHash")]
pub parent_hash: HeaderHash,
/// State root after this transition.
pub state_root: H256,
#[serde(rename="stateRoot")]
pub state_root: H256,
/// Unix time at which this header was produced.
pub timestamp: u64,
pub timestamp: u64,
/// Block number.
pub number: u64,
}
@@ -71,7 +44,8 @@ pub struct Header {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Body {
/// Parachain proposal blocks.
pub para_blocks: Vec<ParachainProposal>,
#[serde(rename="paraBlocks")]
pub para_blocks: Vec<parachain::Proposal>,
}
@@ -88,8 +62,8 @@ mod tests {
timestamp: 10,
number: 67,
}), r#"{
"parent_hash": "0x0000000000000000000000000000000000000000000000000000000000000005",
"state_root": "0x0000000000000000000000000000000000000000000000000000000000000003",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
"timestamp": 10,
"number": 67
}"#);
@@ -99,18 +73,18 @@ mod tests {
fn test_body_serialization() {
assert_eq!(ser::to_string_pretty(&Body {
para_blocks: vec![
ParachainProposal {
parachain::Proposal {
parachain: 5.into(),
header: ParachainBlockHeader(vec![1, 2, 3, 4]),
header: parachain::Header(vec![1, 2, 3, 4]),
proof_hash: 5.into(),
}
],
}), r#"{
"para_blocks": [
"paraBlocks": [
{
"parachain": 5,
"header": "0x01020304",
"proof_hash": "0x0000000000000000000000000000000000000000000000000000000000000005"
"proofHash": "0x0000000000000000000000000000000000000000000000000000000000000005"
}
]
}"#);
+9 -1
View File
@@ -18,8 +18,9 @@
#![warn(missing_docs)]
extern crate serde;
extern crate rustc_hex;
extern crate serde;
extern crate tiny_keccak;
#[macro_use]
extern crate crunchy;
@@ -41,7 +42,14 @@ extern crate pretty_assertions;
mod bytes;
pub mod block;
pub mod hash;
pub mod parachain;
pub mod uint;
pub mod validator;
/// Alias to 160-bit hash when used in the context of an account address.
pub type Address = hash::H160;
/// A hash function.
pub fn hash(data: &[u8]) -> hash::H256 {
tiny_keccak::keccak256(data).into()
}
+100
View File
@@ -0,0 +1,100 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Parachain data types.
use bytes;
/// Unique identifier of a parachain.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)]
pub struct Id(u64);
impl From<Id> for u64 {
fn from(x: Id) -> Self { x.0 }
}
impl From<u64> for Id {
fn from(x: u64) -> Self { Id(x) }
}
/// A parachain block proposal.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Proposal {
/// 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.
#[serde(rename="proofHash")]
pub proof_hash: ProofHash,
}
/// Parachain header raw bytes wrapper type.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Header(#[serde(with="bytes")] pub Vec<u8>);
/// Hash used to refer to proof of block header.
pub type ProofHash = ::hash::H256;
/// Raw proof data.
#[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)
}
}
/// Parachain proof data.
#[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)
}
}
/// Parachain validation code.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ValidationCode(#[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"
]"#
)
}
}
+104
View File
@@ -0,0 +1,104 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Validator primitives.
use bytes;
/// Parachain incoming messages.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IngressPosts(#[serde(with="bytes")] pub Vec<u8>);
/// Parachain incoming messages delta.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IngressPostsDelta(#[serde(with="bytes")] pub Vec<u8>);
/// Parachain outgoing messages.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct EgressPosts(#[serde(with="bytes")] pub Vec<u8>);
/// Validity result of particular proof and ingress queue.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag="type", content="data")]
pub enum ProofValidity {
/// The proof is invalid.
#[serde(rename="invalid")]
Invalid,
#[serde(rename="valid")]
/// 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,
}
}
}
// TODO [ToDr] This shouldn't be here!
/// Validator logic.
pub trait Validator {
/// Validation error.
type Error: ::std::error::Error;
/// Validates if the provided proof holds given a current ingress queue.
///
/// In case of success produces egress posts.
fn validate(
&self,
messages: &IngressPosts,
proof: &::parachain::Proof,
code: &[u8],
) -> Result<ProofValidity, Self::Error>;
}
#[cfg(test)]
mod tests {
use super::*;
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"
]
}"#);
}
}
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "polkadot-validator"
version = "0.1.0"
authors = ["Parity Team <admin@parity.io>"]
[dependencies]
error-chain = "0.11"
polkadot-primitives = { path = "../primitives", version = "0.1" }
polkadot-serializer = { path = "../serializer", version = "0.1" }
serde = "1.0"
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use serializer;
error_chain! {
foreign_links {
Serialization(serializer::Error);
}
errors {
Timeout {
description("Validation task has timed-out."),
display("Validation timeout."),
}
InvalidCode(details: String) {
description("The code is invalid."),
display("invalid code: '{}'", details),
}
}
}
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Validator implementation.
#[warn(missing_docs)]
extern crate polkadot_primitives as primitives;
extern crate polkadot_serializer as serializer;
extern crate serde;
#[macro_use]
extern crate error_chain;
mod error;
mod parachains;
mod validator;
pub use error::{Error, ErrorKind, Result};
pub use validator::Validator;
+46
View File
@@ -0,0 +1,46 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::fmt;
use primitives::validator;
use serde::de::DeserializeOwned;
/// Parachain code implementation.
pub trait ParachainCode: fmt::Debug {
/// Deserialized messages type.
type Messages: DeserializeOwned;
/// Deserialized proof type.
type Proof: DeserializeOwned;
/// Given decoded messages and proof validate it and return egress posts.
fn check(&self, messages: Self::Messages, proof: Self::Proof) ->
Option<(validator::IngressPostsDelta, validator::EgressPosts)>;
}
/// Dummy implementation of the first parachain validation.
#[derive(Debug)]
pub struct ParaChain1;
impl ParachainCode for ParaChain1 {
type Messages = ();
type Proof = ();
fn check(&self, _messages: Self::Messages, _proof: Self::Proof)
-> Option<(validator::IngressPostsDelta, validator::EgressPosts)> {
None
}
}
+79
View File
@@ -0,0 +1,79 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::fmt;
use primitives::{validator, parachain};
use serde::de::DeserializeOwned;
use serializer;
use error::{Error, ErrorKind, Result};
use parachains::{ParachainCode, ParaChain1};
/// A dummy validator implementation.
#[derive(Debug)]
pub struct Validator {
codes: Vec<Box<Code>>,
}
impl Validator {
/// Create a new validator.
pub fn new() -> Self {
Validator {
codes: vec![
Box::new(ParaChain1) as Box<Code>
],
}
}
}
impl validator::Validator for Validator {
type Error = Error;
fn validate(
&self,
messages: &validator::IngressPosts,
proof: &parachain::Proof,
code: &[u8],
) -> Result<validator::ProofValidity> {
ensure!(code.len() == 1, ErrorKind::InvalidCode(format!("The code should be a single byte.")));
match self.codes.get(code[0] as usize) {
Some(code) => code.check(messages, proof),
None => bail!(ErrorKind::InvalidCode(format!("Unknown parachain code."))),
}
}
}
/// Simplified parachain code verification
trait Code: fmt::Debug {
/// Given bytes of messages and proof determine if the proof is valid and return egress posts.
fn check(&self, messages: &validator::IngressPosts, proof: &parachain::Proof) -> Result<validator::ProofValidity>;
}
impl<M, P, T> Code for T where
M: DeserializeOwned,
P: DeserializeOwned,
T: ParachainCode<Messages=M, Proof=P>,
{
fn check(&self, messages: &validator::IngressPosts, proof: &parachain::Proof) -> Result<validator::ProofValidity> {
let messages = serializer::from_slice(&messages.0)?;
let proof = serializer::from_slice(&proof.raw().0)?;
Ok(self.check(messages, proof).into())
}
}