2017-01-25 18:51:41 +01:00
|
|
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
2016-02-05 13:40:41 +01:00
|
|
|
// 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/>.
|
|
|
|
|
2016-01-09 17:15:55 +01:00
|
|
|
//! Ethereum protocol module.
|
|
|
|
//!
|
|
|
|
//! Contains all Ethereum network specific stuff, such as denominations and
|
|
|
|
//! consensus specifications.
|
|
|
|
|
2016-02-03 13:20:32 +01:00
|
|
|
/// Export the ethash module.
|
2016-01-09 17:15:55 +01:00
|
|
|
pub mod ethash;
|
2016-02-03 13:20:32 +01:00
|
|
|
/// Export the denominations module.
|
2016-01-09 17:15:55 +01:00
|
|
|
pub mod denominations;
|
|
|
|
|
2016-02-13 13:15:46 +01:00
|
|
|
pub use self::ethash::{Ethash};
|
2016-01-09 17:15:55 +01:00
|
|
|
pub use self::denominations::*;
|
|
|
|
|
2017-07-10 12:57:40 +02:00
|
|
|
use std::path::Path;
|
2016-01-09 18:20:31 +01:00
|
|
|
use super::spec::*;
|
|
|
|
|
2016-12-12 16:47:57 +01:00
|
|
|
/// Most recent fork block that we support on Mainnet.
|
2017-03-03 13:33:49 +01:00
|
|
|
pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000;
|
2016-12-12 16:47:57 +01:00
|
|
|
|
|
|
|
/// Most recent fork block that we support on Ropsten.
|
|
|
|
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
|
|
|
|
|
2017-03-03 08:20:25 +01:00
|
|
|
/// Most recent fork block that we support on Kovan.
|
|
|
|
pub const FORK_SUPPORTED_KOVAN: u64 = 0;
|
|
|
|
|
2017-07-10 12:57:40 +02:00
|
|
|
fn load<'a, T: 'a + Into<Option<&'a Path>>>(cache_dir: T, b: &[u8]) -> Spec {
|
|
|
|
match cache_dir.into() {
|
|
|
|
Some(path) => Spec::load(path, b),
|
|
|
|
None => Spec::load(&::std::env::temp_dir(), b)
|
|
|
|
}.expect("chain spec is invalid")
|
2016-09-05 17:41:34 +02:00
|
|
|
}
|
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Olympic chain spec.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_olympic(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/olympic.json")) }
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Mainnet chain spec.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_foundation(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/foundation.json")) }
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Classic Mainnet chain spec without the DAO hardfork.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_classic(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/classic.json")) }
|
2016-07-16 13:02:56 +02:00
|
|
|
|
2017-03-02 20:24:27 +01:00
|
|
|
/// Create a new Expanse mainnet chain spec.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_expanse(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/expanse.json")) }
|
2016-09-28 14:21:59 +02:00
|
|
|
|
2017-03-02 20:24:27 +01:00
|
|
|
/// Create a new Kovan testnet chain spec.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_kovan(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/kovan.json")) }
|
|
|
|
|
|
|
|
/// Create a new Foundation Ropsten chain spec.
|
|
|
|
pub fn new_ropsten(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/ropsten.json")) }
|
|
|
|
|
|
|
|
/// Create a new Morden chain spec.
|
|
|
|
pub fn new_morden(cache_dir: &Path) -> Spec { load(cache_dir, include_bytes!("../../res/ethereum/morden.json")) }
|
|
|
|
|
|
|
|
// For tests
|
2017-03-02 20:24:27 +01:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_frontier_test() -> Spec { load(None, include_bytes!("../../res/ethereum/frontier_test.json")) }
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_homestead_test() -> Spec { load(None, include_bytes!("../../res/ethereum/homestead_test.json")) }
|
2016-01-16 21:08:04 +01:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Homestead-EIP150-era chain spec as though it never changed from Homestead/Frontier.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_eip150_test() -> Spec { load(None, include_bytes!("../../res/ethereum/eip150_test.json")) }
|
2016-10-15 14:39:15 +02:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Homestead-EIP161-era chain spec as though it never changed from Homestead/Frontier.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_eip161_test() -> Spec { load(None, include_bytes!("../../res/ethereum/eip161_test.json")) }
|
2016-11-03 22:22:25 +01:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Frontier/Homestead/DAO chain spec with transition points at #5 and #8.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_transition_test() -> Spec { load(None, include_bytes!("../../res/ethereum/transition_test.json")) }
|
2016-07-16 13:02:56 +02:00
|
|
|
|
2017-03-06 21:37:38 +01:00
|
|
|
/// Create a new Foundation Mainnet chain spec without genesis accounts.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_mainnet_like() -> Spec { load(None, include_bytes!("../../res/ethereum/frontier_like_test.json")) }
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2017-05-23 15:49:17 +02:00
|
|
|
/// Create a new Foundation Metropolis era spec.
|
2017-07-10 12:57:40 +02:00
|
|
|
pub fn new_metropolis_test() -> Spec { load(None, include_bytes!("../../res/ethereum/metropolis_test.json")) }
|
2016-01-09 18:20:31 +01:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2016-10-24 18:35:25 +02:00
|
|
|
use util::*;
|
2016-01-09 18:20:31 +01:00
|
|
|
use state::*;
|
|
|
|
use super::*;
|
2016-01-31 10:52:07 +01:00
|
|
|
use tests::helpers::*;
|
2016-10-24 18:35:25 +02:00
|
|
|
use views::BlockView;
|
2016-01-09 18:20:31 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn ensure_db_good() {
|
2017-07-10 12:57:40 +02:00
|
|
|
let spec = new_morden(&::std::env::temp_dir());
|
2016-04-09 19:20:35 +02:00
|
|
|
let engine = &spec.engine;
|
|
|
|
let genesis_header = spec.genesis_header();
|
2017-04-06 19:26:17 +02:00
|
|
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
2017-06-28 09:10:57 +02:00
|
|
|
let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(0), Default::default()).unwrap();
|
2017-02-26 13:10:50 +01:00
|
|
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()).unwrap(), 1u64.into());
|
|
|
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()).unwrap(), 1u64.into());
|
|
|
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000003".into()).unwrap(), 1u64.into());
|
|
|
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000004".into()).unwrap(), 1u64.into());
|
|
|
|
assert_eq!(s.balance(&"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c".into()).unwrap(), U256::from(1u64) << 200);
|
|
|
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000000".into()).unwrap(), 0u64.into());
|
2016-01-09 18:20:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn morden() {
|
2017-07-10 12:57:40 +02:00
|
|
|
let morden = new_morden(&::std::env::temp_dir());
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2016-08-08 11:18:48 +02:00
|
|
|
assert_eq!(morden.state_root(), "f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9".into());
|
2016-01-09 18:20:31 +01:00
|
|
|
let genesis = morden.genesis_block();
|
2016-08-08 11:18:48 +02:00
|
|
|
assert_eq!(BlockView::new(&genesis).header_view().sha3(), "0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303".into());
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2016-04-09 19:20:35 +02:00
|
|
|
let _ = morden.engine;
|
2016-01-09 18:20:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn frontier() {
|
2017-07-10 12:57:40 +02:00
|
|
|
let frontier = new_foundation(&::std::env::temp_dir());
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2016-08-08 11:18:48 +02:00
|
|
|
assert_eq!(frontier.state_root(), "d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544".into());
|
2016-01-09 18:20:31 +01:00
|
|
|
let genesis = frontier.genesis_block();
|
2016-08-08 11:18:48 +02:00
|
|
|
assert_eq!(BlockView::new(&genesis).header_view().sha3(), "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3".into());
|
2016-01-09 18:20:31 +01:00
|
|
|
|
2016-04-09 19:20:35 +02:00
|
|
|
let _ = frontier.engine;
|
2016-01-09 18:20:31 +01:00
|
|
|
}
|
2017-07-10 12:57:40 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn all_spec_files_valid() {
|
|
|
|
let tmp = ::std::env::temp_dir();
|
|
|
|
new_olympic(&tmp);
|
|
|
|
new_foundation(&tmp);
|
|
|
|
new_classic(&tmp);
|
|
|
|
new_expanse(&tmp);
|
|
|
|
new_kovan(&tmp);
|
|
|
|
new_ropsten(&tmp);
|
|
|
|
new_morden(&tmp);
|
|
|
|
new_frontier_test();
|
|
|
|
new_homestead_test();
|
|
|
|
new_eip150_test();
|
|
|
|
new_eip161_test();
|
|
|
|
new_transition_test();
|
|
|
|
new_mainnet_like();
|
|
|
|
new_metropolis_test();
|
|
|
|
}
|
2016-01-11 11:51:31 +01:00
|
|
|
}
|