moved ethcores spec to its own module, added genesis

This commit is contained in:
debris 2016-03-17 15:15:10 +01:00
parent 0f889d4222
commit 1f03ae54d6
10 changed files with 174 additions and 4 deletions

1
Cargo.lock generated
View File

@ -216,6 +216,7 @@ dependencies = [
"ethash 1.1.0", "ethash 1.1.0",
"ethcore-devtools 1.1.0", "ethcore-devtools 1.1.0",
"ethcore-util 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)", "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)", "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)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -21,6 +21,7 @@ clippy = { version = "0.0.50", optional = true }
crossbeam = "0.1.5" crossbeam = "0.1.5"
lazy_static = "0.1" lazy_static = "0.1"
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
ethjson = { path = "../json" }
[features] [features]
jit = ["evmjit"] jit = ["evmjit"]

View File

@ -83,6 +83,7 @@ extern crate time;
extern crate env_logger; extern crate env_logger;
extern crate num_cpus; extern crate num_cpus;
extern crate crossbeam; extern crate crossbeam;
extern crate ethjson;
#[cfg(test)] extern crate ethcore_devtools as devtools; #[cfg(test)] extern crate ethcore_devtools as devtools;
#[cfg(feature = "jit" )] extern crate evmjit; #[cfg(feature = "jit" )] extern crate evmjit;

View File

@ -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 <http://www.gnu.org/licenses/>.
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<u8>,
},
}
/// 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<H256>,
/// Gas used.
pub gas_used: U256,
/// Extra data.
pub extra_data: Vec<u8>,
}
impl From<ethjson::spec::Genesis> 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),
}
}
}

22
ethcore/src/spec/mod.rs Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
//! Blockchain params.
mod genesis;
pub mod spec;
pub use self::spec::*;

View File

@ -21,6 +21,8 @@ use engine::*;
use pod_state::*; use pod_state::*;
use null_engine::*; use null_engine::*;
use account_db::*; use account_db::*;
use ethereum;
use super::genesis::{Seal as GenesisSeal, Genesis};
/// Convert JSON value to equivalent RLP representation. /// Convert JSON value to equivalent RLP representation.
// TODO: handle container types. // TODO: handle container types.
@ -106,7 +108,7 @@ impl Spec {
pub fn to_engine(self) -> Result<Box<Engine>, Error> { pub fn to_engine(self) -> Result<Box<Engine>, Error> {
match self.engine_name.as_ref() { match self.engine_name.as_ref() {
"NullEngine" => Ok(NullEngine::new_boxed(self)), "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())) _ => 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"])))); 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. /// Alter the value of the genesis state.
pub fn set_genesis_state(&mut self, s: PodState) { pub fn set_genesis_state(&mut self, s: PodState) {
self.genesis_state = s; 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. /// 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)] #[cfg(test)]

View File

@ -59,6 +59,11 @@ impl BlockChain {
timestamp: self.genesis_block.timestamp, timestamp: self.genesis_block.timestamp,
parent_hash: self.genesis_block.parent_hash.clone(), parent_hash: self.genesis_block.parent_hash.clone(),
gas_limit: self.genesis_block.gas_limit, 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()),
} }
} }
} }

View File

@ -53,7 +53,7 @@ pub struct Header {
pub parent_hash: H256, pub parent_hash: H256,
/// Receipt root. /// Receipt root.
#[serde(rename="receiptTrie")] #[serde(rename="receiptTrie")]
pub receipt_root: H256, pub receipts_root: H256,
/// State root. /// State root.
#[serde(rename="stateRoot")] #[serde(rename="stateRoot")]
pub state_root: H256, pub state_root: H256,

View File

@ -33,7 +33,7 @@ pub struct Genesis {
// new seal // TODO: consider moving it to a separate seal structure // new seal // TODO: consider moving it to a separate seal structure
#[serde(rename="sealFields")] #[serde(rename="sealFields")]
/// Number of seal fields. /// Number of seal fields.
pub seal_fields: Option<Uint>, pub seal_fields: Option<usize>,
#[serde(rename="sealRlp")] #[serde(rename="sealRlp")]
/// Seal rlp. /// Seal rlp.
pub seal_rlp: Option<Bytes>, pub seal_rlp: Option<Bytes>,
@ -50,6 +50,21 @@ pub struct Genesis {
/// Gas limit. /// Gas limit.
#[serde(rename="gasLimit")] #[serde(rename="gasLimit")]
pub gas_limit: Uint, pub gas_limit: Uint,
/// Transactions root.
#[serde(rename="transactionsRoot")]
pub transactions_root: Option<H256>,
/// Receipts root.
#[serde(rename="receiptsRoot")]
pub receipts_root: Option<H256>,
/// State root.
#[serde(rename="stateRoot")]
pub state_root: Option<H256>,
/// Gas used.
#[serde(rename="gasUsed")]
pub gas_used: Option<Uint>,
/// Extra data.
#[serde(rename="extraData")]
pub extra_data: Option<Bytes>,
} }
#[cfg(test)] #[cfg(test)]

View File

@ -31,6 +31,12 @@ impl Into<U256> for Uint {
} }
} }
impl Into<u64> for Uint {
fn into(self) -> u64 {
u64::from(self.0)
}
}
impl Deserialize for Uint { impl Deserialize for Uint {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer { where D: Deserializer {