diff --git a/Cargo.lock b/Cargo.lock
index 1a701042e..daf0501ba 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -216,6 +216,7 @@ dependencies = [
"ethash 1.1.0",
"ethcore-devtools 1.1.0",
"ethcore-util 1.1.0",
+ "ethjson 0.1.0",
"heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml
index 1d16cc34a..cf75949f1 100644
--- a/ethcore/Cargo.toml
+++ b/ethcore/Cargo.toml
@@ -21,6 +21,7 @@ clippy = { version = "0.0.50", optional = true }
crossbeam = "0.1.5"
lazy_static = "0.1"
ethcore-devtools = { path = "../devtools" }
+ethjson = { path = "../json" }
[features]
jit = ["evmjit"]
diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs
index 572cda2fa..662dea641 100644
--- a/ethcore/src/lib.rs
+++ b/ethcore/src/lib.rs
@@ -83,6 +83,7 @@ extern crate time;
extern crate env_logger;
extern crate num_cpus;
extern crate crossbeam;
+extern crate ethjson;
#[cfg(test)] extern crate ethcore_devtools as devtools;
#[cfg(feature = "jit" )] extern crate evmjit;
diff --git a/ethcore/src/spec/genesis.rs b/ethcore/src/spec/genesis.rs
new file mode 100644
index 000000000..686e8f6d1
--- /dev/null
+++ b/ethcore/src/spec/genesis.rs
@@ -0,0 +1,91 @@
+// 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 .
+
+use util::rlp::*;
+use util::numbers::{Uint, U256};
+use util::hash::{H64, Address, H256};
+use ethjson;
+
+/// Genesis seal type.
+pub enum Seal {
+ /// Classic ethereum seal.
+ Ethereum {
+ /// Seal nonce.
+ nonce: H64,
+ /// Seal mix hash.
+ mix_hash: H256,
+ },
+ /// Generic seal.
+ Generic {
+ /// Number of seal fields.
+ fields: usize,
+ /// Seal rlp.
+ rlp: Vec,
+ },
+}
+
+/// Genesis components.
+pub struct Genesis {
+ /// Seal.
+ pub seal: Seal,
+ /// Difficulty.
+ pub difficulty: U256,
+ /// Author.
+ pub author: Address,
+ /// Timestamp.
+ pub timestamp: u64,
+ /// Parent hash.
+ pub parent_hash: H256,
+ /// Gas limit.
+ pub gas_limit: U256,
+ /// Transactions root.
+ pub transactions_root: H256,
+ /// Receipts root.
+ pub receipts_root: H256,
+ /// State root.
+ pub state_root: Option,
+ /// Gas used.
+ pub gas_used: U256,
+ /// Extra data.
+ pub extra_data: Vec,
+}
+
+impl From for Genesis {
+ fn from(g: ethjson::spec::Genesis) -> Self {
+ Genesis {
+ seal: match (g.nonce, g.mix_hash) {
+ (Some(nonce), Some(mix_hash)) => Seal::Ethereum {
+ nonce: nonce.into(),
+ mix_hash: mix_hash.into(),
+ },
+ _ => Seal::Generic {
+ fields: g.seal_fields.unwrap(),
+ rlp: g.seal_rlp.unwrap().into(),
+ }
+ },
+ difficulty: g.difficulty.into(),
+ author: g.author.into(),
+ timestamp: g.timestamp.into(),
+ parent_hash: g.parent_hash.into(),
+ gas_limit: g.gas_limit.into(),
+ transactions_root: g.transactions_root.map_or_else(|| SHA3_NULL_RLP.clone(), Into::into),
+ receipts_root: g.receipts_root.map_or_else(|| SHA3_NULL_RLP.clone(), Into::into),
+ state_root: g.state_root.map(Into::into),
+ gas_used: g.gas_used.map_or_else(U256::zero, Into::into),
+ extra_data: g.extra_data.map_or_else(Vec::new, Into::into),
+ }
+ }
+}
diff --git a/ethcore/src/spec/mod.rs b/ethcore/src/spec/mod.rs
new file mode 100644
index 000000000..e9c7a0356
--- /dev/null
+++ b/ethcore/src/spec/mod.rs
@@ -0,0 +1,22 @@
+// 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 params.
+
+mod genesis;
+pub mod spec;
+
+pub use self::spec::*;
diff --git a/ethcore/src/spec.rs b/ethcore/src/spec/spec.rs
similarity index 92%
rename from ethcore/src/spec.rs
rename to ethcore/src/spec/spec.rs
index 2208350cc..c7e2e4e9f 100644
--- a/ethcore/src/spec.rs
+++ b/ethcore/src/spec/spec.rs
@@ -21,6 +21,8 @@ use engine::*;
use pod_state::*;
use null_engine::*;
use account_db::*;
+use ethereum;
+use super::genesis::{Seal as GenesisSeal, Genesis};
/// Convert JSON value to equivalent RLP representation.
// TODO: handle container types.
@@ -106,7 +108,7 @@ impl Spec {
pub fn to_engine(self) -> Result, Error> {
match self.engine_name.as_ref() {
"NullEngine" => Ok(NullEngine::new_boxed(self)),
- "Ethash" => Ok(super::ethereum::Ethash::new_boxed(self)),
+ "Ethash" => Ok(ethereum::Ethash::new_boxed(self)),
_ => Err(Error::UnknownEngineName(self.engine_name.clone()))
}
}
@@ -197,6 +199,32 @@ impl Spec {
self.state_root_memo = RwLock::new(genesis.find("stateRoot").and_then(|_| Some(H256::from_json(&genesis["stateRoot"]))));
}
+ /// Overwrite the genesis components.
+ pub fn overwrite_genesis_params(&mut self, g: Genesis) {
+ let (seal_fields, seal_rlp) = match g.seal {
+ GenesisSeal::Generic { fields, rlp } => (fields, rlp),
+ GenesisSeal::Ethereum { nonce, mix_hash } => {
+ let mut s = RlpStream::new();
+ s.append(&mix_hash);
+ s.append(&nonce);
+ (2, s.out())
+ }
+ };
+
+ self.parent_hash = g.parent_hash;
+ self.transactions_root = g.transactions_root;
+ self.receipts_root = g.receipts_root;
+ self.author = g.author;
+ self.difficulty = g.difficulty;
+ self.gas_limit = g.gas_limit;
+ self.gas_used = g.gas_used;
+ self.timestamp = g.timestamp;
+ self.extra_data = g.extra_data;
+ self.seal_fields = seal_fields;
+ self.seal_rlp = seal_rlp;
+ self.state_root_memo = RwLock::new(g.state_root);
+ }
+
/// Alter the value of the genesis state.
pub fn set_genesis_state(&mut self, s: PodState) {
self.genesis_state = s;
@@ -304,7 +332,7 @@ impl Spec {
}
/// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus.
- pub fn new_test() -> Spec { Self::from_json_utf8(include_bytes!("../res/null_morden.json")) }
+ pub fn new_test() -> Spec { Self::from_json_utf8(include_bytes!("../../res/null_morden.json")) }
}
#[cfg(test)]
diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs
index 75d321a4d..d9e879ae9 100644
--- a/json/src/blockchain/blockchain.rs
+++ b/json/src/blockchain/blockchain.rs
@@ -59,6 +59,11 @@ impl BlockChain {
timestamp: self.genesis_block.timestamp,
parent_hash: self.genesis_block.parent_hash.clone(),
gas_limit: self.genesis_block.gas_limit,
+ transactions_root: Some(self.genesis_block.transactions_root.clone()),
+ receipts_root: Some(self.genesis_block.receipts_root.clone()),
+ state_root: Some(self.genesis_block.state_root.clone()),
+ gas_used: Some(self.genesis_block.gas_used),
+ extra_data: Some(self.genesis_block.extra_data.clone()),
}
}
}
diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs
index f4ebee01b..ece6d6359 100644
--- a/json/src/blockchain/header.rs
+++ b/json/src/blockchain/header.rs
@@ -53,7 +53,7 @@ pub struct Header {
pub parent_hash: H256,
/// Receipt root.
#[serde(rename="receiptTrie")]
- pub receipt_root: H256,
+ pub receipts_root: H256,
/// State root.
#[serde(rename="stateRoot")]
pub state_root: H256,
diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs
index a8b5b30e3..a2b484397 100644
--- a/json/src/spec/genesis.rs
+++ b/json/src/spec/genesis.rs
@@ -33,7 +33,7 @@ pub struct Genesis {
// new seal // TODO: consider moving it to a separate seal structure
#[serde(rename="sealFields")]
/// Number of seal fields.
- pub seal_fields: Option,
+ pub seal_fields: Option,
#[serde(rename="sealRlp")]
/// Seal rlp.
pub seal_rlp: Option,
@@ -50,6 +50,21 @@ pub struct Genesis {
/// Gas limit.
#[serde(rename="gasLimit")]
pub gas_limit: Uint,
+ /// Transactions root.
+ #[serde(rename="transactionsRoot")]
+ pub transactions_root: Option,
+ /// Receipts root.
+ #[serde(rename="receiptsRoot")]
+ pub receipts_root: Option,
+ /// State root.
+ #[serde(rename="stateRoot")]
+ pub state_root: Option,
+ /// Gas used.
+ #[serde(rename="gasUsed")]
+ pub gas_used: Option,
+ /// Extra data.
+ #[serde(rename="extraData")]
+ pub extra_data: Option,
}
#[cfg(test)]
diff --git a/json/src/uint.rs b/json/src/uint.rs
index 2d24c3f7e..f6eae80e4 100644
--- a/json/src/uint.rs
+++ b/json/src/uint.rs
@@ -31,6 +31,12 @@ impl Into for Uint {
}
}
+impl Into for Uint {
+ fn into(self) -> u64 {
+ u64::from(self.0)
+ }
+}
+
impl Deserialize for Uint {
fn deserialize(deserializer: &mut D) -> Result
where D: Deserializer {