diff --git a/Cargo.toml b/Cargo.toml index 7b1833e11..ee4b5b111 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] description = "Parity Ethereum client" name = "parity" +# NOTE Make sure to update util/version/Cargo.toml as well version = "1.8.10" license = "GPL-3.0" authors = ["Parity Technologies "] @@ -60,6 +61,7 @@ parity-reactor = { path = "util/reactor" } parity-rpc = { path = "rpc" } parity-rpc-client = { path = "rpc_client" } parity-updater = { path = "updater" } +parity-version = { path = "util/version" } parity-whisper = { path = "whisper" } path = { path = "util/path" } panic_hook = { path = "panic_hook" } diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index ae3216ba3..bd9f2bcb1 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -37,6 +37,7 @@ parity-hash-fetch = { path = "../hash-fetch" } parity-reactor = { path = "../util/reactor" } parity-ui = { path = "./ui" } hash = { path = "../util/hash" } +parity-version = { path = "../util/version" } clippy = { version = "0.0.103", optional = true} diff --git a/dapps/src/handlers/content.rs b/dapps/src/handlers/content.rs index 13d1fb0b9..711a985bd 100644 --- a/dapps/src/handlers/content.rs +++ b/dapps/src/handlers/content.rs @@ -19,7 +19,7 @@ use hyper::{self, mime, header}; use hyper::StatusCode; -use util::version; +use parity_version::version; use handlers::add_security_headers; use Embeddable; diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 36b5bec4c..7f42e0b8c 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -44,6 +44,7 @@ extern crate parity_dapps_glue as parity_dapps; extern crate parity_hash_fetch as hash_fetch; extern crate parity_ui; extern crate hash; +extern crate parity_version; #[macro_use] extern crate futures; diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 408f2ae13..0ae134126 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -74,7 +74,6 @@ vm = { path = "vm" } wasm = { path = "wasm" } hash = { path = "../util/hash" } triehash = { path = "../util/triehash" } -semantic_version = { path = "../util/semantic_version" } unexpected = { path = "../util/unexpected" } [dev-dependencies] diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index c7d2a01e1..64c1420a1 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -90,7 +90,14 @@ impl Pending { match self.requests[idx].respond_local(cache) { Some(response) => { self.requests.supply_response_unchecked(&response); + + // update header and back-references after each from-cache + // response to ensure that the requests are left in a consistent + // state and increase the likelihood of being able to answer + // the next request from cache. self.update_header_refs(idx, &response); + self.fill_unanswered(); + self.responses.push(response); } None => break, diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 6d7ab52cb..78bce3dd2 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -257,9 +257,9 @@ impl AccountProvider { Ok(Address::from(account.address).into()) } - /// Import a new presale wallet. - pub fn import_wallet(&self, json: &[u8], password: &str) -> Result { - let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password)?; + /// Import a new wallet. + pub fn import_wallet(&self, json: &[u8], password: &str, gen_id: bool) -> Result { + let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?; if self.blacklisted_accounts.contains(&account.address) { self.sstore.remove_account(&account, password)?; return Err(SSError::InvalidAccount.into()); diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 5f9bc9863..dc677c23e 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -41,7 +41,6 @@ use itertools::{self, Itertools}; use rlp::{UntrustedRlp, encode}; use bigint::prelude::{U256, U128}; use bigint::hash::{H256, H520}; -use semantic_version::SemanticVersion; use parking_lot::{Mutex, RwLock}; use unexpected::{Mismatch, OutOfBounds}; use util::Address; @@ -483,8 +482,6 @@ impl IoHandler<()> for TransitionHandler { impl Engine for AuthorityRound { fn name(&self) -> &str { "AuthorityRound" } - fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) } - fn machine(&self) -> &EthereumMachine { &self.machine } /// Two fields - consensus step and the corresponding proposer signature. @@ -919,7 +916,6 @@ mod tests { fn has_valid_metadata() { let engine = Spec::new_test_round().engine; assert!(!engine.name().is_empty()); - assert!(engine.version().major >= 1); } #[test] diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 8aedbff72..d8ef0ed65 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -29,7 +29,6 @@ use ethjson; use header::Header; use client::EngineClient; use machine::{AuxiliaryData, Call, EthereumMachine}; -use semantic_version::SemanticVersion; use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; @@ -95,7 +94,6 @@ impl BasicAuthority { impl Engine for BasicAuthority { fn name(&self) -> &str { "BasicAuthority" } - fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) } fn machine(&self) -> &EthereumMachine { &self.machine } @@ -218,7 +216,6 @@ mod tests { fn has_valid_metadata() { let engine = new_test_authority().engine; assert!(!engine.name().is_empty()); - assert!(engine.version().major >= 1); } #[test] diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 9c7538207..dd813d11c 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -54,7 +54,6 @@ use ethkey::Signature; use parity_machine::{Machine, LocalizedMachine as Localized}; use bigint::prelude::U256; use bigint::hash::H256; -use semantic_version::SemanticVersion; use util::*; use unexpected::{Mismatch, OutOfBounds}; use bytes::Bytes; @@ -178,8 +177,6 @@ pub enum EpochChange { pub trait Engine: Sync + Send { /// The name of this engine. fn name(&self) -> &str; - /// The version of this engine. Should be of the form - fn version(&self) -> SemanticVersion { SemanticVersion::new(0, 0, 0) } /// Get access to the underlying state machine. // TODO: decouple. diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index fcd5437b7..b8bdee43a 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -50,7 +50,6 @@ use super::transition::TransitionHandler; use super::vote_collector::VoteCollector; use self::message::*; use self::params::TendermintParams; -use semantic_version::SemanticVersion; use machine::{AuxiliaryData, EthereumMachine}; #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] @@ -443,8 +442,6 @@ impl Tendermint { impl Engine for Tendermint { fn name(&self) -> &str { "Tendermint" } - fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) } - /// (consensus view, proposal signature, authority signatures) fn seal_fields(&self) -> usize { 3 } @@ -857,7 +854,6 @@ mod tests { fn has_valid_metadata() { let engine = Spec::new_test_tendermint().engine; assert!(!engine.name().is_empty()); - assert!(engine.version().major >= 1); } #[test] diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index b7aae5588..1a5ffb3b9 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -31,7 +31,6 @@ use engines::{self, Engine}; use ethjson; use rlp::{self, UntrustedRlp}; use machine::EthereumMachine; -use semantic_version::SemanticVersion; /// Number of blocks in an ethash snapshot. // make dependent on difficulty incrment divisor? @@ -169,7 +168,6 @@ impl engines::EpochVerifier for Arc { impl Engine for Arc { fn name(&self) -> &str { "Ethash" } - fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) } fn machine(&self) -> &EthereumMachine { &self.machine } // Two fields - nonce and mix. @@ -577,7 +575,6 @@ mod tests { fn has_valid_metadata() { let engine = test_spec().engine; assert!(!engine.name().is_empty()); - assert!(engine.version().major >= 1); } #[test] diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 09b272cb3..82931136a 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -30,15 +30,6 @@ pub use self::denominations::*; use machine::EthereumMachine; use super::spec::*; -/// Most recent fork block that we support on Mainnet. -pub const FORK_SUPPORTED_FOUNDATION: u64 = 4370000; - -/// Most recent fork block that we support on Ropsten. -pub const FORK_SUPPORTED_ROPSTEN: u64 = 10; - -/// Most recent fork block that we support on Kovan. -pub const FORK_SUPPORTED_KOVAN: u64 = 0; - fn load<'a, T: Into>>>(params: T, b: &[u8]) -> Spec { match params.into() { Some(params) => Spec::load(params, b), diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index c480beabe..7f2f77460 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -110,7 +110,6 @@ extern crate memorydb; extern crate patricia_trie as trie; extern crate triehash; extern crate ansi_term; -extern crate semantic_version; extern crate unexpected; extern crate kvdb; extern crate kvdb_rocksdb; diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 2d9a37e81..f4b6f0b4b 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -35,6 +35,15 @@ use std::cell::{RefCell, Cell}; const STORAGE_CACHE_ITEMS: usize = 8192; +/// Boolean type for clean/dirty status. +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub enum Filth { + /// Data has not been changed. + Clean, + /// Data has been changed. + Dirty, +} + /// Single account in the system. /// Keeps track of changes to the code and storage. /// The changes are applied in `commit_storage` and `commit_code` diff --git a/ethstore/src/dir/disk.rs b/ethstore/src/dir/disk.rs index ebd67de2e..79776a3d3 100755 --- a/ethstore/src/dir/disk.rs +++ b/ethstore/src/dir/disk.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::{fs, io}; +use std::io::Write; use std::path::{PathBuf, Path}; use std::collections::HashMap; use time; @@ -152,31 +153,39 @@ impl DiskDirectory where T: KeyFileManager { ) } - /// insert account with given file name - pub fn insert_with_filename(&self, account: SafeAccount, filename: String) -> Result { + + /// insert account with given filename. if the filename is a duplicate of any stored account and dedup is set to + /// true, a random suffix is appended to the filename. + pub fn insert_with_filename(&self, account: SafeAccount, mut filename: String, dedup: bool) -> Result { + // path to keyfile + let mut keyfile_path = self.path.join(filename.as_str()); + + // check for duplicate filename and append random suffix + if dedup && keyfile_path.exists() { + let suffix = ::random::random_string(4); + filename.push_str(&format!("-{}", suffix)); + keyfile_path.set_file_name(&filename); + } + // update account filename let original_account = account.clone(); let mut account = account; - account.filename = Some(filename.clone()); + account.filename = Some(filename); { - // Path to keyfile - let mut keyfile_path = self.path.clone(); - keyfile_path.push(filename.as_str()); - // save the file let mut file = fs::File::create(&keyfile_path)?; - if let Err(err) = self.key_manager.write(original_account, &mut file).map_err(|e| Error::Custom(format!("{:?}", e))) { - drop(file); - fs::remove_file(keyfile_path).expect("Expected to remove recently created file"); - return Err(err); - } + + // write key content + self.key_manager.write(original_account, &mut file).map_err(|e| Error::Custom(format!("{:?}", e)))?; + + file.flush()?; if let Err(_) = restrict_permissions_to_owner(keyfile_path.as_path()) { - drop(file); - fs::remove_file(keyfile_path).expect("Expected to remove recently created file"); return Err(Error::Io(io::Error::last_os_error())); } + + file.sync_all()?; } Ok(account) @@ -199,17 +208,13 @@ impl KeyDirectory for DiskDirectory where T: KeyFileManager { fn update(&self, account: SafeAccount) -> Result { // Disk store handles updates correctly iff filename is the same - self.insert(account) + let filename = account_filename(&account); + self.insert_with_filename(account, filename, false) } fn insert(&self, account: SafeAccount) -> Result { - // build file path - let filename = account.filename.as_ref().cloned().unwrap_or_else(|| { - let timestamp = time::strftime("%Y-%m-%dT%H-%M-%S", &time::now_utc()).expect("Time-format string is valid."); - format!("UTC--{}Z--{}", timestamp, Uuid::from(account.id)) - }); - - self.insert_with_filename(account, filename) + let filename = account_filename(&account); + self.insert_with_filename(account, filename, true) } fn remove(&self, account: &SafeAccount) -> Result<(), Error> { @@ -285,6 +290,14 @@ impl KeyFileManager for DiskKeyFileManager { } } +fn account_filename(account: &SafeAccount) -> String { + // build file path + account.filename.clone().unwrap_or_else(|| { + let timestamp = time::strftime("%Y-%m-%dT%H-%M-%S", &time::now_utc()).expect("Time-format string is valid."); + format!("UTC--{}Z--{}", timestamp, Uuid::from(account.id)) + }) +} + #[cfg(test)] mod test { extern crate tempdir; @@ -317,6 +330,38 @@ mod test { let _ = fs::remove_dir_all(dir); } + #[test] + fn should_handle_duplicate_filenames() { + // given + let mut dir = env::temp_dir(); + dir.push("ethstore_should_handle_duplicate_filenames"); + let keypair = Random.generate().unwrap(); + let password = "hello world"; + let directory = RootDiskDirectory::create(dir.clone()).unwrap(); + + // when + let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()); + let filename = "test".to_string(); + let dedup = true; + + directory.insert_with_filename(account.clone(), "foo".to_string(), dedup).unwrap(); + let file1 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap(); + let file2 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap(); + let file3 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap(); + + // then + // the first file should have the original names + assert_eq!(file1, filename); + + // the following duplicate files should have a suffix appended + assert!(file2 != file3); + assert_eq!(file2.len(), filename.len() + 5); + assert_eq!(file3.len(), filename.len() + 5); + + // cleanup + let _ = fs::remove_dir_all(dir); + } + #[test] fn should_manage_vaults() { // given diff --git a/ethstore/src/dir/vault.rs b/ethstore/src/dir/vault.rs index a7b351643..a605d6336 100755 --- a/ethstore/src/dir/vault.rs +++ b/ethstore/src/dir/vault.rs @@ -106,7 +106,7 @@ impl VaultDiskDirectory { fn copy_to_vault(&self, vault: &VaultDiskDirectory) -> Result<(), Error> { for account in self.load()? { let filename = account.filename.clone().expect("self is instance of DiskDirectory; DiskDirectory fills filename in load; qed"); - vault.insert_with_filename(account, filename)?; + vault.insert_with_filename(account, filename, true)?; } Ok(()) diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index fea5bada7..25f03cb6f 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -158,9 +158,14 @@ impl SecretStore for EthStore { self.insert_account(vault, keypair.secret().clone(), password) } - fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result { + fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result { let json_keyfile = json::KeyFile::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?; let mut safe_account = SafeAccount::from_file(json_keyfile, None); + + if gen_id { + safe_account.id = Random::random(); + } + let secret = safe_account.crypto.secret(password).map_err(|_| Error::InvalidPassword)?; safe_account.address = KeyPair::from_secret(secret)?.address(); self.store.import(vault, safe_account) diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs index c71db3fe2..104e28edf 100755 --- a/ethstore/src/secret_store.rs +++ b/ethstore/src/secret_store.rs @@ -116,7 +116,7 @@ pub trait SecretStore: SimpleSecretStore { /// Imports presale wallet fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result; /// Imports existing JSON wallet - fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result; + fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result; /// Copies account between stores and vaults. fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &str, new_password: &str) -> Result<(), Error>; /// Checks if password matches given account. diff --git a/ipc-common-types/Cargo.toml b/ipc-common-types/Cargo.toml index a9efe1439..2a732071a 100644 --- a/ipc-common-types/Cargo.toml +++ b/ipc-common-types/Cargo.toml @@ -14,3 +14,4 @@ semver = "0.6" ethcore-ipc = { path = "../ipc/rpc" } ethcore-util = { path = "../util" } ethcore-bigint = { path = "../util/bigint" } +parity-version = { path = "../util/version" } diff --git a/ipc-common-types/src/lib.rs b/ipc-common-types/src/lib.rs index c1d18a8d7..6b5bd65cc 100644 --- a/ipc-common-types/src/lib.rs +++ b/ipc-common-types/src/lib.rs @@ -20,6 +20,7 @@ extern crate semver; extern crate ethcore_util as util; extern crate ethcore_bigint as bigint; extern crate ethcore_ipc as ipc; +extern crate parity_version as version; mod types; diff --git a/ipc-common-types/src/types/version_info.rs b/ipc-common-types/src/types/version_info.rs index ef386824d..3eccb1057 100644 --- a/ipc-common-types/src/types/version_info.rs +++ b/ipc-common-types/src/types/version_info.rs @@ -20,7 +20,7 @@ use std::fmt; use std::str::FromStr; use semver::{Version}; use bigint::hash::H160; -use util::misc::raw_package_info; +use version::raw_package_info; use release_track::ReleaseTrack; /// Version information of a particular release. diff --git a/parity/cli/usage.rs b/parity/cli/usage.rs index 0a2443303..344b9e118 100644 --- a/parity/cli/usage.rs +++ b/parity/cli/usage.rs @@ -152,7 +152,7 @@ macro_rules! usage { use toml; use std::{fs, io, process, cmp}; use std::io::{Read, Write}; - use util::version; + use parity_version::version; use clap::{Arg, App, SubCommand, AppSettings, ArgSettings, Error as ClapError, ErrorKind as ClapErrorKind}; use helpers::replace_home; use std::ffi::OsStr; diff --git a/parity/configuration.rs b/parity/configuration.rs index 0ec19a105..766a7b429 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -25,7 +25,8 @@ use cli::{Args, ArgsError}; use hash::keccak; use bigint::prelude::U256; use bigint::hash::H256; -use util::{version_data, Address}; +use util::Address; +use parity_version::{version_data, version}; use bytes::Bytes; use ansi_term::Colour; use ethsync::{NetworkConfiguration, is_valid_node_url}; diff --git a/parity/main.rs b/parity/main.rs index 144af116a..cf5b6e92f 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -73,6 +73,7 @@ extern crate parity_local_store as local_store; extern crate parity_reactor; extern crate parity_rpc; extern crate parity_updater as updater; +extern crate parity_version; extern crate parity_whisper; extern crate path; extern crate rpc_cli; diff --git a/parity/params.rs b/parity/params.rs index f508b59f1..278589e96 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -17,8 +17,9 @@ use std::{str, fs, fmt}; use std::time::Duration; use bigint::prelude::U256; -use util::{Address, version_data}; +use util::Address; use util::journaldb::Algorithm; +use parity_version::version_data; use ethcore::spec::{Spec, SpecParams}; use ethcore::ethereum; use ethcore::client::Mode; diff --git a/parity/run.rs b/parity/run.rs index e226d0f14..2bf1aad9e 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -41,7 +41,7 @@ use parity_reactor::EventLoop; use parity_rpc::{NetworkSettings, informant, is_major_importing}; use updater::{UpdatePolicy, Updater}; use ansi_term::Colour; -use util::version; +use parity_version::version; use parking_lot::{Condvar, Mutex}; use node_filter::NodeFilter; use util::journaldb::Algorithm; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 9f0e544ee..1dca54c1c 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -54,6 +54,7 @@ fetch = { path = "../util/fetch" } node-health = { path = "../dapps/node-health" } parity-reactor = { path = "../util/reactor" } parity-updater = { path = "../updater" } +parity-version = { path = "../util/version" } rlp = { path = "../util/rlp" } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index d5e4cebe8..42449885d 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -61,6 +61,7 @@ extern crate fetch; extern crate node_health; extern crate parity_reactor; extern crate parity_updater as updater; +extern crate parity_version as version; extern crate rlp; extern crate stats; extern crate hash; diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index b7b0b9a95..b280bce1e 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use std::collections::{BTreeMap, HashSet}; -use util::misc::version_data; +use version::version_data; use crypto::{ecies, DEFAULT_MAC}; use ethkey::{Brain, Generator}; diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index a08d60efd..2de5056b9 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -20,7 +20,7 @@ use std::str::FromStr; use std::collections::{BTreeMap, HashSet}; use util::Address; -use util::misc::version_data; +use version::version_data; use crypto::{DEFAULT_MAC, ecies}; use ethkey::{Brain, Generator}; diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index d41837186..4cefbf20f 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -95,7 +95,7 @@ impl ParityAccounts for ParityAccountsClient { let store = self.account_provider()?; store.import_presale(json.as_bytes(), &pass) - .or_else(|_| store.import_wallet(json.as_bytes(), &pass)) + .or_else(|_| store.import_wallet(json.as_bytes(), &pass, true)) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } diff --git a/rpc/src/v1/impls/web3.rs b/rpc/src/v1/impls/web3.rs index b636ba608..5f4612290 100644 --- a/rpc/src/v1/impls/web3.rs +++ b/rpc/src/v1/impls/web3.rs @@ -17,7 +17,7 @@ //! Web3 rpc implementation. use hash::keccak; use jsonrpc_core::Error; -use util::version; +use version::version; use v1::traits::Web3; use v1::types::{H256, Bytes}; diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 9153a17b3..e25f3e4d3 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -234,14 +234,14 @@ fn rpc_parity_chain_id() { #[test] fn rpc_parity_default_extra_data() { - use util::misc; + use version::version_data; use bytes::ToPretty; let deps = Dependencies::new(); let io = deps.default_client(); let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultExtraData", "params": [], "id": 1}"#; - let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, misc::version_data().to_hex()); + let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, version_data().to_hex()); assert_eq!(io.handle_request_sync(request), Some(response)); } diff --git a/rpc/src/v1/tests/mocked/parity_accounts.rs b/rpc/src/v1/tests/mocked/parity_accounts.rs index b3ea644fa..95da64495 100644 --- a/rpc/src/v1/tests/mocked/parity_accounts.rs +++ b/rpc/src/v1/tests/mocked/parity_accounts.rs @@ -480,7 +480,7 @@ fn should_export_account() { // given let tester = setup(); let wallet = r#"{"id":"6a186c80-7797-cff2-bc2e-7c1d6a6cc76e","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"a1c6ff99070f8032ca1c4e8add006373"},"ciphertext":"df27e3db64aa18d984b6439443f73660643c2d119a6f0fa2fa9a6456fc802d75","kdf":"pbkdf2","kdfparams":{"c":10240,"dklen":32,"prf":"hmac-sha256","salt":"ddc325335cda5567a1719313e73b4842511f3e4a837c9658eeb78e51ebe8c815"},"mac":"3dc888ae79cbb226ff9c455669f6cf2d79be72120f2298f6cb0d444fddc0aa3d"},"address":"0042e5d2a662eeaca8a7e828c174f98f35d8925b","name":"parity-export-test","meta":"{\"passwordHint\":\"parity-export-test\",\"timestamp\":1490017814987}"}"#; - tester.accounts.import_wallet(wallet.as_bytes(), "parity-export-test").unwrap(); + tester.accounts.import_wallet(wallet.as_bytes(), "parity-export-test", false).unwrap(); let accounts = tester.accounts.accounts().unwrap(); assert_eq!(accounts.len(), 1); @@ -501,6 +501,26 @@ fn should_export_account() { assert_eq!(result, Some(response.into())); } +#[test] +fn should_import_wallet() { + let tester = setup(); + + let id = "6a186c80-7797-cff2-bc2e-7c1d6a6cc76e"; + let request = r#"{"jsonrpc":"2.0","method":"parity_newAccountFromWallet","params":["{\"id\":\"\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"478736fb55872c1baf01b27b1998c90b\"},\"ciphertext\":\"fe5a63cc0055d7b0b3b57886f930ad9b63f48950d1348145d95996c41e05f4e0\",\"kdf\":\"pbkdf2\",\"kdfparams\":{\"c\":10240,\"dklen\":32,\"prf\":\"hmac-sha256\",\"salt\":\"658436d6738a19731149a98744e5cf02c8d5aa1f8e80c1a43cc9351c70a984e4\"},\"mac\":\"c7384b26ecf25539d942030230062af9b69de5766cbcc4690bffce1536644631\"},\"address\":\"00bac56a8a27232baa044c03f43bf3648c961735\",\"name\":\"hello world\",\"meta\":\"{}\"}", "himom"],"id":1}"#; + let request = request.replace("", id); + let response = r#"{"jsonrpc":"2.0","result":"0x00bac56a8a27232baa044c03f43bf3648c961735","id":1}"#; + + let res = tester.io.handle_request_sync(&request).unwrap(); + + assert_eq!(res, response); + + let account_meta = tester.accounts.account_meta("0x00bac56a8a27232baa044c03f43bf3648c961735".into()).unwrap(); + let account_uuid: String = account_meta.uuid.unwrap().into(); + + // the RPC should import the account with a new id + assert!(account_uuid != id); +} + #[test] fn should_sign_message() { let tester = setup(); diff --git a/rpc/src/v1/tests/mocked/web3.rs b/rpc/src/v1/tests/mocked/web3.rs index 46a83bb3d..aceb36e56 100644 --- a/rpc/src/v1/tests/mocked/web3.rs +++ b/rpc/src/v1/tests/mocked/web3.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use jsonrpc_core::IoHandler; -use util::version; +use version::version; use v1::{Web3, Web3Client}; #[test] diff --git a/updater/Cargo.toml b/updater/Cargo.toml index 0d4b29025..564e50681 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -24,4 +24,5 @@ parity-hash-fetch = { path = "../hash-fetch" } ipc-common-types = { path = "../ipc-common-types" } ethcore-ipc = { path = "../ipc/rpc" } parity-reactor = { path = "../util/reactor" } +parity-version = { path = "../util/version" } path = { path = "../util/path" } diff --git a/updater/src/lib.rs b/updater/src/lib.rs index 9ba948d9f..18c5ed943 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -30,6 +30,7 @@ extern crate ethcore_ipc as ipc; extern crate futures; extern crate target_info; extern crate parity_reactor; +extern crate parity_version as version; extern crate path; mod updater; diff --git a/updater/src/types/version_info.rs b/updater/src/types/version_info.rs new file mode 100644 index 000000000..ea9b44577 --- /dev/null +++ b/updater/src/types/version_info.rs @@ -0,0 +1,68 @@ +// Copyright 2015-2017 Parity Technologies (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 . + +//! Types used in the public API + +use std::fmt; +use semver::{Version}; +use bigint::hash::H160; +use version::raw_package_info; +use types::ReleaseTrack; + +/// Version information of a particular release. +#[derive(Debug, Clone, PartialEq)] +pub struct VersionInfo { + /// The track on which it was released. + pub track: ReleaseTrack, + /// The version. + pub version: Version, + /// The (SHA1?) 160-bit hash of this build's code base. + pub hash: H160, +} + +impl fmt::Display for VersionInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}.{}.{}-{}-{}", self.version.major, self.version.minor, self.version.patch, self.track, self.hash) + } +} + +impl VersionInfo { + /// Get information for this (currently running) binary. + pub fn this() -> Self { + let raw = raw_package_info(); + VersionInfo { + track: raw.0.into(), + version: { let mut v = Version::parse(raw.1).expect("Environment variables are known to be valid; qed"); v.build = vec![]; v.pre = vec![]; v }, + hash: raw.2.parse::().unwrap_or_else(|_| H160::zero()), + } + } + + /// Compose the information from the provided raw fields. + pub fn from_raw(semver: u32, track: u8, hash: H160) -> Self { + let t = track.into(); + VersionInfo { + version: Version { + major: (semver >> 16) as u64, + minor: ((semver >> 8) & 0xff) as u64, + patch: (semver & 0xff) as u64, + build: vec![], + pre: vec![], + }, + track: t, + hash: hash, + } + } +} diff --git a/updater/src/updater.rs b/updater/src/updater.rs index efa34adab..252d060fb 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -35,7 +35,7 @@ use bigint::hash::{H160, H256}; use util::Address; use bytes::Bytes; use parking_lot::Mutex; -use util::misc; +use version; /// Filter for releases. #[derive(Debug, Eq, PartialEq, Clone)] @@ -116,7 +116,7 @@ fn platform() -> String { } else if cfg!(target_os = "linux") { format!("{}-unknown-linux-gnu", Target::arch()) } else { - misc::platform() + version::platform() } } diff --git a/util/Cargo.toml b/util/Cargo.toml index 9fa5a3671..c4d82f00a 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -5,7 +5,6 @@ license = "GPL-3.0" name = "ethcore-util" version = "1.8.10" authors = ["Parity Technologies "] -build = "build.rs" [dependencies] log = "0.3" diff --git a/util/build.rs b/util/build.rs deleted file mode 100644 index 08ef81697..000000000 --- a/util/build.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (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 vergen; -extern crate rustc_version; - -use vergen::*; -use std::env; -use std::fs::File; -use std::io::Write; -use std::path::Path; - -fn main() { - vergen(OutputFns::all()).unwrap(); - let out_dir = env::var("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("rustc_version.rs"); - let mut f = File::create(&dest_path).unwrap(); - f.write_all(format!(" - /// Returns compiler version. - pub fn rustc_version() -> &'static str {{ - \"{}\" - }} - ", rustc_version::version()).as_bytes()).unwrap(); -} diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index 606f7ac43..ead89f51b 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -36,6 +36,7 @@ hash = { path = "../hash" } serde = "1.0" serde_json = "1.0" serde_derive = "1.0" +parity-version = { path = "../version" } [features] default = [] diff --git a/util/network/src/host.rs b/util/network/src/host.rs index 5074be126..663b78029 100644 --- a/util/network/src/host.rs +++ b/util/network/src/host.rs @@ -30,7 +30,7 @@ use mio::*; use mio::deprecated::{EventLoop}; use mio::tcp::*; use bigint::hash::*; -use util::version; +use version::version; use rlp::*; use session::{Session, SessionInfo, SessionData}; use error::*; diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index f6c5d3456..39b3a4eb9 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -82,6 +82,7 @@ extern crate ipnetwork; extern crate hash; extern crate serde; extern crate serde_json; +extern crate parity_version as version; #[macro_use] extern crate log; diff --git a/util/semantic_version/Cargo.toml b/util/semantic_version/Cargo.toml deleted file mode 100644 index 5cd888d0a..000000000 --- a/util/semantic_version/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "semantic_version" -version = "0.1.0" -authors = ["Parity Technologies "] - -[dependencies] diff --git a/util/semantic_version/src/lib.rs b/util/semantic_version/src/lib.rs deleted file mode 100644 index 0a8eeb499..000000000 --- a/util/semantic_version/src/lib.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (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 . - -//! Semantic version formatting and comparing. - -/// A version value with strict meaning. Use `as_u32` to convert to a simple integer. -/// -/// # Example -/// ``` -/// extern crate semantic_version; -/// use semantic_version::*; -/// -/// fn main() { -/// assert_eq!(SemanticVersion::new(1, 2, 3).as_u32(), 0x010203); -/// } -/// ``` -pub struct SemanticVersion { - /// Major version - API/feature removals & breaking changes. - pub major: u8, - /// Minor version - API/feature additions. - pub minor: u8, - /// Tiny version - bug fixes. - pub tiny: u8, -} - -impl SemanticVersion { - /// Create a new object. - pub fn new(major: u8, minor: u8, tiny: u8) -> SemanticVersion { SemanticVersion{major: major, minor: minor, tiny: tiny} } - - /// Convert to a `u32` representation. - pub fn as_u32(&self) -> u32 { ((self.major as u32) << 16) + ((self.minor as u32) << 8) + self.tiny as u32 } -} - -// TODO: implement Eq, Comparison and Debug/Display for SemanticVersion. diff --git a/util/src/lib.rs b/util/src/lib.rs index 4c50013a5..522b31995 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -87,6 +87,7 @@ //! cargo build --release //! ``` +extern crate util_error as error; extern crate rustc_hex; extern crate rocksdb; extern crate env_logger; @@ -106,9 +107,7 @@ extern crate ethcore_logger; extern crate hash as keccak; extern crate hashdb; extern crate memorydb; -extern crate patricia_trie as trie; extern crate kvdb; -extern crate util_error as error; #[cfg(test)] extern crate kvdb_memorydb; @@ -116,12 +115,10 @@ extern crate kvdb_memorydb; #[macro_use] extern crate log as rlog; -pub mod misc; pub mod overlaydb; pub mod journaldb; pub mod cache; -pub use misc::*; pub use hashdb::*; pub use memorydb::MemoryDB; pub use overlaydb::*; diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 078bd6964..e1fa1546e 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -28,7 +28,7 @@ target_info = "0.1" [build-dependencies] vergen = "0.1" -rustc_version = "0.2.0" +rustc_version = "0.1.0" toml = "0.4" [features] diff --git a/util/version/build.rs b/util/version/build.rs new file mode 100644 index 000000000..c54baa440 --- /dev/null +++ b/util/version/build.rs @@ -0,0 +1,57 @@ +// Copyright 2015-2017 Parity Technologies (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_version; +extern crate toml; +extern crate vergen; + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::Path; +use vergen::{vergen, OutputFns}; + +const ERROR_MSG: &'static str = "Failed to generate metadata files"; + +fn main() { + vergen(OutputFns::all()).expect(ERROR_MSG); + + let version = rustc_version::version(); + + let cargo: toml::Value = toml::from_str(include_str!("./Cargo.toml")).expect(ERROR_MSG); + let track = cargo["package"]["metadata"]["track"].as_str().expect("'track' has to be a string!"); + + create_file("meta.rs", format!(" + /// This versions track. + #[allow(unused)] + pub const TRACK: &str = {track:?}; + + /// Returns compiler version. + pub fn rustc_version() -> &'static str {{ + \"{version}\" + }} + ", + track = track, + version = version, + )); +} + +fn create_file(filename: &str, data: String) { + let out_dir = env::var("OUT_DIR").expect(ERROR_MSG); + let dest_path = Path::new(&out_dir).join(filename); + let mut f = File::create(&dest_path).expect(ERROR_MSG); + f.write_all(data.as_bytes()).expect(ERROR_MSG); +} diff --git a/util/src/misc.rs b/util/version/src/lib.rs similarity index 77% rename from util/src/misc.rs rename to util/version/src/lib.rs index e33580ca0..6c56bfb7e 100644 --- a/util/src/misc.rs +++ b/util/version/src/lib.rs @@ -14,32 +14,33 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Diff misc. +//! Parity version specific information. + +extern crate target_info; +extern crate ethcore_bytes as bytes; +extern crate rlp; -use rlp::RlpStream; use target_info::Target; use bytes::Bytes; +use rlp::RlpStream; -include!(concat!(env!("OUT_DIR"), "/version.rs")); -include!(concat!(env!("OUT_DIR"), "/rustc_version.rs")); +mod vergen { + #![allow(unused)] + include!(concat!(env!("OUT_DIR"), "/version.rs")); +} + +mod generated { + include!(concat!(env!("OUT_DIR"), "/meta.rs")); +} #[cfg(feature = "final")] -const THIS_TRACK: &'static str = "stable"; -// ^^^ should be reset to "stable" or "beta" according to the release branch. +const THIS_TRACK: &'static str = generated::TRACK; +// ^^^ should be reset in Cargo.toml to "stable" or "beta" according to the release branch. #[cfg(not(feature = "final"))] const THIS_TRACK: &'static str = "unstable"; // ^^^ This gets used when we're not building a final release; should stay as "unstable". -/// Boolean type for clean/dirty status. -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub enum Filth { - /// Data has not been changed. - Clean, - /// Data has been changed. - Dirty, -} - /// Get the platform identifier. pub fn platform() -> String { let env = Target::env(); @@ -49,11 +50,11 @@ pub fn platform() -> String { /// Get the standard version string for this software. pub fn version() -> String { - let sha3 = short_sha(); + let sha3 = vergen::short_sha(); let sha3_dash = if sha3.is_empty() { "" } else { "-" }; - let commit_date = commit_date().replace("-", ""); + let commit_date = vergen::commit_date().replace("-", ""); let date_dash = if commit_date.is_empty() { "" } else { "-" }; - format!("Parity/v{}-{}{}{}{}{}/{}/rustc{}", env!("CARGO_PKG_VERSION"), THIS_TRACK, sha3_dash, sha3, date_dash, commit_date, platform(), rustc_version()) + format!("Parity/v{}-{}{}{}{}{}/{}/rustc{}", env!("CARGO_PKG_VERSION"), THIS_TRACK, sha3_dash, sha3, date_dash, commit_date, platform(), generated::rustc_version()) } /// Get the standard version data for this software. @@ -65,12 +66,12 @@ pub fn version_data() -> Bytes { env!("CARGO_PKG_VERSION_PATCH").parse::().expect("Environment variables are known to be valid; qed"); s.append(&v); s.append(&"Parity"); - s.append(&rustc_version()); + s.append(&generated::rustc_version()); s.append(&&Target::os()[0..2]); s.out() } /// Provide raw information on the package. pub fn raw_package_info() -> (&'static str, &'static str, &'static str) { - (THIS_TRACK, env!["CARGO_PKG_VERSION"], sha()) + (THIS_TRACK, env!["CARGO_PKG_VERSION"], vergen::sha()) }