From 6d939ddfced2480d53b01e1dcb2f7f041869f367 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 15 Mar 2016 13:36:27 +0100 Subject: [PATCH 1/8] updating lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfe37dbb4..ecdae1a0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -184,11 +184,11 @@ dependencies = [ [[package]] name = "eth-secp256k1" version = "0.5.4" -source = "git+https://github.com/ethcore/rust-secp256k1#283a0677d8327536be58a87e0494d7e0e7b1d1d8" +source = "git+https://github.com/ethcore/rust-secp256k1#b6fdd43bbcf6d46adb72a92dd1632a0fc834cbf5" dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", From 9dea31031c18a0728a4096c3372e3e0aff19a0d4 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 15 Mar 2016 14:35:45 +0100 Subject: [PATCH 2/8] Enact block with uncles test --- ethcore/src/block.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 1ef28188b..d4aa35445 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -423,6 +423,37 @@ mod tests { #[test] fn enact_block_with_uncle() { - // TODO: test for when there's an uncle. + use spec::*; + let engine = Spec::new_test().to_engine().unwrap(); + let genesis_header = engine.spec().genesis_header(); + + let mut db_result = get_temp_journal_db(); + let mut db = db_result.take(); + engine.spec().ensure_db_good(db.as_hashdb_mut()); + let mut open_block = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]); + let mut uncle1_header = Header::new(); + uncle1_header.extra_data = b"uncle1".to_vec(); + let mut uncle2_header = Header::new(); + uncle2_header.extra_data = b"uncle2".to_vec(); + open_block.push_uncle(uncle1_header).unwrap(); + open_block.push_uncle(uncle2_header).unwrap(); + let b = open_block.close().seal(engine.deref(), vec![]).unwrap(); + + let orig_bytes = b.rlp_bytes(); + let orig_db = b.drain(); + + let mut db_result = get_temp_journal_db(); + let mut db = db_result.take(); + engine.spec().ensure_db_good(db.as_hashdb_mut()); + let e = enact_and_seal(&orig_bytes, engine.deref(), db, &genesis_header, vec![genesis_header.hash()]).unwrap(); + + let bytes = e.rlp_bytes(); + assert_eq!(bytes, orig_bytes); + let uncles = BlockView::new(&bytes).uncles(); + assert_eq!(uncles[1].extra_data, b"uncle2"); + + let db = e.drain(); + assert_eq!(orig_db.keys(), db.keys()); + assert!(orig_db.keys().iter().filter(|k| orig_db.get(k.0) != db.get(k.0)).next() == None); } } From d96858d38c1d6a78ffef8799ddb59eeb6926e847 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 15 Mar 2016 18:17:48 +0100 Subject: [PATCH 3/8] proper blockchain json parsing --- Cargo.lock | 13 +++++ Cargo.toml | 1 + json/Cargo.toml | 21 ++++++++ json/build.rs | 45 ++++++++++++++++ json/src/blockchain/account.rs | 30 +++++++++++ json/src/blockchain/block.rs | 35 +++++++++++++ json/src/blockchain/blockchain.rs | 35 +++++++++++++ json/src/blockchain/header.rs | 51 ++++++++++++++++++ json/src/blockchain/mod.rs | 25 +++++++++ json/src/blockchain/state.rs | 34 ++++++++++++ json/src/blockchain/test.rs | 32 ++++++++++++ json/src/blockchain/transaction.rs | 35 +++++++++++++ json/src/bytes.rs | 81 ++++++++++++++++++++++++++++ json/src/hash.rs | 81 ++++++++++++++++++++++++++++ json/src/lib.rs | 28 ++++++++++ json/src/lib.rs.in | 25 +++++++++ json/src/uint.rs | 84 ++++++++++++++++++++++++++++++ 17 files changed, 656 insertions(+) create mode 100644 json/Cargo.toml create mode 100644 json/build.rs create mode 100644 json/src/blockchain/account.rs create mode 100644 json/src/blockchain/block.rs create mode 100644 json/src/blockchain/blockchain.rs create mode 100644 json/src/blockchain/header.rs create mode 100644 json/src/blockchain/mod.rs create mode 100644 json/src/blockchain/state.rs create mode 100644 json/src/blockchain/test.rs create mode 100644 json/src/blockchain/transaction.rs create mode 100644 json/src/bytes.rs create mode 100644 json/src/hash.rs create mode 100644 json/src/lib.rs create mode 100644 json/src/lib.rs.in create mode 100644 json/src/uint.rs diff --git a/Cargo.lock b/Cargo.lock index dfe37dbb4..f099dc670 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,7 @@ dependencies = [ "ethcore-devtools 1.1.0", "ethcore-rpc 1.1.0", "ethcore-util 1.1.0", + "ethjson 0.1.0", "ethminer 1.1.0", "ethsync 1.1.0", "fdlimit 0.1.0", @@ -286,6 +287,18 @@ dependencies = [ "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethjson" +version = "0.1.0" +dependencies = [ + "ethcore-util 1.1.0", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethminer" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index 782dd1c79..fd1d16cff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ ethsync = { path = "sync" } ethminer = { path = "miner" } ethcore-devtools = { path = "devtools" } ethcore-rpc = { path = "rpc", optional = true } +ethjson = { path = "json" } [features] default = ["rpc"] diff --git a/json/Cargo.toml b/json/Cargo.toml new file mode 100644 index 000000000..61599c331 --- /dev/null +++ b/json/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "ethjson" +version = "0.1.0" +authors = ["debris "] +build = "build.rs" + +[dependencies] +ethcore-util = { path = "../util" } +rustc-serialize = "0.3" +serde = "0.7.0" +serde_json = "0.7.0" +serde_macros = { version = "0.7.0", optional = true } +clippy = { version = "0.0.50", optional = true } + +[build-dependencies] +serde_codegen = { version = "0.7.0", optional = true } +syntex = "0.29.0" + +[features] +default = ["serde_codegen"] +nightly = ["serde_macros"] diff --git a/json/build.rs b/json/build.rs new file mode 100644 index 000000000..a23790d86 --- /dev/null +++ b/json/build.rs @@ -0,0 +1,45 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +#[cfg(not(feature = "serde_macros"))] +mod inner { + extern crate syntex; + extern crate serde_codegen; + + use std::env; + use std::path::Path; + + pub fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + + let src = Path::new("src/lib.rs.in"); + let dst = Path::new(&out_dir).join("lib.rs"); + + let mut registry = syntex::Registry::new(); + + serde_codegen::register(&mut registry); + registry.expand("", &src, &dst).unwrap(); + } +} + +#[cfg(feature = "serde_macros")] +mod inner { + pub fn main() {} +} + +fn main() { + inner::main(); +} diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs new file mode 100644 index 000000000..0d72d7fd7 --- /dev/null +++ b/json/src/blockchain/account.rs @@ -0,0 +1,30 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test account deserializer. + +use std::collections::BTreeMap; +use uint::Uint; +use bytes::Bytes; + +/// Blockchain test account deserializer. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Account { + balance: Uint, + code: Bytes, + nonce: Uint, + storage: BTreeMap, +} diff --git a/json/src/blockchain/block.rs b/json/src/blockchain/block.rs new file mode 100644 index 000000000..5dd423e7c --- /dev/null +++ b/json/src/blockchain/block.rs @@ -0,0 +1,35 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test block deserializer. + +use uint::Uint; +use bytes::Bytes; +use blockchain::header::Header; +use blockchain::transaction::Transaction; + +/// Blockchain test block deserializer. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Block { + #[serde(rename="blockHeader")] + header: Header, + #[serde(rename="blocknumber")] + number: Uint, + rlp: Bytes, + transactions: Vec, + #[serde(rename="uncleHeaders")] + uncles: Vec
, +} diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs new file mode 100644 index 000000000..675e10718 --- /dev/null +++ b/json/src/blockchain/blockchain.rs @@ -0,0 +1,35 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain deserialization. + +use bytes::Bytes; +use blockchain::state::State; +use blockchain::header::Header; + +/// Blockchain deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct BlockChain { + #[serde(rename="genesisBlockHeader")] + genesis_block: Header, + #[serde(rename="genesisRLP")] + genesis_rlp: Bytes, + blocks: Vec
, + #[serde(rename="postState")] + post_state: State, + #[serde(rename="preState")] + pre_state: State, +} diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs new file mode 100644 index 000000000..ea58c76a1 --- /dev/null +++ b/json/src/blockchain/header.rs @@ -0,0 +1,51 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test header deserializer. + +use hash::Hash; +use uint::Uint; +use bytes::Bytes; + +/// Blockchain test header deserializer. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Header { + bloom: Hash, // TODO Bloom + coinbase: Hash, + difficulty: Uint, + #[serde(rename="extraData")] + extra_data: Bytes, + #[serde(rename="gasLimit")] + gas_limit: Uint, + #[serde(rename="gasUsed")] + gas_used: Uint, + hash: Hash, + #[serde(rename="mixHash")] + mix_hash: Hash, + nonce: Uint, // TODO fix parsing + number: Uint, + #[serde(rename="parentHash")] + parent_hash: Hash, + #[serde(rename="receiptTrie")] + receipt_trie: Hash, + #[serde(rename="stateRoot")] + state_root: Hash, + timestamp: Uint, + #[serde(rename="transactionsTrie")] + transactions_trie: Hash, + #[serde(rename="uncleHash")] + uncle_hash: Hash, +} diff --git a/json/src/blockchain/mod.rs b/json/src/blockchain/mod.rs new file mode 100644 index 000000000..046b2e534 --- /dev/null +++ b/json/src/blockchain/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test deserialization. + +pub mod account; +pub mod block; +pub mod blockchain; +pub mod header; +pub mod state; +pub mod transaction; +pub mod test; diff --git a/json/src/blockchain/state.rs b/json/src/blockchain/state.rs new file mode 100644 index 000000000..c934d7c0a --- /dev/null +++ b/json/src/blockchain/state.rs @@ -0,0 +1,34 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test state deserializer. + +use std::collections::BTreeMap; +use std::ops::Deref; +use hash::Hash; +use blockchain::account::Account; + +/// Blockchain test state deserializer. +#[derive(Debug, PartialEq, Deserialize)] +pub struct State(BTreeMap); + +impl Deref for State { + type Target = BTreeMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/json/src/blockchain/test.rs b/json/src/blockchain/test.rs new file mode 100644 index 000000000..6097a60e6 --- /dev/null +++ b/json/src/blockchain/test.rs @@ -0,0 +1,32 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test deserializer. + +use std::collections::BTreeMap; +use std::ops::Deref; +use blockchain::blockchain::BlockChain; + +/// Blockchain test deserializer. +pub struct Test(BTreeMap); + +impl Deref for Test { + type Target = BTreeMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/json/src/blockchain/transaction.rs b/json/src/blockchain/transaction.rs new file mode 100644 index 000000000..5d04748f5 --- /dev/null +++ b/json/src/blockchain/transaction.rs @@ -0,0 +1,35 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Blockchain test transaction deserialization. + +use uint::Uint; +use bytes::Bytes; + +/// Blockchain test transaction deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Transaction { + data: Bytes, + #[serde(rename="gasLimit")] + gas_limit: Uint, + #[serde(rename="gasPrice")] + gas_price: Uint, + nonce: Uint, + r: Uint, + s: Uint, + v: Uint, + value: Uint +} diff --git a/json/src/bytes.rs b/json/src/bytes.rs new file mode 100644 index 000000000..034c90d62 --- /dev/null +++ b/json/src/bytes.rs @@ -0,0 +1,81 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Lenient bytes json deserialization for test json files. + +use rustc_serialize::hex::FromHex; +use serde::{Deserialize, Deserializer, Error}; +use serde::de::Visitor; + +/// Lenient bytes json deserialization for test json files. +#[derive(Default, Debug, PartialEq)] +pub struct Bytes(Vec); + +impl Into> for Bytes { + fn into(self) -> Vec { + self.0 + } +} + +impl Deserialize for Bytes { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(BytesVisitor) + } +} + +struct BytesVisitor; + +impl Visitor for BytesVisitor { + type Value = Bytes; + + fn visit_str(&mut self, value: &str) -> Result where E: Error { + let v = match value.len() { + 0 => vec![], + 2 if value.starts_with("0x") => vec![], + _ if value.starts_with("0x") => try!(FromHex::from_hex(&value[2..]).map_err(|_| Error::custom("Invalid hex value."))), + _ => try!(FromHex::from_hex(value).map_err(|_| Error::custom("Invalid hex value"))) + }; + Ok(Bytes(v)) + } + + fn visit_string(&mut self, value: String) -> Result where E: Error { + self.visit_str(value.as_ref()) + } +} + +#[cfg(test)] +//mod test { + //use std::str::FromStr; + //use serde_json; + //use util::hash::H256; + //use hash::Hash; + + //#[test] + //fn uint_deserialization() { + //let s = r#"["", "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae"]"#; + //let deserialized: Vec = serde_json::from_str(s).unwrap(); + //assert_eq!(deserialized, vec![ + //Hash(H256::from(0)), + //Hash(H256::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae").unwrap()) + //]); + //} + + //#[test] + //fn uint_into() { + //assert_eq!(H256::from(0), Hash(H256::from(0)).into()); + //} +//} diff --git a/json/src/hash.rs b/json/src/hash.rs new file mode 100644 index 000000000..e5bbedbfa --- /dev/null +++ b/json/src/hash.rs @@ -0,0 +1,81 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Lenient hash json deserialization for test json files. + +use std::str::FromStr; +use serde::{Deserialize, Deserializer, Error}; +use serde::de::Visitor; +use util::hash::H256; + +/// Lenient hash json deserialization for test json files. +#[derive(Default, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Hash(H256); + +impl Into for Hash { + fn into(self) -> H256 { + self.0 + } +} + +impl Deserialize for Hash { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(HashVisitor) + } +} + +struct HashVisitor; + +impl Visitor for HashVisitor { + type Value = Hash; + + fn visit_str(&mut self, value: &str) -> Result where E: Error { + let value = match value.len() { + 0 => H256::from(0), + _ => try!(H256::from_str(value).map_err(|_| Error::custom("invalid hex value."))) + }; + + Ok(Hash(value)) + } + + fn visit_string(&mut self, value: String) -> Result where E: Error { + self.visit_str(value.as_ref()) + } +} + +#[cfg(test)] +mod test { + use std::str::FromStr; + use serde_json; + use util::hash::H256; + use hash::Hash; + + #[test] + fn uint_deserialization() { + let s = r#"["", "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae"]"#; + let deserialized: Vec = serde_json::from_str(s).unwrap(); + assert_eq!(deserialized, vec![ + Hash(H256::from(0)), + Hash(H256::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae").unwrap()) + ]); + } + + #[test] + fn uint_into() { + assert_eq!(H256::from(0), Hash(H256::from(0)).into()); + } +} diff --git a/json/src/lib.rs b/json/src/lib.rs new file mode 100644 index 000000000..b94e1fa55 --- /dev/null +++ b/json/src/lib.rs @@ -0,0 +1,28 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Json deserialization module. + +#![warn(missing_docs)] +#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))] +#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))] + +#[cfg(feature = "serde_macros")] +include!("lib.rs.in"); + +#[cfg(not(feature = "serde_macros"))] +include!(concat!(env!("OUT_DIR"), "/lib.rs")); + diff --git a/json/src/lib.rs.in b/json/src/lib.rs.in new file mode 100644 index 000000000..6d3437811 --- /dev/null +++ b/json/src/lib.rs.in @@ -0,0 +1,25 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +extern crate rustc_serialize; +extern crate serde; +extern crate serde_json; +extern crate ethcore_util as util; + +pub mod hash; +pub mod uint; +pub mod bytes; +pub mod blockchain; diff --git a/json/src/uint.rs b/json/src/uint.rs new file mode 100644 index 000000000..f7f34f1dd --- /dev/null +++ b/json/src/uint.rs @@ -0,0 +1,84 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Lenient uint json deserialization for test json files. + +use std::str::FromStr; +use serde::{Deserialize, Deserializer, Error}; +use serde::de::Visitor; +use util::numbers::{U256, Uint as U}; + +/// Lenient uint json deserialization for test json files. +#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Uint(U256); + +impl Into for Uint { + fn into(self) -> U256 { + self.0 + } +} + +impl Deserialize for Uint { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(UintVisitor) + } +} + +struct UintVisitor; + +impl Visitor for UintVisitor { + type Value = Uint; + + fn visit_str(&mut self, value: &str) -> Result where E: Error { + let value = match value.len() { + 0 => U256::from(0), + 2 if value.starts_with("0x") => U256::from(0), + _ if value.starts_with("0x") => try!(U256::from_str(&value[2..]).map_err(|_| Error::custom("invalid hex value."))), + _ => try!(U256::from_dec_str(value).map_err(|_| Error::custom("invalid decimal value."))) + }; + + Ok(Uint(value)) + } + + fn visit_string(&mut self, value: String) -> Result where E: Error { + self.visit_str(value.as_ref()) + } +} + +#[cfg(test)] +mod test { + use serde_json; + use util::numbers::U256; + use uint::Uint; + + #[test] + fn uint_deserialization() { + let s = r#"["0xa", "10", "", "0x"]"#; + let deserialized: Vec = serde_json::from_str(s).unwrap(); + assert_eq!(deserialized, vec![ + Uint(U256::from(10)), + Uint(U256::from(10)), + Uint(U256::from(0)), + Uint(U256::from(0)) + ]); + } + + #[test] + fn uint_into() { + assert_eq!(U256::from(10), Uint(U256::from(10)).into()); + } +} From e538b417f005303dc95e7ece9f9ca77134a5edfa Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 15 Mar 2016 18:14:52 +0100 Subject: [PATCH 4/8] Missing return --- sync/src/chain.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 363597d40..8f0194289 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -481,6 +481,7 @@ impl ChainSync { trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h); if !self.have_common_block { trace!(target: "sync", "NewBlock ignored while seeking"); + return Ok(()); } let header: BlockHeader = try!(header_rlp.as_val()); let mut unknown = false; @@ -1497,6 +1498,7 @@ mod tests { let mut queue = VecDeque::new(); let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5)); + sync.have_common_block = true; let mut io = TestIo::new(&mut client, &mut queue, None); let block = UntrustedRlp::new(&block_data); From b4849d1c5870db13020f356bdffe4cee7c6a7161 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 15 Mar 2016 18:23:59 +0100 Subject: [PATCH 5/8] finished blockchain test deserialization --- json/src/blockchain/header.rs | 22 ++++----- json/src/blockchain/state.rs | 6 +-- json/src/bytes.rs | 40 +++++++-------- json/src/hash.rs | 91 ++++++++++++++++++++--------------- 4 files changed, 86 insertions(+), 73 deletions(-) diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs index ea58c76a1..fc27fc1f5 100644 --- a/json/src/blockchain/header.rs +++ b/json/src/blockchain/header.rs @@ -16,15 +16,15 @@ //! Blockchain test header deserializer. -use hash::Hash; +use hash::{H64, H256, Bloom}; use uint::Uint; use bytes::Bytes; /// Blockchain test header deserializer. #[derive(Debug, PartialEq, Deserialize)] pub struct Header { - bloom: Hash, // TODO Bloom - coinbase: Hash, + bloom: Bloom, + coinbase: H256, difficulty: Uint, #[serde(rename="extraData")] extra_data: Bytes, @@ -32,20 +32,20 @@ pub struct Header { gas_limit: Uint, #[serde(rename="gasUsed")] gas_used: Uint, - hash: Hash, + hash: H256, #[serde(rename="mixHash")] - mix_hash: Hash, - nonce: Uint, // TODO fix parsing + mix_hash: H256, + nonce: H64, number: Uint, #[serde(rename="parentHash")] - parent_hash: Hash, + parent_hash: H256, #[serde(rename="receiptTrie")] - receipt_trie: Hash, + receipt_trie: H256, #[serde(rename="stateRoot")] - state_root: Hash, + state_root: H256, timestamp: Uint, #[serde(rename="transactionsTrie")] - transactions_trie: Hash, + transactions_trie: H256, #[serde(rename="uncleHash")] - uncle_hash: Hash, + uncle_hash: H256, } diff --git a/json/src/blockchain/state.rs b/json/src/blockchain/state.rs index c934d7c0a..2af0dbf21 100644 --- a/json/src/blockchain/state.rs +++ b/json/src/blockchain/state.rs @@ -18,15 +18,15 @@ use std::collections::BTreeMap; use std::ops::Deref; -use hash::Hash; +use hash::Address; use blockchain::account::Account; /// Blockchain test state deserializer. #[derive(Debug, PartialEq, Deserialize)] -pub struct State(BTreeMap); +pub struct State(BTreeMap); impl Deref for State { - type Target = BTreeMap; + type Target = BTreeMap; fn deref(&self) -> &Self::Target { &self.0 diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 034c90d62..c9e31e888 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -58,24 +58,26 @@ impl Visitor for BytesVisitor { } #[cfg(test)] -//mod test { - //use std::str::FromStr; - //use serde_json; - //use util::hash::H256; - //use hash::Hash; +mod test { + use serde_json; + use bytes::Bytes; - //#[test] - //fn uint_deserialization() { - //let s = r#"["", "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae"]"#; - //let deserialized: Vec = serde_json::from_str(s).unwrap(); - //assert_eq!(deserialized, vec![ - //Hash(H256::from(0)), - //Hash(H256::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae").unwrap()) - //]); - //} + #[test] + fn bytes_deserialization() { + let s = r#"["", "0x", "0x12", "1234"]"#; + let deserialized: Vec = serde_json::from_str(s).unwrap(); + assert_eq!(deserialized, vec![ + Bytes(vec![]), + Bytes(vec![]), + Bytes(vec![0x12]), + Bytes(vec![0x12, 0x34]) + ]); + } - //#[test] - //fn uint_into() { - //assert_eq!(H256::from(0), Hash(H256::from(0)).into()); - //} -//} + #[test] + fn bytes_into() { + let bytes = Bytes(vec![0xff, 0x11]); + let v: Vec = bytes.into(); + assert_eq!(vec![0xff, 0x11], v); + } +} diff --git a/json/src/hash.rs b/json/src/hash.rs index e5bbedbfa..8ed28c33c 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -19,63 +19,74 @@ use std::str::FromStr; use serde::{Deserialize, Deserializer, Error}; use serde::de::Visitor; -use util::hash::H256; +use util::hash::{H64 as Hash64, Address as Hash160, H256 as Hash256, H2048 as Hash2048}; -/// Lenient hash json deserialization for test json files. -#[derive(Default, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Hash(H256); -impl Into for Hash { - fn into(self) -> H256 { - self.0 +macro_rules! impl_hash { + ($name: ident, $inner: ident) => { + /// Lenient hash json deserialization for test json files. + #[derive(Default, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] + pub struct $name($inner); + + impl Into<$inner> for $name { + fn into(self) -> $inner { + self.0 + } + } + + impl Deserialize for $name { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + + struct HashVisitor; + + impl Visitor for HashVisitor { + type Value = $name; + + fn visit_str(&mut self, value: &str) -> Result where E: Error { + let value = match value.len() { + 0 => $inner::from(0), + _ => try!($inner::from_str(value).map_err(|_| Error::custom("invalid hex value."))) + }; + + Ok($name(value)) + } + + fn visit_string(&mut self, value: String) -> Result where E: Error { + self.visit_str(value.as_ref()) + } + } + + deserializer.deserialize(HashVisitor) + } + } } } -impl Deserialize for Hash { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer { - deserializer.deserialize(HashVisitor) - } -} - -struct HashVisitor; - -impl Visitor for HashVisitor { - type Value = Hash; - - fn visit_str(&mut self, value: &str) -> Result where E: Error { - let value = match value.len() { - 0 => H256::from(0), - _ => try!(H256::from_str(value).map_err(|_| Error::custom("invalid hex value."))) - }; - - Ok(Hash(value)) - } - - fn visit_string(&mut self, value: String) -> Result where E: Error { - self.visit_str(value.as_ref()) - } -} +impl_hash!(H64, Hash64); +impl_hash!(Address, Hash160); +impl_hash!(H256, Hash256); +impl_hash!(Bloom, Hash2048); #[cfg(test)] mod test { use std::str::FromStr; use serde_json; - use util::hash::H256; - use hash::Hash; + use util::hash; + use hash::H256; #[test] - fn uint_deserialization() { + fn hash_deserialization() { let s = r#"["", "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae"]"#; - let deserialized: Vec = serde_json::from_str(s).unwrap(); + let deserialized: Vec = serde_json::from_str(s).unwrap(); assert_eq!(deserialized, vec![ - Hash(H256::from(0)), - Hash(H256::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae").unwrap()) + H256(hash::H256::from(0)), + H256(hash::H256::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae").unwrap()) ]); } #[test] - fn uint_into() { - assert_eq!(H256::from(0), Hash(H256::from(0)).into()); + fn hash_into() { + assert_eq!(hash::H256::from(0), H256(hash::H256::from(0)).into()); } } From 196c6e8eccb73b885596e5225ce714abff35c80e Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 15 Mar 2016 19:32:07 +0100 Subject: [PATCH 6/8] tests for loading test json files --- json/src/blockchain/account.rs | 20 ++++++ json/src/blockchain/block.rs | 39 +++++++++- json/src/blockchain/blockchain.rs | 114 +++++++++++++++++++++++++++++- json/src/blockchain/header.rs | 34 ++++++++- json/src/bytes.rs | 8 ++- json/src/hash.rs | 4 +- json/src/uint.rs | 8 ++- 7 files changed, 215 insertions(+), 12 deletions(-) diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs index 0d72d7fd7..eb6f0a1dd 100644 --- a/json/src/blockchain/account.rs +++ b/json/src/blockchain/account.rs @@ -28,3 +28,23 @@ pub struct Account { nonce: Uint, storage: BTreeMap, } + +#[cfg(test)] +mod tests { + use serde_json; + use blockchain::account::Account; + + #[test] + fn header_deserialization() { + let s = r#"{ + "balance" : "0x09184e72a078", + "code" : "0x600140600155", + "nonce" : "0x00", + "storage" : { + "0x01" : "0x9a10c2b5bb8f3c602e674006d9b21f09167df57c87a78a5ce96d4159ecb76520" + } + }"#; + let _deserialized: Account= serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/blockchain/block.rs b/json/src/blockchain/block.rs index 5dd423e7c..ed297077c 100644 --- a/json/src/blockchain/block.rs +++ b/json/src/blockchain/block.rs @@ -16,7 +16,6 @@ //! Blockchain test block deserializer. -use uint::Uint; use bytes::Bytes; use blockchain::header::Header; use blockchain::transaction::Transaction; @@ -26,10 +25,44 @@ use blockchain::transaction::Transaction; pub struct Block { #[serde(rename="blockHeader")] header: Header, - #[serde(rename="blocknumber")] - number: Uint, rlp: Bytes, transactions: Vec, #[serde(rename="uncleHeaders")] uncles: Vec
, } + +#[cfg(test)] +mod tests { + use serde_json; + use blockchain::block::Block; + + #[test] + fn block_deserialization() { + let s = r#"{ + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "65ebf1b97fb89b14680267e0723d69267ec4bf9a96d4a60ffcb356ae0e81c18f", + "mixHash" : "13735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd06", + "nonce" : "931dcc53e5edc514", + "number" : "0x01", + "parentHash" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3", + "timestamp" : "0x56850b7b", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "1", + "rlp" : "0xf901fcf901f7a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba808456850b7b80a013735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd0688931dcc53e5edc514c0c0", + "transactions" : [], + "uncleHeaders" : [] + }"#; + let _deserialized: Block = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index 675e10718..f6b1259ca 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -19,6 +19,7 @@ use bytes::Bytes; use blockchain::state::State; use blockchain::header::Header; +use blockchain::block::Block; /// Blockchain deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -27,9 +28,118 @@ pub struct BlockChain { genesis_block: Header, #[serde(rename="genesisRLP")] genesis_rlp: Bytes, - blocks: Vec
, + blocks: Vec, #[serde(rename="postState")] post_state: State, - #[serde(rename="preState")] + #[serde(rename="pre")] pre_state: State, } + +#[cfg(test)] +mod tests { + use serde_json; + use blockchain::blockchain::BlockChain; + + #[test] + fn blockchain_deserialization() { + let s = r#"{ + "blocks" : [{ + "blockHeader" : { + "bloom" : "00000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x0102030405060708091011121314151617181920212223242526272829303132", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x560b", + "hash" : "06b5b1742bde29468510c92641f36b719c61b3fc3e9a21c92a23978f4f7faa2a", + "mixHash" : "5266ca43e81d25925a9ba573c3e4f9180bc076d316d90e63c6f8708b272f5ce2", + "nonce" : "59ba4daed1898e21", + "number" : "0x01", + "parentHash" : "f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524d", + "receiptTrie" : "c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296", + "stateRoot" : "bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bf", + "timestamp" : "0x56850c2c", + "transactionsTrie" : "498785da562aa0c5dd5937cf15f22139b0b1bcf3b4fc48986e1bb1dae9292796", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90285f90219a0f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bfa0498785da562aa0c5dd5937cf15f22139b0b1bcf3b4fc48986e1bb1dae9292796a0c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefba82560b8456850c2ca00102030405060708091011121314151617181920212223242526272829303132a05266ca43e81d25925a9ba573c3e4f9180bc076d316d90e63c6f8708b272f5ce28859ba4daed1898e21f866f864800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d8785012a05f200801ca0ee0b9ec878fbd4258a9473199d8ecc32996a20c323c004e79e0cda20e0418ce3a04e6bc63927d1510bab54f37e46fa036faf4b2c465d271920d9afea1fadf7bd21c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xc350", + "gasPrice" : "0x0a", + "nonce" : "0x00", + "r" : "0xee0b9ec878fbd4258a9473199d8ecc32996a20c323c004e79e0cda20e0418ce3", + "s" : "0x4e6bc63927d1510bab54f37e46fa036faf4b2c465d271920d9afea1fadf7bd21", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1c", + "value" : "0x012a05f200" + } + ], + "uncleHeaders" : [ + ] + }], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524d", + "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0102030405060708", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", + "lastblockhash" : "06b5b1742bde29468510c92641f36b719c61b3fc3e9a21c92a23978f4f7faa2a", + "postState" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x012a05f264", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x4563918244f75c6e", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x012a029592", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x64", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }"#; + let _deserialized: BlockChain = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + //} +} diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs index fc27fc1f5..e97039213 100644 --- a/json/src/blockchain/header.rs +++ b/json/src/blockchain/header.rs @@ -16,7 +16,7 @@ //! Blockchain test header deserializer. -use hash::{H64, H256, Bloom}; +use hash::{H64, Address, H256, Bloom}; use uint::Uint; use bytes::Bytes; @@ -24,7 +24,7 @@ use bytes::Bytes; #[derive(Debug, PartialEq, Deserialize)] pub struct Header { bloom: Bloom, - coinbase: H256, + coinbase: Address, difficulty: Uint, #[serde(rename="extraData")] extra_data: Bytes, @@ -49,3 +49,33 @@ pub struct Header { #[serde(rename="uncleHash")] uncle_hash: H256, } + +#[cfg(test)] +mod tests { + use serde_json; + use blockchain::header::Header; + + #[test] + fn header_deserialization() { + let s = r#"{ + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "65ebf1b97fb89b14680267e0723d69267ec4bf9a96d4a60ffcb356ae0e81c18f", + "mixHash" : "13735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd06", + "nonce" : "931dcc53e5edc514", + "number" : "0x01", + "parentHash" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3", + "timestamp" : "0x56850b7b", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }"#; + let _deserialized: Header = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/bytes.rs b/json/src/bytes.rs index c9e31e888..28b7636d4 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -46,8 +46,12 @@ impl Visitor for BytesVisitor { let v = match value.len() { 0 => vec![], 2 if value.starts_with("0x") => vec![], - _ if value.starts_with("0x") => try!(FromHex::from_hex(&value[2..]).map_err(|_| Error::custom("Invalid hex value."))), - _ => try!(FromHex::from_hex(value).map_err(|_| Error::custom("Invalid hex value"))) + _ if value.starts_with("0x") => try!(FromHex::from_hex(&value[2..]).map_err(|_| { + Error::custom(format!("Invalid hex value {}.", value).as_ref()) + })), + _ => try!(FromHex::from_hex(value).map_err(|_| { + Error::custom(format!("Invalid hex value {}.", value).as_ref()) + })) }; Ok(Bytes(v)) } diff --git a/json/src/hash.rs b/json/src/hash.rs index 8ed28c33c..098f2e7a8 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -46,7 +46,9 @@ macro_rules! impl_hash { fn visit_str(&mut self, value: &str) -> Result where E: Error { let value = match value.len() { 0 => $inner::from(0), - _ => try!($inner::from_str(value).map_err(|_| Error::custom("invalid hex value."))) + _ => try!($inner::from_str(value).map_err(|_| { + Error::custom(format!("Invalid hex value {}.", value).as_ref()) + })) }; Ok($name(value)) diff --git a/json/src/uint.rs b/json/src/uint.rs index f7f34f1dd..41e717277 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -47,8 +47,12 @@ impl Visitor for UintVisitor { let value = match value.len() { 0 => U256::from(0), 2 if value.starts_with("0x") => U256::from(0), - _ if value.starts_with("0x") => try!(U256::from_str(&value[2..]).map_err(|_| Error::custom("invalid hex value."))), - _ => try!(U256::from_dec_str(value).map_err(|_| Error::custom("invalid decimal value."))) + _ if value.starts_with("0x") => try!(U256::from_str(&value[2..]).map_err(|_| { + Error::custom(format!("Invalid hex value {}.", value).as_ref()) + })), + _ => try!(U256::from_dec_str(value).map_err(|_| { + Error::custom(format!("Invalid decimal value {}.", value).as_ref()) + })) }; Ok(Uint(value)) From b9584b7ec9c028057ca3008ea421d9f419c00e0a Mon Sep 17 00:00:00 2001 From: arkpar Date: Wed, 16 Mar 2016 18:25:32 +0100 Subject: [PATCH 7/8] restart sync on getting old unknown header --- sync/src/chain.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 8f0194289..4f6c2100a 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -402,6 +402,12 @@ impl ChainSync { debug!(target: "sync", "Mismatched block header {}", number + 1); self.remove_downloaded_blocks(number + 1); } + if self.have_common_block && number < self.current_base_block() + 1 { + // unkown header + debug!(target: "sync", "Old block header {:?} ({}) is unknown, restarting sync", hash, number); + self.restart(io); + return Ok(()); + } } let hdr = Header { data: try!(r.at(i)).as_raw().to_vec(), From 5cd3eaa1112464860f9da357ee6103befaf8581e Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 17 Mar 2016 09:54:05 +0100 Subject: [PATCH 8/8] Update install-parity.sh --- install-parity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install-parity.sh b/install-parity.sh index 439700306..74387ca7f 100755 --- a/install-parity.sh +++ b/install-parity.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/beta-0.9/parity_linux_0.9.0-0_amd64.deb +PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/v1.0.0-rc1/parity_linux_1.0.0.rc1-0_amd64.deb function run_installer()