diff --git a/Cargo.lock b/Cargo.lock index 80c31ce3378..83d6d0a9409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -537,6 +537,7 @@ dependencies = [ "ethkey 0.3.0", "ethstore 0.2.0", "evm 0.1.0", + "fake-hardware-wallet 0.0.1", "fetch 0.1.0", "hardware-wallet 1.12.0", "hashdb 0.1.1", @@ -1064,6 +1065,14 @@ dependencies = [ "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fake-hardware-wallet" +version = "0.0.1" +dependencies = [ + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ethkey 0.3.0", +] + [[package]] name = "fdlimit" version = "0.1.1" @@ -2230,6 +2239,7 @@ dependencies = [ "ethkey 0.3.0", "ethstore 0.2.0", "fake-fetch 0.0.1", + "fake-hardware-wallet 0.0.1", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index fe05badb4a5..d02dbd8229f 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -36,7 +36,6 @@ ethjson = { path = "../json" } ethkey = { path = "../ethkey" } ethstore = { path = "../ethstore" } evm = { path = "evm" } -hardware-wallet = { path = "../hw" } heapsize = "0.4" itertools = "0.5" lazy_static = "1.0" @@ -70,6 +69,12 @@ journaldb = { path = "../util/journaldb" } tempdir = "0.3" kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } +[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))'.dependencies] +hardware-wallet = { path = "../hw" } + +[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))'.dependencies] +fake-hardware-wallet = { path = "../util/fake-hardware-wallet" } + [dev-dependencies] trie-standardmap = { path = "../util/trie-standardmap" } diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 72b2ef5bebe..d4a5da49e98 100644 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -18,9 +18,6 @@ mod stores; -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))] -mod no_hw; - use ethstore::{ SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore, random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret, @@ -37,18 +34,9 @@ use std::time::{Instant, Duration}; pub use ethstore::ethkey::Signature; pub use ethstore::{Derivation, IndexDerivation, KeyFile}; +pub use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo}; pub use super::transaction::{Action, Transaction}; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] -mod hw { - pub use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo}; -} - -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))] -mod hw { - pub use account_provider::no_hw::{HardwareError, HardwareWalletManager}; -} - /// Type of unlock. #[derive(Clone, PartialEq)] enum Unlock { @@ -76,7 +64,7 @@ pub enum SignError { /// Account does not exist. NotFound, /// Low-level hardware device error. - Hardware(hw::HardwareError), + Hardware(HardwareError), /// Low-level error from store SStore(SSError), } @@ -92,8 +80,8 @@ impl fmt::Display for SignError { } } -impl From for SignError { - fn from(e: hw::HardwareError) -> Self { +impl From for SignError { + fn from(e: HardwareError) -> Self { SignError::Hardware(e) } } @@ -143,7 +131,7 @@ pub struct AccountProvider { /// Accounts unlocked with rolling tokens transient_sstore: EthMultiStore, /// Accounts in hardware wallets. - hardware_store: Option, + hardware_store: Option, /// When unlocking account permanently we additionally keep a raw secret in memory /// to increase the performance of transaction signing. unlock_keep_secret: bool, @@ -179,16 +167,13 @@ impl AccountProvider { pub fn new(sstore: Box, settings: AccountProviderSettings) -> Self { let mut hardware_store = None; - #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] - { - if settings.enable_hardware_wallets { - match hw::HardwareWalletManager::new() { - Ok(manager) => { - manager.set_key_path(if settings.hardware_wallet_classic_key { hw::KeyPath::EthereumClassic } else { hw::KeyPath::Ethereum }); - hardware_store = Some(manager) - }, - Err(e) => debug!("Error initializing hardware wallets: {}", e), - } + if settings.enable_hardware_wallets { + match HardwareWalletManager::new() { + Ok(manager) => { + manager.set_key_path(if settings.hardware_wallet_classic_key { KeyPath::EthereumClassic } else { KeyPath::Ethereum }); + hardware_store = Some(manager) + }, + Err(e) => debug!("Error initializing hardware wallets: {}", e), } } @@ -850,7 +835,7 @@ impl AccountProvider { chain_id: chain_id, }; match self.hardware_store.as_ref().map(|s| s.sign_transaction(&address, &t_info, rlp_encoded_transaction)) { - None | Some(Err(hw::HardwareError::KeyNotFound)) => Err(SignError::NotFound), + None | Some(Err(HardwareError::KeyNotFound)) => Err(SignError::NotFound), Some(Err(e)) => Err(From::from(e)), Some(Ok(s)) => Ok(s), } diff --git a/ethcore/src/account_provider/no_hw.rs b/ethcore/src/account_provider/no_hw.rs deleted file mode 100644 index 9f65dd06c7a..00000000000 --- a/ethcore/src/account_provider/no_hw.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! Dummy module for platforms that does not provide support for hardware wallets (libusb) - -use super::{fmt, Address}; - -pub struct WalletInfo { - pub address: Address, - pub name: String, - pub manufacturer: String, -} - -#[derive(Debug)] -/// `ErrorType` for devices with no `hardware wallet` -pub enum HardwareError { - NoWallet, -} - -/// `HardwareWalletManager` for devices with no `hardware wallet` -pub struct HardwareWalletManager; - -impl HardwareWalletManager { - pub fn wallet_info(&self, _: &Address) -> Option { - None - } - - pub fn list_wallets(&self) -> Vec { - Vec::with_capacity(0) - } - - pub fn list_locked_wallets(&self) -> Result, HardwareError> { - Err(HardwareError::NoWallet) - } - - pub fn pin_matrix_ack(&self, _: &str, _: &str) -> Result { - Err(HardwareError::NoWallet) - } -} - -impl fmt::Display for HardwareError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "") - } -} diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index e992f245328..763043d62db 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -112,6 +112,9 @@ extern crate journaldb; #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] extern crate hardware_wallet; +#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))] +extern crate fake_hardware_wallet as hardware_wallet; + #[cfg(test)] extern crate tempdir; @@ -160,7 +163,6 @@ pub mod state; pub mod state_db; // Test helpers made public for usage outside ethcore -pub mod test_helpers; pub mod trace; pub mod verification; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index d227f45f535..8487844bd6f 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -64,6 +64,12 @@ rlp = { path = "../util/rlp" } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } +[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))'.dependencies] +hardware-wallet = { path = "../hw" } + +[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))'.dependencies] +fake-hardware-wallet = { path = "../util/fake-hardware-wallet" } + [dev-dependencies] ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-network = { path = "../util/network" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 54784a9a1db..6356dc28448 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -58,20 +58,21 @@ extern crate ethcore_transaction as transaction; extern crate ethereum_types; extern crate ethkey; extern crate ethstore; -extern crate vm; extern crate fetch; +extern crate keccak_hash as hash; extern crate node_health; extern crate parity_reactor; extern crate parity_updater as updater; extern crate parity_version as version; +extern crate patricia_trie as trie; extern crate rlp; extern crate stats; -extern crate keccak_hash as hash; +extern crate vm; #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] extern crate hardware_wallet; - -extern crate patricia_trie as trie; +#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))] +extern crate fake_hardware_wallet as hardware_wallet; #[macro_use] extern crate log; diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs index a34e2e61f39..c6f10400a58 100644 --- a/rpc/src/v1/helpers/dispatch.rs +++ b/rpc/src/v1/helpers/dispatch.rs @@ -51,8 +51,6 @@ use v1::types::{ SignRequest as RpcSignRequest, DecryptRequest as RpcDecryptRequest, }; - -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] use rlp; pub use self::nonce::Reservations; @@ -436,11 +434,8 @@ fn sign_transaction( data: filled.data, }; - #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] - { - if accounts.is_hardware_address(&filled.from) { - return hardware_signature(accounts, filled.from, t, chain_id).map(WithToken::No) - } + if accounts.is_hardware_address(&filled.from) { + return hardware_signature(accounts, filled.from, t, chain_id).map(WithToken::No) } let hash = t.hash(chain_id); @@ -726,7 +721,6 @@ fn signature(accounts: &AccountProvider, address: Address, hash: H256, password: } // obtain a hardware signature from the given account. -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] fn hardware_signature(accounts: &AccountProvider, address: Address, t: Transaction, chain_id: Option) -> Result { diff --git a/util/fake-hardware-wallet/Cargo.toml b/util/fake-hardware-wallet/Cargo.toml new file mode 100644 index 00000000000..600cd098c5d --- /dev/null +++ b/util/fake-hardware-wallet/Cargo.toml @@ -0,0 +1,10 @@ +[package] +description = "Fake hardware-wallet, for OS' that don't support libusb" +name = "fake-hardware-wallet" +version = "0.0.1" +license = "GPL-3.0" +authors = ["Parity Technologies "] + +[dependencies] +ethereum-types = "0.3" +ethkey = { path = "../../ethkey" } diff --git a/util/fake-hardware-wallet/src/lib.rs b/util/fake-hardware-wallet/src/lib.rs new file mode 100644 index 00000000000..b00d1892ee8 --- /dev/null +++ b/util/fake-hardware-wallet/src/lib.rs @@ -0,0 +1,101 @@ +// Copyright 2015-2018 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 . + +//! Dummy module for platforms that does not provide support for hardware wallets (libusb) + +extern crate ethereum_types; +extern crate ethkey; + +use std::fmt; +use ethereum_types::U256; +use ethkey::{Address, Signature}; + +pub struct WalletInfo { + pub address: Address, + pub name: String, + pub manufacturer: String, +} + +#[derive(Debug)] +/// `ErrorType` for devices with no `hardware wallet` +pub enum Error { + NoWallet, + KeyNotFound, +} + +pub struct TransactionInfo { + /// Nonce + pub nonce: U256, + /// Gas price + pub gas_price: U256, + /// Gas limit + pub gas_limit: U256, + /// Receiver + pub to: Option
, + /// Value + pub value: U256, + /// Data + pub data: Vec, + /// Chain ID + pub chain_id: Option, +} + +pub enum KeyPath { + /// Ethereum. + Ethereum, + /// Ethereum classic. + EthereumClassic, +} + +/// `HardwareWalletManager` for devices with no `hardware wallet` +pub struct HardwareWalletManager; + +impl HardwareWalletManager { + pub fn new() -> Result { + Err(Error::NoWallet) + } + + pub fn set_key_path(&self, _key_path: KeyPath) {} + + pub fn wallet_info(&self, _: &Address) -> Option { + None + } + + pub fn list_wallets(&self) -> Vec { + Vec::with_capacity(0) + } + + pub fn list_locked_wallets(&self) -> Result, Error> { + Err(Error::NoWallet) + } + + pub fn pin_matrix_ack(&self, _: &str, _: &str) -> Result { + Err(Error::NoWallet) + } + + pub fn sign_transaction(&self, _address: &Address, _transaction: &TransactionInfo, _rlp_transaction: &[u8]) -> Result { + Err(Error::NoWallet) } + + pub fn sign_message(&self, _address: &Address, _msg: &[u8]) -> Result { + Err(Error::NoWallet) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "") + } +}