From 28391d2f52599724c5df93037f20d0c0316c918c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 26 May 2016 17:46:44 +0200 Subject: [PATCH 01/10] Basic signing queue --- Cargo.lock | 6 ++ rpc/Cargo.toml | 1 + rpc/src/lib.rs | 1 + rpc/src/v1/types/mod.rs.in | 8 +- signer/Cargo.toml | 9 ++- signer/build.rs | 27 +++++++ signer/src/lib.rs | 9 +++ signer/src/signing_queue.rs | 74 +++++++++++++++++++ {rpc/src/v1 => signer/src}/types/bytes.rs | 17 ++++- signer/src/types/mod.rs | 21 ++++++ signer/src/types/mod.rs.in | 19 +++++ .../src}/types/transaction_request.rs | 7 +- 12 files changed, 190 insertions(+), 9 deletions(-) create mode 100644 signer/src/signing_queue.rs rename {rpc/src/v1 => signer/src}/types/bytes.rs (77%) create mode 100644 signer/src/types/mod.rs create mode 100644 signer/src/types/mod.rs.in rename {rpc/src/v1 => signer/src}/types/transaction_request.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index 11c04d77d..39404a419 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,6 +301,7 @@ dependencies = [ "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.2.0", "ethcore 1.2.0", + "ethcore-signer 1.2.0", "ethcore-util 1.2.0", "ethminer 1.2.0", "ethsync 1.2.0", @@ -324,7 +325,12 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-util 1.2.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)", "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)", ] [[package]] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 2cdbb0a2b..c8bfa0485 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -19,6 +19,7 @@ ethcore = { path = "../ethcore" } ethash = { path = "../ethash" } ethsync = { path = "../sync" } ethminer = { path = "../miner" } +ethcore-signer = { path = "../signer" } rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 7d9818615..ae824adf2 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -27,6 +27,7 @@ extern crate serde_json; extern crate jsonrpc_core; extern crate jsonrpc_http_server; extern crate ethcore_util as util; +extern crate ethcore_signer as signer; extern crate ethcore; extern crate ethsync; extern crate ethminer; diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index d896a64dc..9b56221b5 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -14,31 +14,31 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +// TODO import signer types + mod block; mod block_number; -mod bytes; mod filter; mod index; mod log; mod optionals; mod sync; mod transaction; -mod transaction_request; mod call_request; mod receipt; mod trace; mod trace_filter; +pub use signer::types::bytes::Bytes; +pub use signer::types::transaction_request::TransactionRequest; pub use self::block::{Block, BlockTransactions}; pub use self::block_number::BlockNumber; -pub use self::bytes::Bytes; pub use self::filter::Filter; pub use self::index::Index; 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::call_request::CallRequest; pub use self::receipt::Receipt; pub use self::trace::Trace; diff --git a/signer/Cargo.toml b/signer/Cargo.toml index f72865f4f..0d7f562ab 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -9,13 +9,20 @@ 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" +serde_macros = { version = "0.7.0", optional = true } +rustc-serialize = "0.3" ethcore-util = { path = "../util" } log = "0.3" env_logger = "0.3" clippy = { version = "0.0.69", optional = true} [features] -default = [] +default = ["serde_codegen"] +nightly = ["serde_macros"] dev = ["clippy"] diff --git a/signer/build.rs b/signer/build.rs index 41b9a1b3e..2bcfc7da5 100644 --- a/signer/build.rs +++ b/signer/build.rs @@ -19,7 +19,34 @@ 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 fd17758d2..ed8ec12ce 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -34,6 +34,15 @@ extern crate log; extern crate env_logger; +extern crate serde; +extern crate serde_json; +extern crate rustc_serialize; + +extern crate ethcore_util as util; + +mod signing_queue; +pub mod types; + #[cfg(test)] mod tests { #[test] diff --git a/signer/src/signing_queue.rs b/signer/src/signing_queue.rs new file mode 100644 index 000000000..7758f5df3 --- /dev/null +++ b/signer/src/signing_queue.rs @@ -0,0 +1,74 @@ +// 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::HashSet; +use types::transaction_request::TransactionRequest; + +pub trait SigningQueue { + fn add_request(&mut self, transaction: TransactionRequest); + + fn remove_request(&mut self, id: TransactionRequest); + + fn requests(&self) -> &HashSet; +} + +impl SigningQueue for HashSet { + fn add_request(&mut self, transaction: TransactionRequest) { + self.insert(transaction); + } + + fn remove_request(&mut self, id: TransactionRequest) { + self.remove(&id); + } + + fn requests(&self) -> &HashSet { + self + } +} + + +#[cfg(test)] +mod test { + use std::collections::HashSet; + use util::hash::Address; + use util::numbers::U256; + use types::transaction_request::TransactionRequest; + use super::*; + + #[test] + fn should_work_for_hashset() { + // given + let mut queue = HashSet::new(); + + let request = TransactionRequest { + from: Address::from(1), + to: Some(Address::from(2)), + gas_price: None, + gas: None, + value: Some(U256::from(10_000_000)), + data: None, + nonce: None, + }; + + // when + queue.add_request(request.clone()); + let all = queue.requests(); + + // then + assert_eq!(all.len(), 1); + assert!(all.contains(&request)); + } +} diff --git a/rpc/src/v1/types/bytes.rs b/signer/src/types/bytes.rs similarity index 77% rename from rpc/src/v1/types/bytes.rs rename to signer/src/types/bytes.rs index 4febacec9..aa2772894 100644 --- a/rpc/src/v1/types/bytes.rs +++ b/signer/src/types/bytes.rs @@ -14,6 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +// 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 rustc_serialize::hex::ToHex; use serde::{Serialize, Serializer, Deserialize, Deserializer, Error}; use serde::de::Visitor; @@ -80,4 +96,3 @@ mod tests { } } - diff --git a/signer/src/types/mod.rs b/signer/src/types/mod.rs new file mode 100644 index 000000000..adf9be071 --- /dev/null +++ b/signer/src/types/mod.rs @@ -0,0 +1,21 @@ +// 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 . + +#[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 new file mode 100644 index 000000000..7040780f3 --- /dev/null +++ b/signer/src/types/mod.rs.in @@ -0,0 +1,19 @@ +// 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 . + + +pub mod transaction_request; +pub mod bytes; diff --git a/rpc/src/v1/types/transaction_request.rs b/signer/src/types/transaction_request.rs similarity index 97% rename from rpc/src/v1/types/transaction_request.rs rename to signer/src/types/transaction_request.rs index f00fa9ef0..f95d7ff4c 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/signer/src/types/transaction_request.rs @@ -16,9 +16,9 @@ use util::hash::Address; use util::numbers::U256; -use v1::types::Bytes; +use types::bytes::Bytes; -#[derive(Debug, Default, PartialEq, Deserialize)] +#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize)] pub struct TransactionRequest { pub from: Address, pub to: Option
, @@ -37,7 +37,7 @@ mod tests { use serde_json; use util::numbers::{U256}; use util::hash::Address; - use v1::types::Bytes; + use types::bytes::Bytes; use super::*; #[test] @@ -126,3 +126,4 @@ mod tests { }); } } + From a61bf90c17bb68ee7f1c599366f15b1efbd85795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 26 May 2016 18:33:08 +0200 Subject: [PATCH 02/10] Adding docs --- signer/src/lib.rs | 2 ++ signer/src/types/bytes.rs | 23 ++++++----------------- signer/src/types/mod.rs.in | 1 + signer/src/types/transaction_request.rs | 10 ++++++++++ 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/signer/src/lib.rs b/signer/src/lib.rs index ed8ec12ce..d8e7f63ec 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -17,6 +17,8 @@ #![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 //! diff --git a/signer/src/types/bytes.rs b/signer/src/types/bytes.rs index aa2772894..d8896f849 100644 --- a/signer/src/types/bytes.rs +++ b/signer/src/types/bytes.rs @@ -14,27 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -// 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 rustc_serialize::hex::ToHex; use serde::{Serialize, Serializer, Deserialize, Deserializer, Error}; use serde::de::Visitor; use util::common::FromHex; +///! Serializable wrapper around vector of bytes + /// Wrapper structure around vector of bytes. #[derive(Debug, PartialEq, Eq, Default, Hash, Clone)] pub struct Bytes(pub Vec); @@ -44,7 +30,10 @@ impl Bytes { pub fn new(bytes: Vec) -> Bytes { Bytes(bytes) } - pub fn to_vec(self) -> Vec { let Bytes(x) = self; x } + /// Convert back to vector + pub fn to_vec(self) -> Vec { + let Bytes(x) = self; x + } } impl Serialize for Bytes { diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in index 7040780f3..8e9befa4f 100644 --- a/signer/src/types/mod.rs.in +++ b/signer/src/types/mod.rs.in @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +///! Reusable types with JSON Serialization. pub mod transaction_request; pub mod bytes; diff --git a/signer/src/types/transaction_request.rs b/signer/src/types/transaction_request.rs index f95d7ff4c..83840515b 100644 --- a/signer/src/types/transaction_request.rs +++ b/signer/src/types/transaction_request.rs @@ -14,19 +14,29 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! `TransactionRequest` type + use util::hash::Address; use util::numbers::U256; use types::bytes::Bytes; +/// Transaction request coming from RPC #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize)] pub struct TransactionRequest { + /// Sender pub from: Address, + /// Recipient pub to: Option
, + /// Gas Price #[serde(rename="gasPrice")] pub gas_price: Option, + /// Gas pub gas: Option, + /// Value of transaction in wei pub value: Option, + /// Additional data sent with transaction pub data: Option, + /// Transaction's nonce pub nonce: Option, } From b77fdcdd6876a2f05f1a0b63f6f9f50d7d5088ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 13:03:00 +0200 Subject: [PATCH 03/10] WebSockets server for signer --- Cargo.lock | 27 ++++++++ dapps/src/lib.rs | 6 +- parity/cli.rs | 7 ++ parity/main.rs | 24 ++++++- parity/setup_log.rs | 2 + parity/signer.rs | 67 +++++++++++++++++++ signer/Cargo.toml | 4 +- signer/src/lib.rs | 12 ++++ signer/src/types/bytes.rs | 4 +- signer/src/types/mod.rs | 2 + signer/src/types/mod.rs.in | 2 - signer/src/ws_server.rs | 128 +++++++++++++++++++++++++++++++++++++ 12 files changed, 275 insertions(+), 10 deletions(-) create mode 100644 parity/signer.rs create mode 100644 signer/src/ws_server.rs diff --git a/Cargo.lock b/Cargo.lock index 8379e101e..66df9192a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,6 +105,11 @@ name = "bloomchain" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "byteorder" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bytes" version = "0.3.0" @@ -356,6 +361,7 @@ dependencies = [ "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)", ] [[package]] @@ -1167,6 +1173,14 @@ dependencies = [ "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha1" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sha3" version = "0.1.0" @@ -1411,6 +1425,19 @@ name = "winapi-build" version = "0.1.1" 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" +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)", + "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)", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index c6e75072d..e0676881f 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -34,9 +34,9 @@ //! let io = IoHandler::new(); //! io.add_method("say_hello", SayHello); //! let _server = Server::start_unsecure_http( -//! &"127.0.0.1:3030".parse().unwrap(), -//! Arc::new(io) -//! ); +//! &"127.0.0.1:3030".parse().unwrap(), +//! Arc::new(io) +//! ); //! } //! ``` //! diff --git a/parity/cli.rs b/parity/cli.rs index 4bb74f188..60b622bf7 100644 --- a/parity/cli.rs +++ b/parity/cli.rs @@ -97,6 +97,11 @@ API and Console Options: --dapps-pass PASSWORD Specify password for Dapps server. Use only in conjunction with --dapps-user. + --signer Enable Trusted Signer WebSocket endpoint used by + System UIs. + --signer-port PORT Specify the port of Trusted Signer server + [default: 8180]. + Sealing/Mining Options: --force-sealing Force the node to author new blocks as if it were always sealing/mining. @@ -234,6 +239,8 @@ pub struct Args { pub flag_dapps_interface: String, pub flag_dapps_user: Option, pub flag_dapps_pass: Option, + pub flag_signer: bool, + pub flag_signer_port: u16, pub flag_force_sealing: bool, pub flag_author: String, pub flag_usd_per_tx: String, diff --git a/parity/main.rs b/parity/main.rs index e87828f64..1e9ab33f5 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -50,6 +50,11 @@ extern crate ethcore_rpc; #[cfg(feature = "dapps")] extern crate ethcore_dapps; +#[cfg(feature = "ethcore-signer")] +extern crate ethcore_signer; + + + #[macro_use] mod die; mod price_info; @@ -63,6 +68,7 @@ mod io_handler; mod cli; mod configuration; mod migration; +mod signer; use std::io::{Write, Read, BufReader, BufRead}; use std::ops::Deref; @@ -89,6 +95,7 @@ use informant::Informant; use die::*; use cli::print_version; use rpc::RpcServer; +use signer::SignerServer; use dapps::WebappServer; use io_handler::ClientIoHandler; use configuration::Configuration; @@ -231,6 +238,14 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) settings: network_settings.clone(), }); + // Set up a signer + let signer_server = signer::start(signer::Configuration { + enabled: conf.args.flag_signer, + port: conf.args.flag_signer_port, + }, signer::Dependencies { + panic_handler: panic_handler.clone(), + }); + // Register IO handler let io_handler = Arc::new(ClientIoHandler { client: service.client(), @@ -241,7 +256,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) service.io().register_handler(io_handler).expect("Error registering IO handler"); // Handle exit - wait_for_exit(panic_handler, rpc_server, dapps_server); + wait_for_exit(panic_handler, rpc_server, dapps_server, signer_server); } fn flush_stdout() { @@ -453,7 +468,12 @@ fn execute_account_cli(conf: Configuration) { } } -fn wait_for_exit(panic_handler: Arc, _rpc_server: Option, _dapps_server: Option) { +fn wait_for_exit( + panic_handler: Arc, + _rpc_server: Option, + _dapps_server: Option, + _signer_server: Option + ) { let exit = Arc::new(Condvar::new()); // Handle possible exits diff --git a/parity/setup_log.rs b/parity/setup_log.rs index 0fbc76fb3..4ed153fc2 100644 --- a/parity/setup_log.rs +++ b/parity/setup_log.rs @@ -27,6 +27,8 @@ pub fn setup_log(init: &Option) -> Arc { let mut levels = String::new(); let mut builder = LogBuilder::new(); + // Disable ws info logging by default. + builder.filter(Some("ws"), LogLevelFilter::Warn); builder.filter(None, LogLevelFilter::Info); if env::var("RUST_LOG").is_ok() { diff --git a/parity/signer.rs b/parity/signer.rs new file mode 100644 index 000000000..e7f7a9cb9 --- /dev/null +++ b/parity/signer.rs @@ -0,0 +1,67 @@ +// 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::sync::Arc; +use util::panics::{PanicHandler, ForwardPanic}; +use die::*; + +#[cfg(feature = "ethcore-signer")] +use ethcore_signer as signer; +#[cfg(feature = "ethcore-signer")] +pub use ethcore_signer::Server as SignerServer; +#[cfg(not(feature = "ethcore-signer"))] +pub struct SignerServer; + +pub struct Configuration { + pub enabled: bool, + pub port: u16, +} + +pub struct Dependencies { + pub panic_handler: Arc, +} + +#[cfg(feature = "ethcore-signer")] +pub fn start(conf: Configuration, deps: Dependencies) -> Option { + if !conf.enabled { + return None; + } + + let addr = format!("127.0.0.1:{}", conf.port).parse().unwrap_or_else(|_| die!("Invalid port specified: {}", conf.port)); + let start_result = signer::Server::start(addr); + + match start_result { + Err(signer::ServerError::IoError(err)) => die_with_io_error("Trusted Signer", err), + Err(e) => die!("Trusted Signer: {:?}", e), + Ok(server) => { + deps.panic_handler.forward_from(&server); + Some(server) + }, + } +} + +#[cfg(not(feature = "ethcore-signer"))] +pub fn start(conf: Configuration) -> !{ + if !conf.enabled { + return None; + } + + die!("Your Parity version has been compiled without Trusted Signer support.") +} + + + + diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 0d7f562ab..be77a3fd9 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -15,11 +15,13 @@ syntex = "^0.32.0" [dependencies] serde = "0.7.0" serde_json = "0.7.0" -serde_macros = { version = "0.7.0", optional = true } rustc-serialize = "0.3" ethcore-util = { path = "../util" } log = "0.3" env_logger = "0.3" +ws = "0.4.7" + +serde_macros = { version = "0.7.0", optional = true } clippy = { version = "0.0.69", optional = true} [features] diff --git a/signer/src/lib.rs b/signer/src/lib.rs index d8e7f63ec..13f8d2fa6 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -30,7 +30,15 @@ //! and their responsibility is to confirm (or confirm and sign) //! the transaction for you. //! +//! ``` +//! extern crate ethcore_signer; //! +//! use ethcore_signer::Server; +//! +//! fn main() { +//! let _server = Server::start("127.0.0.1:8084".parse().unwrap()); +//! } +//! ``` #[macro_use] extern crate log; @@ -41,10 +49,14 @@ extern crate serde_json; extern crate rustc_serialize; extern crate ethcore_util as util; +extern crate ws; mod signing_queue; +mod ws_server; pub mod types; +pub use ws_server::*; + #[cfg(test)] mod tests { #[test] diff --git a/signer/src/types/bytes.rs b/signer/src/types/bytes.rs index d8896f849..503927676 100644 --- a/signer/src/types/bytes.rs +++ b/signer/src/types/bytes.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Serializable wrapper around vector of bytes + use rustc_serialize::hex::ToHex; use serde::{Serialize, Serializer, Deserialize, Deserializer, Error}; use serde::de::Visitor; use util::common::FromHex; -///! Serializable wrapper around vector of bytes - /// Wrapper structure around vector of bytes. #[derive(Debug, PartialEq, Eq, Default, Hash, Clone)] pub struct Bytes(pub Vec); diff --git a/signer/src/types/mod.rs b/signer/src/types/mod.rs index adf9be071..d5e15046a 100644 --- a/signer/src/types/mod.rs +++ b/signer/src/types/mod.rs @@ -14,6 +14,8 @@ // 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"); diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in index 8e9befa4f..986e3d6e2 100644 --- a/signer/src/types/mod.rs.in +++ b/signer/src/types/mod.rs.in @@ -14,7 +14,5 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -///! Reusable types with JSON Serialization. - pub mod transaction_request; pub mod bytes; diff --git a/signer/src/ws_server.rs b/signer/src/ws_server.rs new file mode 100644 index 000000000..9be392e69 --- /dev/null +++ b/signer/src/ws_server.rs @@ -0,0 +1,128 @@ +// 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 . + +//! `WebSockets` server. + +use ws; +use std; +use std::thread; +use std::ops::Drop; +use std::sync::Arc; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::net::SocketAddr; +use util::panics::{PanicHandler, OnPanicListener, MayPanic}; + +/// Signer startup error +#[derive(Debug)] +pub enum ServerError { + /// Wrapped `std::io::Error` + IoError(std::io::Error), + /// Other `ws-rs` error + Other(ws::Error) +} + +impl From for ServerError { + fn from(err: ws::Error) -> Self { + match err.kind { + ws::ErrorKind::Io(e) => ServerError::IoError(e), + _ => ServerError::Other(err), + } + } +} + +/// `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) -> Result { + let config = { + let mut config = ws::Settings::default(); + config.max_connections = 5; + config.method_strict = true; + config + }; + + // Create WebSocket + let session_id = Arc::new(AtomicUsize::new(1)); + let ws = try!(ws::Builder::new().with_settings(config).build(Factory { + session_id: session_id, + })); + + 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 || { + ws.listen(addr).unwrap() + }).unwrap() + }); + + // Return a handle + Ok(Server { + handle: Some(handle), + broadcaster: broadcaster, + panic_handler: panic_handler, + }) + } +} + +impl MayPanic for Server { + fn on_panic(&self, closure: F) where F: OnPanicListener { + self.panic_handler.on_panic(closure); + } +} + +impl Drop for Server { + fn drop(&mut self) { + self.broadcaster.shutdown().expect("WsServer should close nicely."); + self.handle.take().unwrap().join().unwrap(); + } +} + +struct Session { + id: usize, + out: ws::Sender, +} + +impl ws::Handler for Session { + fn on_open(&mut self, _shake: ws::Handshake) -> ws::Result<()> { + try!(self.out.send(format!("Hello client no: {}. We are not implemented yet.", self.id))); + try!(self.out.close(ws::CloseCode::Normal)); + Ok(()) + } +} + +struct Factory { + session_id: Arc, +} + +impl ws::Factory for Factory { + type Handler = Session; + + fn connection_made(&mut self, sender: ws::Sender) -> Self::Handler { + Session { + id: self.session_id.fetch_add(1, Ordering::SeqCst), + out: sender, + } + } +} From e2db4972be2f136182c9f2f444a8bb44b4e36188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 13:04:54 +0200 Subject: [PATCH 04/10] Removing TODO --- rpc/src/v1/types/mod.rs.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 9b56221b5..9d7fc882a 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -// TODO import signer types - mod block; mod block_number; mod filter; From d0ae713b29c112ce320d15f70d88019f5bac1a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 13:05:54 +0200 Subject: [PATCH 05/10] Shortening the syntax --- signer/src/types/bytes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signer/src/types/bytes.rs b/signer/src/types/bytes.rs index 503927676..76d84d0dd 100644 --- a/signer/src/types/bytes.rs +++ b/signer/src/types/bytes.rs @@ -32,7 +32,7 @@ impl Bytes { } /// Convert back to vector pub fn to_vec(self) -> Vec { - let Bytes(x) = self; x + self.0 } } From cf19e3866366451b2e96beb2f01e35c89f9e2ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 15:46:07 +0200 Subject: [PATCH 06/10] Exposing types from RPC --- Cargo.lock | 2 +- rpc/Cargo.toml | 1 - rpc/src/lib.rs | 1 - rpc/src/v1/mod.rs | 4 +-- rpc/src/v1/types/block.rs | 23 ++++++++++++ rpc/src/v1/types/block_number.rs | 4 +++ {signer/src => rpc/src/v1}/types/bytes.rs | 0 rpc/src/v1/types/call_request.rs | 8 +++++ rpc/src/v1/types/filter.rs | 11 ++++++ rpc/src/v1/types/index.rs | 1 + rpc/src/v1/types/log.rs | 10 ++++++ rpc/src/v1/types/mod.rs | 2 ++ rpc/src/v1/types/mod.rs.in | 6 ++-- rpc/src/v1/types/optionals.rs | 3 ++ rpc/src/v1/types/receipt.rs | 9 +++++ rpc/src/v1/types/sync.rs | 7 ++++ rpc/src/v1/types/trace.rs | 35 +++++++++++++++++++ rpc/src/v1/types/trace_filter.rs | 5 +++ rpc/src/v1/types/transaction.rs | 12 +++++++ .../src/v1}/types/transaction_request.rs | 2 +- signer/Cargo.toml | 3 +- signer/src/lib.rs | 2 +- signer/src/signing_queue.rs | 4 +-- signer/src/types/mod.rs.in | 11 ++++-- signer/src/ws_server.rs | 4 +-- 25 files changed, 154 insertions(+), 16 deletions(-) rename {signer/src => rpc/src/v1}/types/bytes.rs (100%) rename {signer/src => rpc/src/v1}/types/transaction_request.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index 66df9192a..6298ef7ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,7 +331,6 @@ dependencies = [ "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.2.0", "ethcore 1.2.0", - "ethcore-signer 1.2.0", "ethcore-util 1.2.0", "ethminer 1.2.0", "ethsync 1.2.0", @@ -353,6 +352,7 @@ version = "1.2.0" dependencies = [ "clippy 0.0.69 (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", "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)", diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index c8bfa0485..2cdbb0a2b 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -19,7 +19,6 @@ ethcore = { path = "../ethcore" } ethash = { path = "../ethash" } ethsync = { path = "../sync" } ethminer = { path = "../miner" } -ethcore-signer = { path = "../signer" } rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index ae824adf2..7d9818615 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -27,7 +27,6 @@ extern crate serde_json; extern crate jsonrpc_core; extern crate jsonrpc_http_server; extern crate ethcore_util as util; -extern crate ethcore_signer as signer; extern crate ethcore; extern crate ethsync; extern crate ethminer; diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index f3bb450f3..b1ab256c0 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -18,12 +18,12 @@ //! //! Compliant with ethereum rpc. -pub mod traits; mod impls; -mod types; mod helpers; +pub mod traits; pub mod tests; +pub mod types; pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore, Traces, Rpc}; pub use self::impls::*; diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index c38949c08..5810c85e5 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -18,9 +18,12 @@ use serde::{Serialize, Serializer}; use util::numbers::*; use v1::types::{Bytes, Transaction, OptionalValue}; +/// Block Transactions #[derive(Debug)] pub enum BlockTransactions { + /// Only hashes Hashes(Vec), + /// Full transactions Full(Vec) } @@ -34,38 +37,58 @@ impl Serialize for BlockTransactions { } } +/// Block representation #[derive(Debug, Serialize)] pub struct Block { + /// Hash of the block pub hash: OptionalValue, + /// Hash of the parent #[serde(rename="parentHash")] pub parent_hash: H256, + /// Hash of the uncles #[serde(rename="sha3Uncles")] pub uncles_hash: H256, + /// Authors address pub author: Address, // TODO: get rid of this one + /// ? pub miner: Address, + /// State root hash #[serde(rename="stateRoot")] pub state_root: H256, + /// Transactions root hash #[serde(rename="transactionsRoot")] pub transactions_root: H256, + /// Transactions receipts root hash #[serde(rename="receiptsRoot")] pub receipts_root: H256, + /// Block number pub number: OptionalValue, + /// Gas Used #[serde(rename="gasUsed")] pub gas_used: U256, + /// Gas Limit #[serde(rename="gasLimit")] pub gas_limit: U256, + /// Extra data #[serde(rename="extraData")] pub extra_data: Bytes, + /// Logs bloom #[serde(rename="logsBloom")] pub logs_bloom: H2048, + /// Timestamp pub timestamp: U256, + /// Difficulty pub difficulty: U256, + /// Total difficulty #[serde(rename="totalDifficulty")] pub total_difficulty: U256, + /// Seal fields #[serde(rename="sealFields")] pub seal_fields: Vec, + /// Uncles' hashes pub uncles: Vec, + /// Transactions pub transactions: BlockTransactions } diff --git a/rpc/src/v1/types/block_number.rs b/rpc/src/v1/types/block_number.rs index 071486afd..e2d150c66 100644 --- a/rpc/src/v1/types/block_number.rs +++ b/rpc/src/v1/types/block_number.rs @@ -21,9 +21,13 @@ use ethcore::client::BlockID; /// Represents rpc api block number param. #[derive(Debug, PartialEq, Clone)] pub enum BlockNumber { + /// Number Num(u64), + /// Latest block Latest, + /// Earliest block (genesis) Earliest, + /// Pending block (being mined) Pending } diff --git a/signer/src/types/bytes.rs b/rpc/src/v1/types/bytes.rs similarity index 100% rename from signer/src/types/bytes.rs rename to rpc/src/v1/types/bytes.rs diff --git a/rpc/src/v1/types/call_request.rs b/rpc/src/v1/types/call_request.rs index 045b1cd9b..50ebbd1f0 100644 --- a/rpc/src/v1/types/call_request.rs +++ b/rpc/src/v1/types/call_request.rs @@ -18,15 +18,23 @@ use util::hash::Address; use util::numbers::U256; use v1::types::Bytes; +/// Call request #[derive(Debug, Default, PartialEq, Deserialize)] pub struct CallRequest { + /// From pub from: Option
, + /// To pub to: Option
, + /// Gas Price #[serde(rename="gasPrice")] pub gas_price: Option, + /// Gas pub gas: Option, + /// Value pub value: Option, + /// Data pub data: Option, + /// Nonce pub nonce: Option, } diff --git a/rpc/src/v1/types/filter.rs b/rpc/src/v1/types/filter.rs index e50ec9c32..77a3f0500 100644 --- a/rpc/src/v1/types/filter.rs +++ b/rpc/src/v1/types/filter.rs @@ -22,10 +22,14 @@ use v1::types::BlockNumber; use ethcore::filter::Filter as EthFilter; use ethcore::client::BlockID; +/// Variadic value #[derive(Debug, PartialEq, Clone)] pub enum VariadicValue where T: Deserialize { + /// Single Single(T), + /// List Multiple(Vec), + /// None Null, } @@ -44,17 +48,24 @@ impl Deserialize for VariadicValue where T: Deserialize { } } +/// Filter Address pub type FilterAddress = VariadicValue
; +/// Topic pub type Topic = VariadicValue; +/// Filter #[derive(Debug, PartialEq, Clone, Deserialize)] #[serde(deny_unknown_fields)] pub struct Filter { + /// From Block #[serde(rename="fromBlock")] pub from_block: Option, + /// To Block #[serde(rename="toBlock")] pub to_block: Option, + /// Address pub address: Option, + /// Topics pub topics: Option>, } diff --git a/rpc/src/v1/types/index.rs b/rpc/src/v1/types/index.rs index e7cbbd255..d7b17aea2 100644 --- a/rpc/src/v1/types/index.rs +++ b/rpc/src/v1/types/index.rs @@ -22,6 +22,7 @@ use serde::de::Visitor; pub struct Index(usize); impl Index { + /// Convert to usize pub fn value(&self) -> usize { self.0 } diff --git a/rpc/src/v1/types/log.rs b/rpc/src/v1/types/log.rs index 426ca68f1..72a482d1b 100644 --- a/rpc/src/v1/types/log.rs +++ b/rpc/src/v1/types/log.rs @@ -18,21 +18,31 @@ use util::numbers::*; use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use v1::types::Bytes; +/// Log #[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone)] pub struct Log { + /// Address pub address: Address, + /// Topics pub topics: Vec, + /// Data pub data: Bytes, + /// Block Hash #[serde(rename="blockHash")] pub block_hash: Option, + /// Block Number #[serde(rename="blockNumber")] pub block_number: Option, + /// Transaction Hash #[serde(rename="transactionHash")] pub transaction_hash: Option, + /// Transaction Index #[serde(rename="transactionIndex")] pub transaction_index: Option, + /// Log Index #[serde(rename="logIndex")] pub log_index: Option, + /// Log Type #[serde(rename="type")] pub log_type: String, } diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index adf9be071..c1bc34407 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Structures used in RPC communication + #[cfg(feature = "serde_macros")] include!("mod.rs.in"); diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 9d7fc882a..824a061ef 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +mod bytes; mod block; mod block_number; mod filter; @@ -22,13 +23,13 @@ mod log; mod optionals; mod sync; mod transaction; +mod transaction_request; mod call_request; mod receipt; mod trace; mod trace_filter; -pub use signer::types::bytes::Bytes; -pub use signer::types::transaction_request::TransactionRequest; +pub use self::bytes::Bytes; pub use self::block::{Block, BlockTransactions}; pub use self::block_number::BlockNumber; pub use self::filter::Filter; @@ -37,6 +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::call_request::CallRequest; pub use self::receipt::Receipt; pub use self::trace::Trace; diff --git a/rpc/src/v1/types/optionals.rs b/rpc/src/v1/types/optionals.rs index 5db272251..2ed272ade 100644 --- a/rpc/src/v1/types/optionals.rs +++ b/rpc/src/v1/types/optionals.rs @@ -17,9 +17,12 @@ use serde::{Serialize, Serializer}; use serde_json::Value; +/// Optional value #[derive(Debug)] pub enum OptionalValue where T: Serialize { + /// Some Value(T), + /// None Null } diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index 51d914e1a..32a7f5945 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -19,22 +19,31 @@ use util::hash::{Address, H256}; use v1::types::Log; use ethcore::receipt::LocalizedReceipt; +/// Receipt #[derive(Debug, Serialize)] pub struct Receipt { + /// Transaction Hash #[serde(rename="transactionHash")] pub transaction_hash: H256, + /// Transaction index #[serde(rename="transactionIndex")] pub transaction_index: U256, + /// Block hash #[serde(rename="blockHash")] pub block_hash: H256, + /// Block number #[serde(rename="blockNumber")] pub block_number: U256, + /// Cumulative gas used #[serde(rename="cumulativeGasUsed")] pub cumulative_gas_used: U256, + /// Gas used #[serde(rename="gasUsed")] pub gas_used: U256, + /// Contract address #[serde(rename="contractAddress")] pub contract_address: Option
, + /// Logs pub logs: Vec, } diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index c0e480140..6d750425e 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -17,19 +17,26 @@ use serde::{Serialize, Serializer}; use util::numbers::*; +/// Sync info #[derive(Default, Debug, Serialize, PartialEq)] pub struct SyncInfo { + /// Starting block #[serde(rename="startingBlock")] pub starting_block: U256, + /// Current block #[serde(rename="currentBlock")] pub current_block: U256, + /// Highest block seen so far #[serde(rename="highestBlock")] pub highest_block: U256, } +/// Sync status #[derive(Debug, PartialEq)] pub enum SyncStatus { + /// Info when syncing Info(SyncInfo), + /// Not syncing None } diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index 4cd1ac408..6ea58543a 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -19,11 +19,16 @@ use ethcore::trace::trace; use ethcore::trace::LocalizedTrace; use v1::types::Bytes; +/// Create response #[derive(Debug, Serialize)] pub struct Create { + /// Sender from: Address, + /// Value value: U256, + /// Gas gas: U256, + /// Initialization code init: Bytes, } @@ -38,12 +43,18 @@ impl From for Create { } } +/// Call response #[derive(Debug, Serialize)] pub struct Call { + /// Sender from: Address, + /// Recipient to: Address, + /// Transfered Value value: U256, + /// Gas gas: U256, + /// Input data input: Bytes, } @@ -59,10 +70,13 @@ impl From for Call { } } +/// Action #[derive(Debug, Serialize)] pub enum Action { + /// Call #[serde(rename="call")] Call(Call), + /// Create #[serde(rename="create")] Create(Create), } @@ -76,10 +90,13 @@ impl From for Action { } } +/// Call Result #[derive(Debug, Serialize)] pub struct CallResult { + /// Gas used #[serde(rename="gasUsed")] gas_used: U256, + /// Output bytes output: Bytes, } @@ -92,11 +109,15 @@ impl From for CallResult { } } +/// Craete Result #[derive(Debug, Serialize)] pub struct CreateResult { + /// Gas used #[serde(rename="gasUsed")] gas_used: U256, + /// Code code: Bytes, + /// Assigned address address: Address, } @@ -110,14 +131,19 @@ impl From for CreateResult { } } +/// Response #[derive(Debug, Serialize)] pub enum Res { + /// Call #[serde(rename="call")] Call(CallResult), + /// Create #[serde(rename="create")] Create(CreateResult), + /// Call failure #[serde(rename="failedCall")] FailedCall, + /// Creation failure #[serde(rename="failedCreate")] FailedCreate, } @@ -133,19 +159,28 @@ impl From for Res { } } +/// Trace #[derive(Debug, Serialize)] pub struct Trace { + /// Action action: Action, + /// Result result: Res, + /// Trace address #[serde(rename="traceAddress")] trace_address: Vec, + /// Subtraces subtraces: U256, + /// Transaction position #[serde(rename="transactionPosition")] transaction_position: U256, + /// Transaction hash #[serde(rename="transactionHash")] transaction_hash: H256, + /// Block Number #[serde(rename="blockNumber")] block_number: U256, + /// Block Hash #[serde(rename="blockHash")] block_hash: H256, } diff --git a/rpc/src/v1/types/trace_filter.rs b/rpc/src/v1/types/trace_filter.rs index 3d45f4c79..ee2f231f0 100644 --- a/rpc/src/v1/types/trace_filter.rs +++ b/rpc/src/v1/types/trace_filter.rs @@ -21,14 +21,19 @@ use ethcore::client::BlockID; use ethcore::client; use super::BlockNumber; +/// Trace filter #[derive(Debug, PartialEq, Deserialize)] pub struct TraceFilter { + /// From block #[serde(rename="fromBlock")] pub from_block: Option, + /// To block #[serde(rename="toBlock")] pub to_block: Option, + /// From address #[serde(rename="fromAddress")] pub from_address: Option>, + /// To address #[serde(rename="toAddress")] pub to_address: Option>, } diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 8a46d5e15..1c9a41084 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -18,22 +18,34 @@ use util::numbers::*; use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction}; use v1::types::{Bytes, OptionalValue}; +/// Transaction #[derive(Debug, Default, Serialize)] pub struct Transaction { + /// Hash pub hash: H256, + /// Nonce pub nonce: U256, + /// Block hash #[serde(rename="blockHash")] pub block_hash: OptionalValue, + /// Block number #[serde(rename="blockNumber")] pub block_number: OptionalValue, + /// Transaction Index #[serde(rename="transactionIndex")] pub transaction_index: OptionalValue, + /// Sender pub from: Address, + /// Recipient pub to: OptionalValue
, + /// Transfered value pub value: U256, + /// Gas Price #[serde(rename="gasPrice")] pub gas_price: U256, + /// Gas pub gas: U256, + /// Data pub input: Bytes } diff --git a/signer/src/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs similarity index 99% rename from signer/src/types/transaction_request.rs rename to rpc/src/v1/types/transaction_request.rs index 83840515b..2fc806912 100644 --- a/signer/src/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -18,7 +18,7 @@ use util::hash::Address; use util::numbers::U256; -use types::bytes::Bytes; +use v1::types::bytes::Bytes; /// Transaction request coming from RPC #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize)] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index be77a3fd9..59c7f90b2 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -16,10 +16,11 @@ syntex = "^0.32.0" serde = "0.7.0" serde_json = "0.7.0" rustc-serialize = "0.3" -ethcore-util = { path = "../util" } 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} diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 13f8d2fa6..4317338e0 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -49,11 +49,11 @@ extern crate serde_json; extern crate rustc_serialize; extern crate ethcore_util as util; +extern crate ethcore_rpc as rpc; extern crate ws; mod signing_queue; mod ws_server; -pub mod types; pub use ws_server::*; diff --git a/signer/src/signing_queue.rs b/signer/src/signing_queue.rs index 7758f5df3..d320d2375 100644 --- a/signer/src/signing_queue.rs +++ b/signer/src/signing_queue.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use std::collections::HashSet; -use types::transaction_request::TransactionRequest; +use rpc::v1::types::TransactionRequest; pub trait SigningQueue { fn add_request(&mut self, transaction: TransactionRequest); @@ -45,7 +45,7 @@ mod test { use std::collections::HashSet; use util::hash::Address; use util::numbers::U256; - use types::transaction_request::TransactionRequest; + use rpc::v1::types::transaction_request::TransactionRequest; use super::*; #[test] diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in index 986e3d6e2..a59f81ece 100644 --- a/signer/src/types/mod.rs.in +++ b/signer/src/types/mod.rs.in @@ -14,5 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -pub mod transaction_request; -pub mod bytes; + + + + + + + + +// TODO [ToDr] Types are empty for now. But they are about to come. diff --git a/signer/src/ws_server.rs b/signer/src/ws_server.rs index 9be392e69..d2ab02d66 100644 --- a/signer/src/ws_server.rs +++ b/signer/src/ws_server.rs @@ -31,14 +31,14 @@ pub enum ServerError { /// Wrapped `std::io::Error` IoError(std::io::Error), /// Other `ws-rs` error - Other(ws::Error) + WebSocket(ws::Error) } impl From for ServerError { fn from(err: ws::Error) -> Self { match err.kind { ws::ErrorKind::Io(e) => ServerError::IoError(e), - _ => ServerError::Other(err), + _ => ServerError::WebSocket(err), } } } From c4e2f650513f70f4e2f80592e8e191882ad84931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 17:46:15 +0200 Subject: [PATCH 07/10] Exposing RPC over websockets --- Cargo.lock | 1 + parity/main.rs | 5 ++ parity/signer.rs | 47 ++++++++---- rpc/src/v1/types/transaction_request.rs | 2 +- signer/Cargo.toml | 1 + signer/src/lib.rs | 1 + signer/src/signing_queue.rs | 2 +- signer/src/{ws_server.rs => ws_server/mod.rs} | 73 ++++++++++--------- signer/src/ws_server/session.rs | 59 +++++++++++++++ 9 files changed, 140 insertions(+), 51 deletions(-) rename signer/src/{ws_server.rs => ws_server/mod.rs} (70%) create mode 100644 signer/src/ws_server/session.rs diff --git a/Cargo.lock b/Cargo.lock index 6298ef7ea..7950ecc4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,6 +354,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)", "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)", diff --git a/parity/main.rs b/parity/main.rs index 1e9ab33f5..61aa8ab21 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -244,6 +244,11 @@ 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(), }); // Register IO handler diff --git a/parity/signer.rs b/parity/signer.rs index e7f7a9cb9..c4a540721 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -15,6 +15,10 @@ // 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::*; @@ -32,36 +36,51 @@ 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 fn start(conf: Configuration, deps: Dependencies) -> Option { + if !conf.enabled { + None + } else { + Some(do_start(conf, deps)) + } } #[cfg(feature = "ethcore-signer")] -pub fn start(conf: Configuration, deps: Dependencies) -> Option { - if !conf.enabled { - return None; - } +fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { + let addr = format!("127.0.0.1:{}", conf.port).parse().unwrap_or_else(|_| { + die!("Invalid port specified: {}", conf.port) + }); - let addr = format!("127.0.0.1:{}", conf.port).parse().unwrap_or_else(|_| die!("Invalid port specified: {}", conf.port)); - let start_result = signer::Server::start(addr); + 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(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); + server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()); + server.start(addr) + }; match start_result { Err(signer::ServerError::IoError(err)) => die_with_io_error("Trusted Signer", err), Err(e) => die!("Trusted Signer: {:?}", e), Ok(server) => { deps.panic_handler.forward_from(&server); - Some(server) + server }, } } #[cfg(not(feature = "ethcore-signer"))] -pub fn start(conf: Configuration) -> !{ - if !conf.enabled { - return None; - } - +fn do_start(conf: Configuration) -> ! { die!("Your Parity version has been compiled without Trusted Signer support.") } - - diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index 2fc806912..1b51e6b12 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -47,7 +47,7 @@ mod tests { use serde_json; use util::numbers::{U256}; use util::hash::Address; - use types::bytes::Bytes; + use v1::types::bytes::Bytes; use super::*; #[test] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 59c7f90b2..51b1b1e8d 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -16,6 +16,7 @@ syntex = "^0.32.0" serde = "0.7.0" serde_json = "0.7.0" rustc-serialize = "0.3" +jsonrpc-core = "2.0" log = "0.3" env_logger = "0.3" ws = "0.4.7" diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 4317338e0..a39fe68f0 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -50,6 +50,7 @@ extern crate rustc_serialize; extern crate ethcore_util as util; extern crate ethcore_rpc as rpc; +extern crate jsonrpc_core; extern crate ws; mod signing_queue; diff --git a/signer/src/signing_queue.rs b/signer/src/signing_queue.rs index d320d2375..611d467c2 100644 --- a/signer/src/signing_queue.rs +++ b/signer/src/signing_queue.rs @@ -45,7 +45,7 @@ mod test { use std::collections::HashSet; use util::hash::Address; use util::numbers::U256; - use rpc::v1::types::transaction_request::TransactionRequest; + use rpc::v1::types::TransactionRequest; use super::*; #[test] diff --git a/signer/src/ws_server.rs b/signer/src/ws_server/mod.rs similarity index 70% rename from signer/src/ws_server.rs rename to signer/src/ws_server/mod.rs index d2ab02d66..bb10bc5c1 100644 --- a/signer/src/ws_server.rs +++ b/signer/src/ws_server/mod.rs @@ -19,11 +19,14 @@ use ws; use std; use std::thread; +use std::default::Default; use std::ops::Drop; use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::net::SocketAddr; use util::panics::{PanicHandler, OnPanicListener, MayPanic}; +use jsonrpc_core::{IoHandler, IoDelegate}; + +mod session; /// Signer startup error #[derive(Debug)] @@ -43,9 +46,40 @@ impl From for ServerError { } } +/// Builder for `WebSockets` server +pub struct ServerBuilder { + handler: Arc, +} + +impl Default for ServerBuilder { + fn default() -> Self { + ServerBuilder::new() + } +} + +impl ServerBuilder { + /// Creates new `ServerBuilder` + pub fn new() -> Self { + ServerBuilder { + handler: Arc::new(IoHandler::new()) + } + } + + /// 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 { + Server::start(addr, self.handler) + } +} + /// `WebSockets` server implementation. pub struct Server { - handle: Option>>, + handle: Option>>, broadcaster: ws::Sender, panic_handler: Arc, } @@ -53,7 +87,7 @@ pub struct Server { 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) -> Result { + pub fn start(addr: SocketAddr, handler: Arc) -> Result { let config = { let mut config = ws::Settings::default(); config.max_connections = 5; @@ -62,10 +96,7 @@ impl Server { }; // Create WebSocket - let session_id = Arc::new(AtomicUsize::new(1)); - let ws = try!(ws::Builder::new().with_settings(config).build(Factory { - session_id: session_id, - })); + let ws = try!(ws::Builder::new().with_settings(config).build(session::Factory::new(handler))); let panic_handler = PanicHandler::new_in_arc(); let ph = panic_handler.clone(); @@ -98,31 +129,3 @@ impl Drop for Server { self.handle.take().unwrap().join().unwrap(); } } - -struct Session { - id: usize, - out: ws::Sender, -} - -impl ws::Handler for Session { - fn on_open(&mut self, _shake: ws::Handshake) -> ws::Result<()> { - try!(self.out.send(format!("Hello client no: {}. We are not implemented yet.", self.id))); - try!(self.out.close(ws::CloseCode::Normal)); - Ok(()) - } -} - -struct Factory { - session_id: Arc, -} - -impl ws::Factory for Factory { - type Handler = Session; - - fn connection_made(&mut self, sender: ws::Sender) -> Self::Handler { - Session { - id: self.session_id.fetch_add(1, Ordering::SeqCst), - out: sender, - } - } -} diff --git a/signer/src/ws_server/session.rs b/signer/src/ws_server/session.rs new file mode 100644 index 000000000..258e05d5b --- /dev/null +++ b/signer/src/ws_server/session.rs @@ -0,0 +1,59 @@ +// 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 . + +//! Session handlers factory. + +use ws; +use std::sync::Arc; +use jsonrpc_core::IoHandler; + +pub struct Session { + out: ws::Sender, + handler: Arc, +} + +impl ws::Handler for Session { + fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> { + let req = try!(msg.as_text()); + match self.handler.handle_request(req) { + Some(res) => self.out.send(res), + None => Ok(()), + } + } +} + +pub struct Factory { + handler: Arc, +} + +impl Factory { + pub fn new(handler: Arc) -> Self { + Factory { + handler: handler, + } + } +} + +impl ws::Factory for Factory { + type Handler = Session; + + fn connection_made(&mut self, sender: ws::Sender) -> Self::Handler { + Session { + out: sender, + handler: self.handler.clone(), + } + } +} From 6f93ecf1d2d1217cdd3c81e1085e453409faafd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 27 May 2016 15:46:07 +0200 Subject: [PATCH 08/10] Exposing types from RPC --- Cargo.lock | 2 +- parity/signer.rs | 2 +- rpc/Cargo.toml | 1 - rpc/src/lib.rs | 1 - rpc/src/v1/mod.rs | 4 +-- rpc/src/v1/types/block.rs | 23 ++++++++++++ rpc/src/v1/types/block_number.rs | 4 +++ {signer/src => rpc/src/v1}/types/bytes.rs | 0 rpc/src/v1/types/call_request.rs | 8 +++++ rpc/src/v1/types/filter.rs | 11 ++++++ rpc/src/v1/types/index.rs | 1 + rpc/src/v1/types/log.rs | 10 ++++++ rpc/src/v1/types/mod.rs | 2 ++ rpc/src/v1/types/mod.rs.in | 6 ++-- rpc/src/v1/types/optionals.rs | 3 ++ rpc/src/v1/types/receipt.rs | 9 +++++ rpc/src/v1/types/sync.rs | 7 ++++ rpc/src/v1/types/trace.rs | 35 +++++++++++++++++++ rpc/src/v1/types/trace_filter.rs | 5 +++ rpc/src/v1/types/transaction.rs | 12 +++++++ .../src/v1}/types/transaction_request.rs | 4 +-- signer/Cargo.toml | 3 +- signer/src/lib.rs | 2 +- signer/src/signing_queue.rs | 4 +-- signer/src/types/mod.rs.in | 11 ++++-- signer/src/ws_server.rs | 4 +-- 26 files changed, 156 insertions(+), 18 deletions(-) rename {signer/src => rpc/src/v1}/types/bytes.rs (100%) rename {signer/src => rpc/src/v1}/types/transaction_request.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 66df9192a..6298ef7ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,7 +331,6 @@ dependencies = [ "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.2.0", "ethcore 1.2.0", - "ethcore-signer 1.2.0", "ethcore-util 1.2.0", "ethminer 1.2.0", "ethsync 1.2.0", @@ -353,6 +352,7 @@ version = "1.2.0" dependencies = [ "clippy 0.0.69 (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", "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)", diff --git a/parity/signer.rs b/parity/signer.rs index e7f7a9cb9..c78ad36ad 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -54,7 +54,7 @@ pub fn start(conf: Configuration, deps: Dependencies) -> Option { } #[cfg(not(feature = "ethcore-signer"))] -pub fn start(conf: Configuration) -> !{ +pub fn start(conf: Configuration) -> Option { if !conf.enabled { return None; } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index c8bfa0485..2cdbb0a2b 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -19,7 +19,6 @@ ethcore = { path = "../ethcore" } ethash = { path = "../ethash" } ethsync = { path = "../sync" } ethminer = { path = "../miner" } -ethcore-signer = { path = "../signer" } rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index ae824adf2..7d9818615 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -27,7 +27,6 @@ extern crate serde_json; extern crate jsonrpc_core; extern crate jsonrpc_http_server; extern crate ethcore_util as util; -extern crate ethcore_signer as signer; extern crate ethcore; extern crate ethsync; extern crate ethminer; diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index f3bb450f3..b1ab256c0 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -18,12 +18,12 @@ //! //! Compliant with ethereum rpc. -pub mod traits; mod impls; -mod types; mod helpers; +pub mod traits; pub mod tests; +pub mod types; pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore, Traces, Rpc}; pub use self::impls::*; diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index c38949c08..5810c85e5 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -18,9 +18,12 @@ use serde::{Serialize, Serializer}; use util::numbers::*; use v1::types::{Bytes, Transaction, OptionalValue}; +/// Block Transactions #[derive(Debug)] pub enum BlockTransactions { + /// Only hashes Hashes(Vec), + /// Full transactions Full(Vec) } @@ -34,38 +37,58 @@ impl Serialize for BlockTransactions { } } +/// Block representation #[derive(Debug, Serialize)] pub struct Block { + /// Hash of the block pub hash: OptionalValue, + /// Hash of the parent #[serde(rename="parentHash")] pub parent_hash: H256, + /// Hash of the uncles #[serde(rename="sha3Uncles")] pub uncles_hash: H256, + /// Authors address pub author: Address, // TODO: get rid of this one + /// ? pub miner: Address, + /// State root hash #[serde(rename="stateRoot")] pub state_root: H256, + /// Transactions root hash #[serde(rename="transactionsRoot")] pub transactions_root: H256, + /// Transactions receipts root hash #[serde(rename="receiptsRoot")] pub receipts_root: H256, + /// Block number pub number: OptionalValue, + /// Gas Used #[serde(rename="gasUsed")] pub gas_used: U256, + /// Gas Limit #[serde(rename="gasLimit")] pub gas_limit: U256, + /// Extra data #[serde(rename="extraData")] pub extra_data: Bytes, + /// Logs bloom #[serde(rename="logsBloom")] pub logs_bloom: H2048, + /// Timestamp pub timestamp: U256, + /// Difficulty pub difficulty: U256, + /// Total difficulty #[serde(rename="totalDifficulty")] pub total_difficulty: U256, + /// Seal fields #[serde(rename="sealFields")] pub seal_fields: Vec, + /// Uncles' hashes pub uncles: Vec, + /// Transactions pub transactions: BlockTransactions } diff --git a/rpc/src/v1/types/block_number.rs b/rpc/src/v1/types/block_number.rs index 071486afd..e2d150c66 100644 --- a/rpc/src/v1/types/block_number.rs +++ b/rpc/src/v1/types/block_number.rs @@ -21,9 +21,13 @@ use ethcore::client::BlockID; /// Represents rpc api block number param. #[derive(Debug, PartialEq, Clone)] pub enum BlockNumber { + /// Number Num(u64), + /// Latest block Latest, + /// Earliest block (genesis) Earliest, + /// Pending block (being mined) Pending } diff --git a/signer/src/types/bytes.rs b/rpc/src/v1/types/bytes.rs similarity index 100% rename from signer/src/types/bytes.rs rename to rpc/src/v1/types/bytes.rs diff --git a/rpc/src/v1/types/call_request.rs b/rpc/src/v1/types/call_request.rs index 045b1cd9b..50ebbd1f0 100644 --- a/rpc/src/v1/types/call_request.rs +++ b/rpc/src/v1/types/call_request.rs @@ -18,15 +18,23 @@ use util::hash::Address; use util::numbers::U256; use v1::types::Bytes; +/// Call request #[derive(Debug, Default, PartialEq, Deserialize)] pub struct CallRequest { + /// From pub from: Option
, + /// To pub to: Option
, + /// Gas Price #[serde(rename="gasPrice")] pub gas_price: Option, + /// Gas pub gas: Option, + /// Value pub value: Option, + /// Data pub data: Option, + /// Nonce pub nonce: Option, } diff --git a/rpc/src/v1/types/filter.rs b/rpc/src/v1/types/filter.rs index e50ec9c32..77a3f0500 100644 --- a/rpc/src/v1/types/filter.rs +++ b/rpc/src/v1/types/filter.rs @@ -22,10 +22,14 @@ use v1::types::BlockNumber; use ethcore::filter::Filter as EthFilter; use ethcore::client::BlockID; +/// Variadic value #[derive(Debug, PartialEq, Clone)] pub enum VariadicValue where T: Deserialize { + /// Single Single(T), + /// List Multiple(Vec), + /// None Null, } @@ -44,17 +48,24 @@ impl Deserialize for VariadicValue where T: Deserialize { } } +/// Filter Address pub type FilterAddress = VariadicValue
; +/// Topic pub type Topic = VariadicValue; +/// Filter #[derive(Debug, PartialEq, Clone, Deserialize)] #[serde(deny_unknown_fields)] pub struct Filter { + /// From Block #[serde(rename="fromBlock")] pub from_block: Option, + /// To Block #[serde(rename="toBlock")] pub to_block: Option, + /// Address pub address: Option, + /// Topics pub topics: Option>, } diff --git a/rpc/src/v1/types/index.rs b/rpc/src/v1/types/index.rs index e7cbbd255..d7b17aea2 100644 --- a/rpc/src/v1/types/index.rs +++ b/rpc/src/v1/types/index.rs @@ -22,6 +22,7 @@ use serde::de::Visitor; pub struct Index(usize); impl Index { + /// Convert to usize pub fn value(&self) -> usize { self.0 } diff --git a/rpc/src/v1/types/log.rs b/rpc/src/v1/types/log.rs index 426ca68f1..72a482d1b 100644 --- a/rpc/src/v1/types/log.rs +++ b/rpc/src/v1/types/log.rs @@ -18,21 +18,31 @@ use util::numbers::*; use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use v1::types::Bytes; +/// Log #[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone)] pub struct Log { + /// Address pub address: Address, + /// Topics pub topics: Vec, + /// Data pub data: Bytes, + /// Block Hash #[serde(rename="blockHash")] pub block_hash: Option, + /// Block Number #[serde(rename="blockNumber")] pub block_number: Option, + /// Transaction Hash #[serde(rename="transactionHash")] pub transaction_hash: Option, + /// Transaction Index #[serde(rename="transactionIndex")] pub transaction_index: Option, + /// Log Index #[serde(rename="logIndex")] pub log_index: Option, + /// Log Type #[serde(rename="type")] pub log_type: String, } diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index adf9be071..c1bc34407 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Structures used in RPC communication + #[cfg(feature = "serde_macros")] include!("mod.rs.in"); diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 9d7fc882a..824a061ef 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +mod bytes; mod block; mod block_number; mod filter; @@ -22,13 +23,13 @@ mod log; mod optionals; mod sync; mod transaction; +mod transaction_request; mod call_request; mod receipt; mod trace; mod trace_filter; -pub use signer::types::bytes::Bytes; -pub use signer::types::transaction_request::TransactionRequest; +pub use self::bytes::Bytes; pub use self::block::{Block, BlockTransactions}; pub use self::block_number::BlockNumber; pub use self::filter::Filter; @@ -37,6 +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::call_request::CallRequest; pub use self::receipt::Receipt; pub use self::trace::Trace; diff --git a/rpc/src/v1/types/optionals.rs b/rpc/src/v1/types/optionals.rs index 5db272251..2ed272ade 100644 --- a/rpc/src/v1/types/optionals.rs +++ b/rpc/src/v1/types/optionals.rs @@ -17,9 +17,12 @@ use serde::{Serialize, Serializer}; use serde_json::Value; +/// Optional value #[derive(Debug)] pub enum OptionalValue where T: Serialize { + /// Some Value(T), + /// None Null } diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index 51d914e1a..32a7f5945 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -19,22 +19,31 @@ use util::hash::{Address, H256}; use v1::types::Log; use ethcore::receipt::LocalizedReceipt; +/// Receipt #[derive(Debug, Serialize)] pub struct Receipt { + /// Transaction Hash #[serde(rename="transactionHash")] pub transaction_hash: H256, + /// Transaction index #[serde(rename="transactionIndex")] pub transaction_index: U256, + /// Block hash #[serde(rename="blockHash")] pub block_hash: H256, + /// Block number #[serde(rename="blockNumber")] pub block_number: U256, + /// Cumulative gas used #[serde(rename="cumulativeGasUsed")] pub cumulative_gas_used: U256, + /// Gas used #[serde(rename="gasUsed")] pub gas_used: U256, + /// Contract address #[serde(rename="contractAddress")] pub contract_address: Option
, + /// Logs pub logs: Vec, } diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index c0e480140..6d750425e 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -17,19 +17,26 @@ use serde::{Serialize, Serializer}; use util::numbers::*; +/// Sync info #[derive(Default, Debug, Serialize, PartialEq)] pub struct SyncInfo { + /// Starting block #[serde(rename="startingBlock")] pub starting_block: U256, + /// Current block #[serde(rename="currentBlock")] pub current_block: U256, + /// Highest block seen so far #[serde(rename="highestBlock")] pub highest_block: U256, } +/// Sync status #[derive(Debug, PartialEq)] pub enum SyncStatus { + /// Info when syncing Info(SyncInfo), + /// Not syncing None } diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index 4cd1ac408..6ea58543a 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -19,11 +19,16 @@ use ethcore::trace::trace; use ethcore::trace::LocalizedTrace; use v1::types::Bytes; +/// Create response #[derive(Debug, Serialize)] pub struct Create { + /// Sender from: Address, + /// Value value: U256, + /// Gas gas: U256, + /// Initialization code init: Bytes, } @@ -38,12 +43,18 @@ impl From for Create { } } +/// Call response #[derive(Debug, Serialize)] pub struct Call { + /// Sender from: Address, + /// Recipient to: Address, + /// Transfered Value value: U256, + /// Gas gas: U256, + /// Input data input: Bytes, } @@ -59,10 +70,13 @@ impl From for Call { } } +/// Action #[derive(Debug, Serialize)] pub enum Action { + /// Call #[serde(rename="call")] Call(Call), + /// Create #[serde(rename="create")] Create(Create), } @@ -76,10 +90,13 @@ impl From for Action { } } +/// Call Result #[derive(Debug, Serialize)] pub struct CallResult { + /// Gas used #[serde(rename="gasUsed")] gas_used: U256, + /// Output bytes output: Bytes, } @@ -92,11 +109,15 @@ impl From for CallResult { } } +/// Craete Result #[derive(Debug, Serialize)] pub struct CreateResult { + /// Gas used #[serde(rename="gasUsed")] gas_used: U256, + /// Code code: Bytes, + /// Assigned address address: Address, } @@ -110,14 +131,19 @@ impl From for CreateResult { } } +/// Response #[derive(Debug, Serialize)] pub enum Res { + /// Call #[serde(rename="call")] Call(CallResult), + /// Create #[serde(rename="create")] Create(CreateResult), + /// Call failure #[serde(rename="failedCall")] FailedCall, + /// Creation failure #[serde(rename="failedCreate")] FailedCreate, } @@ -133,19 +159,28 @@ impl From for Res { } } +/// Trace #[derive(Debug, Serialize)] pub struct Trace { + /// Action action: Action, + /// Result result: Res, + /// Trace address #[serde(rename="traceAddress")] trace_address: Vec, + /// Subtraces subtraces: U256, + /// Transaction position #[serde(rename="transactionPosition")] transaction_position: U256, + /// Transaction hash #[serde(rename="transactionHash")] transaction_hash: H256, + /// Block Number #[serde(rename="blockNumber")] block_number: U256, + /// Block Hash #[serde(rename="blockHash")] block_hash: H256, } diff --git a/rpc/src/v1/types/trace_filter.rs b/rpc/src/v1/types/trace_filter.rs index 3d45f4c79..ee2f231f0 100644 --- a/rpc/src/v1/types/trace_filter.rs +++ b/rpc/src/v1/types/trace_filter.rs @@ -21,14 +21,19 @@ use ethcore::client::BlockID; use ethcore::client; use super::BlockNumber; +/// Trace filter #[derive(Debug, PartialEq, Deserialize)] pub struct TraceFilter { + /// From block #[serde(rename="fromBlock")] pub from_block: Option, + /// To block #[serde(rename="toBlock")] pub to_block: Option, + /// From address #[serde(rename="fromAddress")] pub from_address: Option>, + /// To address #[serde(rename="toAddress")] pub to_address: Option>, } diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 8a46d5e15..1c9a41084 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -18,22 +18,34 @@ use util::numbers::*; use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction}; use v1::types::{Bytes, OptionalValue}; +/// Transaction #[derive(Debug, Default, Serialize)] pub struct Transaction { + /// Hash pub hash: H256, + /// Nonce pub nonce: U256, + /// Block hash #[serde(rename="blockHash")] pub block_hash: OptionalValue, + /// Block number #[serde(rename="blockNumber")] pub block_number: OptionalValue, + /// Transaction Index #[serde(rename="transactionIndex")] pub transaction_index: OptionalValue, + /// Sender pub from: Address, + /// Recipient pub to: OptionalValue
, + /// Transfered value pub value: U256, + /// Gas Price #[serde(rename="gasPrice")] pub gas_price: U256, + /// Gas pub gas: U256, + /// Data pub input: Bytes } diff --git a/signer/src/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs similarity index 98% rename from signer/src/types/transaction_request.rs rename to rpc/src/v1/types/transaction_request.rs index 83840515b..1b51e6b12 100644 --- a/signer/src/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -18,7 +18,7 @@ use util::hash::Address; use util::numbers::U256; -use types::bytes::Bytes; +use v1::types::bytes::Bytes; /// Transaction request coming from RPC #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize)] @@ -47,7 +47,7 @@ mod tests { use serde_json; use util::numbers::{U256}; use util::hash::Address; - use types::bytes::Bytes; + use v1::types::bytes::Bytes; use super::*; #[test] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index be77a3fd9..59c7f90b2 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -16,10 +16,11 @@ syntex = "^0.32.0" serde = "0.7.0" serde_json = "0.7.0" rustc-serialize = "0.3" -ethcore-util = { path = "../util" } 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} diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 13f8d2fa6..4317338e0 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -49,11 +49,11 @@ extern crate serde_json; extern crate rustc_serialize; extern crate ethcore_util as util; +extern crate ethcore_rpc as rpc; extern crate ws; mod signing_queue; mod ws_server; -pub mod types; pub use ws_server::*; diff --git a/signer/src/signing_queue.rs b/signer/src/signing_queue.rs index 7758f5df3..611d467c2 100644 --- a/signer/src/signing_queue.rs +++ b/signer/src/signing_queue.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use std::collections::HashSet; -use types::transaction_request::TransactionRequest; +use rpc::v1::types::TransactionRequest; pub trait SigningQueue { fn add_request(&mut self, transaction: TransactionRequest); @@ -45,7 +45,7 @@ mod test { use std::collections::HashSet; use util::hash::Address; use util::numbers::U256; - use types::transaction_request::TransactionRequest; + use rpc::v1::types::TransactionRequest; use super::*; #[test] diff --git a/signer/src/types/mod.rs.in b/signer/src/types/mod.rs.in index 986e3d6e2..a59f81ece 100644 --- a/signer/src/types/mod.rs.in +++ b/signer/src/types/mod.rs.in @@ -14,5 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -pub mod transaction_request; -pub mod bytes; + + + + + + + + +// TODO [ToDr] Types are empty for now. But they are about to come. diff --git a/signer/src/ws_server.rs b/signer/src/ws_server.rs index 9be392e69..d2ab02d66 100644 --- a/signer/src/ws_server.rs +++ b/signer/src/ws_server.rs @@ -31,14 +31,14 @@ pub enum ServerError { /// Wrapped `std::io::Error` IoError(std::io::Error), /// Other `ws-rs` error - Other(ws::Error) + WebSocket(ws::Error) } impl From for ServerError { fn from(err: ws::Error) -> Self { match err.kind { ws::ErrorKind::Io(e) => ServerError::IoError(e), - _ => ServerError::Other(err), + _ => ServerError::WebSocket(err), } } } From 50e5c88b7b2da1f62d6f076b9ce7a8c04e8da984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 May 2016 19:10:17 +0200 Subject: [PATCH 09/10] Fixing compilation --- parity/signer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/signer.rs b/parity/signer.rs index c4a540721..5e3339bcc 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -64,7 +64,7 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { 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(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) }; From 1176f6acec6a99e008521f541b857adfe8676e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sun, 29 May 2016 13:25:31 +0200 Subject: [PATCH 10/10] fixing test --- signer/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/signer/src/lib.rs b/signer/src/lib.rs index a39fe68f0..f3a963ac7 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -33,10 +33,11 @@ //! ``` //! extern crate ethcore_signer; //! -//! use ethcore_signer::Server; +//! use ethcore_signer::ServerBuilder; //! //! fn main() { -//! let _server = Server::start("127.0.0.1:8084".parse().unwrap()); +//! let builder = ServerBuilder::new(); +//! let _server = builder.start("127.0.0.1:8084".parse().unwrap()).unwrap(); //! } //! ```