diff --git a/ethcore/res/ethereum/frontier-dogmatic.json b/ethcore/res/ethereum/classic.json similarity index 99% rename from ethcore/res/ethereum/frontier-dogmatic.json rename to ethcore/res/ethereum/classic.json index a57ad8ed8..39e5f68c5 100644 --- a/ethcore/res/ethereum/frontier-dogmatic.json +++ b/ethcore/res/ethereum/classic.json @@ -1,5 +1,6 @@ { - "name": "Frontier/Homestead", + "name": "Ethereum Classic", + "forkName": "classic", "engine": { "Ethash": { "params": { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b7e78edb1..0bb387e74 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -149,9 +149,9 @@ const HISTORY: u64 = 1200; const CLIENT_DB_VER_STR: &'static str = "5.3"; /// Get the path for the databases given the root path and information on the databases. -pub fn get_db_path(path: &Path, pruning: journaldb::Algorithm, genesis_hash: H256) -> PathBuf { +pub fn get_db_path(path: &Path, pruning: journaldb::Algorithm, genesis_hash: H256, fork_name: Option<&String>) -> PathBuf { let mut dir = path.to_path_buf(); - dir.push(H64::from(genesis_hash).hex()); + dir.push(format!("{:?}{}", H64::from(genesis_hash), fork_name.map(|f| format!("-{}", f)).unwrap_or_default())); //TODO: sec/fat: pruned/full versioning // version here is a bit useless now, since it's controlled only be the pruning algo. dir.push(format!("v{}-sec-{}", CLIENT_DB_VER_STR, pruning)); @@ -174,7 +174,7 @@ impl Client { miner: Arc, message_channel: IoChannel, ) -> Result, ClientError> { - let path = get_db_path(path, config.pruning, spec.genesis_header().hash()); + let path = get_db_path(path, config.pruning, spec.genesis_header().hash(), spec.fork_name.as_ref()); let gb = spec.genesis_block(); let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path)); let tracedb = Arc::new(try!(TraceDB::new(config.tracing, &path, chain.clone()))); diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index fbddccbcf..f48a433d7 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -33,14 +33,10 @@ use super::spec::*; pub fn new_olympic() -> Spec { Spec::load(include_bytes!("../../res/ethereum/olympic.json")) } /// Create a new Frontier mainnet chain spec. -pub fn new_frontier() -> Spec { - Spec::load(include_bytes!("../../res/ethereum/frontier.json")) -} +pub fn new_frontier() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier.json")) } /// Create a new Frontier mainnet chain spec without the DAO hardfork. -pub fn new_frontier_dogmatic() -> Spec { - Spec::load(include_bytes!("../../res/ethereum/frontier-dogmatic.json")) -} +pub fn new_classic() -> Spec { Spec::load(include_bytes!("../../res/ethereum/classic.json")) } /// Create a new Frontier chain spec as though it never changes to Homestead. pub fn new_frontier_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_test.json")) } diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index 57b72cb2e..e0aae18bc 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -62,6 +62,9 @@ impl ClientService { panic_handler.forward_from(&io_service); info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name())); + if spec.fork_name.is_some() { + warn!("Your chain is an alternative fork. {}", Colour::Red.bold().paint("TRANSACTIONS MAY BE REPLAYED ON THE MAINNET!")); + } let client = try!(Client::new(config, spec, db_path, miner, io_service.channel())); panic_handler.forward_from(client.deref()); let client_io = Arc::new(ClientIoHandler { diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index e71d7d432..0e61b34c5 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -58,6 +58,8 @@ pub struct Spec { pub name: String, /// What engine are we using for this? pub engine: Box, + /// The fork identifier for this chain. Only needed to distinguish two chains sharing the same genesis. + pub fork_name: Option, /// Known nodes on the network in enode format. pub nodes: Vec, @@ -105,6 +107,7 @@ impl From for Spec { name: s.name.into(), params: params.clone(), engine: Spec::engine(s.engine, params, builtins), + fork_name: s.fork_name.map(Into::into), nodes: s.nodes.unwrap_or_else(Vec::new), parent_hash: g.parent_hash, transactions_root: g.transactions_root, @@ -118,7 +121,7 @@ impl From for Spec { seal_fields: seal.fields, seal_rlp: seal.rlp, state_root_memo: RwLock::new(g.state_root), - genesis_state: From::from(s.accounts) + genesis_state: From::from(s.accounts), } } } diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index a26477f72..da37ba7dd 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -26,6 +26,9 @@ use spec::{Params, Genesis, Engine, State}; pub struct Spec { /// Spec name. pub name: String, + /// Special fork name. + #[serde(rename="forkName")] + pub fork_name: Option, /// Engine. pub engine: Engine, /// Spec params. diff --git a/parity/configuration.rs b/parity/configuration.rs index ba0ae8bfb..ce9b7d679 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -201,7 +201,7 @@ impl Configuration { pub fn spec(&self) -> Spec { match self.chain().as_str() { "frontier" | "homestead" | "mainnet" => ethereum::new_frontier(), - "homestead-dogmatic" => ethereum::new_frontier_dogmatic(), + "frontier-dogmatic" | "homestead-dogmatic" | "classic" => ethereum::new_classic(), "morden" | "testnet" => ethereum::new_morden(), "olympic" => ethereum::new_olympic(), f => Spec::load(contents(f).unwrap_or_else(|_| { @@ -288,7 +288,7 @@ impl Configuration { let mut latest_era = None; let jdb_types = [journaldb::Algorithm::Archive, journaldb::Algorithm::EarlyMerge, journaldb::Algorithm::OverlayRecent, journaldb::Algorithm::RefCounted]; for i in jdb_types.into_iter() { - let db = journaldb::new(&append_path(&get_db_path(Path::new(&self.path()), *i, spec.genesis_header().hash()), "state"), *i, kvdb::DatabaseConfig::default()); + let db = journaldb::new(&append_path(&get_db_path(Path::new(&self.path()), *i, spec.genesis_header().hash(), spec.fork_name.as_ref()), "state"), *i, kvdb::DatabaseConfig::default()); trace!(target: "parity", "Looking for best DB: {} at {:?}", i, db.latest_era()); match (latest_era, db.latest_era()) { (Some(best), Some(this)) if best >= this => {} diff --git a/parity/main.rs b/parity/main.rs index b61a35247..8406c3768 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -188,7 +188,7 @@ fn execute_upgrades(conf: &Configuration, spec: &Spec, client_config: &ClientCon _ => {}, } - let db_path = get_db_path(Path::new(&conf.path()), client_config.pruning, spec.genesis_header().hash()); + let db_path = get_db_path(Path::new(&conf.path()), client_config.pruning, spec.genesis_header().hash(), spec.fork_name.as_ref()); let result = migrate(&db_path, client_config.pruning); if let Err(err) = result { die_with_message(&format!("{} DB path: {}", err, db_path.to_string_lossy()));