From 129ad0bbcbefb60af3e945a220a202cae78ba930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 20:18:37 +0200 Subject: [PATCH 01/38] Splitting methods requiring signing into separate trait --- parity/dapps.rs | 1 + parity/rpc.rs | 1 + parity/signer.rs | 3 +- rpc/src/v1/impls/eth.rs | 58 +++++++++++++++++++++++++++------- rpc/src/v1/impls/mod.rs | 4 +-- rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/mocked/eth.rs | 5 ++- rpc/src/v1/traits/eth.rs | 25 ++++++++++----- rpc/src/v1/traits/mod.rs | 2 +- 9 files changed, 75 insertions(+), 26 deletions(-) diff --git a/parity/dapps.rs b/parity/dapps.rs index 986e3dd07..ebc254604 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -99,6 +99,7 @@ pub fn setup_dapps_server( server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(NetClient::new(&deps.sync).to_delegate()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); + server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()); server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()); diff --git a/parity/rpc.rs b/parity/rpc.rs index 60766263b..c05a98cb6 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -103,6 +103,7 @@ fn setup_rpc_server(apis: Vec<&str>, deps: &Arc) -> Server { modules.insert("eth".to_owned(), "1.0".to_owned()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); + server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); }, "personal" => { modules.insert("personal".to_owned(), "1.0".to_owned()); diff --git a/parity/signer.rs b/parity/signer.rs index c4a540721..e5f1b89cf 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -63,8 +63,9 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(NetClient::new(&deps.sync).to_delegate()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); + server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); - server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()); + server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()); server.start(addr) }; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 7627dd61e..f5af2543e 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -35,7 +35,7 @@ use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Act use ethcore::log_entry::LogEntry; use ethcore::filter::Filter as EthcoreFilter; use self::ethash::SeedHashCompute; -use v1::traits::{Eth, EthFilter}; +use v1::traits::{Eth, EthFilter, EthSigning}; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; use v1::helpers::{PollFilter, PollManager}; use v1::impls::{dispatch_transaction, sign_and_dispatch}; @@ -494,17 +494,6 @@ impl Eth for EthClient where }) } - fn send_transaction(&self, params: Params) -> Result { - from_params::<(TransactionRequest, )>(params) - .and_then(|(request, )| { - let accounts = take_weak!(self.accounts); - match accounts.account_secret(&request.from) { - Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret), - Err(_) => to_value(&H256::zero()) - } - }) - } - fn send_raw_transaction(&self, params: Params) -> Result { from_params::<(Bytes, )>(params) .and_then(|(raw_transaction, )| { @@ -726,3 +715,48 @@ impl EthFilter for EthFilterClient where }) } } + + +/// Implementation of functions that require signing when no trusted signer is used. +pub struct EthSigningUnsafeClient where + C: BlockChainClient, + A: AccountProvider, + M: MinerService { + client: Weak, + accounts: Weak, + miner: Weak, +} + +impl EthSigningUnsafeClient where + C: BlockChainClient, + A: AccountProvider, + M: MinerService { + + /// Creates new EthClient. + pub fn new(client: &Arc, accounts: &Arc, miner: &Arc) + -> Self { + EthSigningUnsafeClient { + client: Arc::downgrade(client), + miner: Arc::downgrade(miner), + accounts: Arc::downgrade(accounts), + } + } +} + +impl EthSigning for EthSigningUnsafeClient where + C: BlockChainClient + 'static, + A: AccountProvider + 'static, + M: MinerService + 'static { + + fn send_transaction(&self, params: Params) -> Result { + from_params::<(TransactionRequest, )>(params) + .and_then(|(request, )| { + let accounts = take_weak!(self.accounts); + match accounts.account_secret(&request.from) { + Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret), + Err(_) => to_value(&H256::zero()) + } + }) + } + +} diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index b79772103..13e4fd512 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -34,7 +34,7 @@ mod traces; mod rpc; pub use self::web3::Web3Client; -pub use self::eth::{EthClient, EthFilterClient}; +pub use self::eth::{EthClient, EthFilterClient, EthSigningUnsafeClient}; pub use self::net::NetClient; pub use self::personal::PersonalClient; pub use self::ethcore::EthcoreClient; @@ -96,4 +96,4 @@ fn sign_and_dispatch(client: &Weak, miner: &Weak, request: Transacti trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty()); dispatch_transaction(&*client, &*miner, signed_transaction) -} \ No newline at end of file +} diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index b1ab256c0..49f9e3a38 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -25,5 +25,5 @@ pub mod traits; pub mod tests; pub mod types; -pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore, Traces, Rpc}; +pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, Net, Ethcore, Traces, Rpc}; pub use self::impls::*; diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 32a2cd99a..ce097307c 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -26,7 +26,7 @@ use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use ethcore::receipt::LocalizedReceipt; use ethcore::transaction::{Transaction, Action}; use ethminer::ExternalMiner; -use v1::{Eth, EthClient}; +use v1::{Eth, EthClient, EthSigning, EthSigningUnsafeClient}; use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService}; fn blockchain_client() -> Arc { @@ -70,8 +70,11 @@ impl Default for EthTester { let hashrates = Arc::new(RwLock::new(HashMap::new())); let external_miner = Arc::new(ExternalMiner::new(hashrates.clone())); let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate(); + let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate(); let io = IoHandler::new(); io.add_delegate(eth); + io.add_delegate(sign); + EthTester { client: client, sync: sync, diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index a28f72c5c..970bc5dd2 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -74,12 +74,6 @@ pub trait Eth: Sized + Send + Sync + 'static { /// Returns the code at given address at given time (block number). fn code_at(&self, _: Params) -> Result { rpc_unimplemented!() } - /// Signs the data with given address signature. - fn sign(&self, _: Params) -> Result { rpc_unimplemented!() } - - /// Sends transaction. - fn send_transaction(&self, _: Params) -> Result { rpc_unimplemented!() } - /// Sends signed transaction. fn send_raw_transaction(&self, _: Params) -> Result { rpc_unimplemented!() } @@ -150,8 +144,6 @@ pub trait Eth: Sized + Send + Sync + 'static { delegate.add_method("eth_getUncleCountByBlockHash", Eth::block_uncles_count_by_hash); delegate.add_method("eth_getUncleCountByBlockNumber", Eth::block_uncles_count_by_number); delegate.add_method("eth_getCode", Eth::code_at); - delegate.add_method("eth_sign", Eth::sign); - delegate.add_method("eth_sendTransaction", Eth::send_transaction); delegate.add_method("eth_sendRawTransaction", Eth::send_raw_transaction); delegate.add_method("eth_call", Eth::call); delegate.add_method("eth_estimateGas", Eth::estimate_gas); @@ -208,3 +200,20 @@ pub trait EthFilter: Sized + Send + Sync + 'static { delegate } } + +/// Signing methods implementation relying on unlocked accounts. +pub trait EthSigning: Sized + Send + Sync + 'static { + /// Signs the data with given address signature. + fn sign(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sends transaction. + fn send_transaction(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Should be used to convert object to io delegate. + fn to_delegate(self) -> IoDelegate { + let mut delegate = IoDelegate::new(Arc::new(self)); + delegate.add_method("eth_sign", EthSigning::sign); + delegate.add_method("eth_sendTransaction", EthSigning::send_transaction); + delegate + } +} diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index bebf95bb7..f3004a8d4 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -29,7 +29,7 @@ pub mod traces; pub mod rpc; pub use self::web3::Web3; -pub use self::eth::{Eth, EthFilter}; +pub use self::eth::{Eth, EthFilter, EthSigning}; pub use self::net::Net; pub use self::personal::Personal; pub use self::ethcore::Ethcore; From 07399d377fae34008b5420abef13c2e11e5a4161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 13:42:53 +0200 Subject: [PATCH 02/38] Single place where RPC apis are created. --- dapps/src/lib.rs | 13 ++-- parity/dapps.rs | 26 ++----- parity/main.rs | 23 +++--- parity/rpc.rs | 80 +++++---------------- parity/rpc_apis.rs | 136 ++++++++++++++++++++++++++++++++++++ parity/signer.rs | 20 ++---- rpc/src/lib.rs | 18 +++-- rpc/src/v1/traits/mod.rs | 2 + signer/src/ws_server/mod.rs | 12 ++-- 9 files changed, 201 insertions(+), 129 deletions(-) create mode 100644 parity/rpc_apis.rs diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index e0676881f..ef86f2661 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -52,6 +52,7 @@ extern crate serde_json; extern crate jsonrpc_core; extern crate jsonrpc_http_server; extern crate parity_dapps; +extern crate ethcore_rpc; mod endpoint; mod apps; @@ -66,6 +67,7 @@ use std::net::SocketAddr; use std::collections::HashMap; use jsonrpc_core::{IoHandler, IoDelegate}; use router::auth::{Authorization, NoAuth, HttpBasicAuth}; +use ethcore_rpc::Extendable; static DAPPS_DOMAIN : &'static str = ".parity"; @@ -74,6 +76,12 @@ pub struct ServerBuilder { handler: Arc, } +impl Extendable for ServerBuilder { + fn add_delegate(&self, delegate: IoDelegate) { + self.handler.add_delegate(delegate); + } +} + impl ServerBuilder { /// Construct new dapps server pub fn new() -> Self { @@ -82,11 +90,6 @@ impl ServerBuilder { } } - /// Add io delegate. - pub fn add_delegate(&self, delegate: IoDelegate) where D: Send + Sync + 'static { - self.handler.add_delegate(delegate); - } - /// Asynchronously start server with no authentication, /// returns result with `Server` handle on success or an error. pub fn start_unsecure_http(&self, addr: &SocketAddr) -> Result { diff --git a/parity/dapps.rs b/parity/dapps.rs index ebc254604..4ea74d7f2 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -17,14 +17,9 @@ use std::sync::Arc; use std::str::FromStr; use std::net::SocketAddr; -use ethcore::client::Client; -use ethsync::EthSync; -use ethminer::{Miner, ExternalMiner}; -use util::RotatingLogger; use util::panics::PanicHandler; -use util::keys::store::AccountService; -use util::network_settings::NetworkSettings; use die::*; +use rpc_apis; #[cfg(feature = "dapps")] pub use ethcore_dapps::Server as WebappServer; @@ -41,13 +36,7 @@ pub struct Configuration { pub struct Dependencies { pub panic_handler: Arc, - pub client: Arc, - pub sync: Arc, - pub secret_store: Arc, - pub miner: Arc, - pub external_miner: Arc, - pub logger: Arc, - pub settings: Arc, + pub apis: Arc, } pub fn new(configuration: Configuration, deps: Dependencies) -> Option { @@ -92,18 +81,11 @@ pub fn setup_dapps_server( url: &SocketAddr, auth: Option<(String, String)> ) -> WebappServer { - use ethcore_rpc::v1::*; use ethcore_dapps as dapps; let server = dapps::ServerBuilder::new(); - server.add_delegate(Web3Client::new().to_delegate()); - server.add_delegate(NetClient::new(&deps.sync).to_delegate()); - server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); - server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); - server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); - server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()); - server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()); - + // TODO [ToDr] Specify apis + let server = rpc_apis::setup_rpc(server, deps.apis.clone(), None); let start_result = match auth { None => { server.start_unsecure_http(url) diff --git a/parity/main.rs b/parity/main.rs index 61aa8ab21..874bb35b5 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -69,6 +69,7 @@ mod cli; mod configuration; mod migration; mod signer; +mod rpc_apis; use std::io::{Write, Read, BufReader, BufRead}; use std::ops::Deref; @@ -197,8 +198,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) // Sync let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone()); - let dependencies = Arc::new(rpc::Dependencies { - panic_handler: panic_handler.clone(), + let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies { client: client.clone(), sync: sync.clone(), secret_store: account_service.clone(), @@ -208,6 +208,11 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) settings: network_settings.clone(), }); + let dependencies = rpc::Dependencies { + panic_handler: panic_handler.clone(), + apis: deps_for_rpc_apis.clone(), + }; + // Setup http rpc let rpc_server = rpc::new_http(rpc::HttpConfiguration { enabled: network_settings.rpc_enabled, @@ -229,13 +234,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) pass: conf.args.flag_dapps_pass.clone(), }, dapps::Dependencies { panic_handler: panic_handler.clone(), - client: client.clone(), - sync: sync.clone(), - secret_store: account_service.clone(), - miner: miner.clone(), - external_miner: external_miner.clone(), - logger: logger.clone(), - settings: network_settings.clone(), + apis: deps_for_rpc_apis.clone(), }); // Set up a signer @@ -244,11 +243,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) port: conf.args.flag_signer_port, }, signer::Dependencies { panic_handler: panic_handler.clone(), - client: client.clone(), - sync: sync.clone(), - secret_store: account_service.clone(), - miner: miner.clone(), - external_miner: external_miner.clone(), + apis: deps_for_rpc_apis.clone(), }); // Register IO handler diff --git a/parity/rpc.rs b/parity/rpc.rs index c05a98cb6..af998ff97 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -15,19 +15,13 @@ // along with Parity. If not, see . -use std::collections::BTreeMap; use std::str::FromStr; use std::sync::Arc; use std::net::SocketAddr; -use ethcore::client::Client; -use ethsync::EthSync; -use ethminer::{Miner, ExternalMiner}; -use util::RotatingLogger; use util::panics::PanicHandler; -use util::keys::store::AccountService; -use util::network_settings::NetworkSettings; use die::*; use jsonipc; +use rpc_apis; #[cfg(feature = "rpc")] pub use ethcore_rpc::Server as RpcServer; @@ -52,16 +46,10 @@ pub struct IpcConfiguration { pub struct Dependencies { pub panic_handler: Arc, - pub client: Arc, - pub sync: Arc, - pub secret_store: Arc, - pub miner: Arc, - pub external_miner: Arc, - pub logger: Arc, - pub settings: Arc, + pub apis: Arc, } -pub fn new_http(conf: HttpConfiguration, deps: &Arc) -> Option { +pub fn new_http(conf: HttpConfiguration, deps: &Dependencies) -> Option { if !conf.enabled { return None; } @@ -78,59 +66,23 @@ pub fn new_http(conf: HttpConfiguration, deps: &Arc) -> Option) -> Option { +pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Option { if !conf.enabled { return None; } let apis = conf.apis.split(',').collect(); Some(setup_ipc_rpc_server(deps, &conf.socket_addr, apis)) } -fn setup_rpc_server(apis: Vec<&str>, deps: &Arc) -> Server { - use ethcore_rpc::v1::*; - +fn setup_rpc_server(apis: Vec<&str>, deps: &Dependencies) -> Server { + let apis = rpc_apis::from_str(apis); let server = Server::new(); - let mut modules = BTreeMap::new(); - for api in apis.into_iter() { - match api { - "web3" => { - modules.insert("web3".to_owned(), "1.0".to_owned()); - server.add_delegate(Web3Client::new().to_delegate()); - }, - "net" => { - modules.insert("net".to_owned(), "1.0".to_owned()); - server.add_delegate(NetClient::new(&deps.sync).to_delegate()); - }, - "eth" => { - modules.insert("eth".to_owned(), "1.0".to_owned()); - server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); - server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); - server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); - }, - "personal" => { - modules.insert("personal".to_owned(), "1.0".to_owned()); - server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()) - }, - "ethcore" => { - modules.insert("ethcore".to_owned(), "1.0".to_owned()); - server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()) - }, - "traces" => { - modules.insert("traces".to_owned(), "1.0".to_owned()); - server.add_delegate(TracesClient::new(&deps.client).to_delegate()) - }, - _ => { - die!("{}: Invalid API name to be enabled.", api); - }, - } - } - server.add_delegate(RpcClient::new(modules).to_delegate()); - server + rpc_apis::setup_rpc(server, deps.apis.clone(), Some(apis)) } #[cfg(not(feature = "rpc"))] pub fn setup_http_rpc_server( - _deps: Dependencies, + _deps: &Dependencies, _url: &SocketAddr, - _cors_domain: Option, + _cors_domain: Vec, _apis: Vec<&str>, ) -> ! { die!("Your Parity version has been compiled without JSON-RPC support.") @@ -138,27 +90,31 @@ pub fn setup_http_rpc_server( #[cfg(feature = "rpc")] pub fn setup_http_rpc_server( - dependencies: &Arc, + dependencies: &Dependencies, url: &SocketAddr, cors_domains: Vec, apis: Vec<&str>, ) -> RpcServer { let server = setup_rpc_server(apis, dependencies); let start_result = server.start_http(url, cors_domains); - let deps = dependencies.clone(); + let ph = dependencies.panic_handler.clone(); match start_result { Err(RpcServerError::IoError(err)) => die_with_io_error("RPC", err), Err(e) => die!("RPC: {:?}", e), Ok(server) => { server.set_panic_handler(move || { - deps.panic_handler.notify_all("Panic in RPC thread.".to_owned()); + ph.notify_all("Panic in RPC thread.".to_owned()); }); server }, } } - -pub fn setup_ipc_rpc_server(dependencies: &Arc, addr: &str, apis: Vec<&str>) -> jsonipc::Server { +#[cfg(not(feature = "rpc"))] +pub fn setup_ipc_rpc_server(_dependencies: &Dependencies, _addr: &str, _apis: Vec<&str>) -> ! { + die!("Your Parity version has been compiled without JSON-RPC support.") +} +#[cfg(feature = "rpc")] +pub fn setup_ipc_rpc_server(dependencies: &Dependencies, addr: &str, apis: Vec<&str>) -> jsonipc::Server { let server = setup_rpc_server(apis, dependencies); match server.start_ipc(addr) { Err(jsonipc::Error::Io(io_error)) => die_with_io_error("RPC", io_error), diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs new file mode 100644 index 000000000..1f1994d9e --- /dev/null +++ b/parity/rpc_apis.rs @@ -0,0 +1,136 @@ +// 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 . + +use std::collections::BTreeMap; +use std::str::FromStr; +use std::sync::Arc; + +use die::*; +use ethsync::EthSync; +use ethminer::{Miner, ExternalMiner}; +use ethcore::client::Client; +use util::RotatingLogger; +use util::keys::store::AccountService; +use util::network_settings::NetworkSettings; + +use ethcore_rpc::Extendable; + +pub enum Api { + Web3, + Net, + Eth, + Personal, + Ethcore, + Traces, + Rpc, +} +pub enum ApiError { + UnknownApi(String) +} + +impl FromStr for Api { + type Err = ApiError; + + fn from_str(s: &str) -> Result { + use self::Api::*; + + match s { + "web3" => Ok(Web3), + "net" => Ok(Net), + "eth" => Ok(Eth), + "personal" => Ok(Personal), + "ethcore" => Ok(Ethcore), + "traces" => Ok(Traces), + "rpc" => Ok(Rpc), + e => Err(ApiError::UnknownApi(e.into())), + } + } +} + +pub struct Dependencies { + pub client: Arc, + pub sync: Arc, + pub secret_store: Arc, + pub miner: Arc, + pub external_miner: Arc, + pub logger: Arc, + pub settings: Arc, +} + +fn to_modules(apis: &[Api]) -> BTreeMap { + let mut modules = BTreeMap::new(); + for api in apis { + let (name, version) = match *api { + Api::Web3 => ("web3", "1.0"), + Api::Net => ("net", "1.0"), + Api::Eth => ("eth", "1.0"), + Api::Personal => ("personal", "1.0"), + Api::Ethcore => ("ethcore", "1.0"), + Api::Traces => ("traces", "1.0"), + Api::Rpc => ("rpc", "1.0"), + }; + modules.insert(name.into(), version.into()); + } + modules +} + +pub fn from_str(apis: Vec<&str>) -> Vec { + apis.into_iter() + .map(Api::from_str) + .collect::, ApiError>>() + .unwrap_or_else(|e| match e { + ApiError::UnknownApi(s) => die!("Unknown RPC API specified: {}", s), + }) +} + +pub fn setup_rpc(server: T, deps: Arc, apis: Option>) -> T { + use ethcore_rpc::v1::*; + + let apis = match apis { + Some(api) => api, + None => vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::Traces, Api::Rpc], + }; + + for api in &apis { + match *api { + Api::Web3 => { + server.add_delegate(Web3Client::new().to_delegate()); + }, + Api::Net => { + server.add_delegate(NetClient::new(&deps.sync).to_delegate()); + }, + Api::Eth => { + server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); + server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); + server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); + }, + Api::Personal => { + server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()) + }, + Api::Ethcore => { + server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()) + }, + Api::Traces => { + server.add_delegate(TracesClient::new(&deps.client).to_delegate()) + }, + Api::Rpc => { + let modules = to_modules(&apis); + server.add_delegate(RpcClient::new(modules).to_delegate()); + } + } + } + server +} diff --git a/parity/signer.rs b/parity/signer.rs index e5f1b89cf..b2224b106 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -15,12 +15,9 @@ // along with Parity. If not, see . use std::sync::Arc; -use ethcore::client::Client; -use ethsync::EthSync; -use ethminer::{Miner, ExternalMiner}; -use util::keys::store::AccountService; use util::panics::{PanicHandler, ForwardPanic}; use die::*; +use rpc_apis; #[cfg(feature = "ethcore-signer")] use ethcore_signer as signer; @@ -36,11 +33,7 @@ pub struct Configuration { pub struct Dependencies { pub panic_handler: Arc, - pub client: Arc, - pub sync: Arc, - pub secret_store: Arc, - pub miner: Arc, - pub external_miner: Arc, + pub apis: Arc, } pub fn start(conf: Configuration, deps: Dependencies) -> Option { @@ -58,14 +51,9 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { }); let start_result = { - use ethcore_rpc::v1::*; let server = signer::ServerBuilder::new(); - server.add_delegate(Web3Client::new().to_delegate()); - server.add_delegate(NetClient::new(&deps.sync).to_delegate()); - server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); - server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); - server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); - server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()); + // TODO [ToDr] Setup APIS + let server = rpc_apis::setup_rpc(server, deps.apis, None); server.start(addr) }; diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 7d9818615..a82c70af0 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -40,11 +40,24 @@ use self::jsonrpc_core::{IoHandler, IoDelegate}; pub use jsonrpc_http_server::{Server, RpcServerError}; pub mod v1; +/// An object that can be extended with `IoDelegates` +pub trait Extendable { + /// Add `Delegate` to this object. + fn add_delegate(&self, delegate: IoDelegate); +} + /// Http server. pub struct RpcServer { handler: Arc, } +impl Extendable for RpcServer { + /// Add io delegate. + fn add_delegate(&self, delegate: IoDelegate) { + self.handler.add_delegate(delegate); + } +} + impl RpcServer { /// Construct new http server object. pub fn new() -> RpcServer { @@ -53,11 +66,6 @@ impl RpcServer { } } - /// Add io delegate. - pub fn add_delegate(&self, delegate: IoDelegate) where D: Send + Sync + 'static { - self.handler.add_delegate(delegate); - } - /// Start http server asynchronously and returns result with `Server` handle on success or an error. pub fn start_http(&self, addr: &SocketAddr, cors_domains: Vec) -> Result { let cors_domains = cors_domains.into_iter() diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index f3004a8d4..e5d5f3324 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -35,3 +35,5 @@ pub use self::personal::Personal; pub use self::ethcore::Ethcore; pub use self::traces::Traces; pub use self::rpc::Rpc; + + diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index bb10bc5c1..bc8fb33f8 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -25,6 +25,7 @@ use std::sync::Arc; use std::net::SocketAddr; use util::panics::{PanicHandler, OnPanicListener, MayPanic}; use jsonrpc_core::{IoHandler, IoDelegate}; +use rpc::Extendable; mod session; @@ -57,6 +58,12 @@ impl Default for ServerBuilder { } } +impl Extendable for ServerBuilder { + fn add_delegate(&self, delegate: IoDelegate) { + self.handler.add_delegate(delegate); + } +} + impl ServerBuilder { /// Creates new `ServerBuilder` pub fn new() -> Self { @@ -65,11 +72,6 @@ impl ServerBuilder { } } - /// Adds rpc delegate - pub fn add_delegate(&self, delegate: IoDelegate) where D: Send + Sync + 'static { - self.handler.add_delegate(delegate); - } - /// Starts a new `WebSocket` server in separate thread. /// Returns a `Server` handle which closes the server when droped. pub fn start(self, addr: SocketAddr) -> Result { From ffa113511b9c6cfa5973a52f11db66364710c2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 14:21:43 +0200 Subject: [PATCH 03/38] Separating eth_filter --- rpc/src/v1/impls/eth.rs | 224 +++------------------------------ rpc/src/v1/impls/eth_filter.rs | 214 +++++++++++++++++++++++++++++++ rpc/src/v1/impls/mod.rs | 4 +- 3 files changed, 237 insertions(+), 205 deletions(-) create mode 100644 rpc/src/v1/impls/eth_filter.rs diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index f5af2543e..2c18640d7 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -18,7 +18,6 @@ extern crate ethash; -use std::collections::HashSet; use std::sync::{Arc, Weak, Mutex}; use std::ops::Deref; use ethsync::{SyncProvider, SyncState}; @@ -35,9 +34,8 @@ use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Act use ethcore::log_entry::LogEntry; use ethcore::filter::Filter as EthcoreFilter; use self::ethash::SeedHashCompute; -use v1::traits::{Eth, EthFilter, EthSigning}; +use v1::traits::{Eth, EthSigning}; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; -use v1::helpers::{PollFilter, PollManager}; use v1::impls::{dispatch_transaction, sign_and_dispatch}; use util::keys::store::AccountProvider; use serde; @@ -170,6 +168,25 @@ impl EthClient where } } +pub fn pending_logs(miner: &M, filter: &EthcoreFilter) -> Vec where M: MinerService { + let receipts = miner.pending_receipts(); + + let pending_logs = receipts.into_iter() + .flat_map(|(hash, r)| r.logs.into_iter().map(|l| (hash.clone(), l)).collect::>()) + .collect::>(); + + let result = pending_logs.into_iter() + .filter(|pair| filter.matches(&pair.1)) + .map(|pair| { + let mut log = Log::from(pair.1); + log.transaction_hash = Some(pair.0); + log + }) + .collect(); + + result +} + const MAX_QUEUE_SIZE_TO_MINE_ON: usize = 4; // because uncles go back 6. fn params_len(params: &Params) -> usize { @@ -193,25 +210,6 @@ fn from_params_default_third(params: Params) -> Result<(F1, F2, BlockNum } } -fn pending_logs(miner: &M, filter: &EthcoreFilter) -> Vec where M: MinerService { - let receipts = miner.pending_receipts(); - - let pending_logs = receipts.into_iter() - .flat_map(|(hash, r)| r.logs.into_iter().map(|l| (hash.clone(), l)).collect::>()) - .collect::>(); - - let result = pending_logs.into_iter() - .filter(|pair| filter.matches(&pair.1)) - .map(|pair| { - let mut log = Log::from(pair.1); - log.transaction_hash = Some(pair.0); - log - }) - .collect(); - - result -} - // must be in range [-32099, -32000] const UNSUPPORTED_REQUEST_CODE: i64 = -32000; @@ -533,188 +531,6 @@ impl Eth for EthClient where } } -/// Eth filter rpc implementation. -pub struct EthFilterClient where - C: BlockChainClient, - M: MinerService { - - client: Weak, - miner: Weak, - polls: Mutex>, -} - -impl EthFilterClient where - C: BlockChainClient, - M: MinerService { - - /// Creates new Eth filter client. - pub fn new(client: &Arc, miner: &Arc) -> Self { - EthFilterClient { - client: Arc::downgrade(client), - miner: Arc::downgrade(miner), - polls: Mutex::new(PollManager::new()), - } - } -} - -impl EthFilter for EthFilterClient where - C: BlockChainClient + 'static, - M: MinerService + 'static { - - fn new_filter(&self, params: Params) -> Result { - from_params::<(Filter,)>(params) - .and_then(|(filter,)| { - let mut polls = self.polls.lock().unwrap(); - let block_number = take_weak!(self.client).chain_info().best_block_number; - let id = polls.create_poll(PollFilter::Logs(block_number, Default::default(), filter)); - to_value(&U256::from(id)) - }) - } - - fn new_block_filter(&self, params: Params) -> Result { - match params { - Params::None => { - let mut polls = self.polls.lock().unwrap(); - let id = polls.create_poll(PollFilter::Block(take_weak!(self.client).chain_info().best_block_number)); - to_value(&U256::from(id)) - }, - _ => Err(Error::invalid_params()) - } - } - - fn new_pending_transaction_filter(&self, params: Params) -> Result { - match params { - Params::None => { - let mut polls = self.polls.lock().unwrap(); - let pending_transactions = take_weak!(self.miner).pending_transactions_hashes(); - let id = polls.create_poll(PollFilter::PendingTransaction(pending_transactions)); - - to_value(&U256::from(id)) - }, - _ => Err(Error::invalid_params()) - } - } - - fn filter_changes(&self, params: Params) -> Result { - let client = take_weak!(self.client); - from_params::<(Index,)>(params) - .and_then(|(index,)| { - let mut polls = self.polls.lock().unwrap(); - match polls.poll_mut(&index.value()) { - None => Ok(Value::Array(vec![] as Vec)), - Some(filter) => match *filter { - PollFilter::Block(ref mut block_number) => { - // + 1, cause we want to return hashes including current block hash. - let current_number = client.chain_info().best_block_number + 1; - let hashes = (*block_number..current_number).into_iter() - .map(BlockID::Number) - .filter_map(|id| client.block_hash(id)) - .collect::>(); - - *block_number = current_number; - - to_value(&hashes) - }, - PollFilter::PendingTransaction(ref mut previous_hashes) => { - // get hashes of pending transactions - let current_hashes = take_weak!(self.miner).pending_transactions_hashes(); - - let new_hashes = - { - let previous_hashes_set = previous_hashes.iter().collect::>(); - - // find all new hashes - current_hashes - .iter() - .filter(|hash| !previous_hashes_set.contains(hash)) - .cloned() - .collect::>() - }; - - // save all hashes of pending transactions - *previous_hashes = current_hashes; - - // return new hashes - to_value(&new_hashes) - }, - PollFilter::Logs(ref mut block_number, ref mut previous_logs, ref filter) => { - // retrive the current block number - let current_number = client.chain_info().best_block_number; - - // check if we need to check pending hashes - let include_pending = filter.to_block == Some(BlockNumber::Pending); - - // build appropriate filter - let mut filter: EthcoreFilter = filter.clone().into(); - filter.from_block = BlockID::Number(*block_number); - filter.to_block = BlockID::Latest; - - // retrieve logs in range from_block..min(BlockID::Latest..to_block) - let mut logs = client.logs(filter.clone()) - .into_iter() - .map(From::from) - .collect::>(); - - // additionally retrieve pending logs - if include_pending { - let pending_logs = pending_logs(take_weak!(self.miner).deref(), &filter); - - // remove logs about which client was already notified about - let new_pending_logs: Vec<_> = pending_logs.iter() - .filter(|p| !previous_logs.contains(p)) - .cloned() - .collect(); - - // save all logs retrieved by client - *previous_logs = pending_logs.into_iter().collect(); - - // append logs array with new pending logs - logs.extend(new_pending_logs); - } - - // save current block number as next from block number - *block_number = current_number; - - to_value(&logs) - } - } - } - }) - } - - fn filter_logs(&self, params: Params) -> Result { - from_params::<(Index,)>(params) - .and_then(|(index,)| { - let mut polls = self.polls.lock().unwrap(); - match polls.poll(&index.value()) { - Some(&PollFilter::Logs(ref _block_number, ref _previous_log, ref filter)) => { - let include_pending = filter.to_block == Some(BlockNumber::Pending); - let filter: EthcoreFilter = filter.clone().into(); - let mut logs = take_weak!(self.client).logs(filter.clone()) - .into_iter() - .map(From::from) - .collect::>(); - - if include_pending { - logs.extend(pending_logs(take_weak!(self.miner).deref(), &filter)); - } - - to_value(&logs) - }, - // just empty array - _ => Ok(Value::Array(vec![] as Vec)), - } - }) - } - - fn uninstall_filter(&self, params: Params) -> Result { - from_params::<(Index,)>(params) - .and_then(|(index,)| { - self.polls.lock().unwrap().remove_poll(&index.value()); - to_value(&true) - }) - } -} /// Implementation of functions that require signing when no trusted signer is used. diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs new file mode 100644 index 000000000..a17e64052 --- /dev/null +++ b/rpc/src/v1/impls/eth_filter.rs @@ -0,0 +1,214 @@ +// 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 . + +//! Eth Filter RPC implementation + +use std::ops::Deref; +use std::sync::{Arc, Weak, Mutex}; +use std::collections::HashSet; +use jsonrpc_core::*; +use util::numbers::*; +use ethminer::{MinerService}; +use ethcore::filter::Filter as EthcoreFilter; +use ethcore::client::{BlockChainClient, BlockID}; +use v1::traits::EthFilter; +use v1::types::{BlockNumber, Index, Filter, Log}; +use v1::helpers::{PollFilter, PollManager}; +use v1::impls::eth::pending_logs; + + +/// Eth filter rpc implementation. +pub struct EthFilterClient where + C: BlockChainClient, + M: MinerService { + + client: Weak, + miner: Weak, + polls: Mutex>, +} + +impl EthFilterClient where + C: BlockChainClient, + M: MinerService { + + /// Creates new Eth filter client. + pub fn new(client: &Arc, miner: &Arc) -> Self { + EthFilterClient { + client: Arc::downgrade(client), + miner: Arc::downgrade(miner), + polls: Mutex::new(PollManager::new()), + } + } +} + +impl EthFilter for EthFilterClient where + C: BlockChainClient + 'static, + M: MinerService + 'static { + + fn new_filter(&self, params: Params) -> Result { + from_params::<(Filter,)>(params) + .and_then(|(filter,)| { + let mut polls = self.polls.lock().unwrap(); + let block_number = take_weak!(self.client).chain_info().best_block_number; + let id = polls.create_poll(PollFilter::Logs(block_number, Default::default(), filter)); + to_value(&U256::from(id)) + }) + } + + fn new_block_filter(&self, params: Params) -> Result { + match params { + Params::None => { + let mut polls = self.polls.lock().unwrap(); + let id = polls.create_poll(PollFilter::Block(take_weak!(self.client).chain_info().best_block_number)); + to_value(&U256::from(id)) + }, + _ => Err(Error::invalid_params()) + } + } + + fn new_pending_transaction_filter(&self, params: Params) -> Result { + match params { + Params::None => { + let mut polls = self.polls.lock().unwrap(); + let pending_transactions = take_weak!(self.miner).pending_transactions_hashes(); + let id = polls.create_poll(PollFilter::PendingTransaction(pending_transactions)); + + to_value(&U256::from(id)) + }, + _ => Err(Error::invalid_params()) + } + } + + fn filter_changes(&self, params: Params) -> Result { + let client = take_weak!(self.client); + from_params::<(Index,)>(params) + .and_then(|(index,)| { + let mut polls = self.polls.lock().unwrap(); + match polls.poll_mut(&index.value()) { + None => Ok(Value::Array(vec![] as Vec)), + Some(filter) => match *filter { + PollFilter::Block(ref mut block_number) => { + // + 1, cause we want to return hashes including current block hash. + let current_number = client.chain_info().best_block_number + 1; + let hashes = (*block_number..current_number).into_iter() + .map(BlockID::Number) + .filter_map(|id| client.block_hash(id)) + .collect::>(); + + *block_number = current_number; + + to_value(&hashes) + }, + PollFilter::PendingTransaction(ref mut previous_hashes) => { + // get hashes of pending transactions + let current_hashes = take_weak!(self.miner).pending_transactions_hashes(); + + let new_hashes = + { + let previous_hashes_set = previous_hashes.iter().collect::>(); + + // find all new hashes + current_hashes + .iter() + .filter(|hash| !previous_hashes_set.contains(hash)) + .cloned() + .collect::>() + }; + + // save all hashes of pending transactions + *previous_hashes = current_hashes; + + // return new hashes + to_value(&new_hashes) + }, + PollFilter::Logs(ref mut block_number, ref mut previous_logs, ref filter) => { + // retrive the current block number + let current_number = client.chain_info().best_block_number; + + // check if we need to check pending hashes + let include_pending = filter.to_block == Some(BlockNumber::Pending); + + // build appropriate filter + let mut filter: EthcoreFilter = filter.clone().into(); + filter.from_block = BlockID::Number(*block_number); + filter.to_block = BlockID::Latest; + + // retrieve logs in range from_block..min(BlockID::Latest..to_block) + let mut logs = client.logs(filter.clone()) + .into_iter() + .map(From::from) + .collect::>(); + + // additionally retrieve pending logs + if include_pending { + let pending_logs = pending_logs(take_weak!(self.miner).deref(), &filter); + + // remove logs about which client was already notified about + let new_pending_logs: Vec<_> = pending_logs.iter() + .filter(|p| !previous_logs.contains(p)) + .cloned() + .collect(); + + // save all logs retrieved by client + *previous_logs = pending_logs.into_iter().collect(); + + // append logs array with new pending logs + logs.extend(new_pending_logs); + } + + // save current block number as next from block number + *block_number = current_number; + + to_value(&logs) + } + } + } + }) + } + + fn filter_logs(&self, params: Params) -> Result { + from_params::<(Index,)>(params) + .and_then(|(index,)| { + let mut polls = self.polls.lock().unwrap(); + match polls.poll(&index.value()) { + Some(&PollFilter::Logs(ref _block_number, ref _previous_log, ref filter)) => { + let include_pending = filter.to_block == Some(BlockNumber::Pending); + let filter: EthcoreFilter = filter.clone().into(); + let mut logs = take_weak!(self.client).logs(filter.clone()) + .into_iter() + .map(From::from) + .collect::>(); + + if include_pending { + logs.extend(pending_logs(take_weak!(self.miner).deref(), &filter)); + } + + to_value(&logs) + }, + // just empty array + _ => Ok(Value::Array(vec![] as Vec)), + } + }) + } + + fn uninstall_filter(&self, params: Params) -> Result { + from_params::<(Index,)>(params) + .and_then(|(index,)| { + self.polls.lock().unwrap().remove_poll(&index.value()); + to_value(&true) + }) + } +} diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index 13e4fd512..979463a5d 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -27,6 +27,7 @@ macro_rules! take_weak { mod web3; mod eth; +mod eth_filter; mod net; mod personal; mod ethcore; @@ -34,7 +35,8 @@ mod traces; mod rpc; pub use self::web3::Web3Client; -pub use self::eth::{EthClient, EthFilterClient, EthSigningUnsafeClient}; +pub use self::eth::{EthClient, EthSigningUnsafeClient}; +pub use self::eth_filter::EthFilterClient; pub use self::net::NetClient; pub use self::personal::PersonalClient; pub use self::ethcore::EthcoreClient; From f794018e958cdbe79383aaaefa03b702b21804ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 14:32:31 +0200 Subject: [PATCH 04/38] Separating eth_signing --- rpc/src/v1/impls/eth.rs | 52 ++---------------------- rpc/src/v1/impls/eth_filter.rs | 2 +- rpc/src/v1/impls/eth_signing.rs | 71 +++++++++++++++++++++++++++++++++ rpc/src/v1/impls/mod.rs | 4 +- 4 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 rpc/src/v1/impls/eth_signing.rs diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 2c18640d7..f7c34ffa7 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -34,9 +34,9 @@ use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Act use ethcore::log_entry::LogEntry; use ethcore::filter::Filter as EthcoreFilter; use self::ethash::SeedHashCompute; -use v1::traits::{Eth, EthSigning}; -use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; -use v1::impls::{dispatch_transaction, sign_and_dispatch}; +use v1::traits::Eth; +use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; +use v1::impls::dispatch_transaction; use util::keys::store::AccountProvider; use serde; @@ -530,49 +530,3 @@ impl Eth for EthClient where }) } } - - - -/// Implementation of functions that require signing when no trusted signer is used. -pub struct EthSigningUnsafeClient where - C: BlockChainClient, - A: AccountProvider, - M: MinerService { - client: Weak, - accounts: Weak, - miner: Weak, -} - -impl EthSigningUnsafeClient where - C: BlockChainClient, - A: AccountProvider, - M: MinerService { - - /// Creates new EthClient. - pub fn new(client: &Arc, accounts: &Arc, miner: &Arc) - -> Self { - EthSigningUnsafeClient { - client: Arc::downgrade(client), - miner: Arc::downgrade(miner), - accounts: Arc::downgrade(accounts), - } - } -} - -impl EthSigning for EthSigningUnsafeClient where - C: BlockChainClient + 'static, - A: AccountProvider + 'static, - M: MinerService + 'static { - - fn send_transaction(&self, params: Params) -> Result { - from_params::<(TransactionRequest, )>(params) - .and_then(|(request, )| { - let accounts = take_weak!(self.accounts); - match accounts.account_secret(&request.from) { - Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret), - Err(_) => to_value(&H256::zero()) - } - }) - } - -} diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index a17e64052..c6aecdca2 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -21,7 +21,7 @@ use std::sync::{Arc, Weak, Mutex}; use std::collections::HashSet; use jsonrpc_core::*; use util::numbers::*; -use ethminer::{MinerService}; +use ethminer::MinerService; use ethcore::filter::Filter as EthcoreFilter; use ethcore::client::{BlockChainClient, BlockID}; use v1::traits::EthFilter; diff --git a/rpc/src/v1/impls/eth_signing.rs b/rpc/src/v1/impls/eth_signing.rs new file mode 100644 index 000000000..9c193e1d2 --- /dev/null +++ b/rpc/src/v1/impls/eth_signing.rs @@ -0,0 +1,71 @@ +// 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 . + +//! Eth Signing RPC implementation. + +use std::sync::{Arc, Weak}; +use jsonrpc_core::*; +use ethminer::MinerService; +use ethcore::client::BlockChainClient; +use util::numbers::*; +use util::keys::store::AccountProvider; +use v1::traits::EthSigning; +use v1::types::TransactionRequest; +use v1::impls::sign_and_dispatch; + +/// Implementation of functions that require signing when no trusted signer is used. +pub struct EthSigningUnsafeClient where + C: BlockChainClient, + A: AccountProvider, + M: MinerService { + client: Weak, + accounts: Weak, + miner: Weak, +} + +impl EthSigningUnsafeClient where + C: BlockChainClient, + A: AccountProvider, + M: MinerService { + + /// Creates new EthClient. + pub fn new(client: &Arc, accounts: &Arc, miner: &Arc) + -> Self { + EthSigningUnsafeClient { + client: Arc::downgrade(client), + miner: Arc::downgrade(miner), + accounts: Arc::downgrade(accounts), + } + } +} + +impl EthSigning for EthSigningUnsafeClient where + C: BlockChainClient + 'static, + A: AccountProvider + 'static, + M: MinerService + 'static { + + fn send_transaction(&self, params: Params) -> Result { + from_params::<(TransactionRequest, )>(params) + .and_then(|(request, )| { + let accounts = take_weak!(self.accounts); + match accounts.account_secret(&request.from) { + Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret), + Err(_) => to_value(&H256::zero()) + } + }) + } + +} diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index 979463a5d..d3b7944f7 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -28,6 +28,7 @@ macro_rules! take_weak { mod web3; mod eth; mod eth_filter; +mod eth_signing; mod net; mod personal; mod ethcore; @@ -35,8 +36,9 @@ mod traces; mod rpc; pub use self::web3::Web3Client; -pub use self::eth::{EthClient, EthSigningUnsafeClient}; +pub use self::eth::EthClient; pub use self::eth_filter::EthFilterClient; +pub use self::eth_signing::EthSigningUnsafeClient; pub use self::net::NetClient; pub use self::personal::PersonalClient; pub use self::ethcore::EthcoreClient; From 6d5ba59515ac23cad62861b66b02ec96c1c6e0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 17:07:40 +0200 Subject: [PATCH 05/38] Stubs for Personal Signer methods --- parity/main.rs | 5 +- parity/rpc_apis.rs | 11 ++- rpc/src/lib.rs | 1 + rpc/src/v1/helpers/mod.rs | 2 + .../src/v1/helpers}/signing_queue.rs | 35 ++++++---- rpc/src/v1/impls/eth_signing.rs | 28 ++++++++ rpc/src/v1/impls/mod.rs | 4 +- rpc/src/v1/impls/personal.rs | 2 +- rpc/src/v1/impls/personal_signer.rs | 69 +++++++++++++++++++ rpc/src/v1/mod.rs | 1 + rpc/src/v1/tests/mocked/eth_signing.rs | 17 +++++ rpc/src/v1/tests/mocked/personal_signer.rs | 17 +++++ rpc/src/v1/traits/mod.rs | 2 +- rpc/src/v1/traits/personal.rs | 23 +++++++ rpc/src/v1/types/transaction_request.rs | 2 +- signer/src/lib.rs | 2 - 16 files changed, 198 insertions(+), 23 deletions(-) rename {signer/src => rpc/src/v1/helpers}/signing_queue.rs (58%) create mode 100644 rpc/src/v1/impls/personal_signer.rs create mode 100644 rpc/src/v1/tests/mocked/eth_signing.rs create mode 100644 rpc/src/v1/tests/mocked/personal_signer.rs diff --git a/parity/main.rs b/parity/main.rs index 874bb35b5..5c8cc60e0 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -79,6 +79,7 @@ use std::fs::File; use std::str::{FromStr, from_utf8}; use std::thread::sleep; use std::time::Duration; +use std::collections::HashSet; use rustc_serialize::hex::FromHex; use ctrlc::CtrlC; use util::{H256, ToPretty, NetworkConfiguration, PayloadInfo, Bytes}; @@ -199,6 +200,8 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone()); let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies { + signer_enabled: conf.args.flag_signer, + signer_queue: Arc::new(Mutex::new(HashSet::new())), client: client.clone(), sync: sync.clone(), secret_store: account_service.clone(), @@ -239,7 +242,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) // Set up a signer let signer_server = signer::start(signer::Configuration { - enabled: conf.args.flag_signer, + enabled: deps_for_rpc_apis.signer_enabled, port: conf.args.flag_signer_port, }, signer::Dependencies { panic_handler: panic_handler.clone(), diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 1f1994d9e..7d6e55fee 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -26,7 +26,7 @@ use util::RotatingLogger; use util::keys::store::AccountService; use util::network_settings::NetworkSettings; -use ethcore_rpc::Extendable; +use ethcore_rpc::{SigningQueue, Extendable}; pub enum Api { Web3, @@ -61,6 +61,8 @@ impl FromStr for Api { } pub struct Dependencies { + pub signer_enabled: bool, + pub signer_queue: Arc, pub client: Arc, pub sync: Arc, pub secret_store: Arc, @@ -115,7 +117,12 @@ pub fn setup_rpc(server: T, deps: Arc, apis: Option Api::Eth => { server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); - server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); + + if deps.signer_enabled { + server.add_delegate(EthSigningQueueClient::new(&deps.signer_queue).to_delegate()); + } else { + server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); + } }, Api::Personal => { server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()) diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index a82c70af0..80ecf8b71 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -39,6 +39,7 @@ use self::jsonrpc_core::{IoHandler, IoDelegate}; pub use jsonrpc_http_server::{Server, RpcServerError}; pub mod v1; +pub use v1::SigningQueue; /// An object that can be extended with `IoDelegates` pub trait Extendable { diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index b1a5c05ba..8e5a5564d 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -16,6 +16,8 @@ mod poll_manager; mod poll_filter; +mod signing_queue; pub use self::poll_manager::PollManager; pub use self::poll_filter::PollFilter; +pub use self::signing_queue::SigningQueue; diff --git a/signer/src/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs similarity index 58% rename from signer/src/signing_queue.rs rename to rpc/src/v1/helpers/signing_queue.rs index 611d467c2..b6ab6126f 100644 --- a/signer/src/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -14,44 +14,51 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Mutex; use std::collections::HashSet; -use rpc::v1::types::TransactionRequest; +use v1::types::TransactionRequest; -pub trait SigningQueue { - fn add_request(&mut self, transaction: TransactionRequest); +/// A queue of transactions awaiting to be confirmed and signed. +pub trait SigningQueue: Send + Sync { + /// Add new request to the queue. + fn add_request(&self, transaction: TransactionRequest); - fn remove_request(&mut self, id: TransactionRequest); + /// Remove request from the queue. + fn remove_request(&self, id: TransactionRequest); - fn requests(&self) -> &HashSet; + /// Return copy of all the requests in the queue. + fn requests(&self) -> HashSet; } -impl SigningQueue for HashSet { - fn add_request(&mut self, transaction: TransactionRequest) { - self.insert(transaction); +impl SigningQueue for Mutex> { + fn add_request(&self, transaction: TransactionRequest) { + self.lock().unwrap().insert(transaction); } - fn remove_request(&mut self, id: TransactionRequest) { - self.remove(&id); + fn remove_request(&self, id: TransactionRequest) { + self.lock().unwrap().remove(&id); } - fn requests(&self) -> &HashSet { - self + fn requests(&self) -> HashSet { + let queue = self.lock().unwrap(); + queue.clone() } } #[cfg(test)] mod test { + use std::sync::Mutex; use std::collections::HashSet; use util::hash::Address; use util::numbers::U256; - use rpc::v1::types::TransactionRequest; + use v1::types::TransactionRequest; use super::*; #[test] fn should_work_for_hashset() { // given - let mut queue = HashSet::new(); + let mut queue = Mutex::new(HashSet::new()); let request = TransactionRequest { from: Address::from(1), diff --git a/rpc/src/v1/impls/eth_signing.rs b/rpc/src/v1/impls/eth_signing.rs index 9c193e1d2..2a4c845b8 100644 --- a/rpc/src/v1/impls/eth_signing.rs +++ b/rpc/src/v1/impls/eth_signing.rs @@ -22,10 +22,38 @@ use ethminer::MinerService; use ethcore::client::BlockChainClient; use util::numbers::*; use util::keys::store::AccountProvider; +use v1::helpers::SigningQueue; use v1::traits::EthSigning; use v1::types::TransactionRequest; use v1::impls::sign_and_dispatch; + +/// Implementation of functions that require signing when no trusted signer is used. +pub struct EthSigningQueueClient { + queue: Weak, +} + +impl EthSigningQueueClient { + /// Creates a new signing queue client given shared signing queue. + pub fn new(queue: &Arc) -> Self { + EthSigningQueueClient { + queue: Arc::downgrade(queue), + } + } +} + +impl EthSigning for EthSigningQueueClient { + fn send_transaction(&self, params: Params) -> Result { + from_params::<(TransactionRequest, )>(params) + .and_then(|(request, )| { + let queue = take_weak!(self.queue); + queue.add_request(request); + // TODO [ToDr] Block and wait for confirmation? + to_value(&H256::zero()) + }) + } +} + /// Implementation of functions that require signing when no trusted signer is used. pub struct EthSigningUnsafeClient where C: BlockChainClient, diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index d3b7944f7..d3a9b70a2 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -31,6 +31,7 @@ mod eth_filter; mod eth_signing; mod net; mod personal; +mod personal_signer; mod ethcore; mod traces; mod rpc; @@ -38,9 +39,10 @@ mod rpc; pub use self::web3::Web3Client; pub use self::eth::EthClient; pub use self::eth_filter::EthFilterClient; -pub use self::eth_signing::EthSigningUnsafeClient; +pub use self::eth_signing::{EthSigningUnsafeClient, EthSigningQueueClient}; pub use self::net::NetClient; pub use self::personal::PersonalClient; +pub use self::personal_signer::SignerClient; pub use self::ethcore::EthcoreClient; pub use self::traces::TracesClient; pub use self::rpc::RpcClient; diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 19e902996..30d541772 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -20,7 +20,7 @@ use jsonrpc_core::*; use v1::traits::Personal; use v1::types::TransactionRequest; use v1::impls::sign_and_dispatch; -use util::keys::store::*; +use util::keys::store::AccountProvider; use util::numbers::*; use ethcore::client::BlockChainClient; use ethminer::MinerService; diff --git a/rpc/src/v1/impls/personal_signer.rs b/rpc/src/v1/impls/personal_signer.rs new file mode 100644 index 000000000..bfb3c9eb5 --- /dev/null +++ b/rpc/src/v1/impls/personal_signer.rs @@ -0,0 +1,69 @@ +// 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 . + +//! Transactions Confirmations (personal) rpc implementation + +use std::sync::{Arc, Weak}; +use jsonrpc_core::*; +use v1::traits::SignerPersonal; +use v1::types::TransactionRequest; +use v1::impls::sign_and_dispatch; +use v1::helpers::SigningQueue; +use util::keys::store::AccountProvider; +use util::numbers::*; +use ethcore::client::BlockChainClient; +use ethminer::MinerService; + +/// Transactions confirmation (personal) rpc implementation. +pub struct SignerClient + where A: AccountProvider, C: BlockChainClient, M: MinerService { + queue: Weak, + accounts: Weak, + client: Weak, + miner: Weak, +} + +impl SignerClient + where A: AccountProvider, C: BlockChainClient, M: MinerService { + + /// Create new instance of signer client. + pub fn new(store: &Arc, client: &Arc, miner: &Arc, queue: &Arc) -> Self { + SignerClient { + queue: Arc::downgrade(queue), + accounts: Arc::downgrade(store), + client: Arc::downgrade(client), + miner: Arc::downgrade(miner), + } + } +} + +impl SignerPersonal for SignerClient + where A: AccountProvider, C: BlockChainClient, M: MinerService { + + fn transactions_to_confirm(&self, params: Params) -> Result { + let queue = take_weak!(self.queue); + to_value(&queue.requests()) + } + + fn confirm_transaction(&self, params: Params) -> Result { + Err(Error::internal_error()) + } + + fn reject_transaction(&self, params: Params) -> Result { + Err(Error::internal_error()) + } +} + diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 49f9e3a38..308e921d2 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -27,3 +27,4 @@ pub mod types; pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, Net, Ethcore, Traces, Rpc}; pub use self::impls::*; +pub use self::helpers::SigningQueue; diff --git a/rpc/src/v1/tests/mocked/eth_signing.rs b/rpc/src/v1/tests/mocked/eth_signing.rs new file mode 100644 index 000000000..05ceaf3d3 --- /dev/null +++ b/rpc/src/v1/tests/mocked/eth_signing.rs @@ -0,0 +1,17 @@ +// 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 . + + diff --git a/rpc/src/v1/tests/mocked/personal_signer.rs b/rpc/src/v1/tests/mocked/personal_signer.rs new file mode 100644 index 000000000..05ceaf3d3 --- /dev/null +++ b/rpc/src/v1/tests/mocked/personal_signer.rs @@ -0,0 +1,17 @@ +// 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 . + + diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index e5d5f3324..2355d6137 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -31,7 +31,7 @@ pub mod rpc; pub use self::web3::Web3; pub use self::eth::{Eth, EthFilter, EthSigning}; pub use self::net::Net; -pub use self::personal::Personal; +pub use self::personal::{Personal, SignerPersonal}; pub use self::ethcore::Ethcore; pub use self::traces::Traces; pub use self::rpc::Rpc; diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs index 0619d7ada..d8eb7ee75 100644 --- a/rpc/src/v1/traits/personal.rs +++ b/rpc/src/v1/traits/personal.rs @@ -43,3 +43,26 @@ pub trait Personal: Sized + Send + Sync + 'static { delegate } } + +/// Personal extension for transactions confirmations rpc interface. +pub trait SignerPersonal: Sized + Send + Sync + 'static { + + /// Returns a list of transactions to confirm. + fn transactions_to_confirm(&self, _: Params) -> Result; + + /// Confirm and send a specific transaction. + fn confirm_transaction(&self, _: Params) -> Result; + + /// Reject the transaction request. + fn reject_transaction(&self, _: Params) -> Result; + + /// Should be used to convert object to io delegate. + fn to_delegate(self) -> IoDelegate { + let mut delegate = IoDelegate::new(Arc::new(self)); + delegate.add_method("personal_transactionsToConfirm", SignerPersonal::transactions_to_confirm); + delegate.add_method("personal_confirmTransaction", SignerPersonal::confirm_transaction); + delegate.add_method("personal_rejectTransaction", SignerPersonal::reject_transaction); + delegate + } +} + diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index 1b51e6b12..276f14f07 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -21,7 +21,7 @@ use util::numbers::U256; use v1::types::bytes::Bytes; /// Transaction request coming from RPC -#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize)] +#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct TransactionRequest { /// Sender pub from: Address, diff --git a/signer/src/lib.rs b/signer/src/lib.rs index a39fe68f0..60f7e9aba 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -53,9 +53,7 @@ extern crate ethcore_rpc as rpc; extern crate jsonrpc_core; extern crate ws; -mod signing_queue; mod ws_server; - pub use ws_server::*; #[cfg(test)] From 8c3b56511ae0a45ced33e8236420bb953bc14099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 17:22:43 +0200 Subject: [PATCH 06/38] Test for EthSigningQueueClient --- rpc/src/v1/helpers/signing_queue.rs | 2 +- rpc/src/v1/tests/mocked/eth_signing.rs | 60 ++++++++++++++++++++++++++ rpc/src/v1/tests/mocked/mod.rs | 2 + 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index b6ab6126f..c7abd4924 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -58,7 +58,7 @@ mod test { #[test] fn should_work_for_hashset() { // given - let mut queue = Mutex::new(HashSet::new()); + let queue = Mutex::new(HashSet::new()); let request = TransactionRequest { from: Address::from(1), diff --git a/rpc/src/v1/tests/mocked/eth_signing.rs b/rpc/src/v1/tests/mocked/eth_signing.rs index 05ceaf3d3..07adc44b5 100644 --- a/rpc/src/v1/tests/mocked/eth_signing.rs +++ b/rpc/src/v1/tests/mocked/eth_signing.rs @@ -14,4 +14,64 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::HashSet; +use std::sync::{Arc, Mutex}; +use jsonrpc_core::IoHandler; +use v1::impls::EthSigningQueueClient; +use v1::traits::EthSigning; +use v1::helpers::SigningQueue; +use util::keys::TestAccount; +struct EthSignerTester { + pub queue: Arc, + pub io: IoHandler, +} + +impl Default for EthSignerTester { + fn default() -> Self { + let queue : Arc = Arc::new(Mutex::new(HashSet::new())); + let io = IoHandler::new(); + io.add_delegate(EthSigningQueueClient::new(&queue).to_delegate()); + + EthSignerTester { + queue: queue, + io: io, + } + } +} + +fn eth_signer() -> EthSignerTester { + EthSignerTester::default() +} + + + +#[test] +fn should_add_transaction_to_queue() { + // given + let tester = eth_signer(); + let account = TestAccount::new("123"); + let address = account.address(); + assert_eq!(tester.queue.requests().len(), 0); + + // when + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_sendTransaction", + "params": [{ + "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a" + }], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":"0x0000000000000000000000000000000000000000000000000000000000000000","id":1}"#; + + + // then + assert_eq!(tester.io.handle_request(&request), Some(response.to_owned())); + assert_eq!(tester.queue.requests().len(), 1); + +} diff --git a/rpc/src/v1/tests/mocked/mod.rs b/rpc/src/v1/tests/mocked/mod.rs index 98caf6e08..450960f78 100644 --- a/rpc/src/v1/tests/mocked/mod.rs +++ b/rpc/src/v1/tests/mocked/mod.rs @@ -17,8 +17,10 @@ //! RPC serialization tests. mod eth; +mod eth_signing; mod net; mod web3; mod personal; +mod personal_signer; mod ethcore; mod rpc; From 99f9747a3f916cc1ffa7eac1f8d8bf9b5bc94d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 18:50:00 +0200 Subject: [PATCH 07/38] TransactionConfirmation API --- rpc/src/v1/helpers/mod.rs | 2 +- rpc/src/v1/helpers/signing_queue.rs | 52 ++++--- rpc/src/v1/impls/personal_signer.rs | 36 ++++- rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/mocked/eth_signing.rs | 20 ++- rpc/src/v1/tests/mocked/personal.rs | 2 +- rpc/src/v1/tests/mocked/personal_signer.rs | 152 +++++++++++++++++++++ rpc/src/v1/traits/mod.rs | 2 +- rpc/src/v1/traits/personal.rs | 8 +- rpc/src/v1/types/mod.rs.in | 2 +- rpc/src/v1/types/transaction_request.rs | 39 ++++++ 11 files changed, 274 insertions(+), 43 deletions(-) diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index 8e5a5564d..2acf98bf2 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -20,4 +20,4 @@ mod signing_queue; pub use self::poll_manager::PollManager; pub use self::poll_filter::PollFilter; -pub use self::signing_queue::SigningQueue; +pub use self::signing_queue::{ConfirmationsQueue, SigningQueue}; diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index c7abd4924..4e26fbaf6 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -15,41 +15,57 @@ // along with Parity. If not, see . use std::sync::Mutex; -use std::collections::HashSet; -use v1::types::TransactionRequest; +use std::collections::HashMap; +use v1::types::{TransactionRequest, TransactionConfirmation}; +use util::U256; /// A queue of transactions awaiting to be confirmed and signed. pub trait SigningQueue: Send + Sync { /// Add new request to the queue. - fn add_request(&self, transaction: TransactionRequest); + fn add_request(&self, transaction: TransactionRequest) -> U256; /// Remove request from the queue. - fn remove_request(&self, id: TransactionRequest); + fn remove_request(&self, id: U256) -> Option; /// Return copy of all the requests in the queue. - fn requests(&self) -> HashSet; + fn requests(&self) -> Vec; } -impl SigningQueue for Mutex> { - fn add_request(&self, transaction: TransactionRequest) { - self.lock().unwrap().insert(transaction); +#[derive(Default)] +pub struct ConfirmationsQueue { + id: Mutex, + queue: Mutex>, +} + +impl SigningQueue for ConfirmationsQueue { + fn add_request(&self, transaction: TransactionRequest) -> U256 { + // Increment id + let id = { + let mut last_id = self.id.lock().unwrap(); + *last_id = *last_id + U256::from(1); + *last_id + }; + let mut queue = self.queue.lock().unwrap(); + queue.insert(id, TransactionConfirmation { + id: id, + transaction: transaction, + }); + id } - fn remove_request(&self, id: TransactionRequest) { - self.lock().unwrap().remove(&id); + fn remove_request(&self, id: U256) -> Option { + self.queue.lock().unwrap().remove(&id) } - fn requests(&self) -> HashSet { - let queue = self.lock().unwrap(); - queue.clone() + fn requests(&self) -> Vec { + let queue = self.queue.lock().unwrap(); + queue.values().cloned().collect() } } #[cfg(test)] mod test { - use std::sync::Mutex; - use std::collections::HashSet; use util::hash::Address; use util::numbers::U256; use v1::types::TransactionRequest; @@ -58,7 +74,7 @@ mod test { #[test] fn should_work_for_hashset() { // given - let queue = Mutex::new(HashSet::new()); + let queue = ConfirmationsQueue::default(); let request = TransactionRequest { from: Address::from(1), @@ -76,6 +92,8 @@ mod test { // then assert_eq!(all.len(), 1); - assert!(all.contains(&request)); + let el = all.get(0).unwrap(); + assert_eq!(el.id, U256::from(1)); + assert_eq!(el.transaction, request); } } diff --git a/rpc/src/v1/impls/personal_signer.rs b/rpc/src/v1/impls/personal_signer.rs index bfb3c9eb5..6afedfea9 100644 --- a/rpc/src/v1/impls/personal_signer.rs +++ b/rpc/src/v1/impls/personal_signer.rs @@ -18,8 +18,8 @@ use std::sync::{Arc, Weak}; use jsonrpc_core::*; -use v1::traits::SignerPersonal; -use v1::types::TransactionRequest; +use v1::traits::PersonalSigner; +use v1::types::TransactionModification; use v1::impls::sign_and_dispatch; use v1::helpers::SigningQueue; use util::keys::store::AccountProvider; @@ -50,20 +50,44 @@ impl SignerClient } } -impl SignerPersonal for SignerClient +impl PersonalSigner for SignerClient where A: AccountProvider, C: BlockChainClient, M: MinerService { - fn transactions_to_confirm(&self, params: Params) -> Result { + fn transactions_to_confirm(&self, _params: Params) -> Result { let queue = take_weak!(self.queue); to_value(&queue.requests()) } fn confirm_transaction(&self, params: Params) -> Result { - Err(Error::internal_error()) + from_params::<(U256, TransactionModification, String)>(params).and_then( + |(id, modification, pass)| { + let accounts = take_weak!(self.accounts); + let queue = take_weak!(self.queue); + queue.remove_request(id) + .and_then(|confirmation| { + let mut request = confirmation.transaction; + // apply modification + if let Some(gas_price) = modification.gas_price { + request.gas_price = Some(gas_price); + } + match accounts.locked_account_secret(&request.from, &pass) { + Ok(secret) => Some(sign_and_dispatch(&self.client, &self.miner, request, secret)), + Err(_) => None + } + }) + .unwrap_or_else(|| to_value(&H256::zero())) + } + ) } fn reject_transaction(&self, params: Params) -> Result { - Err(Error::internal_error()) + from_params::<(U256, )>(params).and_then( + |(id, )| { + let queue = take_weak!(self.queue); + let res = queue.remove_request(id); + to_value(&res.is_some()) + } + ) } } diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 308e921d2..deb580d2b 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -25,6 +25,6 @@ pub mod traits; pub mod tests; pub mod types; -pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, Net, Ethcore, Traces, Rpc}; +pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, PersonalSigner, Net, Ethcore, Traces, Rpc}; pub use self::impls::*; pub use self::helpers::SigningQueue; diff --git a/rpc/src/v1/tests/mocked/eth_signing.rs b/rpc/src/v1/tests/mocked/eth_signing.rs index 07adc44b5..7522fabec 100644 --- a/rpc/src/v1/tests/mocked/eth_signing.rs +++ b/rpc/src/v1/tests/mocked/eth_signing.rs @@ -14,42 +14,40 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::collections::HashSet; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use jsonrpc_core::IoHandler; use v1::impls::EthSigningQueueClient; use v1::traits::EthSigning; -use v1::helpers::SigningQueue; +use v1::helpers::{ConfirmationsQueue, SigningQueue}; use util::keys::TestAccount; -struct EthSignerTester { +struct EthSigningTester { pub queue: Arc, pub io: IoHandler, } -impl Default for EthSignerTester { +impl Default for EthSigningTester { fn default() -> Self { - let queue : Arc = Arc::new(Mutex::new(HashSet::new())); + let queue: Arc = Arc::new(ConfirmationsQueue::default()); let io = IoHandler::new(); io.add_delegate(EthSigningQueueClient::new(&queue).to_delegate()); - EthSignerTester { + EthSigningTester { queue: queue, io: io, } } } -fn eth_signer() -> EthSignerTester { - EthSignerTester::default() +fn eth_signing() -> EthSigningTester { + EthSigningTester::default() } - #[test] fn should_add_transaction_to_queue() { // given - let tester = eth_signer(); + let tester = eth_signing(); let account = TestAccount::new("123"); let address = account.address(); assert_eq!(tester.queue.requests().len(), 0); diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index 991b13cba..8bc3ab3c8 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -176,4 +176,4 @@ fn sign_and_send_transaction() { let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; assert_eq!(tester.io.handle_request(request.as_ref()), Some(response)); -} \ No newline at end of file +} diff --git a/rpc/src/v1/tests/mocked/personal_signer.rs b/rpc/src/v1/tests/mocked/personal_signer.rs index 05ceaf3d3..b6d28b986 100644 --- a/rpc/src/v1/tests/mocked/personal_signer.rs +++ b/rpc/src/v1/tests/mocked/personal_signer.rs @@ -14,4 +14,156 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; +use std::str::FromStr; +use std::collections::HashMap; +use jsonrpc_core::IoHandler; +use util::numbers::*; +use util::keys::{TestAccount, TestAccountProvider}; +use ethcore::client::TestBlockChainClient; +use ethcore::transaction::{Transaction, Action}; +use v1::{SignerClient, PersonalSigner}; +use v1::tests::helpers::TestMinerService; +use v1::helpers::{SigningQueue, ConfirmationsQueue}; +use v1::types::TransactionRequest; + + +struct PersonalSignerTester { + queue: Arc, + accounts: Arc, + io: IoHandler, + miner: Arc, + // these unused fields are necessary to keep the data alive + // as the handler has only weak pointers. + _client: Arc, +} + +fn blockchain_client() -> Arc { + let client = TestBlockChainClient::new(); + Arc::new(client) +} + +fn accounts_provider() -> Arc { + let accounts = HashMap::new(); + let ap = TestAccountProvider::new(accounts); + Arc::new(ap) +} + +fn miner_service() -> Arc { + Arc::new(TestMinerService::default()) +} + +fn signer_tester() -> PersonalSignerTester { + let queue: Arc = Arc::new(ConfirmationsQueue::default()); + let accounts = accounts_provider(); + let client = blockchain_client(); + let miner = miner_service(); + + let io = IoHandler::new(); + io.add_delegate(SignerClient::new(&accounts, &client, &miner, &queue).to_delegate()); + + PersonalSignerTester { + queue: queue, + accounts: accounts, + io: io, + miner: miner, + _client: client, + } +} + + +#[test] +fn should_return_list_of_transactions_in_queue() { + // given + let tester = signer_tester(); + tester.queue.add_request(TransactionRequest { + from: Address::from(1), + to: Some(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + gas_price: Some(U256::from(10_000)), + gas: Some(U256::from(10_000_000)), + value: Some(U256::from(1)), + data: None, + nonce: None, + }); + + // when + let request = r#"{"jsonrpc":"2.0","method":"personal_transactionsToConfirm","params":[],"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":[{"id":"0x01","transaction":{"data":null,"from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x01"}}],"id":1}"#; + + // then + assert_eq!(tester.io.handle_request(&request), Some(response.to_owned())); +} + + +#[test] +fn should_reject_transaction_from_queue_without_dispatching() { + // given + let tester = signer_tester(); + tester.queue.add_request(TransactionRequest { + from: Address::from(1), + to: Some(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + gas_price: Some(U256::from(10_000)), + gas: Some(U256::from(10_000_000)), + value: Some(U256::from(1)), + data: None, + nonce: None, + }); + assert_eq!(tester.queue.requests().len(), 1); + + // when + let request = r#"{"jsonrpc":"2.0","method":"personal_rejectTransaction","params":["0x01"],"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + // then + assert_eq!(tester.io.handle_request(&request), Some(response.to_owned())); + assert_eq!(tester.queue.requests().len(), 0); + assert_eq!(tester.miner.imported_transactions.lock().unwrap().len(), 0); +} + +#[test] +fn should_confirm_transaction_and_dispatch() { + // given + let tester = signer_tester(); + let account = TestAccount::new("test"); + let address = account.address(); + let secret = account.secret.clone(); + let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap(); + tester.accounts.accounts + .write() + .unwrap() + .insert(address, account); + tester.queue.add_request(TransactionRequest { + from: address, + to: Some(recipient), + gas_price: Some(U256::from(10_000)), + gas: Some(U256::from(10_000_000)), + value: Some(U256::from(1)), + data: None, + nonce: None, + }); + let t = Transaction { + nonce: U256::zero(), + gas_price: U256::from(0x1000), + gas: U256::from(10_000_000), + action: Action::Call(recipient), + value: U256::from(0x1), + data: vec![] + }.sign(&secret); + + assert_eq!(tester.queue.requests().len(), 1); + + // when + let request = r#"{ + "jsonrpc":"2.0", + "method":"personal_confirmTransaction", + "params":["0x01", {"gasPrice":"0x1000"}, "test"], + "id":1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; + + // then + assert_eq!(tester.io.handle_request(&request), Some(response.to_owned())); + assert_eq!(tester.queue.requests().len(), 0); + assert_eq!(tester.miner.imported_transactions.lock().unwrap().len(), 1); +} diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index 2355d6137..5384b0ef4 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -31,7 +31,7 @@ pub mod rpc; pub use self::web3::Web3; pub use self::eth::{Eth, EthFilter, EthSigning}; pub use self::net::Net; -pub use self::personal::{Personal, SignerPersonal}; +pub use self::personal::{Personal, PersonalSigner}; pub use self::ethcore::Ethcore; pub use self::traces::Traces; pub use self::rpc::Rpc; diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs index d8eb7ee75..cde66be2c 100644 --- a/rpc/src/v1/traits/personal.rs +++ b/rpc/src/v1/traits/personal.rs @@ -45,7 +45,7 @@ pub trait Personal: Sized + Send + Sync + 'static { } /// Personal extension for transactions confirmations rpc interface. -pub trait SignerPersonal: Sized + Send + Sync + 'static { +pub trait PersonalSigner: Sized + Send + Sync + 'static { /// Returns a list of transactions to confirm. fn transactions_to_confirm(&self, _: Params) -> Result; @@ -59,9 +59,9 @@ pub trait SignerPersonal: Sized + Send + Sync + 'static { /// Should be used to convert object to io delegate. fn to_delegate(self) -> IoDelegate { let mut delegate = IoDelegate::new(Arc::new(self)); - delegate.add_method("personal_transactionsToConfirm", SignerPersonal::transactions_to_confirm); - delegate.add_method("personal_confirmTransaction", SignerPersonal::confirm_transaction); - delegate.add_method("personal_rejectTransaction", SignerPersonal::reject_transaction); + delegate.add_method("personal_transactionsToConfirm", PersonalSigner::transactions_to_confirm); + delegate.add_method("personal_confirmTransaction", PersonalSigner::confirm_transaction); + delegate.add_method("personal_rejectTransaction", PersonalSigner::reject_transaction); delegate } } diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 824a061ef..b4e82a28b 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -38,7 +38,7 @@ pub use self::log::Log; pub use self::optionals::OptionalValue; pub use self::sync::{SyncStatus, SyncInfo}; pub use self::transaction::Transaction; -pub use self::transaction_request::TransactionRequest; +pub use self::transaction_request::{TransactionRequest, TransactionConfirmation, TransactionModification}; pub use self::call_request::CallRequest; pub use self::receipt::Receipt; pub use self::trace::Trace; diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index 276f14f07..93d6a479b 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -40,6 +40,24 @@ pub struct TransactionRequest { pub nonce: Option, } +/// Transaction confirmation waiting in a queue +#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Serialize)] +pub struct TransactionConfirmation { + /// Id of this confirmation + pub id: U256, + /// TransactionRequest + pub transaction: TransactionRequest, +} + +/// Possible modifications to the confirmed transaction sent by SystemUI +#[derive(Debug, PartialEq, Deserialize)] +pub struct TransactionModification { + /// Modified gas price + #[serde(rename="gasPrice")] + pub gas_price: Option, +} + + #[cfg(test)] mod tests { use std::str::FromStr; @@ -135,5 +153,26 @@ mod tests { nonce: None, }); } + + #[test] + fn should_deserialize_modification() { + // given + let s1 = r#"{ + "gasPrice":"0x0ba43b7400" + }"#; + let s2 = r#"{}"#; + + // when + let res1: TransactionModification = serde_json::from_str(s1).unwrap(); + let res2: TransactionModification = serde_json::from_str(s2).unwrap(); + + // then + assert_eq!(res1, TransactionModification { + gas_price: Some(U256::from_str("0ba43b7400").unwrap()), + }); + assert_eq!(res2, TransactionModification { + gas_price: None, + }); + } } From a7dfa83da1384cec65d888334bc5abcc4f72933f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 19:05:23 +0200 Subject: [PATCH 08/38] Exposing PersonalSigner API --- parity/main.rs | 3 +-- parity/rpc_apis.rs | 19 ++++++++++++++++--- rpc/src/lib.rs | 2 +- rpc/src/v1/helpers/signing_queue.rs | 1 + rpc/src/v1/impls/eth_signing.rs | 6 +++--- rpc/src/v1/impls/personal_signer.rs | 6 +++--- rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/mocked/eth_signing.rs | 4 ++-- rpc/src/v1/tests/mocked/personal_signer.rs | 4 ++-- 9 files changed, 30 insertions(+), 17 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 5c8cc60e0..59f08c1fe 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -79,7 +79,6 @@ use std::fs::File; use std::str::{FromStr, from_utf8}; use std::thread::sleep; use std::time::Duration; -use std::collections::HashSet; use rustc_serialize::hex::FromHex; use ctrlc::CtrlC; use util::{H256, ToPretty, NetworkConfiguration, PayloadInfo, Bytes}; @@ -201,7 +200,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies { signer_enabled: conf.args.flag_signer, - signer_queue: Arc::new(Mutex::new(HashSet::new())), + signer_queue: Arc::new(rpc_apis::ConfirmationsQueue::default()), client: client.clone(), sync: sync.clone(), secret_store: account_service.clone(), diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 7d6e55fee..4278fb060 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -26,7 +26,17 @@ use util::RotatingLogger; use util::keys::store::AccountService; use util::network_settings::NetworkSettings; -use ethcore_rpc::{SigningQueue, Extendable}; +#[cfg(feature="rpc")] +pub use ethcore_rpc::ConfirmationsQueue; +#[cfg(not(feature="rpc"))] +#[derive(Default)] +pub struct ConfirmationsQueue; + +#[cfg(feature="rpc")] +use ethcore_rpc::Extendable; + + + pub enum Api { Web3, @@ -62,7 +72,7 @@ impl FromStr for Api { pub struct Dependencies { pub signer_enabled: bool, - pub signer_queue: Arc, + pub signer_queue: Arc, pub client: Arc, pub sync: Arc, pub secret_store: Arc, @@ -125,7 +135,10 @@ pub fn setup_rpc(server: T, deps: Arc, apis: Option } }, Api::Personal => { - server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()) + server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()); + if deps.signer_enabled { + server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_queue).to_delegate()); + } }, Api::Ethcore => { server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()) diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 80ecf8b71..699ee9ba1 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -39,7 +39,7 @@ use self::jsonrpc_core::{IoHandler, IoDelegate}; pub use jsonrpc_http_server::{Server, RpcServerError}; pub mod v1; -pub use v1::SigningQueue; +pub use v1::{SigningQueue, ConfirmationsQueue}; /// An object that can be extended with `IoDelegates` pub trait Extendable { diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index 4e26fbaf6..b2e89522d 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -31,6 +31,7 @@ pub trait SigningQueue: Send + Sync { fn requests(&self) -> Vec; } +/// Queue for all unconfirmed transactions. #[derive(Default)] pub struct ConfirmationsQueue { id: Mutex, diff --git a/rpc/src/v1/impls/eth_signing.rs b/rpc/src/v1/impls/eth_signing.rs index 2a4c845b8..f4a972fb5 100644 --- a/rpc/src/v1/impls/eth_signing.rs +++ b/rpc/src/v1/impls/eth_signing.rs @@ -22,7 +22,7 @@ use ethminer::MinerService; use ethcore::client::BlockChainClient; use util::numbers::*; use util::keys::store::AccountProvider; -use v1::helpers::SigningQueue; +use v1::helpers::{SigningQueue, ConfirmationsQueue}; use v1::traits::EthSigning; use v1::types::TransactionRequest; use v1::impls::sign_and_dispatch; @@ -30,12 +30,12 @@ use v1::impls::sign_and_dispatch; /// Implementation of functions that require signing when no trusted signer is used. pub struct EthSigningQueueClient { - queue: Weak, + queue: Weak, } impl EthSigningQueueClient { /// Creates a new signing queue client given shared signing queue. - pub fn new(queue: &Arc) -> Self { + pub fn new(queue: &Arc) -> Self { EthSigningQueueClient { queue: Arc::downgrade(queue), } diff --git a/rpc/src/v1/impls/personal_signer.rs b/rpc/src/v1/impls/personal_signer.rs index 6afedfea9..cf4e927ac 100644 --- a/rpc/src/v1/impls/personal_signer.rs +++ b/rpc/src/v1/impls/personal_signer.rs @@ -21,7 +21,7 @@ use jsonrpc_core::*; use v1::traits::PersonalSigner; use v1::types::TransactionModification; use v1::impls::sign_and_dispatch; -use v1::helpers::SigningQueue; +use v1::helpers::{SigningQueue, ConfirmationsQueue}; use util::keys::store::AccountProvider; use util::numbers::*; use ethcore::client::BlockChainClient; @@ -30,7 +30,7 @@ use ethminer::MinerService; /// Transactions confirmation (personal) rpc implementation. pub struct SignerClient where A: AccountProvider, C: BlockChainClient, M: MinerService { - queue: Weak, + queue: Weak, accounts: Weak, client: Weak, miner: Weak, @@ -40,7 +40,7 @@ impl SignerClient where A: AccountProvider, C: BlockChainClient, M: MinerService { /// Create new instance of signer client. - pub fn new(store: &Arc, client: &Arc, miner: &Arc, queue: &Arc) -> Self { + pub fn new(store: &Arc, client: &Arc, miner: &Arc, queue: &Arc) -> Self { SignerClient { queue: Arc::downgrade(queue), accounts: Arc::downgrade(store), diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index deb580d2b..54628d892 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -27,4 +27,4 @@ pub mod types; pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, PersonalSigner, Net, Ethcore, Traces, Rpc}; pub use self::impls::*; -pub use self::helpers::SigningQueue; +pub use self::helpers::{SigningQueue, ConfirmationsQueue}; diff --git a/rpc/src/v1/tests/mocked/eth_signing.rs b/rpc/src/v1/tests/mocked/eth_signing.rs index 7522fabec..6eb6e3fd6 100644 --- a/rpc/src/v1/tests/mocked/eth_signing.rs +++ b/rpc/src/v1/tests/mocked/eth_signing.rs @@ -22,13 +22,13 @@ use v1::helpers::{ConfirmationsQueue, SigningQueue}; use util::keys::TestAccount; struct EthSigningTester { - pub queue: Arc, + pub queue: Arc, pub io: IoHandler, } impl Default for EthSigningTester { fn default() -> Self { - let queue: Arc = Arc::new(ConfirmationsQueue::default()); + let queue = Arc::new(ConfirmationsQueue::default()); let io = IoHandler::new(); io.add_delegate(EthSigningQueueClient::new(&queue).to_delegate()); diff --git a/rpc/src/v1/tests/mocked/personal_signer.rs b/rpc/src/v1/tests/mocked/personal_signer.rs index b6d28b986..cd1f81d9a 100644 --- a/rpc/src/v1/tests/mocked/personal_signer.rs +++ b/rpc/src/v1/tests/mocked/personal_signer.rs @@ -29,7 +29,7 @@ use v1::types::TransactionRequest; struct PersonalSignerTester { - queue: Arc, + queue: Arc, accounts: Arc, io: IoHandler, miner: Arc, @@ -54,7 +54,7 @@ fn miner_service() -> Arc { } fn signer_tester() -> PersonalSignerTester { - let queue: Arc = Arc::new(ConfirmationsQueue::default()); + let queue = Arc::new(ConfirmationsQueue::default()); let accounts = accounts_provider(); let client = blockchain_client(); let miner = miner_service(); From d4e66ba52f2f5d7cdbd98731cb8644afda708023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 19:26:01 +0200 Subject: [PATCH 09/38] Defining ApiSets dependent on context --- parity/dapps.rs | 3 +-- parity/rpc.rs | 2 +- parity/rpc_apis.rs | 30 +++++++++++++++++++++--------- parity/signer.rs | 3 +-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/parity/dapps.rs b/parity/dapps.rs index 4ea74d7f2..91742d9e3 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -84,8 +84,7 @@ pub fn setup_dapps_server( use ethcore_dapps as dapps; let server = dapps::ServerBuilder::new(); - // TODO [ToDr] Specify apis - let server = rpc_apis::setup_rpc(server, deps.apis.clone(), None); + let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext); let start_result = match auth { None => { server.start_unsecure_http(url) diff --git a/parity/rpc.rs b/parity/rpc.rs index af998ff97..66f504408 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -75,7 +75,7 @@ pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Option, deps: &Dependencies) -> Server { let apis = rpc_apis::from_str(apis); let server = Server::new(); - rpc_apis::setup_rpc(server, deps.apis.clone(), Some(apis)) + rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::List(apis)) } #[cfg(not(feature = "rpc"))] diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 4278fb060..c73a70fee 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -35,9 +35,6 @@ pub struct ConfirmationsQueue; #[cfg(feature="rpc")] use ethcore_rpc::Extendable; - - - pub enum Api { Web3, Net, @@ -47,10 +44,17 @@ pub enum Api { Traces, Rpc, } + pub enum ApiError { UnknownApi(String) } +pub enum ApiSet { + SafeContext, + UnsafeContext, + List(Vec), +} + impl FromStr for Api { type Err = ApiError; @@ -108,14 +112,22 @@ pub fn from_str(apis: Vec<&str>) -> Vec { }) } -pub fn setup_rpc(server: T, deps: Arc, apis: Option>) -> T { +fn list_apis(apis: ApiSet, signer_enabled: bool) -> Vec { + match apis { + ApiSet::List(apis) => apis, + ApiSet::UnsafeContext if signer_enabled => { + vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc] + } + _ => { + vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::Traces, Api::Rpc] + } + } +} + +pub fn setup_rpc(server: T, deps: Arc, apis: ApiSet) -> T { use ethcore_rpc::v1::*; - let apis = match apis { - Some(api) => api, - None => vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::Traces, Api::Rpc], - }; - + let apis = list_apis(apis, deps.signer_enabled); for api in &apis { match *api { Api::Web3 => { diff --git a/parity/signer.rs b/parity/signer.rs index b2224b106..d549b89cb 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -52,8 +52,7 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { let start_result = { let server = signer::ServerBuilder::new(); - // TODO [ToDr] Setup APIS - let server = rpc_apis::setup_rpc(server, deps.apis, None); + let server = rpc_apis::setup_rpc(server, deps.apis, rpc_apis::ApiSet::SafeContext); server.start(addr) }; From 1ba39538a717d4c74077d308a729a65d84b30791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 19:47:34 +0200 Subject: [PATCH 10/38] Removing types --- Cargo.lock | 5 ----- signer/Cargo.toml | 8 -------- signer/build.rs | 27 --------------------------- signer/src/lib.rs | 6 ------ signer/src/types/mod.rs | 23 ----------------------- signer/src/types/mod.rs.in | 25 ------------------------- 6 files changed, 94 deletions(-) delete mode 100644 signer/src/types/mod.rs delete mode 100644 signer/src/types/mod.rs.in diff --git a/Cargo.lock b/Cargo.lock index 7950ecc4a..62ec76bd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,12 +356,7 @@ dependencies = [ "ethcore-util 1.2.0", "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 51b1b1e8d..170c9320e 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -9,13 +9,8 @@ build = "build.rs" [build-dependencies] rustc_version = "0.1" -serde_codegen = { version = "0.7.0", optional = true } -syntex = "^0.32.0" [dependencies] -serde = "0.7.0" -serde_json = "0.7.0" -rustc-serialize = "0.3" jsonrpc-core = "2.0" log = "0.3" env_logger = "0.3" @@ -23,10 +18,7 @@ ws = "0.4.7" ethcore-util = { path = "../util" } ethcore-rpc = { path = "../rpc" } -serde_macros = { version = "0.7.0", optional = true } clippy = { version = "0.0.69", optional = true} [features] -default = ["serde_codegen"] -nightly = ["serde_macros"] dev = ["clippy"] diff --git a/signer/build.rs b/signer/build.rs index 2bcfc7da5..41b9a1b3e 100644 --- a/signer/build.rs +++ b/signer/build.rs @@ -19,34 +19,7 @@ extern crate rustc_version; use rustc_version::{version_meta, Channel}; fn main() { - serde::main(); if let Channel::Nightly = version_meta().channel { println!("cargo:rustc-cfg=nightly"); } } - -#[cfg(not(feature = "serde_macros"))] -mod serde { - extern crate syntex; - extern crate serde_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/types/mod.rs.in"); - let dst = Path::new(&out_dir).join("mod.rs"); - - let mut registry = syntex::Registry::new(); - - serde_codegen::register(&mut registry); - registry.expand("", &src, &dst).unwrap(); - } -} - -#[cfg(feature = "serde_macros")] -mod serde { - pub fn main() {} -} diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 60f7e9aba..74018d9b1 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -17,8 +17,6 @@ #![warn(missing_docs)] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] -// Generated by serde -#![cfg_attr(all(nightly, feature="dev"), allow(redundant_closure_call))] //! Signer module //! @@ -44,10 +42,6 @@ extern crate log; extern crate env_logger; -extern crate serde; -extern crate serde_json; -extern crate rustc_serialize; - extern crate ethcore_util as util; extern crate ethcore_rpc as rpc; extern crate jsonrpc_core; diff --git a/signer/src/types/mod.rs b/signer/src/types/mod.rs deleted file mode 100644 index d5e15046a..000000000 --- a/signer/src/types/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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 . - -//! Reusable types with JSON Serialization. - -#[cfg(feature = "serde_macros")] -include!("mod.rs.in"); - -#[cfg(not(feature = "serde_macros"))] -include!(concat!(env!("OUT_DIR"), "/mod.rs")); diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in deleted file mode 100644 index a59f81ece..000000000 --- a/signer/src/types/mod.rs.in +++ /dev/null @@ -1,25 +0,0 @@ -// 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 . - - - - - - - - - -// TODO [ToDr] Types are empty for now. But they are about to come. From ba296408d54245110c450a9193d755ea77b004f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 30 May 2016 18:50:11 +0200 Subject: [PATCH 11/38] Supporting sending notification to WS connected SystemUIs --- rpc/src/v1/helpers/signing_queue.rs | 271 +++++++++++++++++++++++++--- rpc/src/v1/impls/eth.rs | 2 +- rpc/src/v1/impls/eth_signing.rs | 8 +- rpc/src/v1/impls/mod.rs | 12 +- rpc/src/v1/impls/personal.rs | 2 +- rpc/src/v1/impls/personal_signer.rs | 18 +- 6 files changed, 273 insertions(+), 40 deletions(-) diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index b2e89522d..65aef8a33 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -14,10 +14,34 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::sync::Mutex; +use std::thread; +use std::time::{Instant, Duration}; +use std::sync::{mpsc, Mutex, RwLock}; use std::collections::HashMap; use v1::types::{TransactionRequest, TransactionConfirmation}; -use util::U256; +use util::{U256, H256}; + + +/// Messages that queue informs about +#[derive(Debug, PartialEq)] +pub enum QueueMessage { + /// Receiver should stop work upon receiving `Finish` message. + Finish, + /// Informs about new transaction request. + NewRequest(U256), +} + +/// Defines possible errors returned from queue receiving method. +#[derive(Debug, PartialEq)] +pub enum QueueError { + /// Returned when method has been already used (no receiver available). + AlreadyUsed, + /// Returned when receiver encounters an error. + ReceiverError(mpsc::RecvError), +} + +/// Message Receiver type +pub type QueueMessageReceiver = mpsc::Receiver; /// A queue of transactions awaiting to be confirmed and signed. pub trait SigningQueue: Send + Sync { @@ -25,17 +49,106 @@ pub trait SigningQueue: Send + Sync { fn add_request(&self, transaction: TransactionRequest) -> U256; /// Remove request from the queue. - fn remove_request(&self, id: U256) -> Option; + /// Notify possible waiters that transaction was rejected. + fn request_rejected(&self, id: U256) -> Option; + + /// Remove request from the queue. + /// Notify possible waiters that transaction was confirmed and got given hash. + fn request_confirmed(&self, id: U256, hash: H256) -> Option; + + /// Returns a request if it is contained in the queue. + fn peek(&self, id: &U256) -> Option; /// Return copy of all the requests in the queue. fn requests(&self) -> Vec; + + /// Blocks for some time waiting for confirmation. + /// Returns `None` when timeout reached or transaction was rejected. + /// Returns transaction hash when transaction was confirmed. + fn wait_with_timeout(&self, id: U256) -> Option; +} + +/// Time you need to confirm the transaction in UI. +/// Unless we have a multi-threaded RPC this will lock +/// any other incoming call! +const QUEUE_TIMEOUT_DURATION_SEC : u64 = 20; + +#[derive(Debug, Clone)] +enum QueueStatus { + Waiting, + Rejected, + Confirmed(H256), } /// Queue for all unconfirmed transactions. -#[derive(Default)] pub struct ConfirmationsQueue { id: Mutex, - queue: Mutex>, + waiters: RwLock>, + queue: RwLock>, + sender: Mutex>, + receiver: Mutex>>, +} + +impl Default for ConfirmationsQueue { + fn default() -> Self { + let (send, recv) = mpsc::channel(); + + ConfirmationsQueue { + id: Mutex::new(U256::from(0)), + waiters: RwLock::new(HashMap::new()), + queue: RwLock::new(HashMap::new()), + sender: Mutex::new(send), + receiver: Mutex::new(Some(recv)), + } + } +} + +impl ConfirmationsQueue { + /// Blocks the thread and starts listening for notifications. + /// For each event `listener` callback function will be invoked. + /// This method can be used only once. + pub fn start_listening(&self, listener: F) -> Result<(), QueueError> + where F: Fn(QueueMessage) -> () { + let recv = self.receiver.lock().unwrap().take(); + if let None = recv { + return Err(QueueError::AlreadyUsed); + } + let recv = recv.expect("Check for none is done earlier."); + + loop { + let message = try!(recv.recv().map_err(|e| QueueError::ReceiverError(e))); + if let QueueMessage::Finish = message { + return Ok(()); + } + + listener(message); + } + } + + /// Notifies receiver that the communcation is over. + pub fn finish(&self) { + self.notify(QueueMessage::Finish); + } + + fn notify(&self, message: QueueMessage) { + // We don't really care about the result + let _ = self.sender.lock().unwrap().send(message); + } + + fn remove(&self, id: U256) -> Option { + self.queue.write().unwrap().remove(&id) + } + + fn update_status(&self, id: U256, status: QueueStatus) { + let mut waiters = self.waiters.write().unwrap(); + waiters.insert(id, status); + } +} + +impl Drop for ConfirmationsQueue { + fn drop(&mut self) { + self.finish(); + } } impl SigningQueue for ConfirmationsQueue { @@ -46,38 +159,98 @@ impl SigningQueue for ConfirmationsQueue { *last_id = *last_id + U256::from(1); *last_id }; - let mut queue = self.queue.lock().unwrap(); - queue.insert(id, TransactionConfirmation { - id: id, - transaction: transaction, - }); + // Add request to queue + { + let mut queue = self.queue.write().unwrap(); + queue.insert(id, TransactionConfirmation { + id: id, + transaction: transaction, + }); + } + // Notify listeners + self.notify(QueueMessage::NewRequest(id)); id } - fn remove_request(&self, id: U256) -> Option { - self.queue.lock().unwrap().remove(&id) + fn peek(&self, id: &U256) -> Option { + self.queue.read().unwrap().get(id).cloned() + } + + fn request_rejected(&self, id: U256) -> Option { + let o = self.remove(id); + self.update_status(id, QueueStatus::Rejected); + o + } + + fn request_confirmed(&self, id: U256, hash: H256) -> Option { + let o = self.remove(id); + self.update_status(id, QueueStatus::Confirmed(hash)); + o } fn requests(&self) -> Vec { - let queue = self.queue.lock().unwrap(); + let queue = self.queue.read().unwrap(); queue.values().cloned().collect() } + + fn wait_with_timeout(&self, id: U256) -> Option { + { + let mut waiters = self.waiters.write().unwrap(); + let r = waiters.insert(id, QueueStatus::Waiting); + match r { + // This is ok, we can have many waiters + Some(QueueStatus::Waiting) | None => {}, + // There already was a response for someone. + // The one waiting for it will cleanup, so... + Some(v) => { + // ... insert old status back + waiters.insert(id, v.clone()); + if let QueueStatus::Confirmed(h) = v { + return Some(h); + } + return None; + }, + } + } + + // Now wait for a response + let deadline = Instant::now() + Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC); + while Instant::now() < deadline { + let status = { + let waiters = self.waiters.read().unwrap(); + waiters.get(&id).expect("Only the waiting thread can remove any message.").clone() + }; + + match status { + QueueStatus::Waiting => thread::sleep(Duration::from_millis(50)), + QueueStatus::Confirmed(h) => { + self.waiters.write().unwrap().remove(&id); + return Some(h); + }, + QueueStatus::Rejected => { + self.waiters.write().unwrap().remove(&id); + return None; + }, + } + } + // We reached the timeout. Just return `None` + None + } } #[cfg(test)] mod test { + use std::time::Duration; + use std::thread; + use std::sync::{Arc, Mutex}; use util::hash::Address; - use util::numbers::U256; + use util::numbers::{U256, H256}; use v1::types::TransactionRequest; use super::*; - #[test] - fn should_work_for_hashset() { - // given - let queue = ConfirmationsQueue::default(); - - let request = TransactionRequest { + fn request() -> TransactionRequest { + TransactionRequest { from: Address::from(1), to: Some(Address::from(2)), gas_price: None, @@ -85,7 +258,63 @@ mod test { value: Some(U256::from(10_000_000)), data: None, nonce: None, - }; + } + } + + #[test] + fn should_wait_for_hash() { + // given + let queue = Arc::new(ConfirmationsQueue::default()); + let request = request(); + + // when + let q = queue.clone(); + let handle = thread::spawn(move || { + let v = q.add_request(request); + q.wait_with_timeout(v).expect("Should return hash") + }); + + let id = U256::from(1); + while queue.peek(&id).is_none() { + // Just wait for the other thread to start + thread::sleep(Duration::from_millis(100)); + } + queue.request_confirmed(id, H256::from(1)); + + // then + assert_eq!(handle.join().expect("Thread should finish nicely"), H256::from(1)); + } + + #[test] + fn should_receive_notification() { + // given + let received = Arc::new(Mutex::new(None)); + let queue = Arc::new(ConfirmationsQueue::default()); + let request = request(); + + // when + let q = queue.clone(); + let r = received.clone(); + let handle = thread::spawn(move || { + q.start_listening(move |notification| { + let mut v = r.lock().unwrap(); + *v = Some(notification); + }).expect("Should be closed nicely.") + }); + let v = queue.add_request(request); + queue.finish(); + + // then + handle.join().expect("Thread should finish nicely"); + let r = received.lock().unwrap().take(); + assert_eq!(r, Some(QueueMessage::NewRequest(v))); + } + + #[test] + fn should_add_transactions() { + // given + let queue = ConfirmationsQueue::default(); + let request = request(); // when queue.add_request(request.clone()); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index f7c34ffa7..44bdef243 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -497,7 +497,7 @@ impl Eth for EthClient where .and_then(|(raw_transaction, )| { let raw_transaction = raw_transaction.to_vec(); match UntrustedRlp::new(&raw_transaction).as_val() { - Ok(signed_transaction) => dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction), + Ok(signed_transaction) => to_value(&dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction)), Err(_) => to_value(&H256::zero()), } }) diff --git a/rpc/src/v1/impls/eth_signing.rs b/rpc/src/v1/impls/eth_signing.rs index f4a972fb5..2ecc00f05 100644 --- a/rpc/src/v1/impls/eth_signing.rs +++ b/rpc/src/v1/impls/eth_signing.rs @@ -47,9 +47,9 @@ impl EthSigning for EthSigningQueueClient { from_params::<(TransactionRequest, )>(params) .and_then(|(request, )| { let queue = take_weak!(self.queue); - queue.add_request(request); - // TODO [ToDr] Block and wait for confirmation? - to_value(&H256::zero()) + let id = queue.add_request(request); + let result = queue.wait_with_timeout(id); + to_value(&result.unwrap_or_else(H256::new)) }) } } @@ -90,7 +90,7 @@ impl EthSigning for EthSigningUnsafeClient where .and_then(|(request, )| { let accounts = take_weak!(self.accounts); match accounts.account_secret(&request.from) { - Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret), + Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)), Err(_) => to_value(&H256::zero()) } }) diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index d3a9b70a2..4bf5c88e7 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -48,16 +48,14 @@ pub use self::traces::TracesClient; pub use self::rpc::RpcClient; use v1::types::TransactionRequest; -use std::sync::Weak; use ethminer::{AccountDetails, MinerService}; use ethcore::client::BlockChainClient; use ethcore::transaction::{Action, SignedTransaction, Transaction}; use util::numbers::*; use util::rlp::encode; use util::bytes::ToPretty; -use jsonrpc_core::{Error, to_value, Value}; -fn dispatch_transaction(client: &C, miner: &M, signed_transaction: SignedTransaction) -> Result +fn dispatch_transaction(client: &C, miner: &M, signed_transaction: SignedTransaction) -> H256 where C: BlockChainClient, M: MinerService { let hash = signed_transaction.hash(); @@ -71,18 +69,16 @@ fn dispatch_transaction(client: &C, miner: &M, signed_transaction: SignedT }; match import { - Ok(_) => to_value(&hash), + Ok(_) => hash, Err(e) => { warn!("Error sending transaction: {:?}", e); - to_value(&H256::zero()) + H256::zero() } } } -fn sign_and_dispatch(client: &Weak, miner: &Weak, request: TransactionRequest, secret: H256) -> Result +fn sign_and_dispatch(client: &C, miner: &M, request: TransactionRequest, secret: H256) -> H256 where C: BlockChainClient, M: MinerService { - let client = take_weak!(client); - let miner = take_weak!(miner); let signed_transaction = { Transaction { diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 30d541772..4a419f1e3 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -83,7 +83,7 @@ impl Personal for PersonalClient .and_then(|(request, password)| { let accounts = take_weak!(self.accounts); match accounts.locked_account_secret(&request.from, &password) { - Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret), + Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)), Err(_) => to_value(&H256::zero()), } }) diff --git a/rpc/src/v1/impls/personal_signer.rs b/rpc/src/v1/impls/personal_signer.rs index cf4e927ac..9fd197db2 100644 --- a/rpc/src/v1/impls/personal_signer.rs +++ b/rpc/src/v1/impls/personal_signer.rs @@ -63,19 +63,27 @@ impl PersonalSigner for SignerClient Some(sign_and_dispatch(&self.client, &self.miner, request, secret)), + Ok(secret) => { + let hash = sign_and_dispatch(&*client, &*miner, request, secret); + queue.request_confirmed(id, hash); + Some(to_value(&hash)) + }, Err(_) => None } }) - .unwrap_or_else(|| to_value(&H256::zero())) + .unwrap_or_else(|| { + queue.request_rejected(id); + to_value(&H256::zero()) + }) } ) } @@ -84,7 +92,7 @@ impl PersonalSigner for SignerClient(params).and_then( |(id, )| { let queue = take_weak!(self.queue); - let res = queue.remove_request(id); + let res = queue.request_rejected(id); to_value(&res.is_some()) } ) From 84882922b462559378ac7a551d7d19bad550ce69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 30 May 2016 19:30:16 +0200 Subject: [PATCH 12/38] Sending a notification on every new messages --- parity/signer.rs | 2 +- signer/src/ws_server/mod.rs | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/parity/signer.rs b/parity/signer.rs index d549b89cb..978e4e636 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -51,7 +51,7 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { }); let start_result = { - let server = signer::ServerBuilder::new(); + let server = signer::ServerBuilder::new(daps.apis.signer_queue.clone()); let server = rpc_apis::setup_rpc(server, deps.apis, rpc_apis::ApiSet::SafeContext); server.start(addr) }; diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index bc8fb33f8..910c1af85 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -25,7 +25,7 @@ use std::sync::Arc; use std::net::SocketAddr; use util::panics::{PanicHandler, OnPanicListener, MayPanic}; use jsonrpc_core::{IoHandler, IoDelegate}; -use rpc::Extendable; +use rpc::{Extendable, ConfirmationsQueue}; mod session; @@ -49,15 +49,10 @@ impl From for ServerError { /// Builder for `WebSockets` server pub struct ServerBuilder { + queue: Arc, handler: Arc, } -impl Default for ServerBuilder { - fn default() -> Self { - ServerBuilder::new() - } -} - impl Extendable for ServerBuilder { fn add_delegate(&self, delegate: IoDelegate) { self.handler.add_delegate(delegate); @@ -66,30 +61,40 @@ impl Extendable for ServerBuilder { impl ServerBuilder { /// Creates new `ServerBuilder` - pub fn new() -> Self { + pub fn new(queue: Arc) -> Self { ServerBuilder { - handler: Arc::new(IoHandler::new()) + queue: queue, + handler: Arc::new(IoHandler::new()), } } /// Starts a new `WebSocket` server in separate thread. /// Returns a `Server` handle which closes the server when droped. pub fn start(self, addr: SocketAddr) -> Result { - Server::start(addr, self.handler) + Server::start(addr, self.handler).and_then(|(server, broadcaster)| { + // Fire up queue notifications broadcasting + let queue = self.queue.clone(); + thread::spawn(move || { + queue.start_listening(|_message| { + broadcaster.send("new_message").unwrap(); + }).expect("It's the only place we are running start_listening. It shouldn't fail."); + }).expect("We should be able to create the thread"); + + Ok(server) + }) } } /// `WebSockets` server implementation. pub struct Server { handle: Option>>, - broadcaster: ws::Sender, panic_handler: Arc, } impl Server { /// Starts a new `WebSocket` server in separate thread. /// Returns a `Server` handle which closes the server when droped. - pub fn start(addr: SocketAddr, handler: Arc) -> Result { + fn start(addr: SocketAddr, handler: Arc) -> Result<(Server, ws::Sender), ServerError> { let config = { let mut config = ws::Settings::default(); config.max_connections = 5; @@ -111,11 +116,10 @@ impl Server { }); // Return a handle - Ok(Server { + Ok((Server { handle: Some(handle), - broadcaster: broadcaster, panic_handler: panic_handler, - }) + }, broadcaster)) } } @@ -127,7 +131,6 @@ impl MayPanic for Server { impl Drop for Server { fn drop(&mut self) { - self.broadcaster.shutdown().expect("WsServer should close nicely."); self.handle.take().unwrap().join().unwrap(); } } From b4bc395c6efd85bae818fffcb64c73462231172a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 30 May 2016 20:23:19 +0200 Subject: [PATCH 13/38] Adding logs to signing queue --- parity/signer.rs | 2 +- rpc/src/v1/helpers/signing_queue.rs | 8 ++++++- signer/src/lib.rs | 8 +++++-- signer/src/ws_server/mod.rs | 37 ++++++++++++++++++----------- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/parity/signer.rs b/parity/signer.rs index 978e4e636..a7de993fb 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -51,7 +51,7 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { }); let start_result = { - let server = signer::ServerBuilder::new(daps.apis.signer_queue.clone()); + let server = signer::ServerBuilder::new(deps.apis.signer_queue.clone()); let server = rpc_apis::setup_rpc(server, deps.apis, rpc_apis::ApiSet::SafeContext); server.start(addr) }; diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index 65aef8a33..b0625b170 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -166,6 +166,7 @@ impl SigningQueue for ConfirmationsQueue { id: id, transaction: transaction, }); + debug!(target: "own_tx", "Signer: New transaction ({:?}) in confirmation queue.", id); } // Notify listeners self.notify(QueueMessage::NewRequest(id)); @@ -177,12 +178,14 @@ impl SigningQueue for ConfirmationsQueue { } fn request_rejected(&self, id: U256) -> Option { + debug!(target: "own_tx", "Signer: Transaction rejected ({:?}).", id); let o = self.remove(id); self.update_status(id, QueueStatus::Rejected); o } fn request_confirmed(&self, id: U256, hash: H256) -> Option { + debug!(target: "own_tx", "Signer: Transaction confirmed ({:?}).", id); let o = self.remove(id); self.update_status(id, QueueStatus::Confirmed(hash)); o @@ -213,6 +216,7 @@ impl SigningQueue for ConfirmationsQueue { } } + info!(target: "own_tx", "Signer: Awaiting transaction confirmation... ({:?}).", id); // Now wait for a response let deadline = Instant::now() + Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC); while Instant::now() < deadline { @@ -233,7 +237,9 @@ impl SigningQueue for ConfirmationsQueue { }, } } - // We reached the timeout. Just return `None` + // We reached the timeout. Just return `None` and make sure to remove waiting. + trace!(target: "own_tx", "Signer: Confirmation timeout reached... ({:?}).", id); + self.waiters.write().unwrap().remove(&id); None } } diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 74018d9b1..8391d42b4 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -30,11 +30,15 @@ //! //! ``` //! extern crate ethcore_signer; +//! extern crate ethcore_rpc; //! -//! use ethcore_signer::Server; +//! use std::sync::Arc; +//! use ethcore_signer::ServerBuilder; +//! use ethcore_rpc::ConfirmationsQueue; //! //! fn main() { -//! let _server = Server::start("127.0.0.1:8084".parse().unwrap()); +//! let queue = Arc::new(ConfirmationsQueue::default()); +//! let _server = ServerBuilder::new(queue).start("127.0.0.1:8084".parse().unwrap()); //! } //! ``` diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index 910c1af85..0a4499af8 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -71,30 +71,22 @@ impl ServerBuilder { /// Starts a new `WebSocket` server in separate thread. /// Returns a `Server` handle which closes the server when droped. pub fn start(self, addr: SocketAddr) -> Result { - Server::start(addr, self.handler).and_then(|(server, broadcaster)| { - // Fire up queue notifications broadcasting - let queue = self.queue.clone(); - thread::spawn(move || { - queue.start_listening(|_message| { - broadcaster.send("new_message").unwrap(); - }).expect("It's the only place we are running start_listening. It shouldn't fail."); - }).expect("We should be able to create the thread"); - - Ok(server) - }) + Server::start(addr, self.handler, self.queue) } } /// `WebSockets` server implementation. pub struct Server { handle: Option>>, + broadcaster_handle: Option>, + queue: Arc, panic_handler: Arc, } impl Server { /// Starts a new `WebSocket` server in separate thread. /// Returns a `Server` handle which closes the server when droped. - fn start(addr: SocketAddr, handler: Arc) -> Result<(Server, ws::Sender), ServerError> { + fn start(addr: SocketAddr, handler: Arc, queue: Arc) -> Result { let config = { let mut config = ws::Settings::default(); config.max_connections = 5; @@ -108,6 +100,7 @@ impl Server { let panic_handler = PanicHandler::new_in_arc(); let ph = panic_handler.clone(); let broadcaster = ws.broadcaster(); + // Spawn a thread with event loop let handle = thread::spawn(move || { ph.catch_panic(move || { @@ -115,11 +108,25 @@ impl Server { }).unwrap() }); + // Spawn a thread for broadcasting + let ph = panic_handler.clone(); + let q = queue.clone(); + let broadcaster_handle = thread::spawn(move || { + ph.catch_panic(move || { + q.start_listening(|_message| { + // TODO [ToDr] Some better structure here for messages. + broadcaster.send("new_message").unwrap(); + }).expect("It's the only place we are running start_listening. It shouldn't fail.") + }).unwrap() + }); + // Return a handle - Ok((Server { + Ok(Server { handle: Some(handle), + broadcaster_handle: Some(broadcaster_handle), + queue: queue, panic_handler: panic_handler, - }, broadcaster)) + }) } } @@ -131,6 +138,8 @@ impl MayPanic for Server { impl Drop for Server { fn drop(&mut self) { + self.queue.finish(); + self.broadcaster_handle.take().unwrap().join().unwrap(); self.handle.take().unwrap().join().unwrap(); } } From baa2f7c5bbf55a4d929d3d63fc6a7afbba6d1eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 30 May 2016 20:39:20 +0200 Subject: [PATCH 14/38] Shutting down broadcaster --- signer/src/ws_server/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index 0a4499af8..c987d7a87 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -116,7 +116,8 @@ impl Server { q.start_listening(|_message| { // TODO [ToDr] Some better structure here for messages. broadcaster.send("new_message").unwrap(); - }).expect("It's the only place we are running start_listening. It shouldn't fail.") + }).expect("It's the only place we are running start_listening. It shouldn't fail."); + broadcaster.shutdown().expect("Broadcaster should close gently.") }).unwrap() }); From 4d29508b4c6ca8bf8874e5a3afbea26dd6505a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 31 May 2016 20:12:47 +0200 Subject: [PATCH 15/38] Minimal System UI --- Cargo.lock | 41 +++++++++++++++++++++++++++++---- signer/Cargo.toml | 3 ++- signer/src/lib.rs | 1 + signer/src/ws_server/mod.rs | 2 +- signer/src/ws_server/session.rs | 23 ++++++++++++++++++ 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c81020f66..c2d455efe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,8 +358,9 @@ dependencies = [ "ethcore-util 1.2.0", "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-minimal-sysui 0.1.0", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.4.6 (git+https://github.com/ethcore/ws-rs.git)", ] [[package]] @@ -701,6 +702,22 @@ dependencies = [ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio" +version = "0.5.0" +source = "git+https://github.com/carllerche/mio.git#f4aa49a9d2c4507fb33a4533d5238e0365f67c99" +dependencies = [ + "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.5.0-pre (git+https://github.com/carllerche/nix-rust?rev=c4257f8a76)", + "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio" version = "0.5.1" @@ -758,6 +775,15 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nix" +version = "0.5.0-pre" +source = "git+https://github.com/carllerche/nix-rust?rev=c4257f8a76#c4257f8a76b69b0d2e9a001d83e4bef67c03b23f" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nix" version = "0.5.0" @@ -921,6 +947,10 @@ dependencies = [ "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", ] +[[package]] +name = "parity-minimal-sysui" +version = "0.1.0" + [[package]] name = "phf" version = "0.7.14" @@ -1426,15 +1456,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ws" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.4.6" +source = "git+https://github.com/ethcore/ws-rs.git#c0c2a3fc30dc77c4e6d4d90756f8bc3b5cfbc311" dependencies = [ "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.5.0 (git+https://github.com/carllerche/mio.git)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 170c9320e..6b9f2036f 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -14,9 +14,10 @@ rustc_version = "0.1" jsonrpc-core = "2.0" log = "0.3" env_logger = "0.3" -ws = "0.4.7" +ws = { git = "https://github.com/ethcore/ws-rs.git" } ethcore-util = { path = "../util" } ethcore-rpc = { path = "../rpc" } +parity-minimal-sysui = { path = "../../parity-dapps-minimal-sysui-rs" } clippy = { version = "0.0.69", optional = true} diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 8391d42b4..fb3e76cca 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -50,6 +50,7 @@ extern crate ethcore_util as util; extern crate ethcore_rpc as rpc; extern crate jsonrpc_core; extern crate ws; +extern crate parity_minimal_sysui as sysui; mod ws_server; pub use ws_server::*; diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index c987d7a87..0d55fd906 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -89,7 +89,7 @@ impl Server { fn start(addr: SocketAddr, handler: Arc, queue: Arc) -> Result { let config = { let mut config = ws::Settings::default(); - config.max_connections = 5; + config.max_connections = 10; config.method_strict = true; config }; diff --git a/signer/src/ws_server/session.rs b/signer/src/ws_server/session.rs index 258e05d5b..02850e739 100644 --- a/signer/src/ws_server/session.rs +++ b/signer/src/ws_server/session.rs @@ -17,6 +17,7 @@ //! Session handlers factory. use ws; +use sysui; use std::sync::Arc; use jsonrpc_core::IoHandler; @@ -26,6 +27,28 @@ pub struct Session { } impl ws::Handler for Session { + fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> { + // Detect if it's a websocket request. + if req.header("sec-websocket-key").is_some() { + return ws::Response::from_request(req); + } + + // Otherwise try to serve a page. + sysui::handle(req.resource()) + .map(|f| { + let content_len = format!("{}", f.content.as_bytes().len()); + let mut res = ws::Response::ok(f.content.into()); + { + let mut headers = res.headers_mut(); + headers.push(("Server".into(), "Parity/SystemUI".as_bytes().to_vec())); + headers.push(("Connection".into(), "Closed".as_bytes().to_vec())); + headers.push(("Content-Length".into(), content_len.as_bytes().to_vec())); + headers.push(("Content-Type".into(), f.mime.as_bytes().to_vec())); + } + Ok(res) + }).unwrap_or_else(|| ws::Response::from_request(req)) + } + fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> { let req = try!(msg.as_text()); match self.handler.handle_request(req) { From ed0d60bc16b7118a3d461912eb27dbedbca6d61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 31 May 2016 20:21:46 +0200 Subject: [PATCH 16/38] Fixing clippy warnings --- signer/src/ws_server/session.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/signer/src/ws_server/session.rs b/signer/src/ws_server/session.rs index 02850e739..442a44317 100644 --- a/signer/src/ws_server/session.rs +++ b/signer/src/ws_server/session.rs @@ -35,18 +35,22 @@ impl ws::Handler for Session { // Otherwise try to serve a page. sysui::handle(req.resource()) - .map(|f| { - let content_len = format!("{}", f.content.as_bytes().len()); - let mut res = ws::Response::ok(f.content.into()); - { - let mut headers = res.headers_mut(); - headers.push(("Server".into(), "Parity/SystemUI".as_bytes().to_vec())); - headers.push(("Connection".into(), "Closed".as_bytes().to_vec())); - headers.push(("Content-Length".into(), content_len.as_bytes().to_vec())); - headers.push(("Content-Type".into(), f.mime.as_bytes().to_vec())); - } - Ok(res) - }).unwrap_or_else(|| ws::Response::from_request(req)) + .map_or_else( + // return error + || ws::Response::from_request(req), + // or serve the file + |f| { + let content_len = format!("{}", f.content.as_bytes().len()); + let mut res = ws::Response::ok(f.content.into()); + { + let mut headers = res.headers_mut(); + headers.push(("Server".into(), b"Parity/SystemUI".to_vec())); + headers.push(("Connection".into(), b"Closed".to_vec())); + headers.push(("Content-Length".into(), content_len.as_bytes().to_vec())); + headers.push(("Content-Type".into(), f.mime.as_bytes().to_vec())); + } + Ok(res) + }) } fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> { From 1fd91108291613776963475db539c2e61077ee5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 1 Jun 2016 17:59:21 +0200 Subject: [PATCH 17/38] Serde bump --- Cargo.lock | 116 ++++++++++++++++++----------------------- Cargo.toml | 4 +- dapps/Cargo.toml | 6 +-- db/Cargo.toml | 2 +- ipc/codegen/Cargo.toml | 14 ++--- ipc/nano/Cargo.toml | 4 +- ipc/tests/Cargo.toml | 4 +- json/Cargo.toml | 2 +- rpc/Cargo.toml | 9 ++-- signer/Cargo.toml | 10 +--- 10 files changed, 74 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc2a8ef8c..a686b849e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ "ethsync 1.2.0", "fdlimit 0.1.0", "hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "json-ipc-server 0.1.0 (git+https://github.com/ethcore/json-ipc-server.git)", + "json-ipc-server 0.1.0 (git+https://github.com/tomusdrw/json-ipc-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -29,7 +29,7 @@ dependencies = [ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -57,10 +57,10 @@ dependencies = [ [[package]] name = "aster" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -257,7 +257,7 @@ dependencies = [ "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -269,8 +269,8 @@ dependencies = [ "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", + "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-http-server 5.1.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", "parity-dapps-builtins 0.5.0 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)", @@ -280,9 +280,9 @@ dependencies = [ "parity-dapps-wallet 0.5.0 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -307,11 +307,11 @@ dependencies = [ name = "ethcore-ipc-codegen" version = "1.2.0" dependencies = [ - "aster 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_codegen 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -319,7 +319,7 @@ name = "ethcore-ipc-nano" version = "1.2.0" dependencies = [ "ethcore-ipc 1.2.0", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", ] @@ -336,15 +336,15 @@ dependencies = [ "ethjson 0.1.0", "ethminer 1.2.0", "ethsync 1.2.0", - "json-ipc-server 0.1.0 (git+https://github.com/ethcore/json-ipc-server.git)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git?branch=multiple_cors_domains)", + "json-ipc-server 0.1.0 (git+https://github.com/tomusdrw/json-ipc-server.git)", + "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-http-server 5.1.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -356,14 +356,9 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -410,9 +405,9 @@ dependencies = [ "ethcore-util 1.2.0", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -579,10 +574,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "json-ipc-server" version = "0.1.0" -source = "git+https://github.com/ethcore/json-ipc-server.git#4f9226c4f84dcce2385a188374e3b5fc66b63e68" +source = "git+https://github.com/tomusdrw/json-ipc-server.git#7b632a7663c0cf109c914370840d795ebb0a6103" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -598,31 +593,20 @@ dependencies = [ [[package]] name = "jsonrpc-core" version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/ethcore/jsonrpc-core.git#a1e871c7555bded9229dd7651de64a265231181f" dependencies = [ "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" version = "5.1.0" -source = "git+https://github.com/ethcore/jsonrpc-http-server.git#12f23b0cd85013ca980240b9d0206bf1fc9c909e" dependencies = [ "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-http-server" -version = "5.1.0" -source = "git+https://github.com/ethcore/jsonrpc-http-server.git?branch=multiple_cors_domains#9c026feeb6573c82c99c8005c5d8244de68a2e30" -dependencies = [ - "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -875,15 +859,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parity-dapps" version = "0.3.0" -source = "git+https://github.com/ethcore/parity-dapps-rs.git#01ff8c2a3e61ea436f0d47acbbb8ac4bea4cd234" +source = "git+https://github.com/ethcore/parity-dapps-rs.git#1f065d93aa49338e4a453c77c839957f2db78895" dependencies = [ - "aster 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_codegen 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1003,20 +987,20 @@ dependencies = [ [[package]] name = "quasi" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quasi_codegen" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aster 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1158,14 +1142,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_codegen" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aster 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_codegen 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1218,15 +1202,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syntex" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syntex_syntax" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index d7813468a..456409ba7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ build = "build.rs" [build-dependencies] rustc_version = "0.1" syntex = "*" -"ethcore-ipc-codegen" = { path = "ipc/codegen" } +ethcore-ipc-codegen = { path = "ipc/codegen" } [dependencies] log = "0.3" @@ -35,7 +35,7 @@ ethcore-dapps = { path = "dapps", optional = true } semver = "0.2" ethcore-ipc-nano = { path = "ipc/nano" } ethcore-ipc = { path = "ipc/rpc" } -json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } +json-ipc-server = { git = "https://github.com/tomusdrw/json-ipc-server.git" } ansi_term = "0.7" [dependencies.hyper] diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index 219904b4c..b7d752779 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -10,8 +10,8 @@ build = "build.rs" [dependencies] log = "0.3" -jsonrpc-core = "2.0" -jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git" } +jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } +jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } hyper = { default-features = false, git = "https://github.com/ethcore/hyper" } url = "1.0" rustc-serialize = "0.3" @@ -31,7 +31,7 @@ clippy = { version = "0.0.69", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } -syntex = "0.32.0" +syntex = "*" [features] default = ["serde_codegen", "extra-dapps"] diff --git a/db/Cargo.toml b/db/Cargo.toml index 24d0e6fbe..b77840d02 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Ethcore "] build = "build.rs" [build-dependencies] -syntex = "0.32" +syntex = "*" ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] diff --git a/ipc/codegen/Cargo.toml b/ipc/codegen/Cargo.toml index 78ca6a7b4..2febd1a2b 100644 --- a/ipc/codegen/Cargo.toml +++ b/ipc/codegen/Cargo.toml @@ -14,13 +14,13 @@ nightly-testing = ["clippy"] with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"] [build-dependencies] -quasi_codegen = { version = "0.10", optional = true } -syntex = { version = "^0.31", optional = true } +quasi_codegen = { version = "0.11", optional = true } +syntex = { version = "*", optional = true } [dependencies] -aster = { version = "0.16", default-features = false } +aster = { version = "0.17", default-features = false } clippy = { version = "^0.*", optional = true } -quasi = { version = "0.10", default-features = false } -quasi_macros = { version = "0.10", optional = true } -syntex = { version = "0.32", optional = true } -syntex_syntax = { version = "0.32", optional = true } +quasi = { version = "0.11", default-features = false } +quasi_macros = { version = "0.11", optional = true } +syntex = { version = "*", optional = true } +syntex_syntax = { version = "*", optional = true } diff --git a/ipc/nano/Cargo.toml b/ipc/nano/Cargo.toml index fb68adeb7..b3260e6fc 100644 --- a/ipc/nano/Cargo.toml +++ b/ipc/nano/Cargo.toml @@ -7,8 +7,8 @@ license = "GPL-3.0" [features] [dependencies] -jsonrpc-core = "2.0" -"ethcore-ipc" = { path = "../rpc" } +jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } +ethcore-ipc = { path = "../rpc" } nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } log = "0.3" diff --git a/ipc/tests/Cargo.toml b/ipc/tests/Cargo.toml index c3a0697c9..f7a5ee9bd 100644 --- a/ipc/tests/Cargo.toml +++ b/ipc/tests/Cargo.toml @@ -8,7 +8,7 @@ build = "build.rs" path = "run.rs" [dependencies] -"ethcore-ipc" = { path = "../rpc" } +ethcore-ipc = { path = "../rpc" } ethcore-devtools = { path = "../../devtools" } semver = "0.2.0" nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } @@ -17,4 +17,4 @@ ethcore-util = { path = "../../util" } [build-dependencies] syntex = "*" -"ethcore-ipc-codegen" = { path = "../codegen" } +ethcore-ipc-codegen = { path = "../codegen" } diff --git a/json/Cargo.toml b/json/Cargo.toml index 9c024c633..3c7810de8 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -14,7 +14,7 @@ clippy = { version = "0.0.69", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } -syntex = "0.32.0" +syntex = "*" [features] default = ["serde_codegen"] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 61b51cf88..815ed7b31 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -12,8 +12,9 @@ build = "build.rs" log = "0.3" serde = "0.7.0" serde_json = "0.7.0" -jsonrpc-core = "2.0" -jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git", branch = "multiple_cors_domains" } +jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } +# jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git", branch = "multiple_cors_domains" } +jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } ethcore-util = { path = "../util" } ethcore = { path = "../ethcore" } ethash = { path = "../ethash" } @@ -25,11 +26,11 @@ rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } clippy = { version = "0.0.69", optional = true} -json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } +json-ipc-server = { git = "https://github.com/tomusdrw/json-ipc-server.git" } [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } -syntex = "^0.32.0" +syntex = "*" [features] default = ["serde_codegen"] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 51b1b1e8d..a311e03f6 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -9,24 +9,16 @@ build = "build.rs" [build-dependencies] rustc_version = "0.1" -serde_codegen = { version = "0.7.0", optional = true } -syntex = "^0.32.0" [dependencies] -serde = "0.7.0" -serde_json = "0.7.0" -rustc-serialize = "0.3" -jsonrpc-core = "2.0" +jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } log = "0.3" env_logger = "0.3" ws = "0.4.7" ethcore-util = { path = "../util" } ethcore-rpc = { path = "../rpc" } -serde_macros = { version = "0.7.0", optional = true } clippy = { version = "0.0.69", optional = true} [features] -default = ["serde_codegen"] -nightly = ["serde_macros"] dev = ["clippy"] From 4742860b2ecbcbc4f8cfd2148b72e8fb31bd6c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 1 Jun 2016 18:00:40 +0200 Subject: [PATCH 18/38] Using ethcore http server --- Cargo.lock | 5 +++-- dapps/Cargo.toml | 3 ++- rpc/Cargo.toml | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a686b849e..161b9d968 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,7 @@ dependencies = [ "ethcore-util 1.2.0", "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", - "jsonrpc-http-server 5.1.0", + "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", "parity-dapps-builtins 0.5.0 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)", @@ -338,7 +338,7 @@ dependencies = [ "ethsync 1.2.0", "json-ipc-server 0.1.0 (git+https://github.com/tomusdrw/json-ipc-server.git)", "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", - "jsonrpc-http-server 5.1.0", + "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -604,6 +604,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "5.1.0" +source = "git+https://github.com/ethcore/jsonrpc-http-server.git#7a4f322a31834737c8f007b00e7d376f7dc07cdb" dependencies = [ "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index b7d752779..3af7aac97 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -11,7 +11,8 @@ build = "build.rs" [dependencies] log = "0.3" jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } -jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } +# jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } +jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git" } hyper = { default-features = false, git = "https://github.com/ethcore/hyper" } url = "1.0" rustc-serialize = "0.3" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 815ed7b31..1dfa1eeed 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -13,8 +13,8 @@ log = "0.3" serde = "0.7.0" serde_json = "0.7.0" jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } -# jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git", branch = "multiple_cors_domains" } -jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } +jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git" } +# jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } ethcore-util = { path = "../util" } ethcore = { path = "../ethcore" } ethash = { path = "../ethash" } From d601e11d59d68e9ae1e91c6df93e499b2475c021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 1 Jun 2016 18:40:44 +0200 Subject: [PATCH 19/38] Removing typeS --- Cargo.lock | 34 +++++++++++++++++----------------- dapps/src/rpc.rs | 4 ++-- signer/build.rs | 27 --------------------------- signer/src/lib.rs | 4 ---- signer/src/types/mod.rs | 23 ----------------------- signer/src/types/mod.rs.in | 25 ------------------------- 6 files changed, 19 insertions(+), 98 deletions(-) delete mode 100644 signer/src/types/mod.rs delete mode 100644 signer/src/types/mod.rs.in diff --git a/Cargo.lock b/Cargo.lock index 161b9d968..0542286ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,7 +72,7 @@ dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -224,8 +224,8 @@ dependencies = [ "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -279,9 +279,9 @@ dependencies = [ "parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)", "parity-dapps-wallet 0.5.0 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -341,9 +341,9 @@ dependencies = [ "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -389,7 +389,7 @@ dependencies = [ "rust-crypto 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.1.0", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -404,9 +404,9 @@ version = "0.1.0" dependencies = [ "ethcore-util 1.2.0", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -593,11 +593,11 @@ dependencies = [ [[package]] name = "jsonrpc-core" version = "2.0.4" -source = "git+https://github.com/ethcore/jsonrpc-core.git#a1e871c7555bded9229dd7651de64a265231181f" +source = "git+https://github.com/ethcore/jsonrpc-core.git#2ffb194e05ada9ddbe3cc6111a431e07d167e672" dependencies = [ - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1138,7 +1138,7 @@ dependencies = [ [[package]] name = "serde" -version = "0.7.0" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1155,11 +1155,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/dapps/src/rpc.rs b/dapps/src/rpc.rs index 7ba0b9584..e282c0440 100644 --- a/dapps/src/rpc.rs +++ b/dapps/src/rpc.rs @@ -23,14 +23,14 @@ pub fn rpc(handler: Arc, panic_handler: Arc Box::new(RpcEndpoint { handler: handler, panic_handler: panic_handler, - cors_domain: Some(AccessControlAllowOrigin::Null) + cors_domain: vec![AccessControlAllowOrigin::Null], }) } struct RpcEndpoint { handler: Arc, panic_handler: Arc () + Send>>>>, - cors_domain: Option, + cors_domain: Vec, } impl Endpoint for RpcEndpoint { diff --git a/signer/build.rs b/signer/build.rs index 2bcfc7da5..41b9a1b3e 100644 --- a/signer/build.rs +++ b/signer/build.rs @@ -19,34 +19,7 @@ extern crate rustc_version; use rustc_version::{version_meta, Channel}; fn main() { - serde::main(); if let Channel::Nightly = version_meta().channel { println!("cargo:rustc-cfg=nightly"); } } - -#[cfg(not(feature = "serde_macros"))] -mod serde { - extern crate syntex; - extern crate serde_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/types/mod.rs.in"); - let dst = Path::new(&out_dir).join("mod.rs"); - - let mut registry = syntex::Registry::new(); - - serde_codegen::register(&mut registry); - registry.expand("", &src, &dst).unwrap(); - } -} - -#[cfg(feature = "serde_macros")] -mod serde { - pub fn main() {} -} diff --git a/signer/src/lib.rs b/signer/src/lib.rs index f3a963ac7..49863ce79 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -17,8 +17,6 @@ #![warn(missing_docs)] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] -// Generated by serde -#![cfg_attr(all(nightly, feature="dev"), allow(redundant_closure_call))] //! Signer module //! @@ -45,8 +43,6 @@ extern crate log; extern crate env_logger; -extern crate serde; -extern crate serde_json; extern crate rustc_serialize; extern crate ethcore_util as util; diff --git a/signer/src/types/mod.rs b/signer/src/types/mod.rs deleted file mode 100644 index d5e15046a..000000000 --- a/signer/src/types/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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 . - -//! Reusable types with JSON Serialization. - -#[cfg(feature = "serde_macros")] -include!("mod.rs.in"); - -#[cfg(not(feature = "serde_macros"))] -include!(concat!(env!("OUT_DIR"), "/mod.rs")); diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in deleted file mode 100644 index a59f81ece..000000000 --- a/signer/src/types/mod.rs.in +++ /dev/null @@ -1,25 +0,0 @@ -// 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 . - - - - - - - - - -// TODO [ToDr] Types are empty for now. But they are about to come. From a7a2b55362905a13c08fa6772038f946eadb1cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 1 Jun 2016 18:00:40 +0200 Subject: [PATCH 20/38] Using ethcore http server --- Cargo.lock | 83 ++++++++++++++++++++++++++------------ dapps/Cargo.toml | 4 +- dapps/src/rpc.rs | 4 +- ipc/nano/Cargo.toml | 2 +- rpc/Cargo.toml | 5 +-- signer/Cargo.toml | 2 +- signer/build.rs | 27 ------------- signer/src/lib.rs | 6 --- signer/src/types/mod.rs | 23 ----------- signer/src/types/mod.rs.in | 25 ------------ 10 files changed, 66 insertions(+), 115 deletions(-) delete mode 100644 signer/src/types/mod.rs delete mode 100644 signer/src/types/mod.rs.in diff --git a/Cargo.lock b/Cargo.lock index a686b849e..c53bad980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,7 +72,7 @@ dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -224,8 +224,8 @@ dependencies = [ "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -269,8 +269,8 @@ dependencies = [ "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", - "jsonrpc-http-server 5.1.0", + "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", "parity-dapps-builtins 0.5.0 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)", @@ -279,9 +279,9 @@ dependencies = [ "parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)", "parity-dapps-wallet 0.5.0 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -319,7 +319,7 @@ name = "ethcore-ipc-nano" version = "1.2.0" dependencies = [ "ethcore-ipc 1.2.0", - "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", ] @@ -337,13 +337,13 @@ dependencies = [ "ethminer 1.2.0", "ethsync 1.2.0", "json-ipc-server 0.1.0 (git+https://github.com/tomusdrw/json-ipc-server.git)", - "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", - "jsonrpc-http-server 5.1.0", + "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -356,7 +356,7 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", - "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -389,7 +389,7 @@ dependencies = [ "rust-crypto 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.1.0", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -404,9 +404,9 @@ version = "0.1.0" dependencies = [ "ethcore-util 1.2.0", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -577,7 +577,7 @@ version = "0.1.0" source = "git+https://github.com/tomusdrw/json-ipc-server.git#7b632a7663c0cf109c914370840d795ebb0a6103" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-core 2.0.5 (git+https://github.com/ethcore/jsonrpc-core.git)", "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -593,20 +593,32 @@ dependencies = [ [[package]] name = "jsonrpc-core" version = "2.0.4" -source = "git+https://github.com/ethcore/jsonrpc-core.git#a1e871c7555bded9229dd7651de64a265231181f" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-core" +version = "2.0.5" +source = "git+https://github.com/ethcore/jsonrpc-core.git#6717dd26b7a0fbac302fa4ea0fd195a22f3c85e5" +dependencies = [ + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" version = "5.1.0" +source = "git+https://github.com/ethcore/jsonrpc-http-server.git#7a4f322a31834737c8f007b00e7d376f7dc07cdb" dependencies = [ "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.4 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-core 2.0.5 (git+https://github.com/ethcore/jsonrpc-core.git)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1137,7 +1149,7 @@ dependencies = [ [[package]] name = "serde" -version = "0.7.0" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1154,11 +1166,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1200,6 +1212,14 @@ name = "strsim" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "syntex" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syntex" version = "0.33.0" @@ -1208,6 +1228,19 @@ dependencies = [ "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syntex_syntax" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syntex_syntax" version = "0.33.0" diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index b7d752779..5372c74a9 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -10,8 +10,8 @@ build = "build.rs" [dependencies] log = "0.3" -jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } -jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } +jsonrpc-core = "2.0" +jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git" } hyper = { default-features = false, git = "https://github.com/ethcore/hyper" } url = "1.0" rustc-serialize = "0.3" diff --git a/dapps/src/rpc.rs b/dapps/src/rpc.rs index 7ba0b9584..e282c0440 100644 --- a/dapps/src/rpc.rs +++ b/dapps/src/rpc.rs @@ -23,14 +23,14 @@ pub fn rpc(handler: Arc, panic_handler: Arc Box::new(RpcEndpoint { handler: handler, panic_handler: panic_handler, - cors_domain: Some(AccessControlAllowOrigin::Null) + cors_domain: vec![AccessControlAllowOrigin::Null], }) } struct RpcEndpoint { handler: Arc, panic_handler: Arc () + Send>>>>, - cors_domain: Option, + cors_domain: Vec, } impl Endpoint for RpcEndpoint { diff --git a/ipc/nano/Cargo.toml b/ipc/nano/Cargo.toml index b3260e6fc..fc229d393 100644 --- a/ipc/nano/Cargo.toml +++ b/ipc/nano/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0" [features] [dependencies] -jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } +jsonrpc-core = "2.0" ethcore-ipc = { path = "../rpc" } nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } log = "0.3" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 815ed7b31..866221606 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -12,9 +12,8 @@ build = "build.rs" log = "0.3" serde = "0.7.0" serde_json = "0.7.0" -jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } -# jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git", branch = "multiple_cors_domains" } -jsonrpc-http-server = { path = "../../../workspace/jsonrpc-http-server" } +jsonrpc-core = "2.0" +jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git" } ethcore-util = { path = "../util" } ethcore = { path = "../ethcore" } ethash = { path = "../ethash" } diff --git a/signer/Cargo.toml b/signer/Cargo.toml index a311e03f6..170c9320e 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -11,7 +11,7 @@ build = "build.rs" rustc_version = "0.1" [dependencies] -jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc-core.git" } +jsonrpc-core = "2.0" log = "0.3" env_logger = "0.3" ws = "0.4.7" diff --git a/signer/build.rs b/signer/build.rs index 2bcfc7da5..41b9a1b3e 100644 --- a/signer/build.rs +++ b/signer/build.rs @@ -19,34 +19,7 @@ extern crate rustc_version; use rustc_version::{version_meta, Channel}; fn main() { - serde::main(); if let Channel::Nightly = version_meta().channel { println!("cargo:rustc-cfg=nightly"); } } - -#[cfg(not(feature = "serde_macros"))] -mod serde { - extern crate syntex; - extern crate serde_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/types/mod.rs.in"); - let dst = Path::new(&out_dir).join("mod.rs"); - - let mut registry = syntex::Registry::new(); - - serde_codegen::register(&mut registry); - registry.expand("", &src, &dst).unwrap(); - } -} - -#[cfg(feature = "serde_macros")] -mod serde { - pub fn main() {} -} diff --git a/signer/src/lib.rs b/signer/src/lib.rs index f3a963ac7..c1fe3d308 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -17,8 +17,6 @@ #![warn(missing_docs)] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] -// Generated by serde -#![cfg_attr(all(nightly, feature="dev"), allow(redundant_closure_call))] //! Signer module //! @@ -45,10 +43,6 @@ extern crate log; extern crate env_logger; -extern crate serde; -extern crate serde_json; -extern crate rustc_serialize; - extern crate ethcore_util as util; extern crate ethcore_rpc as rpc; extern crate jsonrpc_core; diff --git a/signer/src/types/mod.rs b/signer/src/types/mod.rs deleted file mode 100644 index d5e15046a..000000000 --- a/signer/src/types/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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 . - -//! Reusable types with JSON Serialization. - -#[cfg(feature = "serde_macros")] -include!("mod.rs.in"); - -#[cfg(not(feature = "serde_macros"))] -include!(concat!(env!("OUT_DIR"), "/mod.rs")); diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in deleted file mode 100644 index a59f81ece..000000000 --- a/signer/src/types/mod.rs.in +++ /dev/null @@ -1,25 +0,0 @@ -// 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 . - - - - - - - - - -// TODO [ToDr] Types are empty for now. But they are about to come. From 5f68b81f68c2dd846324390c67bfeaa893b42392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 1 Jun 2016 20:32:16 +0200 Subject: [PATCH 21/38] Updating jsonrpc-core --- Cargo.lock | 45 ++++++++++++--------------------------------- Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c53bad980..ab5b435a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ "ethsync 1.2.0", "fdlimit 0.1.0", "hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "json-ipc-server 0.1.0 (git+https://github.com/tomusdrw/json-ipc-server.git)", + "json-ipc-server 0.1.0 (git+https://github.com/ethcore/json-ipc-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -269,7 +269,7 @@ dependencies = [ "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", @@ -319,7 +319,7 @@ name = "ethcore-ipc-nano" version = "1.2.0" dependencies = [ "ethcore-ipc 1.2.0", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", ] @@ -336,8 +336,8 @@ dependencies = [ "ethjson 0.1.0", "ethminer 1.2.0", "ethsync 1.2.0", - "json-ipc-server 0.1.0 (git+https://github.com/tomusdrw/json-ipc-server.git)", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "json-ipc-server 0.1.0 (git+https://github.com/ethcore/json-ipc-server.git)", + "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -356,7 +356,7 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", - "jsonrpc-core 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -574,10 +574,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "json-ipc-server" version = "0.1.0" -source = "git+https://github.com/tomusdrw/json-ipc-server.git#7b632a7663c0cf109c914370840d795ebb0a6103" +source = "git+https://github.com/ethcore/json-ipc-server.git#4f9226c4f84dcce2385a188374e3b5fc66b63e68" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 2.0.5 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -592,19 +592,19 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "2.0.5" +source = "git+https://github.com/ethcore/jsonrpc-core.git#6717dd26b7a0fbac302fa4ea0fd195a22f3c85e5" dependencies = [ "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core" version = "2.0.5" -source = "git+https://github.com/ethcore/jsonrpc-core.git#6717dd26b7a0fbac302fa4ea0fd195a22f3c85e5" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1212,14 +1212,6 @@ name = "strsim" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "syntex" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syntex" version = "0.33.0" @@ -1228,19 +1220,6 @@ dependencies = [ "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "syntex_syntax" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syntex_syntax" version = "0.33.0" diff --git a/Cargo.toml b/Cargo.toml index 456409ba7..e93069c98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ ethcore-dapps = { path = "dapps", optional = true } semver = "0.2" ethcore-ipc-nano = { path = "ipc/nano" } ethcore-ipc = { path = "ipc/rpc" } -json-ipc-server = { git = "https://github.com/tomusdrw/json-ipc-server.git" } +json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } ansi_term = "0.7" [dependencies.hyper] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 866221606..8db7c0491 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -25,7 +25,7 @@ rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } clippy = { version = "0.0.69", optional = true} -json-ipc-server = { git = "https://github.com/tomusdrw/json-ipc-server.git" } +json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } From e9bcce05a1048b3e5720e3d5a5cedcb5fbc0426d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 2 Jun 2016 12:12:31 +0200 Subject: [PATCH 22/38] Refactoring the signing queue --- rpc/src/v1/helpers/signing_queue.rs | 236 ++++++++++++++++------------ rpc/src/v1/impls/eth_signing.rs | 2 +- 2 files changed, 133 insertions(+), 105 deletions(-) diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index b0625b170..4f860e438 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -16,19 +16,23 @@ use std::thread; use std::time::{Instant, Duration}; -use std::sync::{mpsc, Mutex, RwLock}; +use std::sync::{mpsc, Mutex, RwLock, Arc}; use std::collections::HashMap; use v1::types::{TransactionRequest, TransactionConfirmation}; use util::{U256, H256}; -/// Messages that queue informs about +/// Possible events happening in the queue that can be listened to. #[derive(Debug, PartialEq)] -pub enum QueueMessage { +pub enum QueueEvent { /// Receiver should stop work upon receiving `Finish` message. Finish, - /// Informs about new transaction request. + /// Informs about new request. NewRequest(U256), + /// Request rejected. + RequestRejected(U256), + /// Request resolved. + RequestConfirmed(U256), } /// Defines possible errors returned from queue receiving method. @@ -41,19 +45,20 @@ pub enum QueueError { } /// Message Receiver type -pub type QueueMessageReceiver = mpsc::Receiver; +pub type QueueEventReceiver = mpsc::Receiver; /// A queue of transactions awaiting to be confirmed and signed. pub trait SigningQueue: Send + Sync { /// Add new request to the queue. - fn add_request(&self, transaction: TransactionRequest) -> U256; + /// Returns a `ConfirmationPromise` that can be used to await for resolution of given request. + fn add_request(&self, transaction: TransactionRequest) -> ConfirmationPromise; - /// Remove request from the queue. - /// Notify possible waiters that transaction was rejected. + /// Removes a request from the queue. + /// Notifies possible token holders that transaction was rejected. fn request_rejected(&self, id: U256) -> Option; - /// Remove request from the queue. - /// Notify possible waiters that transaction was confirmed and got given hash. + /// Removes a request from the queue. + /// Notifies possible token holders that transaction was confirmed and given hash was assigned. fn request_confirmed(&self, id: U256, hash: H256) -> Option; /// Returns a request if it is contained in the queue. @@ -61,32 +66,89 @@ pub trait SigningQueue: Send + Sync { /// Return copy of all the requests in the queue. fn requests(&self) -> Vec; +} - /// Blocks for some time waiting for confirmation. - /// Returns `None` when timeout reached or transaction was rejected. - /// Returns transaction hash when transaction was confirmed. - fn wait_with_timeout(&self, id: U256) -> Option; +#[derive(Debug, PartialEq)] +enum ConfirmationResult { + /// The transaction has not yet been confirmed nor rejected. + Waiting, + /// The transaction has been rejected. + Rejected, + /// The transaction has been confirmed. + Confirmed(H256), } /// Time you need to confirm the transaction in UI. +/// This is the amount of time token holder will wait before +/// returning `None`. /// Unless we have a multi-threaded RPC this will lock /// any other incoming call! const QUEUE_TIMEOUT_DURATION_SEC : u64 = 20; -#[derive(Debug, Clone)] -enum QueueStatus { - Waiting, - Rejected, - Confirmed(H256), +/// A handle to submitted request. +/// Allows to block and wait for a resolution of that request. +pub struct ConfirmationToken { + result: Arc>, + handle: thread::Thread, + request: TransactionConfirmation, +} + +pub struct ConfirmationPromise { + id: U256, + result: Arc>, +} + +impl ConfirmationToken { + /// Submit solution to all listeners + fn resolve(&self, result: Option) { + let mut res = self.result.lock().unwrap(); + *res = result.map_or(ConfirmationResult::Rejected, |h| ConfirmationResult::Confirmed(h)); + // Notify listener + self.handle.unpark(); + } + + fn as_promise(&self) -> ConfirmationPromise { + ConfirmationPromise { + id: self.request.id, + result: self.result.clone(), + } + } +} + +impl ConfirmationPromise { + /// Blocks current thread and awaits for + /// resolution of the transaction (rejected / confirmed) + /// Returns `None` if transaction was rejected or timeout reached. + /// Returns `Some(hash)` if transaction was confirmed. + pub fn wait_with_timeout(&self) -> Option { + let timeout = Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC); + let deadline = Instant::now() + timeout; + + info!(target: "own_tx", "Signer: Awaiting transaction confirmation... ({:?}).", self.id); + while Instant::now() < deadline { + // Park thread + thread::park_timeout(timeout); + // Take confirmation result + let res = self.result.lock().unwrap(); + // Check the result + match *res { + ConfirmationResult::Rejected => return None, + ConfirmationResult::Confirmed(h) => return Some(h), + ConfirmationResult::Waiting => continue, + } + } + // We reached the timeout. Just return `None` and make sure to remove waiting. + trace!(target: "own_tx", "Signer: Confirmation timeout reached... ({:?}).", self.id); + None + } } /// Queue for all unconfirmed transactions. pub struct ConfirmationsQueue { id: Mutex, - waiters: RwLock>, - queue: RwLock>, - sender: Mutex>, - receiver: Mutex>>, + queue: RwLock>, + sender: Mutex>, + receiver: Mutex>>, } impl Default for ConfirmationsQueue { @@ -95,7 +157,6 @@ impl Default for ConfirmationsQueue { ConfirmationsQueue { id: Mutex::new(U256::from(0)), - waiters: RwLock::new(HashMap::new()), queue: RwLock::new(HashMap::new()), sender: Mutex::new(send), receiver: Mutex::new(Some(recv)), @@ -104,11 +165,11 @@ impl Default for ConfirmationsQueue { } impl ConfirmationsQueue { - /// Blocks the thread and starts listening for notifications. - /// For each event `listener` callback function will be invoked. - /// This method can be used only once. + /// Blocks the thread and starts listening for notifications regarding all actions in the queue. + /// For each event, `listener` callback will be invoked. + /// This method can be used only once (only single consumer of events can exist). pub fn start_listening(&self, listener: F) -> Result<(), QueueError> - where F: Fn(QueueMessage) -> () { + where F: Fn(QueueEvent) -> () { let recv = self.receiver.lock().unwrap().take(); if let None = recv { return Err(QueueError::AlreadyUsed); @@ -117,7 +178,7 @@ impl ConfirmationsQueue { loop { let message = try!(recv.recv().map_err(|e| QueueError::ReceiverError(e))); - if let QueueMessage::Finish = message { + if let QueueEvent::Finish = message { return Ok(()); } @@ -125,23 +186,35 @@ impl ConfirmationsQueue { } } - /// Notifies receiver that the communcation is over. + /// Notifies consumer that the communcation is over. + /// No more events will be sent after this function is invoked. pub fn finish(&self) { - self.notify(QueueMessage::Finish); + self.notify(QueueEvent::Finish); } - fn notify(&self, message: QueueMessage) { + /// Notifies receiver about the event happening in this queue. + fn notify(&self, message: QueueEvent) { // We don't really care about the result let _ = self.sender.lock().unwrap().send(message); } - fn remove(&self, id: U256) -> Option { - self.queue.write().unwrap().remove(&id) - } + /// Removes transaction from this queue and notifies `ConfirmationPromise` holders about the result. + /// Notifies also a receiver about that event. + fn remove(&self, id: U256, result: Option) -> Option { + let token = self.queue.write().unwrap().remove(&id); - fn update_status(&self, id: U256, status: QueueStatus) { - let mut waiters = self.waiters.write().unwrap(); - waiters.insert(id, status); + if let Some(token) = token { + // notify receiver about the event + self.notify(result.map_or_else( + || QueueEvent::RequestRejected(id), + |_| QueueEvent::RequestConfirmed(id) + )); + // notify token holders about resolution + token.resolve(result); + // return a result + return Some(token.request.clone()); + } + None } } @@ -152,7 +225,7 @@ impl Drop for ConfirmationsQueue { } impl SigningQueue for ConfirmationsQueue { - fn add_request(&self, transaction: TransactionRequest) -> U256 { + fn add_request(&self, transaction: TransactionRequest) -> ConfirmationPromise { // Increment id let id = { let mut last_id = self.id.lock().unwrap(); @@ -160,87 +233,42 @@ impl SigningQueue for ConfirmationsQueue { *last_id }; // Add request to queue - { + let res = { let mut queue = self.queue.write().unwrap(); - queue.insert(id, TransactionConfirmation { - id: id, - transaction: transaction, + queue.insert(id, ConfirmationToken { + result: Arc::new(Mutex::new(ConfirmationResult::Waiting)), + handle: thread::current(), + request: TransactionConfirmation { + id: id, + transaction: transaction, + }, }); debug!(target: "own_tx", "Signer: New transaction ({:?}) in confirmation queue.", id); - } + queue.get(&id).map(|token| token.as_promise()).expect("Token was just inserted.") + }; // Notify listeners - self.notify(QueueMessage::NewRequest(id)); - id + self.notify(QueueEvent::NewRequest(id)); + res + } fn peek(&self, id: &U256) -> Option { - self.queue.read().unwrap().get(id).cloned() + self.queue.read().unwrap().get(id).map(|token| token.request.clone()) } fn request_rejected(&self, id: U256) -> Option { debug!(target: "own_tx", "Signer: Transaction rejected ({:?}).", id); - let o = self.remove(id); - self.update_status(id, QueueStatus::Rejected); - o + self.remove(id, None) } fn request_confirmed(&self, id: U256, hash: H256) -> Option { debug!(target: "own_tx", "Signer: Transaction confirmed ({:?}).", id); - let o = self.remove(id); - self.update_status(id, QueueStatus::Confirmed(hash)); - o + self.remove(id, Some(hash)) } fn requests(&self) -> Vec { let queue = self.queue.read().unwrap(); - queue.values().cloned().collect() - } - - fn wait_with_timeout(&self, id: U256) -> Option { - { - let mut waiters = self.waiters.write().unwrap(); - let r = waiters.insert(id, QueueStatus::Waiting); - match r { - // This is ok, we can have many waiters - Some(QueueStatus::Waiting) | None => {}, - // There already was a response for someone. - // The one waiting for it will cleanup, so... - Some(v) => { - // ... insert old status back - waiters.insert(id, v.clone()); - if let QueueStatus::Confirmed(h) = v { - return Some(h); - } - return None; - }, - } - } - - info!(target: "own_tx", "Signer: Awaiting transaction confirmation... ({:?}).", id); - // Now wait for a response - let deadline = Instant::now() + Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC); - while Instant::now() < deadline { - let status = { - let waiters = self.waiters.read().unwrap(); - waiters.get(&id).expect("Only the waiting thread can remove any message.").clone() - }; - - match status { - QueueStatus::Waiting => thread::sleep(Duration::from_millis(50)), - QueueStatus::Confirmed(h) => { - self.waiters.write().unwrap().remove(&id); - return Some(h); - }, - QueueStatus::Rejected => { - self.waiters.write().unwrap().remove(&id); - return None; - }, - } - } - // We reached the timeout. Just return `None` and make sure to remove waiting. - trace!(target: "own_tx", "Signer: Confirmation timeout reached... ({:?}).", id); - self.waiters.write().unwrap().remove(&id); - None + queue.values().map(|token| token.request.clone()).collect() } } @@ -277,7 +305,7 @@ mod test { let q = queue.clone(); let handle = thread::spawn(move || { let v = q.add_request(request); - q.wait_with_timeout(v).expect("Should return hash") + v.wait_with_timeout().expect("Should return hash") }); let id = U256::from(1); @@ -307,13 +335,13 @@ mod test { *v = Some(notification); }).expect("Should be closed nicely.") }); - let v = queue.add_request(request); + queue.add_request(request); queue.finish(); // then handle.join().expect("Thread should finish nicely"); let r = received.lock().unwrap().take(); - assert_eq!(r, Some(QueueMessage::NewRequest(v))); + assert_eq!(r, Some(QueueEvent::NewRequest(U256::from(1)))); } #[test] diff --git a/rpc/src/v1/impls/eth_signing.rs b/rpc/src/v1/impls/eth_signing.rs index d7e997c71..a5b3f2592 100644 --- a/rpc/src/v1/impls/eth_signing.rs +++ b/rpc/src/v1/impls/eth_signing.rs @@ -54,7 +54,7 @@ impl EthSigning for EthSigningQueueClient { .and_then(|(request, )| { let queue = take_weak!(self.queue); let id = queue.add_request(request); - let result = queue.wait_with_timeout(id); + let result = id.wait_with_timeout(); to_value(&result.unwrap_or_else(H256::new)) }) } From ee3f6082045a48e4cbd6f795101a2359b6c6c62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 2 Jun 2016 13:19:44 +0200 Subject: [PATCH 23/38] Fixing wait loop in case of spurious wake-ups. --- rpc/src/v1/helpers/signing_queue.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index 4f860e438..0ded8998c 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -125,9 +125,13 @@ impl ConfirmationPromise { let deadline = Instant::now() + timeout; info!(target: "own_tx", "Signer: Awaiting transaction confirmation... ({:?}).", self.id); - while Instant::now() < deadline { - // Park thread - thread::park_timeout(timeout); + loop { + let now = Instant::now(); + if now >= deadline { + break; + } + // Park thread (may wake up spuriously) + thread::park_timeout(deadline - now); // Take confirmation result let res = self.result.lock().unwrap(); // Check the result @@ -137,7 +141,7 @@ impl ConfirmationPromise { ConfirmationResult::Waiting => continue, } } - // We reached the timeout. Just return `None` and make sure to remove waiting. + // We reached the timeout. Just return `None` trace!(target: "own_tx", "Signer: Confirmation timeout reached... ({:?}).", self.id); None } From cce18cb4c546b5af0b9bf923c25f50d6d43c4c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 2 Jun 2016 13:32:33 +0200 Subject: [PATCH 24/38] Enabling DAOdapp --- dapps/src/apps.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dapps/src/apps.rs b/dapps/src/apps.rs index 130b20fb9..4bf550ce1 100644 --- a/dapps/src/apps.rs +++ b/dapps/src/apps.rs @@ -63,12 +63,12 @@ fn wallet_page(pages: &mut Endpoints) { #[cfg(not(feature = "parity-dapps-wallet"))] fn wallet_page(_pages: &mut Endpoints) {} -#[cfg(feature = "parity-dapps-daodapp")] +#[cfg(feature = "parity-dapps-dao")] fn daodapp_page(pages: &mut Endpoints) { - extern crate parity_dapps_daodapp; - insert::(pages, "dao"); + extern crate parity_dapps_dao; + insert::(pages, "dao"); } -#[cfg(not(feature = "parity-dapps-daodapp"))] +#[cfg(not(feature = "parity-dapps-dao"))] fn daodapp_page(_pages: &mut Endpoints) {} #[cfg(feature = "parity-dapps-makerotc")] From 3ba15f6c647f358174a5a42c9d1556c0c28597a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 2 Jun 2016 20:32:48 +0200 Subject: [PATCH 25/38] Updating httpserver and core --- Cargo.lock | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab5b435a4..e1f2a28b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -590,17 +590,6 @@ dependencies = [ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "jsonrpc-core" -version = "2.0.5" -source = "git+https://github.com/ethcore/jsonrpc-core.git#6717dd26b7a0fbac302fa4ea0fd195a22f3c85e5" -dependencies = [ - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "jsonrpc-core" version = "2.0.5" @@ -615,10 +604,10 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "5.1.0" -source = "git+https://github.com/ethcore/jsonrpc-http-server.git#7a4f322a31834737c8f007b00e7d376f7dc07cdb" +source = "git+https://github.com/ethcore/jsonrpc-http-server.git#77dcac785c02c3a7622d36aa635ee80d63d0b20c" dependencies = [ "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.5 (git+https://github.com/ethcore/jsonrpc-core.git)", + "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] From d7b79c12741f8d521f6edfa5b9dc75ce1a01a3a1 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 2 Jun 2016 20:34:38 +0200 Subject: [PATCH 26/38] don't return a state in state_at if the db prunes and the block is before guaranteed history --- ethcore/src/client/client.rs | 8 ++++++++ util/src/journaldb/archivedb.rs | 2 ++ util/src/journaldb/traits.rs | 3 +++ 3 files changed, 13 insertions(+) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 3ddf7018a..ced8c736c 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -371,6 +371,14 @@ impl Client where V: Verifier { return Some(self.state()) } + let block_number = self.block_number(id.clone()); + + // check that the block is not too old -- blocks within `HISTORY` blocks of the best will + // always be available. + if self.state_db.does_pruning() && self.best_block_number() >= block_number + HISTORY { + return None; + } + self.block_header(id).map(|header| { let db = self.state_db.lock().unwrap().boxed_clone(); State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce()) diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index b554db885..c79bab23e 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -175,6 +175,8 @@ impl JournalDB for ArchiveDB { fn state(&self, id: &H256) -> Option { self.backing.get_by_prefix(&id.bytes()[0..12]).and_then(|b| Some(b.to_vec())) } + + fn does_pruning(&self) -> bool { false } } #[cfg(test)] diff --git a/util/src/journaldb/traits.rs b/util/src/journaldb/traits.rs index 10212f976..d41077655 100644 --- a/util/src/journaldb/traits.rs +++ b/util/src/journaldb/traits.rs @@ -42,4 +42,7 @@ pub trait JournalDB : HashDB + Send + Sync { fn state(&self, _id: &H256) -> Option { None } + + /// Whether this database does pruning. + fn does_pruning(&self) -> bool { true } } From 6c6229c963260daf991586d3bb5df83fd01515df Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 2 Jun 2016 20:52:21 +0200 Subject: [PATCH 27/38] check if state root is valid for old blocks --- ethcore/src/client/client.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index ced8c736c..b9348c997 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -373,15 +373,18 @@ impl Client where V: Verifier { let block_number = self.block_number(id.clone()); - // check that the block is not too old -- blocks within `HISTORY` blocks of the best will - // always be available. - if self.state_db.does_pruning() && self.best_block_number() >= block_number + HISTORY { - return None; - } + self.block_header(id).and_then(|header| { + let root = HeaderView::new(&header).state_root(); + // check that the block is not too old -- blocks within `HISTORY` blocks of the best will + // always be available. If the block could be too old, check if its state root is valid. + if self.state_db.does_pruning() + && self.best_block_number() >= block_number + HISTORY + && self.state_db.exists(root) { + return None; + } - self.block_header(id).map(|header| { let db = self.state_db.lock().unwrap().boxed_clone(); - State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce()) + Some(State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce())) }) } From 1e10445f820fa9158581beece90e1d7b7c3d6206 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 2 Jun 2016 21:01:47 +0200 Subject: [PATCH 28/38] exists -> contains --- ethcore/src/client/client.rs | 14 +++++++++----- util/src/trie/triedb.rs | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b9348c997..9fbe8ae2d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -371,19 +371,23 @@ impl Client where V: Verifier { return Some(self.state()) } - let block_number = self.block_number(id.clone()); + let block_number = match self.block_number(id.clone()) { + Some(num) => num, + None => return None, + }; self.block_header(id).and_then(|header| { + let db = self.state_db.lock().unwrap().boxed_clone(); + let root = HeaderView::new(&header).state_root(); // check that the block is not too old -- blocks within `HISTORY` blocks of the best will // always be available. If the block could be too old, check if its state root is valid. - if self.state_db.does_pruning() - && self.best_block_number() >= block_number + HISTORY - && self.state_db.exists(root) { + if db.does_pruning() + && self.chain.best_block_number() >= block_number + HISTORY + && !db.contains(&root) { return None; } - let db = self.state_db.lock().unwrap().boxed_clone(); Some(State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce())) }) } diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index 06076d273..1c6d2236b 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -59,7 +59,7 @@ impl<'db> TrieDB<'db> { /// Create a new trie with the backing database `db` and `root` /// Panics, if `root` does not exist pub fn new(db: &'db HashDB, root: &'db H256) -> Self { - if !db.exists(root) { + if !db.contains(root) { flushln!("TrieDB::new({}): Trie root not found!", root); panic!("Trie root not found!"); } From ae2deaaf72b5418b56c35d6ba84239841d2055e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 3 Jun 2016 11:15:38 +0200 Subject: [PATCH 29/38] Bumping clippy version --- Cargo.lock | 31 +++++++++++++++++++++++-------- Cargo.toml | 2 +- dapps/Cargo.toml | 2 +- ethcore/Cargo.toml | 2 +- json/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- signer/Cargo.toml | 2 +- sync/Cargo.toml | 2 +- util/Cargo.toml | 2 +- 9 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 723bca872..30cc49392 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "parity" version = "1.2.0" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)", "daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -130,11 +130,26 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.69" +version = "0.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clippy_lints 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", + "quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clippy_lints" +version = "0.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -241,7 +256,7 @@ name = "ethcore" version = "1.2.0" dependencies = [ "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.2.0", @@ -265,7 +280,7 @@ dependencies = [ name = "ethcore-dapps" version = "1.2.0" dependencies = [ - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", @@ -328,7 +343,7 @@ dependencies = [ name = "ethcore-rpc" version = "1.2.0" dependencies = [ - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.2.0", "ethcore 1.2.0", "ethcore-devtools 1.2.0", @@ -351,7 +366,7 @@ dependencies = [ name = "ethcore-signer" version = "1.2.0" dependencies = [ - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", "ethcore-util 1.2.0", @@ -368,7 +383,7 @@ dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 0.1.0", "chrono 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -413,7 +428,7 @@ dependencies = [ name = "ethsync" version = "1.2.0" dependencies = [ - "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.2.0", "ethcore-util 1.2.0", diff --git a/Cargo.toml b/Cargo.toml index ce8823bd2..81deea136 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ daemonize = "0.2" num_cpus = "0.2" number_prefix = "0.2" rpassword = "0.2.1" -clippy = { version = "0.0.69", optional = true} +clippy = { version = "0.0.71", optional = true} ethcore = { path = "ethcore" } ethcore-util = { path = "util" } ethsync = { path = "sync" } diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index 219904b4c..774c49de0 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -27,7 +27,7 @@ parity-dapps-builtins = { git = "https://github.com/ethcore/parity-dapps-builtin parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs.git", version = "0.5.0", optional = true } parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.3.0", optional = true } parity-dapps-makerotc = { git = "https://github.com/ethcore/parity-dapps-makerotc-rs.git", version = "0.2.0", optional = true } -clippy = { version = "0.0.69", optional = true} +clippy = { version = "0.0.71", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 1de24ee32..d558c902d 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -22,7 +22,7 @@ ethcore-util = { path = "../util" } evmjit = { path = "../evmjit", optional = true } ethash = { path = "../ethash" } num_cpus = "0.2" -clippy = { version = "0.0.69", optional = true} +clippy = { version = "0.0.71", optional = true} crossbeam = "0.2.9" lazy_static = "0.1" ethcore-devtools = { path = "../devtools" } diff --git a/json/Cargo.toml b/json/Cargo.toml index 9c024c633..21327d284 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -10,7 +10,7 @@ rustc-serialize = "0.3" serde = "0.7.0" serde_json = "0.7.0" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.69", optional = true} +clippy = { version = "0.0.71", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 2dbefd7f4..ffc0272a0 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -23,7 +23,7 @@ ethcore-devtools = { path = "../devtools" } rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.69", optional = true} +clippy = { version = "0.0.71", optional = true} json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } [build-dependencies] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 170c9320e..2efc4bb9c 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -18,7 +18,7 @@ ws = "0.4.7" ethcore-util = { path = "../util" } ethcore-rpc = { path = "../rpc" } -clippy = { version = "0.0.69", optional = true} +clippy = { version = "0.0.71", optional = true} [features] dev = ["clippy"] diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 1b80e23fc..8c5b4c926 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Ethcore Date: Fri, 3 Jun 2016 11:36:30 +0200 Subject: [PATCH 30/38] Fixing warnings --- ethcore/src/evm/interpreter.rs | 1 - ethcore/src/executive.rs | 14 ++++++------ ethcore/src/trace/executive_tracer.rs | 6 ++--- ethcore/src/trace/mod.rs | 2 +- ethcore/src/trace/noop_tracer.rs | 2 +- parity/hypervisor/service.rs.in | 1 - sync/src/chain.rs | 19 +++++++-------- sync/src/lib.rs | 1 + util/src/hash.rs | 20 ++++++++-------- util/src/network/discovery.rs | 9 ++++---- util/src/network/host.rs | 33 ++++++++++++--------------- 11 files changed, 53 insertions(+), 55 deletions(-) diff --git a/ethcore/src/evm/interpreter.rs b/ethcore/src/evm/interpreter.rs index 1514b3e2e..5b97b66af 100644 --- a/ethcore/src/evm/interpreter.rs +++ b/ethcore/src/evm/interpreter.rs @@ -17,7 +17,6 @@ ///! Rust VM implementation use common::*; -use trace::VMTracer; use super::instructions as instructions; use super::instructions::{Instruction, get_info}; use std::marker::Copy; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 43864ee9e..f7615be09 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -81,14 +81,14 @@ impl<'a> Executive<'a> { } /// Creates `Externalities` from `Executive`. - pub fn as_externalities<'_, T, V>( - &'_ mut self, + pub fn as_externalities<'any, T, V>( + &'any mut self, origin_info: OriginInfo, - substate: &'_ mut Substate, - output: OutputPolicy<'_, '_>, - tracer: &'_ mut T, - vm_tracer: &'_ mut V - ) -> Externalities<'_, T, V> where T: Tracer, V: VMTracer { + substate: &'any mut Substate, + output: OutputPolicy<'any, 'any>, + tracer: &'any mut T, + vm_tracer: &'any mut V + ) -> Externalities<'any, T, V> where T: Tracer, V: VMTracer { Externalities::new(self.state, self.info, self.engine, self.vm_factory, self.depth, origin_info, substate, output, tracer, vm_tracer) } diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index a1a13cf43..ff7c6a62f 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -117,7 +117,7 @@ impl VMTracer for ExecutiveVMTracer { self.data.operations.push(VMOperation { pc: pc, instruction: instruction, - gas_cost: gas_cost.clone(), + gas_cost: gas_cost.clone(), executed: None, }); true @@ -133,10 +133,10 @@ impl VMTracer for ExecutiveVMTracer { self.data.operations.last_mut().expect("trace_executed is always called after a trace_prepare_execute").executed = Some(ex); } - fn prepare_subtrace(&self, code: &Bytes) -> Self { + fn prepare_subtrace(&self, code: &[u8]) -> Self { ExecutiveVMTracer { data: VMTrace { parent_step: self.data.operations.len(), - code: code.clone(), + code: code.to_vec(), operations: vec![], subs: vec![], }} diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index 53c062137..8f6c0b3f6 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -98,7 +98,7 @@ pub trait VMTracer: Send { fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} /// Spawn subtracer which will be used to trace deeper levels of execution. - fn prepare_subtrace(&self, code: &Bytes) -> Self where Self: Sized; + fn prepare_subtrace(&self, code: &[u8]) -> Self where Self: Sized; /// Spawn subtracer which will be used to trace deeper levels of execution. fn done_subtrace(&mut self, sub: Self) where Self: Sized; diff --git a/ethcore/src/trace/noop_tracer.rs b/ethcore/src/trace/noop_tracer.rs index ed0231b79..b6e6ca9fd 100644 --- a/ethcore/src/trace/noop_tracer.rs +++ b/ethcore/src/trace/noop_tracer.rs @@ -75,7 +75,7 @@ impl VMTracer for NoopVMTracer { fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} /// Spawn subtracer which will be used to trace deeper levels of execution. - fn prepare_subtrace(&self, _code: &Bytes) -> Self { NoopVMTracer } + fn prepare_subtrace(&self, _code: &[u8]) -> Self { NoopVMTracer } /// Spawn subtracer which will be used to trace deeper levels of execution. fn done_subtrace(&mut self, _sub: Self) {} diff --git a/parity/hypervisor/service.rs.in b/parity/hypervisor/service.rs.in index 12c39d90a..134194603 100644 --- a/parity/hypervisor/service.rs.in +++ b/parity/hypervisor/service.rs.in @@ -15,7 +15,6 @@ // along with Parity. If not, see . use std::sync::{RwLock,Arc}; -use std::ops::*; use ipc::IpcConfig; use std::collections::HashMap; use std::mem; diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 47c035daa..277be7fea 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -918,7 +918,7 @@ impl ChainSync { let skip: usize = try!(r.val_at(2)); let reverse: bool = try!(r.val_at(3)); let last = io.chain().chain_info().best_block_number; - let mut number = if try!(r.at(0)).size() == 32 { + let number = if try!(r.at(0)).size() == 32 { // id is a hash let hash: H256 = try!(r.val_at(0)); trace!(target: "sync", "-> GetBlockHeaders (hash: {}, max: {}, skip: {}, reverse:{})", hash, max_headers, skip, reverse); @@ -931,11 +931,11 @@ impl ChainSync { try!(r.val_at(0)) }; - if reverse { - number = min(last, number); + let mut number = if reverse { + min(last, number) } else { - number = max(0, number); - } + max(0, number) + }; let max_count = min(MAX_HEADERS_TO_SEND, max_headers); let mut count = 0; let mut data = Bytes::new(); @@ -1188,11 +1188,12 @@ impl ChainSync { let mut sent = 0; let last_parent = HeaderView::new(&io.chain().block_header(BlockID::Hash(chain_info.best_block_hash.clone())).unwrap()).parent_hash(); for (peer_id, peer_number) in lucky_peers { - let mut peer_best = self.peers.get(&peer_id).unwrap().latest_hash.clone(); - if chain_info.best_block_number - peer_number > MAX_PEER_LAG_PROPAGATION as BlockNumber { + let peer_best = if chain_info.best_block_number - peer_number > MAX_PEER_LAG_PROPAGATION as BlockNumber { // If we think peer is too far behind just send one latest hash - peer_best = last_parent.clone(); - } + last_parent.clone() + } else { + self.peers.get(&peer_id).unwrap().latest_hash.clone() + }; sent += match ChainSync::create_new_hashes_rlp(io.chain(), &peer_best, &chain_info.best_block_hash) { Some(rlp) => { { diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 9f69bb7da..9c7da71ab 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -162,6 +162,7 @@ impl NetworkProtocolHandler for EthSync { self.sync.write().unwrap().maintain_sync(&mut NetSyncIo::new(io, self.chain.deref())); } + #[cfg_attr(feature="dev", allow(single_match))] fn message(&self, io: &NetworkContext, message: &SyncMessage) { match *message { SyncMessage::NewChainBlocks { ref imported, ref invalid, ref enacted, ref retracted } => { diff --git a/util/src/hash.rs b/util/src/hash.rs index 1a16cefa4..acb4c5cc5 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -501,8 +501,8 @@ macro_rules! impl_hash { } } - impl<'_> From<&'_ str> for $from { - fn from(s: &'_ str) -> $from { + impl<'a> From<&'a str> for $from { + fn from(s: &'a str) -> $from { use std::str::FromStr; if s.len() % 2 == 1 { $from::from_str(&("0".to_owned() + &(clean_0x(s).to_owned()))[..]).unwrap_or_else(|_| $from::new()) @@ -524,8 +524,8 @@ impl From for H256 { } } -impl<'_> From<&'_ U256> for H256 { - fn from(value: &'_ U256) -> H256 { +impl<'a> From<&'a U256> for H256 { + fn from(value: &'a U256) -> H256 { unsafe { let mut ret: H256 = ::std::mem::uninitialized(); value.to_raw_bytes(&mut ret); @@ -540,8 +540,8 @@ impl From for U256 { } } -impl<'_> From<&'_ H256> for U256 { - fn from(value: &'_ H256) -> U256 { +impl<'a> From<&'a H256> for U256 { + fn from(value: &'a H256) -> U256 { U256::from(value.bytes()) } } @@ -566,8 +566,8 @@ impl From for H64 { } } /* -impl<'_> From<&'_ H256> for Address { - fn from(value: &'_ H256) -> Address { +impl<'a> From<&'a H256> for Address { + fn from(value: &'a H256) -> Address { unsafe { let mut ret: Address = ::std::mem::uninitialized(); ::std::ptr::copy(value.as_ptr().offset(12), ret.as_mut_ptr(), 20); @@ -586,8 +586,8 @@ impl From
for H256 { } } -impl<'_> From<&'_ Address> for H256 { - fn from(value: &'_ Address) -> H256 { +impl<'a> From<&'a Address> for H256 { + fn from(value: &'a Address) -> H256 { unsafe { let mut ret = H256::new(); ::std::ptr::copy(value.as_ptr(), ret.as_mut_ptr().offset(12), 20); diff --git a/util/src/network/discovery.rs b/util/src/network/discovery.rs index d65309246..b67110538 100644 --- a/util/src/network/discovery.rs +++ b/util/src/network/discovery.rs @@ -494,10 +494,11 @@ impl Discovery { } pub fn update_registration(&self, event_loop: &mut EventLoop) -> Result<(), NetworkError> { - let mut registration = EventSet::readable(); - if !self.send_queue.is_empty() { - registration = registration | EventSet::writable(); - } + let registration = if !self.send_queue.is_empty() { + EventSet::readable() | EventSet::writable() + } else { + EventSet::readable() + }; event_loop.reregister(&self.udp_socket, Token(self.token), registration, PollOpt::edge()).expect("Error reregistering UDP socket"); Ok(()) } diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 92a912a40..fe139e383 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -712,28 +712,25 @@ impl Host where Message: Send + Sync + Clone { let mut failure_id = None; let mut deregister = false; let mut expired_session = None; - match token { - FIRST_SESSION ... LAST_SESSION => { - let sessions = self.sessions.write().unwrap(); - if let Some(session) = sessions.get(token).cloned() { - expired_session = Some(session.clone()); - let mut s = session.lock().unwrap(); - if !s.expired() { - if s.is_ready() { - for (p, _) in self.handlers.read().unwrap().iter() { - if s.have_capability(p) { - self.num_sessions.fetch_sub(1, AtomicOrdering::SeqCst); - to_disconnect.push(p); - } + if let FIRST_SESSION ... LAST_SESSION = token { + let sessions = self.sessions.write().unwrap(); + if let Some(session) = sessions.get(token).cloned() { + expired_session = Some(session.clone()); + let mut s = session.lock().unwrap(); + if !s.expired() { + if s.is_ready() { + for (p, _) in self.handlers.read().unwrap().iter() { + if s.have_capability(p) { + self.num_sessions.fetch_sub(1, AtomicOrdering::SeqCst); + to_disconnect.push(p); } } - s.set_expired(); - failure_id = s.id().cloned(); } - deregister = remote || s.done(); + s.set_expired(); + failure_id = s.id().cloned(); } - }, - _ => {}, + deregister = remote || s.done(); + } } if let Some(id) = failure_id { if remote { From 6f850ebdacf6b7b68dac093b558a90d886e91c7e Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 3 Jun 2016 12:10:10 +0200 Subject: [PATCH 31/38] does_pruning -> is_pruned --- ethcore/src/client/client.rs | 2 +- util/src/journaldb/archivedb.rs | 2 +- util/src/journaldb/traits.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 9fbe8ae2d..f74fb33f5 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -382,7 +382,7 @@ impl Client where V: Verifier { let root = HeaderView::new(&header).state_root(); // check that the block is not too old -- blocks within `HISTORY` blocks of the best will // always be available. If the block could be too old, check if its state root is valid. - if db.does_pruning() + if db.is_pruned() && self.chain.best_block_number() >= block_number + HISTORY && !db.contains(&root) { return None; diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index c79bab23e..c6acc1280 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -176,7 +176,7 @@ impl JournalDB for ArchiveDB { self.backing.get_by_prefix(&id.bytes()[0..12]).and_then(|b| Some(b.to_vec())) } - fn does_pruning(&self) -> bool { false } + fn is_pruned(&self) -> bool { false } } #[cfg(test)] diff --git a/util/src/journaldb/traits.rs b/util/src/journaldb/traits.rs index d41077655..74149b062 100644 --- a/util/src/journaldb/traits.rs +++ b/util/src/journaldb/traits.rs @@ -43,6 +43,6 @@ pub trait JournalDB : HashDB + Send + Sync { None } - /// Whether this database does pruning. - fn does_pruning(&self) -> bool { true } + /// Whether this database is pruned. + fn is_pruned(&self) -> bool { true } } From aa465fa2cdbbeafa899b42ede17e879ad037d8ae Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 3 Jun 2016 12:15:27 +0200 Subject: [PATCH 32/38] conditional style fix --- ethcore/src/client/client.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index f74fb33f5..83b9e30ef 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -379,12 +379,11 @@ impl Client where V: Verifier { self.block_header(id).and_then(|header| { let db = self.state_db.lock().unwrap().boxed_clone(); - let root = HeaderView::new(&header).state_root(); // check that the block is not too old -- blocks within `HISTORY` blocks of the best will // always be available. If the block could be too old, check if its state root is valid. - if db.is_pruned() - && self.chain.best_block_number() >= block_number + HISTORY - && !db.contains(&root) { + let root = HeaderView::new(&header).state_root(); + let is_old = self.chain.best_block_number() >= block_number + HISTORY; + if db.is_pruned() && is_old && !db.contains(&root) { return None; } From e6921144dc62fc5f1b81ab7094a12221286b2779 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sun, 5 Jun 2016 22:05:01 +0200 Subject: [PATCH 33/38] simplify conditional in state_at --- ethcore/src/client/client.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 83b9e30ef..65cb13e4c 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -379,11 +379,8 @@ impl Client where V: Verifier { self.block_header(id).and_then(|header| { let db = self.state_db.lock().unwrap().boxed_clone(); - // check that the block is not too old -- blocks within `HISTORY` blocks of the best will - // always be available. If the block could be too old, check if its state root is valid. - let root = HeaderView::new(&header).state_root(); - let is_old = self.chain.best_block_number() >= block_number + HISTORY; - if db.is_pruned() && is_old && !db.contains(&root) { + // TODO [rob]: refactor State::from_existing so we avoid doing redundant lookups. + if !db.contains(&root) { return None; } From 3dff5a9f3f8825e859f807a916766bbb4357dfa4 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sun, 5 Jun 2016 22:14:25 +0200 Subject: [PATCH 34/38] add early exit for pruned blocks --- ethcore/src/client/client.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 65cb13e4c..008ca7860 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -379,6 +379,11 @@ impl Client where V: Verifier { self.block_header(id).and_then(|header| { let db = self.state_db.lock().unwrap().boxed_clone(); + // early exit for pruned blocks + if db.is_pruned() && self.chain.best_block_number() >= block_number + HISTORY { + return None; + } + // TODO [rob]: refactor State::from_existing so we avoid doing redundant lookups. if !db.contains(&root) { return None; From 64b74eae43628784fc9d6f2ef5d3a39fa57cf25a Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sun, 5 Jun 2016 23:50:27 +0200 Subject: [PATCH 35/38] fix travis build --- ethcore/src/client/client.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 008ca7860..4e834e2f8 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -384,12 +384,14 @@ impl Client where V: Verifier { return None; } + let root = HeaderView::new(&header).state_root(); + // TODO [rob]: refactor State::from_existing so we avoid doing redundant lookups. if !db.contains(&root) { return None; } - Some(State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce())) + Some(State::from_existing(db, root, self.engine.account_start_nonce())) }) } From 67b9e08ff0268bc78a9d7476954086e3d9a08903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 6 Jun 2016 10:11:43 +0200 Subject: [PATCH 36/38] Ignoring tests --- ethcore/src/json_tests/chain.rs | 3 ++- ethcore/src/json_tests/homestead_chain.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 53052d8dc..2bee5eb2a 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -85,7 +85,8 @@ declare_test!{BlockchainTests_bcForkStressTest, "BlockchainTests/bcForkStressTes declare_test!{BlockchainTests_bcForkUncle, "BlockchainTests/bcForkUncle"} declare_test!{BlockchainTests_bcGasPricerTest, "BlockchainTests/bcGasPricerTest"} declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"} -declare_test!{BlockchainTests_bcInvalidRLPTest, "BlockchainTests/bcInvalidRLPTest"} +// TODO [ToDr] Ignored because of incorrect JSON (https://github.com/ethereum/tests/pull/113) +declare_test!{ignore => BlockchainTests_bcInvalidRLPTest, "BlockchainTests/bcInvalidRLPTest"} declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"} declare_test!{BlockchainTests_bcRPC_API_Test, "BlockchainTests/bcRPC_API_Test"} declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTest"} diff --git a/ethcore/src/json_tests/homestead_chain.rs b/ethcore/src/json_tests/homestead_chain.rs index 7756840bc..8db8ad224 100644 --- a/ethcore/src/json_tests/homestead_chain.rs +++ b/ethcore/src/json_tests/homestead_chain.rs @@ -26,7 +26,8 @@ declare_test!{BlockchainTests_Homestead_bcBlockGasLimitTest, "BlockchainTests/Ho declare_test!{BlockchainTests_Homestead_bcForkStressTest, "BlockchainTests/Homestead/bcForkStressTest"} declare_test!{BlockchainTests_Homestead_bcGasPricerTest, "BlockchainTests/Homestead/bcGasPricerTest"} declare_test!{BlockchainTests_Homestead_bcInvalidHeaderTest, "BlockchainTests/Homestead/bcInvalidHeaderTest"} -declare_test!{BlockchainTests_Homestead_bcInvalidRLPTest, "BlockchainTests/Homestead/bcInvalidRLPTest"} +// TODO [ToDr] Ignored because of incorrect JSON (https://github.com/ethereum/tests/pull/113) +declare_test!{ignore => BlockchainTests_Homestead_bcInvalidRLPTest, "BlockchainTests/Homestead/bcInvalidRLPTest"} declare_test!{BlockchainTests_Homestead_bcMultiChainTest, "BlockchainTests/Homestead/bcMultiChainTest"} declare_test!{BlockchainTests_Homestead_bcRPC_API_Test, "BlockchainTests/Homestead/bcRPC_API_Test"} declare_test!{BlockchainTests_Homestead_bcStateTest, "BlockchainTests/Homestead/bcStateTest"} From 302126ebcff75cf73d2863f6a027804a29042a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 6 Jun 2016 12:01:59 +0200 Subject: [PATCH 37/38] Allowing connections only from chrome-extension and self-hosted client --- Cargo.lock | 2 +- signer/src/ws_server/mod.rs | 3 ++- signer/src/ws_server/session.rs | 40 +++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0044067dc..b22a8fad5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1448,7 +1448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ws" version = "0.4.6" -source = "git+https://github.com/ethcore/ws-rs.git#c0c2a3fc30dc77c4e6d4d90756f8bc3b5cfbc311" +source = "git+https://github.com/ethcore/ws-rs.git#5b28de58421b017b01f4565b2c35a46679707789" dependencies = [ "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index 0d55fd906..3b4924230 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -95,7 +95,8 @@ impl Server { }; // Create WebSocket - let ws = try!(ws::Builder::new().with_settings(config).build(session::Factory::new(handler))); + let origin = format!("{}", addr); + let ws = try!(ws::Builder::new().with_settings(config).build(session::Factory::new(handler, origin))); let panic_handler = PanicHandler::new_in_arc(); let ph = panic_handler.clone(); diff --git a/signer/src/ws_server/session.rs b/signer/src/ws_server/session.rs index 979914f06..54be63eaf 100644 --- a/signer/src/ws_server/session.rs +++ b/signer/src/ws_server/session.rs @@ -21,13 +21,46 @@ use sysui; use std::sync::Arc; use jsonrpc_core::IoHandler; +fn origin_is_allowed(self_origin: &str, header: Option<&Vec>) -> bool { + match header { + None => false, + Some(h) => { + let v = String::from_utf8(h.clone()).ok(); + match v { + Some(ref origin) if origin.starts_with("chrome-extension://") => true, + Some(ref origin) if origin.starts_with(self_origin) => true, + Some(ref origin) if origin.starts_with(&format!("http://{}", self_origin)) => true, + _ => false + } + } + } +} + +fn auth_is_valid(_header: Option<&Vec>) -> bool { + true +} + pub struct Session { out: ws::Sender, + self_origin: String, handler: Arc, } impl ws::Handler for Session { fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> { + let origin = req.header("origin").or_else(|| req.header("Origin")); + let host = req.header("host").or_else(|| req.header("Host")); + + // Check request origin and host header. + if !origin_is_allowed(&self.self_origin, origin) && !origin_is_allowed(&self.self_origin, host) { + return Ok(ws::Response::forbidden("You are not allowed to access system ui.".into())); + } + + // Check authorization + if !auth_is_valid(req.header("authorization")) { + return Ok(ws::Response::forbidden("You are not authorized.".into())); + } + // Detect if it's a websocket request. if req.header("sec-websocket-key").is_some() { return ws::Response::from_request(req); @@ -37,7 +70,7 @@ impl ws::Handler for Session { sysui::handle(req.resource()) .map_or_else( // return error - || ws::Response::from_request(req), + || Ok(ws::Response::not_found("Page not found".into())), // or serve the file |f| { let content_len = format!("{}", f.content.as_bytes().len()); @@ -67,12 +100,14 @@ impl ws::Handler for Session { pub struct Factory { handler: Arc, + self_origin: String, } impl Factory { - pub fn new(handler: Arc) -> Self { + pub fn new(handler: Arc, self_origin: String) -> Self { Factory { handler: handler, + self_origin: self_origin, } } } @@ -83,6 +118,7 @@ impl ws::Factory for Factory { fn connection_made(&mut self, sender: ws::Sender) -> Self::Handler { Session { out: sender, + self_origin: self.self_origin.clone(), handler: self.handler.clone(), } } From 18ffd946741e597740fc469894c7fc318cc1bd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 6 Jun 2016 12:17:30 +0200 Subject: [PATCH 38/38] Fixing warnings --- ethcore/src/miner/miner.rs | 4 ++-- ethcore/src/state.rs | 2 +- rpc/src/v1/impls/ethcore.rs | 3 +-- rpc/src/v1/impls/traces.rs | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 5dc3864c3..d35601970 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -20,7 +20,7 @@ use std::sync::atomic::AtomicBool; use util::*; use util::keys::store::{AccountProvider}; use views::{BlockView, HeaderView}; -use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockChainClient, BlockID, CallAnalytics}; +use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics}; use block::{ClosedBlock, IsBlock}; use error::*; use transaction::SignedTransaction; @@ -282,7 +282,7 @@ impl MinerService for Miner { } let options = TransactOptions { tracing: false, vm_tracing: analytics.vm_tracing, check_nonce: false }; let mut ret = Executive::new(&mut state, &env_info, self.engine(), chain.vm_factory()).transact(t, options); - + // TODO gav move this into Executive. if analytics.state_diffing { if let Ok(ref mut x) = ret { diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index 06a365bdd..72bd6c8fd 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -287,7 +287,7 @@ impl State { fn query_pod(&mut self, query: &PodState) { for (ref address, ref pod_account) in query.get() { if self.get(address, true).is_some() { - for (ref key, _) in &pod_account.storage { + for key in pod_account.storage.keys() { self.storage_at(address, key); } } diff --git a/rpc/src/v1/impls/ethcore.rs b/rpc/src/v1/impls/ethcore.rs index d9d5859d2..df88657d9 100644 --- a/rpc/src/v1/impls/ethcore.rs +++ b/rpc/src/v1/impls/ethcore.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . //! Ethcore-specific rpc implementation. -use util::{U256, Address, RotatingLogger, FixedHash}; +use util::{U256, Address, RotatingLogger}; use util::network_settings::NetworkSettings; use util::misc::version_data; use std::sync::{Arc, Weak}; @@ -23,7 +23,6 @@ use std::ops::Deref; use std::collections::BTreeMap; use jsonrpc_core::*; use ethcore::miner::MinerService; -use ethcore::client::{BlockChainClient}; use v1::traits::Ethcore; use v1::types::{Bytes}; diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index b6015d498..4cf8b8dfa 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -19,7 +19,7 @@ use std::sync::{Weak, Arc}; use jsonrpc_core::*; use std::collections::BTreeMap; -use util::{H256, U256, FixedHash, Uint}; +use util::{H256, U256, Uint}; use serde; use ethcore::client::{BlockChainClient, CallAnalytics, TransactionID, TraceId}; use ethcore::trace::VMTrace;