From 5180919e52d9d06b9772935d22504ba601088bd9 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 24 Jul 2017 17:45:15 +0300 Subject: [PATCH 01/48] wasm mvp continued --- Cargo.lock | 1 + ethcore/evm/Cargo.toml | 2 + ethcore/evm/src/lib.rs | 1 + ethcore/evm/src/wasm/env.rs | 55 ++++------- ethcore/evm/src/wasm/mod.rs | 3 +- ethcore/evm/src/wasm/runtime.rs | 158 +++++++++++++++++++++++++++++++- ethcore/evm/src/wasm/tests.rs | 108 ++++++++++++++++++++-- ethcore/res/wasm-tests | 2 +- 8 files changed, 281 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c7046b759..16d378150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -878,6 +878,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", + "ethcore-logger 1.8.0", "ethcore-util 1.8.0", "ethjson 0.1.0", "evmjit 1.8.0", diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index b48dd2346..bd95e0587 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -14,8 +14,10 @@ lazy_static = "0.2" log = "0.3" rlp = { path = "../../util/rlp" } parity-wasm = "0.12" +ethcore-logger = { path = "../../logger" } wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } + [dev-dependencies] rustc-hex = "1.0" diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index fa4d12315..55f7c5090 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -24,6 +24,7 @@ extern crate ethjson; extern crate rlp; extern crate parity_wasm; extern crate wasm_utils; +extern crate ethcore_logger; #[macro_use] extern crate lazy_static; diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/evm/src/wasm/env.rs index cabd38bd9..e68e50432 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/evm/src/wasm/env.rs @@ -61,6 +61,21 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ &[I32; 4], Some(I32), ), + Static( + "_ccall", + &[I32; 6], + Some(I32), + ), + Static( + "_dcall", + &[I32; 5], + Some(I32), + ), + Static( + "_scall", + &[I32; 5], + Some(I32), + ), Static( "abort", &[I32], @@ -71,49 +86,19 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ &[], None, ), - Static( - "invoke_vii", - &[I32; 3], - None, - ), - Static( - "invoke_vi", - &[I32; 2], - None, - ), - Static( - "invoke_v", - &[I32], - None, - ), - Static( - "invoke_iii", - &[I32; 3], - Some(I32), - ), - Static( - "___resumeException", - &[I32], - None, - ), Static( "_rust_begin_unwind", &[I32; 4], None, ), - Static( - "___cxa_find_matching_catch_2", - &[], - Some(I32), - ), - Static( - "___gxx_personality_v0", - &[I32; 6], - Some(I32), - ), Static( "_emscripten_memcpy_big", &[I32; 3], Some(I32), + ), + Static( + "___syscall6", + &[I32; 2], + Some(I32), ) ]; diff --git a/ethcore/evm/src/wasm/mod.rs b/ethcore/evm/src/wasm/mod.rs index a7186add5..acad9e5cb 100644 --- a/ethcore/evm/src/wasm/mod.rs +++ b/ethcore/evm/src/wasm/mod.rs @@ -34,7 +34,7 @@ use wasm_utils; use evm::{self, GasLeft, ReturnData}; use action_params::ActionParams; -use self::runtime::Runtime; +use self::runtime::{Runtime, RuntimeContext}; pub use self::runtime::Error as RuntimeError; @@ -82,6 +82,7 @@ impl evm::Evm for WasmInterpreter { env_memory, DEFAULT_STACK_SPACE, params.gas.low_u64(), + RuntimeContext::new(params.address, params.sender), ); let mut cursor = ::std::io::Cursor::new(&*code); diff --git a/ethcore/evm/src/wasm/runtime.rs b/ethcore/evm/src/wasm/runtime.rs index 7beb4c599..adcb14de1 100644 --- a/ethcore/evm/src/wasm/runtime.rs +++ b/ethcore/evm/src/wasm/runtime.rs @@ -25,6 +25,7 @@ use ext; use parity_wasm::interpreter; use util::{Address, H256, U256}; +use call_type::CallType; use super::ptr::{WasmPtr, Error as PtrError}; use super::call_args::CallArgs; @@ -57,6 +58,20 @@ impl From for Error { } } +pub struct RuntimeContext { + address: Address, + sender: Address, +} + +impl RuntimeContext { + pub fn new(address: Address, sender: Address) -> Self { + RuntimeContext { + address: address, + sender: sender, + } + } +} + /// Runtime enviroment data for wasm contract execution pub struct Runtime<'a> { gas_counter: u64, @@ -64,6 +79,7 @@ pub struct Runtime<'a> { dynamic_top: u32, ext: &'a mut ext::Ext, memory: Arc, + context: RuntimeContext, } impl<'a> Runtime<'a> { @@ -73,6 +89,7 @@ impl<'a> Runtime<'a> { memory: Arc, stack_space: u32, gas_limit: u64, + context: RuntimeContext, ) -> Runtime<'b> { Runtime { gas_counter: 0, @@ -80,6 +97,7 @@ impl<'a> Runtime<'a> { dynamic_top: stack_space, memory: memory, ext: ext, + context: context, } } @@ -139,13 +157,13 @@ impl<'a> Runtime<'a> { trace!(target: "wasm", "runtime: create contract"); let mut context = context; let result_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + trace!(target: "wasm", "result_ptr: {:?}", result_ptr); let code_len = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_len: {:?}", code_len); + trace!(target: "wasm", " code_len: {:?}", code_len); let code_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_ptr: {:?}", code_ptr); + trace!(target: "wasm", " code_ptr: {:?}", code_ptr); let endowment = self.pop_u256(&mut context)?; - trace!(target: "wasm", " val: {:?}", endowment); + trace!(target: "wasm", " val: {:?}", endowment); let code = self.memory.get(code_ptr, code_len as usize)?; @@ -167,6 +185,127 @@ impl<'a> Runtime<'a> { } } + pub fn call(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // + // method signature: + // fn ( + // address: *const u8, + // val_ptr: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(true, CallType::Call, context) + } + + + fn call_code(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // + // signature (same as static call): + // fn ( + // address: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(false, CallType::CallCode, context) + } + + fn do_call( + &mut self, + use_val: bool, + call_type: CallType, + context: interpreter::CallerContext, + ) + -> Result, interpreter::Error> + { + + trace!(target: "wasm", "runtime: call code"); + let mut context = context; + let result_alloc_len = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " result_len: {:?}", result_alloc_len); + + let result_ptr = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + + let input_len = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " input_len: {:?}", input_len); + + let input_ptr = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " input_ptr: {:?}", input_ptr); + + let val = if use_val { Some(self.pop_u256(&mut context)?) } + else { None }; + trace!(target: "wasm", " val: {:?}", val); + + let address = self.pop_address(&mut context)?; + trace!(target: "wasm", " address: {:?}", address); + + if let Some(ref val) = val { + let address_balance = self.ext.balance(&self.context.address) + .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))?; + + if &address_balance < val { + trace!(target: "wasm", "runtime: call failed due to balance check"); + return Ok(Some((-1i32).into())); + } + } + + let mut result = Vec::with_capacity(result_alloc_len as usize); + result.resize(result_alloc_len as usize, 0); + let gas = self.gas_left() + .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? + .into(); + // todo: optimize to use memory views once it's in + let payload = self.memory.get(input_ptr, input_len as usize)?; + + let call_result = self.ext.call( + &gas, + &self.context.sender, + &self.context.address, + val, + &payload, + &address, + &mut result[..], + call_type, + ); + + match call_result { + ext::MessageCallResult::Success(gas_left, _) => { + self.gas_counter = self.gas_limit - gas_left.low_u64(); + self.memory.set(result_ptr, &result)?; + Ok(Some(0i32.into())) + }, + ext::MessageCallResult::Failed => { + Ok(Some((-1i32).into())) + } + } + } + + pub fn static_call(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // signature (same as code call): + // fn ( + // address: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(false, CallType::StaticCall, context) + } + + /// Allocate memory using the wasm stack params pub fn malloc(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> @@ -338,6 +477,15 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { "_create" => { self.create(context) }, + "_ccall" => { + self.call(context) + }, + "_dcall" => { + self.call_code(context) + }, + "_scall" => { + self.static_call(context) + }, "_debug" => { self.debug_log(context) }, @@ -348,7 +496,7 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { self.mem_copy(context) }, _ => { - trace!("Unknown env func: '{}'", name); + trace!(target: "wasm", "Trapped due to unhandled function: '{}'", name); self.user_trap(context) } } diff --git a/ethcore/evm/src/wasm/tests.rs b/ethcore/evm/src/wasm/tests.rs index 8ae13daae..c9d02a4ad 100644 --- a/ethcore/evm/src/wasm/tests.rs +++ b/ethcore/evm/src/wasm/tests.rs @@ -21,6 +21,7 @@ use super::WasmInterpreter; use evm::{self, Evm, GasLeft}; use action_params::{ActionParams, ActionValue}; use util::{U256, H256, Address}; +use byteorder::{LittleEndian, ByteOrder}; macro_rules! load_sample { ($name: expr) => { @@ -85,7 +86,7 @@ fn logger() { }; println!("ext.store: {:?}", ext.store); - assert_eq!(gas_left, U256::from(99581)); + assert_eq!(gas_left, U256::from(99590)); let address_val: H256 = address.into(); assert_eq!( ext.store.get(&"0100000000000000000000000000000000000000000000000000000000000000".parse().unwrap()).expect("storage key to exist"), @@ -136,7 +137,7 @@ fn identity() { } }; - assert_eq!(gas_left, U256::from(99_689)); + assert_eq!(gas_left, U256::from(99_687)); assert_eq!( Address::from_slice(&result), @@ -170,7 +171,7 @@ fn dispersion() { } }; - assert_eq!(gas_left, U256::from(99_402)); + assert_eq!(gas_left, U256::from(99_423)); assert_eq!( result, @@ -199,7 +200,7 @@ fn suicide_not() { } }; - assert_eq!(gas_left, U256::from(99_703)); + assert_eq!(gas_left, U256::from(99_656)); assert_eq!( result, @@ -233,12 +234,14 @@ fn suicide() { } }; - assert_eq!(gas_left, U256::from(99_747)); + assert_eq!(gas_left, U256::from(99_740)); assert!(ext.suicides.contains(&refund)); } #[test] fn create() { + ::ethcore_logger::init_log(); + let mut params = ActionParams::default(); params.gas = U256::from(100_000); params.code = Some(Arc::new(load_sample!("creator.wasm"))); @@ -262,7 +265,7 @@ fn create() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Create, - gas: U256::from(99_778), + gas: U256::from(99_767), sender_address: None, receive_address: None, value: Some(1_000_000_000.into()), @@ -270,5 +273,96 @@ fn create() { code_address: None, } )); - assert_eq!(gas_left, U256::from(99_768)); + assert_eq!(gas_left, U256::from(99_759)); } + + +#[test] +fn call_code() { + ::ethcore_logger::init_log(); + + let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); + let receiver: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + + let mut params = ActionParams::default(); + params.sender = sender.clone(); + params.address = receiver.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(load_sample!("call_code.wasm"))); + params.data = Some(Vec::new()); + params.value = ActionValue::transfer(1_000_000_000); + + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Call test should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + trace!(target: "wasm", "fake_calls: {:?}", &ext.calls); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Call, + gas: U256::from(99_061), + sender_address: Some(sender), + receive_address: Some(receiver), + value: None, + data: vec![1u8, 2, 3, 5, 7, 11], + code_address: Some("0d13710000000000000000000000000000000000".parse().unwrap()), + } + )); + assert_eq!(gas_left, U256::from(94196)); + + // siphash result + let res = LittleEndian::read_u32(&result[..]); + assert_eq!(res, 4198595614); +} + +#[test] +fn call_static() { + ::ethcore_logger::init_log(); + + let sender: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + let receiver: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); + + let mut params = ActionParams::default(); + params.sender = sender.clone(); + params.address = receiver.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(load_sample!("call_static.wasm"))); + params.data = Some(Vec::new()); + params.value = ActionValue::transfer(1_000_000_000); + + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Static call test should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + trace!(target: "wasm", "fake_calls: {:?}", &ext.calls); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Call, + gas: U256::from(99_061), + sender_address: Some(sender), + receive_address: Some(receiver), + value: None, + data: vec![1u8, 2, 3, 5, 7, 11], + code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()), + } + )); + assert_eq!(gas_left, U256::from(94196)); + + // siphash result + let res = LittleEndian::read_u32(&result[..]); + assert_eq!(res, 317632590); +} \ No newline at end of file diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index 9ed630431..8361f18c7 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit 9ed6304313fa949ed92aa0570fb2bc759fb6dc58 +Subproject commit 8361f18c7ea133d9b85edf7dea02f05b9feb1938 From 689993a592418f0654f39e4df3ecebd66862fd22 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Tue, 25 Jul 2017 17:58:52 +0200 Subject: [PATCH 02/48] whisper parity.js api --- js/src/api/rpc/shh/shh.js | 62 ++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/js/src/api/rpc/shh/shh.js b/js/src/api/rpc/shh/shh.js index 9312df6c1..8bba37caa 100644 --- a/js/src/api/rpc/shh/shh.js +++ b/js/src/api/rpc/shh/shh.js @@ -14,58 +14,78 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default class Personal { +export default class Shh { constructor (transport) { this._transport = transport; } - addToGroup (identity) { + info () { return this._transport - .execute('shh_addToGroup', identity); + .execute('shh_info'); } - getFilterChanges (filterId) { + newKeyPair () { return this._transport - .execute('shh_getFilterChanges', filterId); + .execute('shh_newKeyPair'); } - getMessages (filterId) { + addPrivateKey (privKey) { return this._transport - .execute('shh_getMessages', filterId); + .execute('shh_addPrivateKey', privKey); } - hasIdentity (identity) { + newSymKey () { return this._transport - .execute('shh_hasIdentity', identity); + .execute('shh_newSymKey'); } - newFilter (options) { + getPublicKey (identity) { return this._transport - .execute('shh_newFilter', options); + .execute('shh_getPublicKey', identity); } - newGroup () { + getPrivateKey (identity) { return this._transport - .execute('shh_newGroup'); + .execute('shh_getPrivateKey', identity); } - newIdentity () { + getSymKey (identity) { return this._transport - .execute('shh_newIdentity'); + .execute('shh_getSymKey', identity); } - post (options) { + deleteKey (identity) { return this._transport - .execute('shh_post', options); + .execute('shh_deleteKey', identity); } - uninstallFilter (filterId) { + post (messageObj) { return this._transport - .execute('shh_uninstallFilter', filterId); + .execute('shh_post', messageObj); } - version () { + newMessageFilter (filterObj) { return this._transport - .execute('shh_version'); + .execute('shh_newMessageFilter', filterObj); + } + + getFilterChanges (identity) { + return this._transport + .execute('shh_getFilterChanges', identity); + } + + deleteMessageFilter (filterId) { + return this._transport + .execute('shh_deleteMessageFilter', filterId); + } + + subscribe (filterObj) { + return this._transport + .execute('shh_subscribe', filterObj); + } + + unsubscribe (subscriptionId) { + return this._transport + .execute('shh_unsubscribe', subscriptionId); } } From 7d348e2260b9094b8892485309b0bc778e517470 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 26 Jul 2017 15:48:00 +0200 Subject: [PATCH 03/48] light client fixes (#6148) * light client fixes * fix memory-lru-cache * clear pending reqs on disconnect --- ethcore/light/src/client/header_chain.rs | 15 ++++++++++ ethcore/light/src/client/mod.rs | 9 ++++-- ethcore/light/src/net/mod.rs | 3 ++ sync/src/light_sync/mod.rs | 14 +++++++++- util/src/cache.rs | 35 ++++++++++++++++++++++-- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index eb70242de..d6ac109c7 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -405,6 +405,7 @@ impl HeaderChain { match id { BlockId::Earliest | BlockId::Number(0) => Some(self.genesis_header.clone()), + BlockId::Hash(hash) if hash == self.genesis_hash() => { Some(self.genesis_header.clone()) } BlockId::Hash(hash) => load_from_db(hash), BlockId::Number(num) => { if self.best_block.read().number < num { return None } @@ -781,4 +782,18 @@ mod tests { assert_eq!(chain.block_header(BlockId::Latest).unwrap().number(), 10); assert!(chain.candidates.read().get(&100).is_some()) } + + #[test] + fn genesis_header_available() { + let spec = Spec::new_test(); + let genesis_header = spec.genesis_header(); + let db = make_db(); + let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6)))); + + let chain = HeaderChain::new(db.clone(), None, &::rlp::encode(&genesis_header), cache.clone()).unwrap(); + + assert!(chain.block_header(BlockId::Earliest).is_some()); + assert!(chain.block_header(BlockId::Number(0)).is_some()); + assert!(chain.block_header(BlockId::Hash(genesis_header.hash())).is_some()); + } } diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index db0d3ad25..044c40133 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -282,6 +282,7 @@ impl Client { let mut good = Vec::new(); for verified_header in self.queue.drain(MAX) { let (num, hash) = (verified_header.number(), verified_header.hash()); + trace!(target: "client", "importing block {}", num); if self.verify_full && !self.check_header(&mut bad, &verified_header) { continue @@ -381,13 +382,17 @@ impl Client { } } - // return true if should skip, false otherwise. may push onto bad if + // return false if should skip, true otherwise. may push onto bad if // should skip. fn check_header(&self, bad: &mut Vec, verified_header: &Header) -> bool { let hash = verified_header.hash(); let parent_header = match self.chain.block_header(BlockId::Hash(*verified_header.parent_hash())) { Some(header) => header, - None => return false, // skip import of block with missing parent. + None => { + trace!(target: "client", "No parent for block ({}, {})", + verified_header.number(), hash); + return false // skip import of block with missing parent. + } }; // Verify Block Family diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index f823678a9..046dc68bd 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -806,6 +806,9 @@ impl LightProtocol { trace!(target: "pip", "Connected peer with chain head {:?}", (status.head_hash, status.head_num)); if (status.network_id, status.genesis_hash) != (self.network_id, self.genesis_hash) { + trace!(target: "pip", "peer {} wrong network: network_id is {} vs our {}, gh is {} vs our {}", + peer, status.network_id, self.network_id, status.genesis_hash, self.genesis_hash); + return Err(Error::WrongNetwork); } diff --git a/sync/src/light_sync/mod.rs b/sync/src/light_sync/mod.rs index 512ba7943..f05e4d7d0 100644 --- a/sync/src/light_sync/mod.rs +++ b/sync/src/light_sync/mod.rs @@ -285,6 +285,13 @@ impl Handler for LightSync { best.clone() }; + { + let mut pending_reqs = self.pending_reqs.lock(); + for unfulfilled in unfulfilled { + pending_reqs.remove(&unfulfilled); + } + } + if new_best.is_none() { debug!(target: "sync", "No peers remain. Reverting to idle"); *self.state.lock() = SyncState::Idle; @@ -503,10 +510,12 @@ impl LightSync { None } }).collect(); + let mut rng = self.rng.lock(); + let mut requested_from = HashSet::new(); // naive request dispatcher: just give to any peer which says it will - // give us responses. + // give us responses. but only one request per peer per state transition. let dispatcher = move |req: HeadersRequest| { rng.shuffle(&mut peer_ids); @@ -521,9 +530,12 @@ impl LightSync { builder.build() }; for peer in &peer_ids { + if requested_from.contains(peer) { continue } match ctx.request_from(*peer, request.clone()) { Ok(id) => { self.pending_reqs.lock().insert(id.clone()); + requested_from.insert(peer.clone()); + return Some(id) } Err(NetError::NoCredits) => {} diff --git a/util/src/cache.rs b/util/src/cache.rs index 9d59f2c97..e6f204192 100644 --- a/util/src/cache.rs +++ b/util/src/cache.rs @@ -32,6 +32,11 @@ pub struct MemoryLruCache { max_size: usize, } +// amount of memory used when the item will be put on the heap. +fn heap_size_of(val: &T) -> usize { + ::std::mem::size_of::() + val.heap_size_of_children() +} + impl MemoryLruCache { /// Create a new cache with a maximum size in bytes. pub fn new(max_size: usize) -> Self { @@ -52,15 +57,17 @@ impl MemoryLruCache { self.inner.set_capacity(cap * 2); } + self.cur_size += heap_size_of(&val); + // account for any element displaced from the cache. if let Some(lru) = self.inner.insert(key, val) { - self.cur_size -= lru.heap_size_of_children(); + self.cur_size -= heap_size_of(&lru); } // remove elements until we are below the memory target. while self.cur_size > self.max_size { match self.inner.remove_lru() { - Some((_, v)) => self.cur_size -= v.heap_size_of_children(), + Some((_, v)) => self.cur_size -= heap_size_of(&v), _ => break, } } @@ -77,3 +84,27 @@ impl MemoryLruCache { self.cur_size } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let mut cache = MemoryLruCache::new(256); + let val1 = vec![0u8; 100]; + let size1 = heap_size_of(&val1); + cache.insert("hello", val1); + + assert_eq!(cache.current_size(), size1); + + let val2 = vec![0u8; 210]; + let size2 = heap_size_of(&val2); + cache.insert("world", val2); + + assert!(cache.get_mut(&"hello").is_none()); + assert!(cache.get_mut(&"world").is_some()); + + assert_eq!(cache.current_size(), size2); + } +} From 5eb8cea6e708e484e409a484ddb53d6088abe95e Mon Sep 17 00:00:00 2001 From: Feynman Liang Date: Wed, 26 Jul 2017 08:25:32 -0700 Subject: [PATCH 04/48] Tendermint epoch transitions (#6085) * Adds signals_epoch_end to tendermint * Adds is_epoch_end * Adds snapshot_components * Adds tendermint Epoch Verifier * Fix documentation typos * Change check_finality_proof to panic * Fix compilation * Adds Unconfirmed path to epoch_verifier * Verify if address is validator in EpochVerifier * check_finality_proof errors on failure * Don't share combine/destructure_proofs * Remove invalid import * Remove duplicate epoch verifier trait * Fix docs * Adds recover stub to tendermint EpochVerifier * Adds verify_light test * Avoid boxed closure * Style fixes --- ethcore/src/engines/authority_round/mod.rs | 4 +- ethcore/src/engines/epoch_verifier.rs | 49 ------ ethcore/src/engines/tendermint/mod.rs | 196 ++++++++++++++++++++- util/rlp/src/untrusted_rlp.rs | 2 +- 4 files changed, 196 insertions(+), 55 deletions(-) delete mode 100644 ethcore/src/engines/epoch_verifier.rs diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 018489f26..3210368db 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -476,8 +476,8 @@ impl Engine for AuthorityRound { /// Attempt to seal the block internally. /// - /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will - /// be returned. + /// This operation is synchronous and may (quite reasonably) not be available, in which case + /// `Seal::None` will be returned. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { // first check to avoid generating signature most of the time // (but there's still a race to the `compare_and_swap`) diff --git a/ethcore/src/engines/epoch_verifier.rs b/ethcore/src/engines/epoch_verifier.rs deleted file mode 100644 index cd712baef..000000000 --- a/ethcore/src/engines/epoch_verifier.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -// Epoch verifiers. - -use error::Error; -use header::Header; - -/// Verifier for all blocks within an epoch with self-contained state. -/// -/// See docs on `Engine` relating to proving functions for more details. -pub trait EpochVerifier: Send + Sync { - /// Get the epoch number. - fn epoch_number(&self) -> u64; - - /// Lightly verify the next block header. - /// This may not be a header belonging to a different epoch. - fn verify_light(&self, header: &Header) -> Result<(), Error>; - - /// Perform potentially heavier checks on the next block header. - fn verify_heavy(&self, header: &Header) -> Result<(), Error> { - self.verify_light(header) - } - - /// Check if the header is the end of an epoch. - fn is_epoch_end(&self, header: &Header, Ancestry) -> EpochChange; - -} - -/// Special "no-op" verifier for stateless, epoch-less engines. -pub struct NoOp; - -impl EpochVerifier for NoOp { - fn epoch_number(&self) -> u64 { 0 } - fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -} diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index f40c7539e..453e8f9fb 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -33,15 +33,15 @@ use error::{Error, BlockError}; use header::{Header, BlockNumber}; use builtin::Builtin; use rlp::UntrustedRlp; -use ethkey::{recover, public_to_address, Signature}; +use ethkey::{Message, public_to_address, recover, Signature}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; -use engines::{Engine, Seal, EngineError}; +use engines::{Engine, Seal, EngineError, ConstructedVerifier}; use state::CleanupMode; use io::IoService; use super::signer::EngineSigner; -use super::validator_set::ValidatorSet; +use super::validator_set::{ValidatorSet, SimpleList}; use super::transition::TransitionHandler; use super::vote_collector::VoteCollector; use self::message::*; @@ -101,6 +101,65 @@ pub struct Tendermint { validators: Box, } +struct EpochVerifier + where F: Fn(&Signature, &Message) -> Result + Send + Sync +{ + subchain_validators: SimpleList, + recover: F +} + +impl super::EpochVerifier for EpochVerifier + where F: Fn(&Signature, &Message) -> Result + Send + Sync +{ + fn verify_light(&self, header: &Header) -> Result<(), Error> { + let message = header.bare_hash(); + + let mut addresses = HashSet::new(); + let ref header_signatures_field = header.seal().get(2).ok_or(BlockError::InvalidSeal)?; + for rlp in UntrustedRlp::new(header_signatures_field).iter() { + let signature: H520 = rlp.as_val()?; + let address = (self.recover)(&signature.into(), &message)?; + + if !self.subchain_validators.contains(header.parent_hash(), &address) { + return Err(EngineError::NotAuthorized(address.to_owned()).into()); + } + addresses.insert(address); + } + + let n = addresses.len(); + let threshold = self.subchain_validators.len() * 2/3; + if n > threshold { + Ok(()) + } else { + Err(EngineError::BadSealFieldSize(OutOfBounds { + min: Some(threshold), + max: None, + found: n + }).into()) + } + } + + fn check_finality_proof(&self, proof: &[u8]) -> Option> { + let header: Header = ::rlp::decode(proof); + self.verify_light(&header).ok().map(|_| vec![header.hash()]) + } +} + +fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof: &[u8]) -> Vec { + let mut stream = ::rlp::RlpStream::new_list(3); + stream.append(&signal_number).append(&set_proof).append(&finality_proof); + stream.out() +} + +fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> { + let rlp = UntrustedRlp::new(combined); + Ok(( + rlp.at(0)?.as_val()?, + rlp.at(1)?.data()?, + rlp.at(2)?.data()?, + )) +} + impl Tendermint { /// Create a new instance of Tendermint engine pub fn new(params: CommonParams, our_params: TendermintParams, builtins: BTreeMap) -> Result, Error> { @@ -427,6 +486,9 @@ impl Engine for Tendermint { } /// Attempt to seal generate a proposal seal. + /// + /// This operation is synchronous and may (quite reasonably) not be available, in which case + /// `Seal::None` will be returned. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { let header = block.header(); let author = header.author(); @@ -566,6 +628,57 @@ impl Engine for Tendermint { Ok(()) } + fn signals_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> super::EpochChange + { + let first = header.number() == 0; + self.validators.signals_epoch_end(first, header, block, receipts) + } + + fn is_epoch_end( + &self, + chain_head: &Header, + _chain: &super::Headers, + transition_store: &super::PendingTransitionStore, + ) -> Option> { + let first = chain_head.number() == 0; + + if let Some(change) = self.validators.is_epoch_end(first, chain_head) { + return Some(change) + } else if let Some(pending) = transition_store(chain_head.hash()) { + let signal_number = chain_head.number(); + let finality_proof = ::rlp::encode(chain_head); + return Some(combine_proofs(signal_number, &pending.proof, &finality_proof)) + } + + None + } + + fn epoch_verifier<'a>(&self, _header: &Header, proof: &'a [u8]) -> ConstructedVerifier<'a> { + let (signal_number, set_proof, finality_proof) = match destructure_proofs(proof) { + Ok(x) => x, + Err(e) => return ConstructedVerifier::Err(e), + }; + + let first = signal_number == 0; + match self.validators.epoch_set(first, self, signal_number, set_proof) { + Ok((list, finalize)) => { + let verifier = Box::new(EpochVerifier { + subchain_validators: list, + recover: |signature: &Signature, message: &Message| { + Ok(public_to_address(&::ethkey::recover(&signature, &message)?)) + }, + }); + + match finalize { + Some(finalize) => ConstructedVerifier::Unconfirmed(verifier, finality_proof, finalize), + None => ConstructedVerifier::Trusted(verifier), + } + } + Err(e) => ConstructedVerifier::Err(e), + } + } + fn set_signer(&self, ap: Arc, address: Address, password: String) { { self.signer.write().set(ap, address, password); @@ -577,6 +690,10 @@ impl Engine for Tendermint { self.signer.read().sign(hash).map_err(Into::into) } + fn snapshot_components(&self) -> Option> { + Some(Box::new(::snapshot::PoaSnapshot)) + } + fn stop(&self) { self.step_service.stop() } @@ -665,6 +782,7 @@ mod tests { use account_provider::AccountProvider; use spec::Spec; use engines::{Engine, EngineError, Seal}; + use engines::epoch::EpochVerifier; use super::*; /// Accounts inserted with "0" and "1" are validators. First proposer is "0". @@ -949,4 +1067,76 @@ mod tests { vote(engine, |mh| tap.sign(v0, None, mh).map(H520::from), h, r, Step::Precommit, proposal); assert_eq!(client.chain_info().best_block_number, 1); } + + #[test] + fn epoch_verifier_verify_light() { + use ethkey::Error as EthkeyError; + + let (spec, tap) = setup(); + let engine = spec.engine; + + let mut parent_header: Header = Header::default(); + parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + + let mut header = Header::default(); + header.set_number(2); + header.set_gas_limit(U256::from_str("222222").unwrap()); + let proposer = insert_and_unlock(&tap, "1"); + header.set_author(proposer); + let mut seal = proposal_seal(&tap, &header, 0); + + let vote_info = message_info_rlp(&VoteStep::new(2, 0, Step::Precommit), Some(header.bare_hash())); + let signature1 = tap.sign(proposer, None, vote_info.sha3()).unwrap(); + + let voter = insert_and_unlock(&tap, "0"); + let signature0 = tap.sign(voter, None, vote_info.sha3()).unwrap(); + + seal[1] = ::rlp::NULL_RLP.to_vec(); + seal[2] = ::rlp::encode_list(&vec![H520::from(signature1.clone())]).into_vec(); + header.set_seal(seal.clone()); + + let epoch_verifier = super::EpochVerifier { + subchain_validators: SimpleList::new(vec![proposer.clone(), voter.clone()]), + recover: { + let signature1 = signature1.clone(); + let signature0 = signature0.clone(); + let proposer = proposer.clone(); + let voter = voter.clone(); + move |s: &Signature, _: &Message| { + if *s == signature1 { + Ok(proposer) + } else if *s == signature0 { + Ok(voter) + } else { + Err(Error::Ethkey(EthkeyError::InvalidSignature)) + } + } + }, + }; + + // One good signature is not enough. + match epoch_verifier.verify_light(&header) { + Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}, + _ => panic!(), + } + + seal[2] = ::rlp::encode_list(&vec![H520::from(signature1.clone()), H520::from(signature0.clone())]).into_vec(); + header.set_seal(seal.clone()); + + assert!(epoch_verifier.verify_light(&header).is_ok()); + + let bad_voter = insert_and_unlock(&tap, "101"); + let bad_signature = tap.sign(bad_voter, None, vote_info.sha3()).unwrap(); + + seal[2] = ::rlp::encode_list(&vec![H520::from(signature1), H520::from(bad_signature)]).into_vec(); + header.set_seal(seal); + + // One good and one bad signature. + match epoch_verifier.verify_light(&header) { + Err(Error::Ethkey(EthkeyError::InvalidSignature)) => {}, + _ => panic!(), + }; + + engine.stop(); + } } diff --git a/util/rlp/src/untrusted_rlp.rs b/util/rlp/src/untrusted_rlp.rs index c027438b0..16714fe98 100644 --- a/util/rlp/src/untrusted_rlp.rs +++ b/util/rlp/src/untrusted_rlp.rs @@ -93,7 +93,7 @@ impl PayloadInfo { /// Data-oriented view onto rlp-slice. /// -/// This is immutable structere. No operations change it. +/// This is an immutable structure. No operations change it. /// /// Should be used in places where, error handling is required, /// eg. on input From b13cd0d484a95a9ce368de5d6d749bafeb602f29 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Thu, 27 Jul 2017 12:18:07 +0200 Subject: [PATCH 05/48] getFilterChanges -> getFilterMessages , subscribe & unsubscribe subscription is currently not working (method not found) --- js/src/api/rpc/shh/shh.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/src/api/rpc/shh/shh.js b/js/src/api/rpc/shh/shh.js index 8bba37caa..c58754abf 100644 --- a/js/src/api/rpc/shh/shh.js +++ b/js/src/api/rpc/shh/shh.js @@ -69,9 +69,9 @@ export default class Shh { .execute('shh_newMessageFilter', filterObj); } - getFilterChanges (identity) { + getFilterMessages (filterId) { return this._transport - .execute('shh_getFilterChanges', identity); + .execute('shh_getFilterMessages', filterId); } deleteMessageFilter (filterId) { @@ -79,13 +79,13 @@ export default class Shh { .execute('shh_deleteMessageFilter', filterId); } - subscribe (filterObj) { + subscribe (filterObj, callback) { return this._transport - .execute('shh_subscribe', filterObj); + .subscribe('shh', callback, filterObj); } unsubscribe (subscriptionId) { return this._transport - .execute('shh_unsubscribe', subscriptionId); + .unsubscribe(subscriptionId); } } From 1be3e5ec5e12b76c7ddff004b5dbe9baf8267591 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 27 Jul 2017 12:38:22 +0200 Subject: [PATCH 06/48] fix subscription name --- whisper/src/rpc/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/whisper/src/rpc/mod.rs b/whisper/src/rpc/mod.rs index 31fe997d5..6cec20c69 100644 --- a/whisper/src/rpc/mod.rs +++ b/whisper/src/rpc/mod.rs @@ -132,9 +132,9 @@ build_rpc_trait! { pub trait WhisperPubSub { type Metadata; - #[pubsub(name = "hello")] { + #[pubsub(name = "shh_subscription")] { /// Subscribe to messages matching the filter. - #[rpc(name = "ssh_subscribe")] + #[rpc(name = "shh_subscribe")] fn subscribe(&self, Self::Metadata, pubsub::Subscriber, types::FilterRequest); /// Unsubscribe from filter matching given ID. Return From 18fbf3c174cc0a4f3e52c12296618aa45c070f22 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 27 Jul 2017 12:52:36 +0200 Subject: [PATCH 07/48] only add pubsub if generic pubsub off --- parity/rpc_apis.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 234a7d299..dba69ae7e 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -282,9 +282,11 @@ impl FullDependencies { } }, Api::EthPubSub => { - let client = EthPubSubClient::new(self.client.clone(), self.remote.clone()); - self.client.add_notify(client.handler()); - handler.extend_with(client.to_delegate()); + if !for_generic_pubsub { + let client = EthPubSubClient::new(self.client.clone(), self.remote.clone()); + self.client.add_notify(client.handler()); + handler.extend_with(client.to_delegate()); + } }, Api::Personal => { handler.extend_with(PersonalClient::new(&self.secret_store, dispatcher.clone(), self.geth_compatibility).to_delegate()); @@ -353,9 +355,13 @@ impl FullDependencies { } } Api::WhisperPubSub => { - if let Some(ref whisper_rpc) = self.whisper_rpc { - let whisper = whisper_rpc.make_handler(); - handler.extend_with(::parity_whisper::rpc::WhisperPubSub::to_delegate(whisper)); + if !for_generic_pubsub { + if let Some(ref whisper_rpc) = self.whisper_rpc { + let whisper = whisper_rpc.make_handler(); + handler.extend_with( + ::parity_whisper::rpc::WhisperPubSub::to_delegate(whisper) + ); + } } } } From 70ef33f6fe5d22b21c435b2e77d8ebced3f30110 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 27 Jul 2017 13:50:12 +0200 Subject: [PATCH 08/48] Light client improvements (#6156) * no seal checking * import command and --no-seal-check for light client * fix eth_call * tweak registry dapps lookup * ignore failed requests to non-server peers --- ethcore/light/src/client/mod.rs | 5 +- ethcore/light/src/on_demand/mod.rs | 34 +++++-- parity/blockchain.rs | 156 ++++++++++++++++++++++++++++- parity/configuration.rs | 2 + parity/dapps.rs | 2 +- parity/run.rs | 1 + rpc/src/v1/helpers/dispatch.rs | 2 +- rpc/src/v1/helpers/light_fetch.rs | 120 ++++++++++++++++------ 8 files changed, 281 insertions(+), 41 deletions(-) diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 044c40133..3f0e50584 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -58,6 +58,8 @@ pub struct Config { pub db_wal: bool, /// Should it do full verification of blocks? pub verify_full: bool, + /// Should it check the seal of blocks? + pub check_seal: bool, } impl Default for Config { @@ -69,6 +71,7 @@ impl Default for Config { db_compaction: CompactionProfile::default(), db_wal: true, verify_full: true, + check_seal: true, } } } @@ -168,7 +171,7 @@ impl Client { let gh = ::rlp::encode(&spec.genesis_header()); Ok(Client { - queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, true), + queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, config.check_seal), engine: spec.engine.clone(), chain: HeaderChain::new(db.clone(), chain_col, &gh, cache)?, report: RwLock::new(ClientReport::default()), diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index c1919ebd1..42469725b 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -54,13 +54,21 @@ struct Peer { } impl Peer { - // whether this peer can fulfill the - fn can_fulfill(&self, c: &Capabilities) -> bool { - let caps = &self.capabilities; + // whether this peer can fulfill the necessary capabilities for the given + // request. + fn can_fulfill(&self, request: &Capabilities) -> bool { + let local_caps = &self.capabilities; + let can_serve_since = |req, local| { + match (req, local) { + (Some(request_block), Some(serve_since)) => request_block >= serve_since, + (Some(_), None) => false, + (None, _) => true, + } + }; - caps.serve_headers == c.serve_headers && - caps.serve_chain_since >= c.serve_chain_since && - caps.serve_state_since >= c.serve_chain_since + local_caps.serve_headers >= request.serve_headers && + can_serve_since(request.serve_chain_since, local_caps.serve_chain_since) && + can_serve_since(request.serve_state_since, local_caps.serve_state_since) } } @@ -244,7 +252,7 @@ impl OnDemand { peers: RwLock::new(HashMap::new()), in_transit: RwLock::new(HashMap::new()), cache: cache, - no_immediate_dispatch: true, + no_immediate_dispatch: false, } } @@ -266,7 +274,6 @@ impl OnDemand { -> Result>, basic_request::NoSuchOutput> { let (sender, receiver) = oneshot::channel(); - if requests.is_empty() { assert!(sender.send(Vec::new()).is_ok(), "receiver still in scope; qed"); return Ok(receiver); @@ -335,6 +342,7 @@ impl OnDemand { // dispatch pending requests, and discard those for which the corresponding // receiver has been dropped. fn dispatch_pending(&self, ctx: &BasicContext) { + // wrapper future for calling `poll_cancel` on our `Senders` to preserve // the invariant that it's always within a task. struct CheckHangup<'a, T: 'a>(&'a mut Sender); @@ -360,6 +368,8 @@ impl OnDemand { if self.pending.read().is_empty() { return } let mut pending = self.pending.write(); + debug!(target: "on_demand", "Attempting to dispatch {} pending requests", pending.len()); + // iterate over all pending requests, and check them for hang-up. // then, try and find a peer who can serve it. let peers = self.peers.read(); @@ -378,16 +388,21 @@ impl OnDemand { match ctx.request_from(*peer_id, pending.net_requests.clone()) { Ok(req_id) => { + trace!(target: "on_demand", "Dispatched request {} to peer {}", req_id, peer_id); self.in_transit.write().insert(req_id, pending); return None } - Err(net::Error::NoCredits) => {} + Err(net::Error::NoCredits) | Err(net::Error::NotServer) => {} Err(e) => debug!(target: "on_demand", "Error dispatching request to peer: {}", e), } } + + // TODO: maximum number of failures _when we have peers_. Some(pending) }) .collect(); // `pending` now contains all requests we couldn't dispatch. + + debug!(target: "on_demand", "Was unable to dispatch {} requests.", pending.len()); } // submit a pending request set. attempts to answer from cache before @@ -395,6 +410,7 @@ impl OnDemand { fn submit_pending(&self, ctx: &BasicContext, mut pending: Pending) { // answer as many requests from cache as we can, and schedule for dispatch // if incomplete. + pending.answer_from_cache(&*self.cache); if let Some(mut pending) = pending.try_complete() { pending.update_net_requests(); diff --git a/parity/blockchain.rs b/parity/blockchain.rs index a70272931..426c8d447 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -93,6 +93,7 @@ pub struct ImportBlockchain { pub check_seal: bool, pub with_color: bool, pub verifier_settings: VerifierSettings, + pub light: bool, } #[derive(Debug, PartialEq)] @@ -138,12 +139,165 @@ pub struct ExportState { pub fn execute(cmd: BlockchainCmd) -> Result<(), String> { match cmd { BlockchainCmd::Kill(kill_cmd) => kill_db(kill_cmd), - BlockchainCmd::Import(import_cmd) => execute_import(import_cmd), + BlockchainCmd::Import(import_cmd) => { + if import_cmd.light { + execute_import_light(import_cmd) + } else { + execute_import(import_cmd) + } + } BlockchainCmd::Export(export_cmd) => execute_export(export_cmd), BlockchainCmd::ExportState(export_cmd) => execute_export_state(export_cmd), } } +fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> { + use light::client::{Service as LightClientService, Config as LightClientConfig}; + use light::cache::Cache as LightDataCache; + + let timer = Instant::now(); + + // load spec file + let spec = cmd.spec.spec(&cmd.dirs.cache)?; + + // load genesis hash + let genesis_hash = spec.genesis_header().hash(); + + // database paths + let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir.clone()); + + // user defaults path + let user_defaults_path = db_dirs.user_defaults_path(); + + // load user defaults + let user_defaults = UserDefaults::load(&user_defaults_path)?; + + fdlimit::raise_fd_limit(); + + // select pruning algorithm + let algorithm = cmd.pruning.to_algorithm(&user_defaults); + + // prepare client and snapshot paths. + let client_path = db_dirs.client_path(algorithm); + + // execute upgrades + let compaction = cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path()); + execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction)?; + + // create dirs used by parity + cmd.dirs.create_dirs(false, false, false)?; + + let cache = Arc::new(::util::Mutex::new( + LightDataCache::new(Default::default(), ::time::Duration::seconds(0)) + )); + + let mut config = LightClientConfig { + queue: Default::default(), + chain_column: ::ethcore::db::COL_LIGHT_CHAIN, + db_cache_size: Some(cmd.cache_config.blockchain() as usize * 1024 * 1024), + db_compaction: compaction, + db_wal: cmd.wal, + verify_full: true, + check_seal: cmd.check_seal, + }; + + config.queue.max_mem_use = cmd.cache_config.queue() as usize * 1024 * 1024; + config.queue.verifier_settings = cmd.verifier_settings; + + let service = LightClientService::start(config, &spec, &client_path, cache) + .map_err(|e| format!("Failed to start client: {}", e))?; + + // free up the spec in memory. + drop(spec); + + let client = service.client(); + + let mut instream: Box = match cmd.file_path { + Some(f) => Box::new(fs::File::open(&f).map_err(|_| format!("Cannot open given file: {}", f))?), + None => Box::new(io::stdin()), + }; + + const READAHEAD_BYTES: usize = 8; + + let mut first_bytes: Vec = vec![0; READAHEAD_BYTES]; + let mut first_read = 0; + + let format = match cmd.format { + Some(format) => format, + None => { + first_read = instream.read(&mut first_bytes).map_err(|_| "Error reading from the file/stream.")?; + match first_bytes[0] { + 0xf9 => DataFormat::Binary, + _ => DataFormat::Hex, + } + } + }; + + let do_import = |bytes: Vec| { + while client.queue_info().is_full() { sleep(Duration::from_secs(1)); } + + let header: ::ethcore::header::Header = ::rlp::UntrustedRlp::new(&bytes).val_at(0) + .map_err(|e| format!("Bad block: {}", e))?; + + if client.best_block_header().number() >= header.number() { return Ok(()) } + + if header.number() % 10000 == 0 { + info!("#{}", header.number()); + } + + match client.import_header(header) { + Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { + trace!("Skipping block already in chain."); + } + Err(e) => { + return Err(format!("Cannot import block: {:?}", e)); + }, + Ok(_) => {}, + } + Ok(()) + }; + + match format { + DataFormat::Binary => { + loop { + let mut bytes = if first_read > 0 {first_bytes.clone()} else {vec![0; READAHEAD_BYTES]}; + let n = if first_read > 0 { + first_read + } else { + instream.read(&mut bytes).map_err(|_| "Error reading from the file/stream.")? + }; + if n == 0 { break; } + first_read = 0; + let s = PayloadInfo::from(&bytes).map_err(|e| format!("Invalid RLP in the file/stream: {:?}", e))?.total(); + bytes.resize(s, 0); + instream.read_exact(&mut bytes[n..]).map_err(|_| "Error reading from the file/stream.")?; + do_import(bytes)?; + } + } + DataFormat::Hex => { + for line in BufReader::new(instream).lines() { + let s = line.map_err(|_| "Error reading from the file/stream.")?; + let s = if first_read > 0 {from_utf8(&first_bytes).unwrap().to_owned() + &(s[..])} else {s}; + first_read = 0; + let bytes = s.from_hex().map_err(|_| "Invalid hex in file/stream.")?; + do_import(bytes)?; + } + } + } + client.flush_queue(); + + let ms = timer.elapsed().as_milliseconds(); + let report = client.report(); + + info!("Import completed in {} seconds, {} headers, {} hdr/s", + ms / 1000, + report.blocks_imported, + (report.blocks_imported * 1000) as u64 / ms, + ); + + Ok(()) +} + fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { let timer = Instant::now(); diff --git a/parity/configuration.rs b/parity/configuration.rs index 6d5990aa0..a0687f2a8 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -243,6 +243,7 @@ impl Configuration { check_seal: !self.args.flag_no_seal_check, with_color: logger_config.color, verifier_settings: self.verifier_settings(), + light: self.args.flag_light, }; Cmd::Blockchain(BlockchainCmd::Import(import_cmd)) } else if self.args.cmd_export { @@ -1184,6 +1185,7 @@ mod tests { check_seal: true, with_color: !cfg!(windows), verifier_settings: Default::default(), + light: false, }))); } diff --git a/parity/dapps.rs b/parity/dapps.rs index 1ddffce1f..14a57833c 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -114,7 +114,7 @@ impl ContractClient for LightRegistrar { tx: Transaction { nonce: self.client.engine().account_start_nonce(header.number()), action: Action::Call(address), - gas: 50_000_000.into(), + gas: 50_000.into(), // should be enough for all registry lookups. TODO: exponential backoff gas_price: 0.into(), value: 0.into(), data: data, diff --git a/parity/run.rs b/parity/run.rs index 6f0b444a0..7c835aa3f 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -211,6 +211,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc) -> db_compaction: compaction, db_wal: cmd.wal, verify_full: true, + check_seal: cmd.check_seal, }; config.queue.max_mem_use = cmd.cache_config.queue() as usize * 1024 * 1024; diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs index ff950d346..ddd238fd8 100644 --- a/rpc/src/v1/helpers/dispatch.rs +++ b/rpc/src/v1/helpers/dispatch.rs @@ -177,7 +177,7 @@ pub fn fetch_gas_price_corpus( ) -> BoxFuture, Error> { const GAS_PRICE_SAMPLE_SIZE: usize = 100; - if let Some(cached) = cache.lock().gas_price_corpus() { + if let Some(cached) = { cache.lock().gas_price_corpus() } { return future::ok(cached).boxed() } diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index a0316f9cb..4b5e0f815 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -26,6 +26,7 @@ use ethcore::filter::Filter as EthcoreFilter; use ethcore::transaction::{Action, Transaction as EthTransaction}; use futures::{future, Future, BoxFuture}; +use futures::future::Either; use jsonrpc_core::Error; use jsonrpc_macros::Trailing; @@ -159,7 +160,9 @@ impl LightFetch { /// helper for getting proved execution. pub fn proved_execution(&self, req: CallRequest, num: Trailing) -> BoxFuture { - const DEFAULT_GAS_PRICE: U256 = U256([0, 0, 0, 21_000_000]); + const DEFAULT_GAS_PRICE: u64 = 21_000; + // starting gas when gas not provided. + const START_GAS: u64 = 50_000; let (sync, on_demand, client) = (self.sync.clone(), self.on_demand.clone(), self.client.clone()); let req: CallRequestHelper = req.into(); @@ -167,21 +170,21 @@ impl LightFetch { let from = req.from.unwrap_or(Address::zero()); let nonce_fut = match req.nonce { - Some(nonce) => future::ok(Some(nonce)).boxed(), - None => self.account(from, id).map(|acc| acc.map(|a| a.nonce)).boxed(), + Some(nonce) => Either::A(future::ok(Some(nonce))), + None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))), }; let gas_price_fut = match req.gas_price { - Some(price) => future::ok(price).boxed(), - None => dispatch::fetch_gas_price_corpus( + Some(price) => Either::A(future::ok(price)), + None => Either::B(dispatch::fetch_gas_price_corpus( self.sync.clone(), self.client.clone(), self.on_demand.clone(), self.cache.clone(), ).map(|corp| match corp.median() { Some(median) => *median, - None => DEFAULT_GAS_PRICE, - }).boxed() + None => DEFAULT_GAS_PRICE.into(), + })) }; // if nonce resolves, this should too since it'll be in the LRU-cache. @@ -190,22 +193,29 @@ impl LightFetch { // fetch missing transaction fields from the network. nonce_fut.join(gas_price_fut).and_then(move |(nonce, gas_price)| { let action = req.to.map_or(Action::Create, Action::Call); - let gas = req.gas.unwrap_or(U256::from(10_000_000)); // better gas amount? let value = req.value.unwrap_or_else(U256::zero); let data = req.data.unwrap_or_default(); - future::done(match nonce { - Some(n) => Ok(EthTransaction { + future::done(match (nonce, req.gas) { + (Some(n), Some(gas)) => Ok((true, EthTransaction { nonce: n, action: action, gas: gas, gas_price: gas_price, value: value, data: data, - }.fake_sign(from)), - None => Err(errors::unknown_block()), + })), + (Some(n), None) => Ok((false, EthTransaction { + nonce: n, + action: action, + gas: START_GAS.into(), + gas_price: gas_price, + value: value, + data: data, + })), + (None, _) => Err(errors::unknown_block()), }) - }).join(header_fut).and_then(move |(tx, hdr)| { + }).join(header_fut).and_then(move |((gas_known, tx), hdr)| { // then request proved execution. // TODO: get last-hashes from network. let env_info = match client.env_info(id) { @@ -213,24 +223,15 @@ impl LightFetch { _ => return future::err(errors::unknown_block()).boxed(), }; - let request = request::TransactionProof { + execute_tx(gas_known, ExecuteParams { + from: from, tx: tx, - header: hdr.into(), + hdr: hdr, env_info: env_info, engine: client.engine().clone(), - }; - - let proved_future = sync.with_context(move |ctx| { - on_demand - .request(ctx, request) - .expect("no back-references; therefore all back-refs valid; qed") - .map_err(errors::on_demand_cancel).boxed() - }); - - match proved_future { - Some(fut) => fut.boxed(), - None => future::err(errors::network_disabled()).boxed(), - } + on_demand: on_demand, + sync: sync, + }) }).boxed() } @@ -320,3 +321,66 @@ impl LightFetch { } } } + +#[derive(Clone)] +struct ExecuteParams { + from: Address, + tx: EthTransaction, + hdr: encoded::Header, + env_info: ::evm::env_info::EnvInfo, + engine: Arc<::ethcore::engines::Engine>, + on_demand: Arc, + sync: Arc, +} + +// has a peer execute the transaction with given params. If `gas_known` is false, +// this will double the gas on each `OutOfGas` error. +fn execute_tx(gas_known: bool, params: ExecuteParams) -> BoxFuture { + if !gas_known { + future::loop_fn(params, |mut params| { + execute_tx(true, params.clone()).and_then(move |res| { + match res { + Ok(executed) => { + // TODO: how to distinguish between actual OOG and + // exception? + if executed.exception.is_some() { + let old_gas = params.tx.gas; + params.tx.gas = params.tx.gas * 2.into(); + if params.tx.gas > params.hdr.gas_limit() { + params.tx.gas = old_gas; + } else { + return Ok(future::Loop::Continue(params)) + } + } + + Ok(future::Loop::Break(Ok(executed))) + } + failed => Ok(future::Loop::Break(failed)), + } + }) + }).boxed() + } else { + trace!(target: "light_fetch", "Placing execution request for {} gas in on_demand", + params.tx.gas); + + let request = request::TransactionProof { + tx: params.tx.fake_sign(params.from), + header: params.hdr.into(), + env_info: params.env_info, + engine: params.engine, + }; + + let on_demand = params.on_demand; + let proved_future = params.sync.with_context(move |ctx| { + on_demand + .request(ctx, request) + .expect("no back-references; therefore all back-refs valid; qed") + .map_err(errors::on_demand_cancel) + }); + + match proved_future { + Some(fut) => fut.boxed(), + None => future::err(errors::network_disabled()).boxed(), + } + } +} From 8238fb37f3bb651b3b519928439defe24ff4893b Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 27 Jul 2017 15:36:55 +0300 Subject: [PATCH 09/48] new env exports added ___syscall140 ___syscall146 ___syscall54 _llvm_trap --- ethcore/evm/src/wasm/env.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/evm/src/wasm/env.rs index e68e50432..19cffad7e 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/evm/src/wasm/env.rs @@ -100,5 +100,25 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ "___syscall6", &[I32; 2], Some(I32), - ) + ), + Static( + "___syscall140", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall146", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall54", + &[I32; 2], + Some(I32) + ), + Static( + "_llvm_trap", + &[I32; 0], + None + ), ]; From 2d9a15324dea66cb90b57d7bc9ec8bbd9acf2997 Mon Sep 17 00:00:00 2001 From: Jutta Steiner Date: Thu, 27 Jul 2017 15:44:39 +0200 Subject: [PATCH 10/48] Including legal disclaimer --- SECURITY.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index ed7c83ab1..c3c8dee44 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -42,3 +42,14 @@ ETBD1Q== =K9Qw -----END PGP PUBLIC KEY BLOCK----- ``` + +Important Legal Information: + +The bug bounty program is an experimental and discretionary rewards program for the Parity community to reward those who are helping to improve the Parity software. +Awards are at the sole discretion of Parity Technologies Ltd.. + +We are not able to issue rewards to individuals who are on sanctions lists or who are in countries on sanctions lists (e.g. North Korea, Iran, etc). + +You are responsible for all taxes. All rewards are subject to applicable law. + +Finally, your testing must not violate any law or compromise any data that is not yours. From 98e0618750fb15e74490c44ed4b0fcc9577dfb0a Mon Sep 17 00:00:00 2001 From: Jutta Steiner Date: Thu, 27 Jul 2017 15:46:26 +0200 Subject: [PATCH 11/48] Update SECURITY.md --- SECURITY.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index c3c8dee44..8257cf733 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -45,8 +45,7 @@ ETBD1Q== Important Legal Information: -The bug bounty program is an experimental and discretionary rewards program for the Parity community to reward those who are helping to improve the Parity software. -Awards are at the sole discretion of Parity Technologies Ltd.. +Your submission might be eligible for a bug bounty. The bug bounty program is an experimental and discretionary rewards program for the Parity community to reward those who are helping to improve the Parity software. Rewards are at the sole discretion of Parity Technologies Ltd.. We are not able to issue rewards to individuals who are on sanctions lists or who are in countries on sanctions lists (e.g. North Korea, Iran, etc). From f245d66c8a8ecd34af0a3ffb437bc795ab95abf7 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Thu, 27 Jul 2017 15:48:49 +0200 Subject: [PATCH 12/48] shh_subscription added --- js/src/api/transport/ws/ws.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/api/transport/ws/ws.js b/js/src/api/transport/ws/ws.js index 3c642d5f8..9c276772d 100644 --- a/js/src/api/transport/ws/ws.js +++ b/js/src/api/transport/ws/ws.js @@ -29,7 +29,7 @@ export default class Ws extends JsonRpcBase { this._url = url; this._token = token; this._messages = {}; - this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [] }; + this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [], 'shh_subscription': [] }; this._sessionHash = null; this._connecting = false; From 0209c6e0ff3b8ab95456397a14d911b465a34916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 27 Jul 2017 17:35:05 +0200 Subject: [PATCH 13/48] Fix connecting to wildcard addresses. (#6167) --- js/src/secureApi.js | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/js/src/secureApi.js b/js/src/secureApi.js index b539f3ece..c34f71dd9 100644 --- a/js/src/secureApi.js +++ b/js/src/secureApi.js @@ -101,13 +101,7 @@ export default class SecureApi extends Api { return 'dapps.parity'; } - const { host } = this._dappsAddress; - - if (!host || host === '0.0.0.0') { - return window.location.hostname; - } - - return host; + return this._dappsAddress.host; } get isConnecting () { @@ -173,6 +167,25 @@ export default class SecureApi extends Api { }); } + /** + * Resolves a wildcard address to `window.location.hostname`; + */ + _resolveHost (url) { + const parts = url ? url.split(':') : []; + const port = parts[1]; + let host = parts[0]; + + if (!host) { + return host; + } + + if (host === '0.0.0.0') { + host = window.location.hostname; + } + + return port ? `${host}:${port}` : host; + } + /** * Returns a Promise that gets resolved with * a boolean: `true` if the node is up, `false` @@ -316,8 +329,8 @@ export default class SecureApi extends Api { this._uiApi.parity.wsUrl() ]) .then(([dappsUrl, wsUrl]) => { - this._dappsUrl = dappsUrl; - this._wsUrl = wsUrl; + this._dappsUrl = this._resolveHost(dappsUrl); + this._wsUrl = this._resolveHost(wsUrl); }); } From 9902714fb4b09ac82cdacf860e96ca5d72bb6b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 27 Jul 2017 17:36:23 +0200 Subject: [PATCH 14/48] Don't display an overlay in case the time sync check fails. (#6164) * Small improvements to time estimation. * Temporarily disable NTP time check by default. --- dapps/src/api/time.rs | 10 ++++++++-- js/src/redux/providers/status.js | 3 ++- js/src/redux/providers/statusReducer.js | 2 +- js/src/views/SyncWarning/syncWarning.js | 2 +- parity/cli/mod.rs | 4 ++-- parity/configuration.rs | 10 +++++----- parity/dapps.rs | 2 +- parity/rpc.rs | 2 +- 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/dapps/src/api/time.rs b/dapps/src/api/time.rs index 084890dc9..b81b4a844 100644 --- a/dapps/src/api/time.rs +++ b/dapps/src/api/time.rs @@ -100,6 +100,10 @@ impl SimpleNtp { impl Ntp for SimpleNtp { fn drift(&self) -> BoxFuture { let address = self.address.clone(); + if &*address == "none" { + return futures::future::err(Error::Ntp("NTP server is not provided.".into())).boxed(); + } + self.pool.spawn_fn(move || { let packet = ntp::request(&*address)?; let dest_time = ::time::now_utc().to_timespec(); @@ -114,7 +118,9 @@ impl Ntp for SimpleNtp { } } -const MAX_RESULTS: usize = 4; +// NOTE In a positive scenario first results will be seen after: +// MAX_RESULTS * UPDATE_TIMEOUT_OK_SECS seconds. +const MAX_RESULTS: usize = 7; const UPDATE_TIMEOUT_OK_SECS: u64 = 30; const UPDATE_TIMEOUT_ERR_SECS: u64 = 2; @@ -225,7 +231,7 @@ mod tests { fn time_checker() -> TimeChecker { let last_result = Arc::new(RwLock::new( - (Instant::now(), vec![Err(Error::Ntp("NTP server unavailable.".into()))].into()) + (Instant::now(), vec![Err(Error::Ntp("NTP server unavailable".into()))].into()) )); TimeChecker { diff --git a/js/src/redux/providers/status.js b/js/src/redux/providers/status.js index c8be9d55f..fc5dc38ba 100644 --- a/js/src/redux/providers/status.js +++ b/js/src/redux/providers/status.js @@ -228,9 +228,10 @@ export default class Status { _overallStatus = (health) => { const all = [health.peers, health.sync, health.time].filter(x => x); + const allNoTime = [health.peers, health.sync].filter(x => x); const statuses = all.map(x => x.status); const bad = statuses.find(x => x === STATUS_BAD); - const needsAttention = statuses.find(x => x === STATUS_WARN); + const needsAttention = allNoTime.map(x => x.status).find(x => x === STATUS_WARN); const message = all.map(x => x.message).filter(x => x); if (all.length) { diff --git a/js/src/redux/providers/statusReducer.js b/js/src/redux/providers/statusReducer.js index 23da8616f..23635cc8a 100644 --- a/js/src/redux/providers/statusReducer.js +++ b/js/src/redux/providers/statusReducer.js @@ -35,7 +35,7 @@ const initialState = { status: DEFAULT_STATUS }, overall: { - isReady: false, + isNotReady: true, status: DEFAULT_STATUS, message: [] } diff --git a/js/src/views/SyncWarning/syncWarning.js b/js/src/views/SyncWarning/syncWarning.js index cf448a9bb..cc4dbed91 100644 --- a/js/src/views/SyncWarning/syncWarning.js +++ b/js/src/views/SyncWarning/syncWarning.js @@ -116,7 +116,7 @@ class SyncWarning extends Component { function mapStateToProps (state) { const { health } = state.nodeStatus; - const isNotAvailableYet = health.overall.isReady; + const isNotAvailableYet = health.overall.isNotReady; const isOk = isNotAvailableYet || health.overall.status === 'ok'; return { diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index d637c20eb..c10069b02 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -359,7 +359,7 @@ usage! { or |c: &Config| otry!(c.vm).jit.clone(), // -- Miscellaneous Options - flag_ntp_server: String = "pool.ntp.org:123", + flag_ntp_server: String = "none", or |c: &Config| otry!(c.misc).ntp_server.clone(), flag_logging: Option = None, or |c: &Config| otry!(c.misc).logging.clone().map(Some), @@ -919,7 +919,7 @@ mod tests { flag_dapps_apis_all: None, // -- Miscellaneous Options - flag_ntp_server: "pool.ntp.org:123".into(), + flag_ntp_server: "none".into(), flag_version: false, flag_logging: Some("own_tx=trace".into()), flag_log_file: Some("/var/log/parity.log".into()), diff --git a/parity/configuration.rs b/parity/configuration.rs index a0687f2a8..40726eeca 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -1277,7 +1277,7 @@ mod tests { support_token_api: true }, UiConfiguration { enabled: true, - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), interface: "127.0.0.1".into(), port: 8180, hosts: Some(vec![]), @@ -1519,7 +1519,7 @@ mod tests { assert_eq!(conf0.directories().signer, "signer".to_owned()); assert_eq!(conf0.ui_config(), UiConfiguration { enabled: true, - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), interface: "127.0.0.1".into(), port: 8180, hosts: Some(vec![]), @@ -1528,7 +1528,7 @@ mod tests { assert_eq!(conf1.directories().signer, "signer".to_owned()); assert_eq!(conf1.ui_config(), UiConfiguration { enabled: true, - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), interface: "127.0.0.1".into(), port: 8180, hosts: Some(vec![]), @@ -1538,7 +1538,7 @@ mod tests { assert_eq!(conf2.directories().signer, "signer".to_owned()); assert_eq!(conf2.ui_config(), UiConfiguration { enabled: true, - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), interface: "127.0.0.1".into(), port: 3123, hosts: Some(vec![]), @@ -1547,7 +1547,7 @@ mod tests { assert_eq!(conf3.directories().signer, "signer".to_owned()); assert_eq!(conf3.ui_config(), UiConfiguration { enabled: true, - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), interface: "test".into(), port: 8180, hosts: Some(vec![]), diff --git a/parity/dapps.rs b/parity/dapps.rs index 14a57833c..cec3765f2 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -47,7 +47,7 @@ impl Default for Configuration { let data_dir = default_data_path(); Configuration { enabled: true, - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), dapps_path: replace_home(&data_dir, "$BASE/dapps").into(), extra_dapps: vec![], extra_embed_on: vec![], diff --git a/parity/rpc.rs b/parity/rpc.rs index 95c6f0bbf..b15c331d6 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -107,7 +107,7 @@ impl Default for UiConfiguration { fn default() -> Self { UiConfiguration { enabled: true && cfg!(feature = "ui-enabled"), - ntp_server: "pool.ntp.org:123".into(), + ntp_server: "none".into(), port: 8180, interface: "127.0.0.1".into(), hosts: Some(vec![]), From 7a810def2836584a104b711da06c69bb1cdf4f31 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Thu, 27 Jul 2017 18:07:25 +0200 Subject: [PATCH 15/48] Shh documentation (jsonrpc interface) --- js/src/jsonrpc/interfaces/shh.js | 201 ++++++++++++++++++++++++------- js/src/jsonrpc/types.js | 2 + 2 files changed, 157 insertions(+), 46 deletions(-) diff --git a/js/src/jsonrpc/interfaces/shh.js b/js/src/jsonrpc/interfaces/shh.js index 801c965d0..87af117fe 100644 --- a/js/src/jsonrpc/interfaces/shh.js +++ b/js/src/jsonrpc/interfaces/shh.js @@ -14,21 +14,37 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { Data, Quantity } from '../types'; +import { Data, Quantity, Float } from '../types'; export default { - version: { - nodoc: 'Not present in Rust code', + info: { desc: 'Returns the current whisper protocol version.', params: [], returns: { - type: String, - desc: 'The current whisper protocol version' + type: Object, + desc: 'The current whisper protocol version', + details: { + minPow: { + type: Float, + desc: 'required PoW threshold for a message to be accepted into the local pool, or null if there is empty space in the pool.' + }, + messages: { + type: Quantity, + desc: 'Number of messages in the pool.' + }, + memory: { + type: Quantity, + desc: 'Amount of memory used by messages in the pool.' + }, + targetMemory: { + type: Quantity, + desc: 'Target amount of memory for the pool.' + } + } } }, post: { - nodoc: 'Not present in Rust code', desc: 'Sends a whisper message.', params: [ { @@ -63,79 +79,122 @@ export default { } }, - newIdentity: { - nodoc: 'Not present in Rust code', - desc: 'Creates new whisper identity in the client.', + newKeyPair: { + desc: 'Generate a new key pair (identity) for asymmetric encryption.', params: [], returns: { type: Data, - desc: '60 Bytes - the address of the new identiy' + desc: '32 Bytes - the address of the new identiy' } }, - hasIdentity: { - nodoc: 'Not present in Rust code', - desc: 'Checks if the client hold the private keys for a given identity.', + addPrivateKey: { + desc: 'Import a private key to use for asymmetric decryption.', params: [ { type: Data, - desc: '60 Bytes - The identity address to check' + desc: '32 Bytes - The private key to import' } ], returns: { - type: Boolean, - desc: '`true` if the client holds the privatekey for that identity, otherwise `false`' + type: Data, + desc: '`32 Bytes` A unique identity to refer to this keypair by.' } }, - newGroup: { - nodoc: 'Not present in Rust code', - desc: '(?)', + newSymKey: { + desc: 'Generate a key pair(identity) for symmetric encryption.', params: [], returns: { - type: Data, desc: '60 Bytes - the address of the new group. (?)' + type: Data, + desc: '32 Bytes - the address of the new identiy' } }, - addToGroup: { - nodoc: 'Not present in Rust code', - desc: '(?)', + getPublicKey: { + desc: 'Get the public key associated with an asymmetric identity.', params: [ { type: Data, - desc: '60 Bytes - The identity address to add to a group (?)' + desc: '32 Bytes - The identity to fetch the public key for.' } ], returns: { - type: Boolean, - desc: '`true` if the identity was successfully added to the group, otherwise `false` (?)' + type: Data, + desc: '`64 Bytes` - The public key of the asymmetric identity.' } }, - newFilter: { - nodoc: 'Not present in Rust code', - desc: 'Creates filter to notify, when client receives whisper message matching the filter options.', + getPrivateKey: { + desc: 'Get the private key associated with an asymmetric identity.', + params: [ + { + type: Data, + desc: '32 Bytes - The identity to fetch the private key for.' + } + ], + returns: { + type: Data, + desc: '`32 Bytes` - The private key of the asymmetric identity.' + } + }, + + getSymKey: { + desc: 'Get the key associated with a symmetric identity.', + params: [ + { + type: Data, + desc: '`32 Bytes` - The identity to fetch the key for.' + } + ], + returns: { + type: Data, + desc: '`64 Bytes` - The key of the asymmetric identity.' + } + }, + + deleteKey: { + desc: 'Delete the key or key pair denoted by the given identity.', + params: [ + { + type: Data, + desc: '`32 Bytes` - The identity to remove.' + } + ], + returns: { + type: Data, + desc: '`true` on successful removal, `false` on unkown identity' + } + }, + + newMessageFilter: { + desc: 'Create a new polled filter for messages.', params: [ { type: Object, desc: 'The filter options:', details: { - to: { - type: Data, desc: '60 Bytes - Identity of the receiver. *When present it will try to decrypt any incoming message if the client holds the private key to this identity.*', + decryptWith: { + type: Data, + desc: '`32 bytes` - Identity of key used for description. null if listening for broadcasts.' + }, + from: { + type: Data, desc: '`32 Bytes` - if present, only accept messages signed by this key.', optional: true }, topics: { - type: Array, desc: 'Array of `Data` topics which the incoming message\'s topics should match. You can use the following combinations' + type: Array, + desc: 'Array of `Data`. Only accept messages matching these topics. Should be non-empty.' } } } ], returns: { - type: Quantity, - desc: 'The newly created filter' + type: Data, + desc: '`32 bytes` - Unique identity for this filter.' } }, - uninstallFilter: { + getFilterMesssages: { nodoc: 'Not present in Rust code', desc: 'Uninstalls a filter with given id. Should always be called when watch is no longer needed.\nAdditonally Filters timeout when they aren\'t requested with [shh_getFilterChanges](#shh_getfilterchanges) for a period of time.', params: [ @@ -150,30 +209,80 @@ export default { } }, - getFilterChanges: { - nodoc: 'Not present in Rust code', + getFilterMessages: { desc: 'Polling method for whisper filters. Returns new messages since the last call of this method.\n**Note** calling the [shh_getMessages](#shh_getmessages) method, will reset the buffer for this method, so that you won\'t receive duplicate messages.', params: [ { - type: Quantity, - desc: 'The filter id' + type: Data, + desc: '`32 bytes` - Unique identity to fetch changes for.' } ], returns: { type: Array, - desc: 'Array of messages received since last poll' + desc: 'Array of `messages` received since last poll', + details: { + from: { + type: Data, + desc: '`64 bytes` - Public key that signed this message or null' + }, + recipient: { + type: Data, + desc: '`32 bytes` - local identity which decrypted this message, or null if broadcast.' + }, + ttl: { + type: Quantity, + desc: 'time to live of the message in seconds.' + }, + topics: { + type: Array, + desc: 'Array of `Data` - Topics which matched the filter' + }, + timestamp: { + type: Quantity, + desc: 'Unix timestamp of the message' + }, + payload: { + type: Data, + desc: 'The message body' + }, + padding: { + type: Data, + desc: 'Optional padding which was decoded.' + } + } } }, - getMessages: { - nodoc: 'Not present in Rust code', - desc: 'Get all messages matching a filter. Unlike `shh_getFilterChanges` this returns all messages.', + deleteMessageFilter: { + desc: 'Delete a message filter by identifier', params: [ { - type: Quantity, - desc: 'The filter id' + type: Data, + desc: '`32 bytes` - The identity of the filter to delete.' } ], - returns: 'See [shh_getFilterChanges](#shh_getfilterchanges)' + returns: { + type: Boolean, + desc: '`true` on deletion, `false` on unrecognized ID.' + } + }, + subscribe: { + desc: 'Open a subscription to a filter.', + params: 'See [shh_newMessageFilter](#shh_newmessagefilter)', + returns: { + type: Quantity, + desc: 'Unique subscription identifier' + } + }, + unsubscribe: { + desc: 'Close a subscribed filter', + params: [{ + type: Quantity, + desc: 'Unique subscription identifier' + }], + returns: { + type: Boolean, + desc: '`true` on success, `false` on unkown subscription ID.' + } } }; diff --git a/js/src/jsonrpc/types.js b/js/src/jsonrpc/types.js index 52e79019e..c750932c9 100644 --- a/js/src/jsonrpc/types.js +++ b/js/src/jsonrpc/types.js @@ -22,6 +22,8 @@ export class Hash {} export class Integer {} +export class Float {} + export class Quantity {} export class BlockNumber { From 671ed1b9dbf123ffb7f27ee9d0824e2dea108f47 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 27 Jul 2017 16:42:35 +0000 Subject: [PATCH 16/48] [ci skip] js-precompiled 20170727-163754 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 704f3ee36..359b2d2f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2009,7 +2009,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/paritytech/js-precompiled.git#9394d746f859365082ae375119ee70a0a18956a5" +source = "git+https://github.com/paritytech/js-precompiled.git#5a357d01c459d3f371a87bfa138567b30603222c" dependencies = [ "parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index d299a421d..612d7c1d8 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "1.8.6", + "version": "1.8.7", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From e84f3082649e2c4d40d33e47564019905a255650 Mon Sep 17 00:00:00 2001 From: Jef Date: Fri, 28 Jul 2017 14:26:22 +0200 Subject: [PATCH 17/48] Fix unsoundness in ethash's unsafe code (#6140) * Fix benchmarks * Fix unsoundness in uses of unsafety * Remove most uses of unsafe indexing and ptr::copy_nonoverlapping This commit also includes a completely absurd optimisation that I promise is an honest win. You can check the benchmarks, I barely believe it myself. * Add safety comment * Add more safety comments --- ethash/src/compute.rs | 287 +++++++++++++++++++++++++++--------------- ethash/src/lib.rs | 4 +- 2 files changed, 192 insertions(+), 99 deletions(-) diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index 1bc546c84..ab2c758df 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -123,7 +123,9 @@ impl Light { } let num_nodes = cache_size / NODE_BYTES; let mut nodes: Vec = Vec::with_capacity(num_nodes); - nodes.resize(num_nodes, unsafe { mem::uninitialized() }); + + unsafe { nodes.set_len(num_nodes) }; + let buf = unsafe { slice::from_raw_parts_mut(nodes.as_mut_ptr() as *mut u8, cache_size) }; file.read_exact(buf)?; Ok(Light { @@ -208,17 +210,20 @@ pub fn slow_get_seedhash(block_number: u64) -> H256 { SeedHashCompute::resume_compute_seedhash([0u8; 32], 0, block_number / ETHASH_EPOCH_LENGTH) } -#[inline] fn fnv_hash(x: u32, y: u32) -> u32 { return x.wrapping_mul(FNV_PRIME) ^ y; } -#[inline] fn sha3_512(input: &[u8], output: &mut [u8]) { unsafe { sha3::sha3_512(output.as_mut_ptr(), output.len(), input.as_ptr(), input.len()) }; } -#[inline] +fn sha3_512_inplace(input: &mut [u8]) { + // This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This + // means that we can reuse the input buffer for both input and output. + unsafe { sha3::sha3_512(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()) }; +} + fn get_cache_size(block_number: u64) -> usize { let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); sz = sz - NODE_BYTES as u64; @@ -228,7 +233,6 @@ fn get_cache_size(block_number: u64) -> usize { sz as usize } -#[inline] fn get_data_size(block_number: u64) -> usize { let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); sz = sz - ETHASH_MIX_BYTES as u64; @@ -238,7 +242,6 @@ fn get_data_size(block_number: u64) -> usize { sz as usize } - /// Difficulty quick check for POW preverification /// /// `header_hash` The hash of the header @@ -246,17 +249,27 @@ fn get_data_size(block_number: u64) -> usize { /// `mix_hash` The mix digest hash /// Boundary recovered from mix hash pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256) -> H256 { - let mut buf = [0u8; 64 + 32]; - unsafe { ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32) }; - unsafe { ptr::copy_nonoverlapping(mem::transmute(&nonce), buf[32..].as_mut_ptr(), 8) }; + unsafe { + // This is safe - the `sha3_512` call below reads the first 40 bytes (which we explicitly set + // with two `copy_nonoverlapping` calls) but writes the first 64, and then we explicitly write + // the next 32 bytes before we read the whole thing with `sha3_256`. + // + // This cannot be elided by the compiler as it doesn't know the implementation of + // `sha3_512`. + let mut buf: [u8; 64 + 32] = mem::uninitialized(); - unsafe { sha3::sha3_512(buf.as_mut_ptr(), 64, buf.as_ptr(), 40) }; - unsafe { ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32) }; + ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32); + ptr::copy_nonoverlapping(mem::transmute(&nonce), buf[32..].as_mut_ptr(), 8); - let mut hash = [0u8; 32]; - unsafe { sha3::sha3_256(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len()) }; - hash.as_mut_ptr(); - hash + sha3::sha3_512(buf.as_mut_ptr(), 64, buf.as_ptr(), 40); + ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32); + + // This is initialized in `sha3_256` + let mut hash: [u8; 32] = mem::uninitialized(); + sha3::sha3_256(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len()); + + hash + } } /// Calculate the light client data @@ -269,118 +282,194 @@ pub fn light_compute(light: &Light, header_hash: &H256, nonce: u64) -> ProofOfWo } fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) -> ProofOfWork { + macro_rules! make_const_array { + ($n:expr, $value:expr) => {{ + // We use explicit lifetimes to ensure that val's borrow is invalidated until the + // transmuted val dies. + unsafe fn make_const_array<'a, T, U>(val: &'a mut [T]) -> &'a mut [U; $n] { + use ::std::mem; + + debug_assert_eq!(val.len() * mem::size_of::(), $n * mem::size_of::()); + mem::transmute(val.as_mut_ptr()) + } + + make_const_array($value) + }} + } + + #[repr(C)] + struct MixBuf { + half_mix: Node, + compress_bytes: [u8; MIX_WORDS], + }; + if full_size % MIX_WORDS != 0 { panic!("Unaligned full size"); } - // pack hash and nonce together into first 40 bytes of s_mix - let mut s_mix: [Node; MIX_NODES + 1] = [Node::default(), Node::default(), Node::default()]; - unsafe { ptr::copy_nonoverlapping(header_hash.as_ptr(), s_mix.get_unchecked_mut(0).bytes.as_mut_ptr(), 32) }; - unsafe { ptr::copy_nonoverlapping(mem::transmute(&nonce), s_mix.get_unchecked_mut(0).bytes[32..].as_mut_ptr(), 8) }; - // compute sha3-512 hash and replicate across mix - unsafe { - sha3::sha3_512(s_mix.get_unchecked_mut(0).bytes.as_mut_ptr(), NODE_BYTES, s_mix.get_unchecked(0).bytes.as_ptr(), 40); - let (f_mix, mut mix) = s_mix.split_at_mut(1); - for w in 0..MIX_WORDS { - *mix.get_unchecked_mut(0).as_words_mut().get_unchecked_mut(w) = *f_mix.get_unchecked(0).as_words().get_unchecked(w % NODE_WORDS); - } + // You may be asking yourself: what in the name of Crypto Jesus is going on here? So: we need + // `half_mix` and `compress_bytes` in a single array later down in the code (we hash them + // together to create `value`) so that we can hash the full array. However, we do a bunch of + // reading and writing to these variables first. We originally allocated two arrays and then + // stuck them together with `ptr::copy_nonoverlapping` at the end, but this method is + // _significantly_ faster - by my benchmarks, a consistent 3-5%. This is the most ridiculous + // optimization I have ever done and I am so sorry. I can only chalk it up to cache locality + // improvements, since I can't imagine that 3-5% of our runtime is taken up by catting two + // arrays together. + let mut buf: MixBuf = MixBuf { + half_mix: unsafe { + // Pack `header_hash` and `nonce` together + // We explicitly write the first 40 bytes, leaving the last 24 as uninitialized. Then + // `sha3_512` reads the first 40 bytes (4th parameter) and overwrites the entire array, + // leaving it fully initialized. + let mut out: [u8; NODE_BYTES] = mem::uninitialized(); - let page_size = 4 * MIX_WORDS; - let num_full_pages = (full_size / page_size) as u32; - let cache: &[Node] = &light.cache; // deref once for better performance + ptr::copy_nonoverlapping( + header_hash.as_ptr(), + out.as_mut_ptr(), + header_hash.len(), + ); + ptr::copy_nonoverlapping( + mem::transmute(&nonce), + out[header_hash.len()..].as_mut_ptr(), + mem::size_of::(), + ); - debug_assert_eq!(ETHASH_ACCESSES, 64); - debug_assert_eq!(MIX_NODES, 2); - debug_assert_eq!(NODE_WORDS, 16); + // compute sha3-512 hash and replicate across mix + sha3::sha3_512( + out.as_mut_ptr(), + NODE_BYTES, + out.as_ptr(), + header_hash.len() + mem::size_of::() + ); + + Node { bytes: out } + }, + // This is fully initialized before being read, see `let mut compress = ...` below + compress_bytes: unsafe { mem::uninitialized() }, + }; + + let mut mix: [_; MIX_NODES] = [buf.half_mix.clone(), buf.half_mix.clone()]; + + let page_size = 4 * MIX_WORDS; + let num_full_pages = (full_size / page_size) as u32; + // deref once for better performance + let cache: &[Node] = &light.cache; + let first_val = buf.half_mix.as_words()[0]; + + debug_assert_eq!(MIX_NODES, 2); + debug_assert_eq!(NODE_WORDS, 16); + + for i in 0..ETHASH_ACCESSES as u32 { + let index = { + // This is trivially safe, but does not work on big-endian. The safety of this is + // asserted in debug builds (see the definition of `make_const_array!`). + let mix_words: &mut [u32; MIX_WORDS] = unsafe { + make_const_array!(MIX_WORDS, &mut mix) + }; + + fnv_hash( + first_val ^ i, + mix_words[i as usize % MIX_WORDS] + ) % num_full_pages + }; unroll! { - // ETHASH_ACCESSES - for i_usize in 0..64 { - let i = i_usize as u32; - - let index = fnv_hash( - f_mix.get_unchecked(0).as_words().get_unchecked(0) ^ i, - *mix.get_unchecked(0).as_words().get_unchecked(i as usize % MIX_WORDS) - ) % num_full_pages; + // MIX_NODES + for n in 0..2 { + let tmp_node = calculate_dag_item( + index * MIX_NODES as u32 + n as u32, + cache, + ); unroll! { - // MIX_NODES - for n in 0..2 { - let tmp_node = calculate_dag_item( - index * MIX_NODES as u32 + n as u32, - cache, - ); - - unroll! { - // NODE_WORDS - for w in 0..16 { - *mix.get_unchecked_mut(n).as_words_mut().get_unchecked_mut(w) = - fnv_hash( - *mix.get_unchecked(n).as_words().get_unchecked(w), - *tmp_node.as_words().get_unchecked(w), - ); - } - } + // NODE_WORDS + for w in 0..16 { + mix[n].as_words_mut()[w] = + fnv_hash( + mix[n].as_words()[w], + tmp_node.as_words()[w], + ); } } } } + } + let mix_words: [u32; MIX_WORDS] = unsafe { mem::transmute(mix) }; + + { + // This is an uninitialized buffer to begin with, but we iterate precisely `compress.len()` + // times and set each index, leaving the array fully initialized. THIS ONLY WORKS ON LITTLE- + // ENDIAN MACHINES. See a future PR to make this and the rest of the code work correctly on + // big-endian arches like mips. + let mut compress: &mut [u32; MIX_WORDS / 4] = unsafe { + make_const_array!(MIX_WORDS / 4, &mut buf.compress_bytes) + }; + + // Compress mix debug_assert_eq!(MIX_WORDS / 4, 8); - - // compress mix unroll! { for i in 0..8 { let w = i * 4; - let mut reduction = *mix.get_unchecked(0).as_words().get_unchecked(w + 0); - reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 1); - reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 2); - reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 3); - *mix.get_unchecked_mut(0).as_words_mut().get_unchecked_mut(i) = reduction; + + let mut reduction = mix_words[w + 0]; + reduction = reduction.wrapping_mul(FNV_PRIME) ^ mix_words[w + 1]; + reduction = reduction.wrapping_mul(FNV_PRIME) ^ mix_words[w + 2]; + reduction = reduction.wrapping_mul(FNV_PRIME) ^ mix_words[w + 3]; + compress[i] = reduction; } } + } - let mut mix_hash = [0u8; 32]; - let mut buf = [0u8; 32 + 64]; - ptr::copy_nonoverlapping(f_mix.get_unchecked_mut(0).bytes.as_ptr(), buf.as_mut_ptr(), 64); - ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), buf[64..].as_mut_ptr(), 32); - ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), mix_hash.as_mut_ptr(), 32); - let mut value: H256 = [0u8; 32]; - sha3::sha3_256(value.as_mut_ptr(), value.len(), buf.as_ptr(), buf.len()); - ProofOfWork { - mix_hash: mix_hash, - value: value, - } + let mix_hash = buf.compress_bytes; + + let value: H256 = unsafe { + // We can interpret the buffer as an array of `u8`s, since it's `repr(C)`. + let read_ptr: *const u8 = mem::transmute(&buf); + // We overwrite the second half since `sha3_256` has an internal buffer and so allows + // overlapping arrays as input. + let write_ptr: *mut u8 = mem::transmute(&mut buf.compress_bytes); + sha3::sha3_256( + write_ptr, + buf.compress_bytes.len(), + read_ptr, + buf.half_mix.bytes.len() + buf.compress_bytes.len(), + ); + buf.compress_bytes + }; + + ProofOfWork { + mix_hash: mix_hash, + value: value, } } fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node { - unsafe { - let num_parent_nodes = cache.len(); - let init = cache.get_unchecked(node_index as usize % num_parent_nodes); - let mut ret = init.clone(); - *ret.as_words_mut().get_unchecked_mut(0) ^= node_index; - sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len()); + let num_parent_nodes = cache.len(); + let mut ret = cache[node_index as usize % num_parent_nodes].clone(); + ret.as_words_mut()[0] ^= node_index; - debug_assert_eq!(NODE_WORDS, 16); - for i in 0..ETHASH_DATASET_PARENTS as u32 { - let parent_index = fnv_hash(node_index ^ i, *ret.as_words().get_unchecked(i as usize % NODE_WORDS)) % num_parent_nodes as u32; - let parent = cache.get_unchecked(parent_index as usize); + sha3_512_inplace(&mut ret.bytes); - unroll! { - for w in 0..16 { - *ret.as_words_mut().get_unchecked_mut(w) = - fnv_hash( - *ret.as_words().get_unchecked(w), - *parent.as_words().get_unchecked(w) - ); - } + debug_assert_eq!(NODE_WORDS, 16); + for i in 0..ETHASH_DATASET_PARENTS as u32 { + let parent_index = fnv_hash( + node_index ^ i, + ret.as_words()[i as usize % NODE_WORDS], + ) % num_parent_nodes as u32; + let parent = &cache[parent_index as usize]; + + unroll! { + for w in 0..16 { + ret.as_words_mut()[w] = fnv_hash(ret.as_words()[w], parent.as_words()[w]); } } - - sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len()); - ret } + + sha3_512_inplace(&mut ret.bytes); + + ret } fn light_new>(cache_dir: T, block_number: u64) -> Light { @@ -391,9 +480,11 @@ fn light_new>(cache_dir: T, block_number: u64) -> Light { assert!(cache_size % NODE_BYTES == 0, "Unaligned cache size"); let num_nodes = cache_size / NODE_BYTES; - let mut nodes = Vec::with_capacity(num_nodes); - nodes.resize(num_nodes, Node::default()); + let mut nodes: Vec = Vec::with_capacity(num_nodes); unsafe { + // Use uninit instead of unnecessarily writing `size_of::() * num_nodes` 0s + nodes.set_len(num_nodes); + sha3_512(&seedhash[0..32], &mut nodes.get_unchecked_mut(0).bytes); for i in 1..num_nodes { sha3::sha3_512(nodes.get_unchecked_mut(i).bytes.as_mut_ptr(), NODE_BYTES, nodes.get_unchecked(i - 1).bytes.as_ptr(), NODE_BYTES); diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs index a9f563af3..9112546c4 100644 --- a/ethash/src/lib.rs +++ b/ethash/src/lib.rs @@ -143,9 +143,11 @@ mod benchmarks { #[bench] fn bench_light_compute(b: &mut Bencher) { + use ::std::env; + let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72]; let nonce = 0xd7b3ac70a301a249; - let light = Light::new(486382); + let light = Light::new(env::temp_dir(), 486382); b.iter(|| light_compute(&light, &hash, nonce)); } From e234b7fdbf2c9ab30044073579fd1bd8488f51b6 Mon Sep 17 00:00:00 2001 From: fro Date: Fri, 28 Jul 2017 16:38:03 +0300 Subject: [PATCH 18/48] realloc test added --- ethcore/evm/src/wasm/env.rs | 37 ++++++++++++++++++++++++++++++++++- ethcore/evm/src/wasm/tests.rs | 24 +++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/evm/src/wasm/env.rs index cabd38bd9..00770bb4a 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/evm/src/wasm/env.rs @@ -115,5 +115,40 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ "_emscripten_memcpy_big", &[I32; 3], Some(I32), - ) + ), + Static( + "___syscall140", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall146", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall54", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall6", + &[I32; 2], + Some(I32) + ), + Static( + "_llvm_trap", + &[I32; 0], + None + ), + Static( + "abortOnCannotGrowMemory", + &[I32; 0], + Some(I32) + ), + Static( + "___setErrNo", + &[I32; 1], + None + ), ]; diff --git a/ethcore/evm/src/wasm/tests.rs b/ethcore/evm/src/wasm/tests.rs index 8ae13daae..8c2ec0b3f 100644 --- a/ethcore/evm/src/wasm/tests.rs +++ b/ethcore/evm/src/wasm/tests.rs @@ -272,3 +272,27 @@ fn create() { )); assert_eq!(gas_left, U256::from(99_768)); } + +// Realloc test +#[test] +fn realloc() { + let code = load_sample!("realloc.wasm"); + + let mut params = ActionParams::default(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.data = Some(vec![0u8]); + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Realloc should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + assert_eq!(gas_left, U256::from(98326)); + assert_eq!(result, vec![0u8; 2]); + +} From ad30a6899b4306d447b6aeefed08c2b27296b0a9 Mon Sep 17 00:00:00 2001 From: Afri Date: Fri, 28 Jul 2017 18:15:04 +0200 Subject: [PATCH 19/48] Update Changelog for 1.6.10 and 1.7.0 (#6183) * Update changelog for 1.6.10 * Update changelog for 1.7.0 * Move 1.7.0 to top * Rephrase contract warp * Update final 1.7.0 changelog * Update beta backports in Changelog --- CHANGELOG.md | 59 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59eb1d0b4..78bf895ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,41 +1,45 @@ -## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-23) - -This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure. - -All Changes: - -- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116) - - Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112) - - Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874) - - Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work) -- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118) -- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104) - - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) - - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) -- Bump to v1.6.10 - -## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-23) +## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-28) Parity 1.7.0 is a major release introducing several important features: -- **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. +- **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. Please, note: The wallet UI integration for the light client is not included, yet. - **Experimental web wallet**. A hosted version of Parity that keeps the keys and signs transactions using your browser storage. Try it at https://wallet.parity.io or run your own with `--public-node`. - **WASM contract support**. Private networks can run contracts compiled into WASM bytecode. _More information and documentation to follow_. - **DApps and RPC server merge**. DApp and RPC are now available through a single API endpoint. DApp server related settings are deprecated. - **Export accounts from the wallet**. Backing up your keys can now simply be managed through the wallet interface. -- **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and light sync. +- **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and, in the near future, light sync. - **PubSub API**. https://github.com/paritytech/parity/wiki/JSONRPC-Parity-Pub-Sub-module - **Signer apps for IOS and Android**. Full list of included changes: +- Backports [#6163](https://github.com/paritytech/parity/pull/6163) + - Light client improvements ([#6156](https://github.com/paritytech/parity/pull/6156)) + - No seal checking + - Import command and --no-seal-check for light client + - Fix eth_call + - Tweak registry dapps lookup + - Ignore failed requests to non-server peers + - Fix connecting to wildcard addresses. ([#6167](https://github.com/paritytech/parity/pull/6167)) + - Don't display an overlay in case the time sync check fails. ([#6164](https://github.com/paritytech/parity/pull/6164)) + - Small improvements to time estimation. + - Temporarily disable NTP time check by default. +- Light client fixes ([#6148](https://github.com/paritytech/parity/pull/6148)) [#6151](https://github.com/paritytech/parity/pull/6151) + - Light client fixes + - Fix memory-lru-cache + - Clear pending reqs on disconnect +- Filter tokens logs from current block, not genesis ([#6128](https://github.com/paritytech/parity/pull/6128)) [#6141](https://github.com/paritytech/parity/pull/6141) +- Fix QR scanner returning null on confirm [#6122](https://github.com/paritytech/parity/pull/6122) - Check QR before lowercase ([#6119](https://github.com/paritytech/parity/pull/6119)) [#6120](https://github.com/paritytech/parity/pull/6120) - Remove chunk to restore from pending set only upon successful import [#6117](https://github.com/paritytech/parity/pull/6117) - Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) - Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) +- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108) - Backported wallet fix [#6105](https://github.com/paritytech/parity/pull/6105) - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) +- Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) +- Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) - Bump snap version and tweak importing detection logic ([#6079](https://github.com/paritytech/parity/pull/6079)) [#6081](https://github.com/paritytech/parity/pull/6081) - bump last tick just before printing info and restore sync detection - bump kovan snapshot version @@ -439,6 +443,23 @@ Full list of included changes: - Update the Wallet Library Registry key [#4817](https://github.com/paritytech/parity/pull/4817) - Update Wallet to new Wallet Code [#4805](https://github.com/paritytech/parity/pull/4805) +## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-25) + +This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure. + +All Changes: + +- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116) + - Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112) + - Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874) + - Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work) +- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118) +- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108) +- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104) + - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) + - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) +- Bump to v1.6.10 + ## Parity [v1.6.9](https://github.com/paritytech/parity/releases/tag/v1.6.9) (2017-07-16) This is a first stable release of 1.6 series. It contains a number of minor fixes and introduces the `--reseal-on-uncles` option for miners. From b5f1524e787235774b033f03851f9123c1b7b019 Mon Sep 17 00:00:00 2001 From: Joseph Mark Date: Sat, 29 Jul 2017 00:06:39 +0700 Subject: [PATCH 20/48] Refactor --allow-ips to handle custom ip-ranges (#6144) * Add checks for additional reserved ip addresses 100.64.0.0/10 and 240.0.0.0/4 are both reserved but not currently filtered. * Add check for special purpose addresses 192.0.0.0/24 - Used for the IANA IPv4 Special Purpose Address Registry * Refactor ip_utils (#5872) * Add checks for all ipv4 special use addresses * Add comprehensive ipv4 test cases * Refactor Ipv6 address checks (#5872) * Refactor AllowIP (#5872) * Add IpFilter struct to wrap predefined filter (AllowIP) with custom allow/block filters. * Refactor parsing of --allow-ips to handle custom filters. * Move AllowIP/IpFilter from ethsync to ethcore-network where they are used. * Revert Cargo.lock * Tests for custom ip filters (#5872) * Add "none" as a valid argument for --allow-ips to allow narrow custom ranges, eg.: --allow-ips="none 10.0.0.0/8" * Add tests for parsing filter arguments and node endpoints. * Add ipnetwork crate to dev dependencies for testing. * Add ipv6 filter tests (#5872) * Revert parity-ui-precompiled to master * Fix minor detail in usage.txt (#5872) * Spaces to tabs * Rename IpFilter::new() to ::default() * Small readability improvements * Test (#5872) * Revert "Test (#5872)" This reverts commit 7a8906430a6dad633fe29df3dca57f1630851fa9. --- Cargo.lock | 10 ++ Cargo.toml | 2 + parity/cli/usage.txt | 10 +- parity/configuration.rs | 68 ++++++- parity/helpers.rs | 5 +- parity/main.rs | 1 + sync/Cargo.toml | 1 + sync/src/api.rs | 42 +---- sync/src/lib.rs | 1 + util/network/Cargo.toml | 1 + util/network/src/discovery.rs | 19 +- util/network/src/host.rs | 10 +- util/network/src/ip_utils.rs | 319 +++++++++++++++++++++++++++++---- util/network/src/lib.rs | 48 ++++- util/network/src/node_table.rs | 82 +++++++-- 15 files changed, 508 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 359b2d2f9..52d0434a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,6 +656,7 @@ dependencies = [ "ethcrypto 0.1.0", "ethkey 0.2.0", "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -862,6 +863,7 @@ dependencies = [ "ethcore-util 1.8.0", "ethkey 0.2.0", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1149,6 +1151,11 @@ dependencies = [ "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipnetwork" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "isatty" version = "0.1.1" @@ -1763,6 +1770,7 @@ dependencies = [ "ethcore-ipc-tests 0.1.0", "ethcore-light 1.8.0", "ethcore-logger 1.8.0", + "ethcore-network 1.8.0", "ethcore-secretstore 1.0.0", "ethcore-stratum 1.8.0", "ethcore-util 1.8.0", @@ -1771,6 +1779,7 @@ dependencies = [ "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3226,6 +3235,7 @@ dependencies = [ "checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" "checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" +"checksum ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "232e76922883005380e831068f731ef0305541c9f77b30df3a1635047b16f370" "checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c" "checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a" "checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5" diff --git a/Cargo.toml b/Cargo.toml index 21961776e..97746c082 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" } ethcore-light = { path = "ethcore/light" } ethcore-logger = { path = "logger" } ethcore-stratum = { path = "stratum" } +ethcore-network = { path = "util/network" } ethkey = { path = "ethkey" } rlp = { path = "util/rlp" } rpc-cli = { path = "rpc_cli" } @@ -65,6 +66,7 @@ rustc_version = "0.2" [dev-dependencies] ethcore-ipc-tests = { path = "ipc/tests" } pretty_assertions = "0.1" +ipnetwork = "0.12.6" [target.'cfg(windows)'.dependencies] winapi = "0.2" diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index 1c9e1e22c..c1d1ab9de 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -148,11 +148,15 @@ Networking Options: These nodes will always have a reserved slot on top of the normal maximum peers. (default: {flag_reserved_peers:?}) --reserved-only Connect only to reserved nodes. (default: {flag_reserved_only}) - --allow-ips FILTER Filter outbound connections. Must be one of: + --allow-ips FILTER Filter outbound connections. FILTER can be one of: private - connect to private network IP addresses only; public - connect to public network IP addresses only; - all - connect to any IP address. - (default: {flag_allow_ips}) + all - connect to any IP address; + none - block all (for use with a custom filter as below); + a custom filter list in the format: "private ip_range1 -ip_range2 ...". + Where ip_range1 would be allowed and ip_range2 blocked; + Custom blocks ("-ip_range") override custom allows ("ip_range"); + (default: {flag_allow_ips}). --max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers}) --no-ancient-blocks Disable downloading old blocks after snapshot restoration or warp sync. (default: {flag_no_ancient_blocks}) diff --git a/parity/configuration.rs b/parity/configuration.rs index 40726eeca..f1399e47c 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -24,7 +24,7 @@ use cli::{Args, ArgsError}; use util::{Hashable, H256, U256, Bytes, version_data, Address}; use util::journaldb::Algorithm; use util::Colour; -use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP}; +use ethsync::{NetworkConfiguration, is_valid_node_url}; use ethcore::ethstore::ethkey::{Secret, Public}; use ethcore::client::{VMType}; use ethcore::miner::{MinerOptions, Banning, StratumOptions}; @@ -48,6 +48,7 @@ use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockcha use presale::ImportWallet; use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts}; use snapshot::{self, SnapshotCommand}; +use network::{IpFilter}; #[derive(Debug, PartialEq)] pub enum Cmd { @@ -461,12 +462,10 @@ impl Configuration { max(self.min_peers(), peers) } - fn allow_ips(&self) -> Result { - match self.args.flag_allow_ips.as_str() { - "all" => Ok(AllowIP::All), - "public" => Ok(AllowIP::Public), - "private" => Ok(AllowIP::Private), - _ => Err("Invalid IP filter value".to_owned()), + fn ip_filter(&self) -> Result { + match IpFilter::parse(self.args.flag_allow_ips.as_str()) { + Ok(allow_ip) => Ok(allow_ip), + Err(_) => Err("Invalid IP filter value".to_owned()), } } @@ -712,7 +711,7 @@ impl Configuration { ret.max_peers = self.max_peers(); ret.min_peers = self.min_peers(); ret.snapshot_peers = self.snapshot_peers(); - ret.allow_ips = self.allow_ips()?; + ret.ip_filter = self.ip_filter()?; ret.max_pending_peers = self.max_pending_peers(); let mut net_path = PathBuf::from(self.directories().base); net_path.push("network"); @@ -968,7 +967,6 @@ impl Configuration { }.into() } - fn ui_interface(&self) -> String { self.interface(&self.args.flag_ui_interface) } @@ -1080,6 +1078,7 @@ impl Configuration { mod tests { use std::io::Write; use std::fs::{File, create_dir}; + use std::str::FromStr; use devtools::{RandomTempPath}; use ethcore::client::{VMType, BlockId}; @@ -1097,6 +1096,11 @@ mod tests { use rpc::{WsConfiguration, UiConfiguration}; use run::RunCmd; + use network::{AllowIP, IpFilter}; + + extern crate ipnetwork; + use self::ipnetwork::IpNetwork; + use super::*; #[derive(Debug, PartialEq)] @@ -1752,4 +1756,50 @@ mod tests { assert_eq!(&conf0.ipfs_config().interface, "0.0.0.0"); assert_eq!(conf0.ipfs_config().hosts, None); } + + #[test] + fn allow_ips() { + let all = parse(&["parity", "--allow-ips", "all"]); + let private = parse(&["parity", "--allow-ips", "private"]); + let block_custom = parse(&["parity", "--allow-ips", "-10.0.0.0/8"]); + let combo = parse(&["parity", "--allow-ips", "public 10.0.0.0/8 -1.0.0.0/8"]); + let ipv6_custom_public = parse(&["parity", "--allow-ips", "public fc00::/7"]); + let ipv6_custom_private = parse(&["parity", "--allow-ips", "private -fc00::/7"]); + + assert_eq!(all.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![], + }); + + assert_eq!(private.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Private, + custom_allow: vec![], + custom_block: vec![], + }); + + assert_eq!(block_custom.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()], + }); + + assert_eq!(combo.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Public, + custom_allow: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()], + custom_block: vec![IpNetwork::from_str("1.0.0.0/8").unwrap()], + }); + + assert_eq!(ipv6_custom_public.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Public, + custom_allow: vec![IpNetwork::from_str("fc00::/7").unwrap()], + custom_block: vec![], + }); + + assert_eq!(ipv6_custom_private.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Private, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str("fc00::/7").unwrap()], + }); + } } diff --git a/parity/helpers.rs b/parity/helpers.rs index 7d28f44fd..2a1b3156d 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -191,7 +191,8 @@ pub fn to_bootnodes(bootnodes: &Option) -> Result, String> { #[cfg(test)] pub fn default_network_config() -> ::ethsync::NetworkConfiguration { - use ethsync::{NetworkConfiguration, AllowIP}; + use ethsync::{NetworkConfiguration}; + use super::network::IpFilter; NetworkConfiguration { config_path: Some(replace_home(&::dir::default_data_path(), "$BASE/network")), net_config_path: None, @@ -206,7 +207,7 @@ pub fn default_network_config() -> ::ethsync::NetworkConfiguration { min_peers: 25, snapshot_peers: 0, max_pending_peers: 64, - allow_ips: AllowIP::All, + ip_filter: IpFilter::default(), reserved_nodes: Vec::new(), allow_non_reserved: true, } diff --git a/parity/main.rs b/parity/main.rs index 8bd6bf53f..311ce8b35 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -55,6 +55,7 @@ extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_light as light; extern crate ethcore_logger; extern crate ethcore_util as util; +extern crate ethcore_network as network; extern crate ethkey; extern crate ethsync; extern crate panic_hook; diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 8e9a2a3eb..b9a411879 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -31,6 +31,7 @@ ethcore-ipc-nano = { path = "../ipc/nano" } ethcore-devtools = { path = "../devtools" } ethkey = { path = "../ethkey" } parking_lot = "0.4" +ipnetwork = "0.12.6" [features] default = [] diff --git a/sync/src/api.rs b/sync/src/api.rs index b8f495f9b..acbc26867 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -19,8 +19,7 @@ use std::collections::{HashMap, BTreeMap}; use std::io; use util::Bytes; use network::{NetworkProtocolHandler, NetworkService, NetworkContext, HostInfo, PeerId, ProtocolId, - NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError, - AllowIP as NetworkAllowIP}; + NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError}; use util::{U256, H256, H512}; use io::{TimerToken}; use ethcore::ethstore::ethkey::Secret; @@ -37,6 +36,7 @@ use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT}; use light::client::AsLightClient; use light::Provider; use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext}; +use network::IpFilter; /// Parity sync protocol pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par"; @@ -539,30 +539,6 @@ impl ManageNetwork for EthSync { } } -/// IP fiter -#[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] -pub enum AllowIP { - /// Connect to any address - All, - /// Connect to private network only - Private, - /// Connect to public network only - Public, -} - -impl AllowIP { - /// Attempt to parse the peer mode from a string. - pub fn parse(s: &str) -> Option { - match s { - "all" => Some(AllowIP::All), - "private" => Some(AllowIP::Private), - "public" => Some(AllowIP::Public), - _ => None, - } - } -} - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "ipc", binary)] /// Network service configuration @@ -598,7 +574,7 @@ pub struct NetworkConfiguration { /// The non-reserved peer mode. pub allow_non_reserved: bool, /// IP Filtering - pub allow_ips: AllowIP, + pub ip_filter: IpFilter, } impl NetworkConfiguration { @@ -629,11 +605,7 @@ impl NetworkConfiguration { max_handshakes: self.max_pending_peers, reserved_protocols: hash_map![WARP_SYNC_PROTOCOL_ID => self.snapshot_peers], reserved_nodes: self.reserved_nodes, - allow_ips: match self.allow_ips { - AllowIP::All => NetworkAllowIP::All, - AllowIP::Private => NetworkAllowIP::Private, - AllowIP::Public => NetworkAllowIP::Public, - }, + ip_filter: self.ip_filter, non_reserved_mode: if self.allow_non_reserved { NonReservedPeerMode::Accept } else { NonReservedPeerMode::Deny }, }) } @@ -656,11 +628,7 @@ impl From for NetworkConfiguration { max_pending_peers: other.max_handshakes, snapshot_peers: *other.reserved_protocols.get(&WARP_SYNC_PROTOCOL_ID).unwrap_or(&0), reserved_nodes: other.reserved_nodes, - allow_ips: match other.allow_ips { - NetworkAllowIP::All => AllowIP::All, - NetworkAllowIP::Private => AllowIP::Private, - NetworkAllowIP::Public => AllowIP::Public, - }, + ip_filter: other.ip_filter, allow_non_reserved: match other.non_reserved_mode { NonReservedPeerMode::Accept => true, _ => false } , } } diff --git a/sync/src/lib.rs b/sync/src/lib.rs index b51c157be..e131bf901 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -37,6 +37,7 @@ extern crate semver; extern crate parking_lot; extern crate smallvec; extern crate rlp; +extern crate ipnetwork; extern crate ethcore_light as light; diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index 8abda59c5..7c44aff7f 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -30,6 +30,7 @@ ethcrypto = { path = "../../ethcrypto" } rlp = { path = "../rlp" } path = { path = "../path" } ethcore-logger = { path ="../../logger" } +ipnetwork = "0.12.6" [features] default = [] diff --git a/util/network/src/discovery.rs b/util/network/src/discovery.rs index 138ba23ba..3dcd8548d 100644 --- a/util/network/src/discovery.rs +++ b/util/network/src/discovery.rs @@ -30,7 +30,7 @@ use node_table::*; use error::NetworkError; use io::{StreamToken, IoContext}; use ethkey::{Secret, KeyPair, sign, recover}; -use AllowIP; +use IpFilter; use PROTOCOL_VERSION; @@ -99,7 +99,7 @@ pub struct Discovery { send_queue: VecDeque, check_timestamps: bool, adding_nodes: Vec, - allow_ips: AllowIP, + ip_filter: IpFilter, } pub struct TableUpdates { @@ -108,7 +108,7 @@ pub struct TableUpdates { } impl Discovery { - pub fn new(key: &KeyPair, listen: SocketAddr, public: NodeEndpoint, token: StreamToken, allow_ips: AllowIP) -> Discovery { + pub fn new(key: &KeyPair, listen: SocketAddr, public: NodeEndpoint, token: StreamToken, ip_filter: IpFilter) -> Discovery { let socket = UdpSocket::bind(&listen).expect("Error binding UDP socket"); Discovery { id: key.public().clone(), @@ -124,7 +124,7 @@ impl Discovery { send_queue: VecDeque::new(), check_timestamps: true, adding_nodes: Vec::new(), - allow_ips: allow_ips, + ip_filter: ip_filter, } } @@ -400,7 +400,7 @@ impl Discovery { } fn is_allowed(&self, entry: &NodeEntry) -> bool { - entry.endpoint.is_allowed(self.allow_ips) && entry.id != self.id + entry.endpoint.is_allowed(&self.ip_filter) && entry.id != self.id } fn on_ping(&mut self, rlp: &UntrustedRlp, node: &NodeId, from: &SocketAddr) -> Result, NetworkError> { @@ -561,7 +561,6 @@ mod tests { use std::str::FromStr; use rustc_hex::FromHex; use ethkey::{Random, Generator}; - use AllowIP; #[test] fn find_node() { @@ -586,8 +585,8 @@ mod tests { let key2 = Random.generate().unwrap(); let ep1 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40444").unwrap(), udp_port: 40444 }; let ep2 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40445").unwrap(), udp_port: 40445 }; - let mut discovery1 = Discovery::new(&key1, ep1.address.clone(), ep1.clone(), 0, AllowIP::All); - let mut discovery2 = Discovery::new(&key2, ep2.address.clone(), ep2.clone(), 0, AllowIP::All); + let mut discovery1 = Discovery::new(&key1, ep1.address.clone(), ep1.clone(), 0, IpFilter::default()); + let mut discovery2 = Discovery::new(&key2, ep2.address.clone(), ep2.clone(), 0, IpFilter::default()); let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:7770").unwrap(); let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:7771").unwrap(); @@ -619,7 +618,7 @@ mod tests { fn removes_expired() { let key = Random.generate().unwrap(); let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40446").unwrap(), udp_port: 40447 }; - let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, AllowIP::All); + let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); for _ in 0..1200 { discovery.add_node(NodeEntry { id: NodeId::random(), endpoint: ep.clone() }); } @@ -648,7 +647,7 @@ mod tests { fn packets() { let key = Random.generate().unwrap(); let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40447").unwrap(), udp_port: 40447 }; - let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, AllowIP::All); + let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); discovery.check_timestamps = false; let from = SocketAddr::from_str("99.99.99.99:40445").unwrap(); diff --git a/util/network/src/host.rs b/util/network/src/host.rs index b0de67499..8aea9184f 100644 --- a/util/network/src/host.rs +++ b/util/network/src/host.rs @@ -35,7 +35,7 @@ use rlp::*; use session::{Session, SessionInfo, SessionData}; use error::*; use io::*; -use {NetworkProtocolHandler, NonReservedPeerMode, AllowIP, PROTOCOL_VERSION}; +use {NetworkProtocolHandler, NonReservedPeerMode, PROTOCOL_VERSION, IpFilter}; use node_table::*; use stats::NetworkStats; use discovery::{Discovery, TableUpdates, NodeEntry}; @@ -106,7 +106,7 @@ pub struct NetworkConfiguration { /// The non-reserved peer mode. pub non_reserved_mode: NonReservedPeerMode, /// IP filter - pub allow_ips: AllowIP, + pub ip_filter: IpFilter, } impl Default for NetworkConfiguration { @@ -132,7 +132,7 @@ impl NetworkConfiguration { max_peers: 50, max_handshakes: 64, reserved_protocols: HashMap::new(), - allow_ips: AllowIP::All, + ip_filter: IpFilter::default(), reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, } @@ -566,7 +566,7 @@ impl Host { } let local_endpoint = self.info.read().local_endpoint.clone(); let public_address = self.info.read().config.public_address.clone(); - let allow_ips = self.info.read().config.allow_ips; + let allow_ips = self.info.read().config.ip_filter.clone(); let public_endpoint = match public_address { None => { let public_address = select_public_address(local_endpoint.address.port()); @@ -660,7 +660,7 @@ impl Host { } let config = &info.config; - (config.min_peers, config.non_reserved_mode == NonReservedPeerMode::Deny, config.max_handshakes as usize, config.allow_ips, info.id().clone()) + (config.min_peers, config.non_reserved_mode == NonReservedPeerMode::Deny, config.max_handshakes as usize, config.ip_filter.clone(), info.id().clone()) }; let session_count = self.session_count(); diff --git a/util/network/src/ip_utils.rs b/util/network/src/ip_utils.rs index a98cf1f88..d637dbee8 100644 --- a/util/network/src/ip_utils.rs +++ b/util/network/src/ip_utils.rs @@ -21,55 +21,193 @@ use std::io; use igd::{PortMappingProtocol, search_gateway_from_timeout}; use std::time::Duration; use node_table::{NodeEndpoint}; +use ipnetwork::{IpNetwork}; /// Socket address extension for rustc beta. To be replaces with now unstable API pub trait SocketAddrExt { - /// Returns true for the special 'unspecified' address 0.0.0.0. - fn is_unspecified_s(&self) -> bool; /// Returns true if the address appears to be globally routable. fn is_global_s(&self) -> bool; + + // Ipv4 specific + fn is_shared_space(&self) -> bool { false } + fn is_special_purpose(&self) -> bool { false } + fn is_benchmarking(&self) -> bool { false } + fn is_future_use(&self) -> bool { false } + + // Ipv6 specific + fn is_unique_local_s(&self) -> bool { false } + fn is_unicast_link_local_s(&self) -> bool { false } + fn is_documentation_s(&self) -> bool { false } + fn is_global_multicast(&self) -> bool { false } + fn is_other_multicast(&self) -> bool { false } + + fn is_reserved(&self) -> bool; + fn is_usable_public(&self) -> bool; + fn is_usable_private(&self) -> bool; + + fn is_within(&self, ipnet: &IpNetwork) -> bool; } impl SocketAddrExt for Ipv4Addr { - fn is_unspecified_s(&self) -> bool { - self.octets() == [0, 0, 0, 0] + fn is_global_s(&self) -> bool { + !self.is_private() && + !self.is_loopback() && + !self.is_link_local() && + !self.is_broadcast() && + !self.is_documentation() } - fn is_global_s(&self) -> bool { - !self.is_private() && !self.is_loopback() && !self.is_link_local() && - !self.is_broadcast() && !self.is_documentation() + // Used for communications between a service provider and its subscribers when using a carrier-grade NAT + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_shared_space(&self) -> bool { + *self >= Ipv4Addr::new(100, 64, 0, 0) && + *self <= Ipv4Addr::new(100, 127, 255, 255) + } + + // Used for the IANA IPv4 Special Purpose Address Registry + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_special_purpose(&self) -> bool { + *self >= Ipv4Addr::new(192, 0, 0, 0) && + *self <= Ipv4Addr::new(192, 0, 0, 255) + } + + // Used for testing of inter-network communications between two separate subnets + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_benchmarking(&self) -> bool { + *self >= Ipv4Addr::new(198, 18, 0, 0) && + *self <= Ipv4Addr::new(198, 19, 255, 255) + } + + // Reserved for future use + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_future_use(&self) -> bool { + *self >= Ipv4Addr::new(240, 0, 0, 0) && + *self <= Ipv4Addr::new(255, 255, 255, 254) + } + + fn is_reserved(&self) -> bool { + self.is_unspecified() || + self.is_loopback() || + self.is_link_local() || + self.is_broadcast() || + self.is_documentation() || + self.is_multicast() || + self.is_shared_space() || + self.is_special_purpose() || + self.is_benchmarking() || + self.is_future_use() + } + + fn is_usable_public(&self) -> bool { + !self.is_reserved() && + !self.is_private() + } + + fn is_usable_private(&self) -> bool { + self.is_private() + } + + fn is_within(&self, ipnet: &IpNetwork) -> bool { + match ipnet { + &IpNetwork::V4(ipnet) => ipnet.contains(*self), + _ => false + } } } impl SocketAddrExt for Ipv6Addr { - fn is_unspecified_s(&self) -> bool { - self.segments() == [0, 0, 0, 0, 0, 0, 0, 0] + fn is_global_s(&self) -> bool { + self.is_global_multicast() || + (!self.is_loopback() && + !self.is_unique_local_s() && + !self.is_unicast_link_local_s() && + !self.is_documentation_s() && + !self.is_other_multicast()) } - fn is_global_s(&self) -> bool { - if self.is_multicast() { - self.segments()[0] & 0x000f == 14 - } else { - !self.is_loopback() && !((self.segments()[0] & 0xffc0) == 0xfe80) && - !((self.segments()[0] & 0xffc0) == 0xfec0) && !((self.segments()[0] & 0xfe00) == 0xfc00) + // unique local address (fc00::/7). + fn is_unique_local_s(&self) -> bool { + (self.segments()[0] & 0xfe00) == 0xfc00 + } + + // unicast and link-local (fe80::/10). + fn is_unicast_link_local_s(&self) -> bool { + (self.segments()[0] & 0xffc0) == 0xfe80 + } + + // reserved for documentation (2001:db8::/32). + fn is_documentation_s(&self) -> bool { + (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) + } + + fn is_global_multicast(&self) -> bool { + self.segments()[0] & 0x000f == 14 + } + + fn is_other_multicast(&self) -> bool { + self.is_multicast() && !self.is_global_multicast() + } + + fn is_reserved(&self) -> bool { + self.is_unspecified() || + self.is_loopback() || + self.is_unicast_link_local_s() || + self.is_documentation_s() || + self.is_other_multicast() + } + + fn is_usable_public(&self) -> bool { + !self.is_reserved() && + !self.is_unique_local_s() + } + + fn is_usable_private(&self) -> bool { + self.is_unique_local_s() + } + + fn is_within(&self, ipnet: &IpNetwork) -> bool { + match ipnet { + &IpNetwork::V6(ipnet) => ipnet.contains(*self), + _ => false } } } impl SocketAddrExt for IpAddr { - fn is_unspecified_s(&self) -> bool { - match *self { - IpAddr::V4(ref ip) => ip.is_unspecified_s(), - IpAddr::V6(ref ip) => ip.is_unspecified_s(), - } - } - fn is_global_s(&self) -> bool { match *self { IpAddr::V4(ref ip) => ip.is_global_s(), IpAddr::V6(ref ip) => ip.is_global_s(), } } + + fn is_reserved(&self) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_reserved(), + IpAddr::V6(ref ip) => ip.is_reserved(), + } + } + + fn is_usable_public(&self) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_usable_public(), + IpAddr::V6(ref ip) => ip.is_usable_public(), + } + } + + fn is_usable_private(&self) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_usable_private(), + IpAddr::V6(ref ip) => ip.is_usable_private(), + } + } + + fn is_within(&self, ipnet: &IpNetwork) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_within(ipnet), + IpAddr::V6(ref ip) => ip.is_within(ipnet) + } + } } #[cfg(not(windows))] @@ -79,7 +217,7 @@ mod getinterfaces { use libc::{getifaddrs, freeifaddrs, ifaddrs, sockaddr, sockaddr_in, sockaddr_in6}; use std::net::{Ipv4Addr, Ipv6Addr, IpAddr}; - fn convert_sockaddr (sa: *mut sockaddr) -> Option { + fn convert_sockaddr(sa: *mut sockaddr) -> Option { if sa == ptr::null_mut() { return None; } let (addr, _) = match unsafe { *sa }.sa_family as i32 { @@ -115,7 +253,7 @@ mod getinterfaces { Some(addr) } - fn convert_ifaddrs (ifa: *mut ifaddrs) -> Option { + fn convert_ifaddrs(ifa: *mut ifaddrs) -> Option { let ifa = unsafe { &mut *ifa }; convert_sockaddr(ifa.ifa_addr) } @@ -158,16 +296,16 @@ pub fn select_public_address(port: u16) -> SocketAddr { Ok(list) => { //prefer IPV4 bindings for addr in &list { //TODO: use better criteria than just the first in the list - match *addr { - IpAddr::V4(a) if !a.is_unspecified_s() && !a.is_loopback() && !a.is_link_local() => { + match addr { + &IpAddr::V4(a) if !a.is_reserved() => { return SocketAddr::V4(SocketAddrV4::new(a, port)); }, _ => {}, } } - for addr in list { + for addr in &list { match addr { - IpAddr::V6(a) if !a.is_unspecified_s() && !a.is_loopback() => { + &IpAddr::V6(a) if !a.is_reserved() => { return SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)); }, _ => {}, @@ -227,7 +365,6 @@ fn can_map_external_address_or_fail() { #[test] fn ipv4_properties() { - #![cfg_attr(feature="dev", allow(too_many_arguments))] fn check(octets: &[u8; 4], unspec: bool, loopback: bool, private: bool, link_local: bool, global: bool, @@ -235,7 +372,7 @@ fn ipv4_properties() { let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]); assert_eq!(octets, &ip.octets()); - assert_eq!(ip.is_unspecified_s(), unspec); + assert_eq!(ip.is_unspecified(), unspec); assert_eq!(ip.is_loopback(), loopback); assert_eq!(ip.is_private(), private); assert_eq!(ip.is_link_local(), link_local); @@ -264,13 +401,131 @@ fn ipv4_properties() { check(&[255, 255, 255, 255], false, false, false, false, false, false, true, false); } +#[test] +fn ipv4_shared_space() { + assert!(!Ipv4Addr::new(100, 63, 255, 255).is_shared_space()); + assert!(Ipv4Addr::new(100, 64, 0, 0).is_shared_space()); + assert!(Ipv4Addr::new(100, 127, 255, 255).is_shared_space()); + assert!(!Ipv4Addr::new(100, 128, 0, 0).is_shared_space()); +} + +#[test] +fn ipv4_special_purpose() { + assert!(!Ipv4Addr::new(191, 255, 255, 255).is_special_purpose()); + assert!(Ipv4Addr::new(192, 0, 0, 0).is_special_purpose()); + assert!(Ipv4Addr::new(192, 0, 0, 255).is_special_purpose()); + assert!(!Ipv4Addr::new(192, 0, 1, 255).is_special_purpose()); +} + +#[test] +fn ipv4_benchmarking() { + assert!(!Ipv4Addr::new(198, 17, 255, 255).is_benchmarking()); + assert!(Ipv4Addr::new(198, 18, 0, 0).is_benchmarking()); + assert!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking()); + assert!(!Ipv4Addr::new(198, 20, 0, 0).is_benchmarking()); +} + +#[test] +fn ipv4_future_use() { + assert!(!Ipv4Addr::new(239, 255, 255, 255).is_future_use()); + assert!(Ipv4Addr::new(240, 0, 0, 0).is_future_use()); + assert!(Ipv4Addr::new(255, 255, 255, 254).is_future_use()); + assert!(!Ipv4Addr::new(255, 255, 255, 255).is_future_use()); +} + +#[test] +fn ipv4_usable_public() { + assert!(!Ipv4Addr::new(0,0,0,0).is_usable_public()); // unspecified + assert!(Ipv4Addr::new(0,0,0,1).is_usable_public()); + + assert!(Ipv4Addr::new(9,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(10,0,0,0).is_usable_public()); // private intra-network + assert!(!Ipv4Addr::new(10,255,255,255).is_usable_public()); // private intra-network + assert!(Ipv4Addr::new(11,0,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(100, 63, 255, 255).is_usable_public()); + assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space + assert!(!Ipv4Addr::new(100, 127, 255, 255).is_usable_public()); // shared space + assert!(Ipv4Addr::new(100, 128, 0, 0).is_usable_public()); + + assert!(Ipv4Addr::new(126,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(127,0,0,0).is_usable_public()); // loopback + assert!(!Ipv4Addr::new(127,255,255,255).is_usable_public()); // loopback + assert!(Ipv4Addr::new(128,0,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(169,253,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(169,254,0,0).is_usable_public()); // link-local + assert!(!Ipv4Addr::new(169,254,255,255).is_usable_public()); // link-local + assert!(Ipv4Addr::new(169,255,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(172,15,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(172,16,0,0).is_usable_public()); // private intra-network + assert!(!Ipv4Addr::new(172,31,255,255).is_usable_public()); // private intra-network + assert!(Ipv4Addr::new(172,32,255,255).is_usable_public()); + + assert!(Ipv4Addr::new(191,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(192,0,0,0).is_usable_public()); // special purpose + assert!(!Ipv4Addr::new(192,0,0,255).is_usable_public()); // special purpose + assert!(Ipv4Addr::new(192,0,1,0).is_usable_public()); + + assert!(Ipv4Addr::new(192,0,1,255).is_usable_public()); + assert!(!Ipv4Addr::new(192,0,2,0).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation + assert!(Ipv4Addr::new(192,0,3,0).is_usable_public()); + + assert!(Ipv4Addr::new(192,167,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(192,168,0,0).is_usable_public()); // private intra-network + assert!(!Ipv4Addr::new(192,168,255,255).is_usable_public()); // private intra-network + assert!(Ipv4Addr::new(192,169,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(198,17,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(198,18,0,0).is_usable_public()); // benchmarking + assert!(!Ipv4Addr::new(198,19,255,255).is_usable_public()); // benchmarking + assert!(Ipv4Addr::new(198,20,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(198,51,99,255).is_usable_public()); + assert!(!Ipv4Addr::new(198,51,100,0).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(198,51,100,255).is_usable_public()); // documentation + assert!(Ipv4Addr::new(198,51,101,0).is_usable_public()); + + assert!(Ipv4Addr::new(203,0,112,255).is_usable_public()); + assert!(!Ipv4Addr::new(203,0,113,0).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(203,0,113,255).is_usable_public()); // documentation + assert!(Ipv4Addr::new(203,0,114,0).is_usable_public()); + + assert!(Ipv4Addr::new(223,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(224,0,0,0).is_usable_public()); // multicast + assert!(!Ipv4Addr::new(239, 255, 255, 255).is_usable_public()); // multicast + assert!(!Ipv4Addr::new(240, 0, 0, 0).is_usable_public()); // future use + assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use + assert!(!Ipv4Addr::new(255, 255, 255, 255).is_usable_public()); // limited broadcast +} + +#[test] +fn ipv4_usable_private() { + assert!(!Ipv4Addr::new(9,255,255,255).is_usable_private()); + assert!(Ipv4Addr::new(10,0,0,0).is_usable_private()); // private intra-network + assert!(Ipv4Addr::new(10,255,255,255).is_usable_private()); // private intra-network + assert!(!Ipv4Addr::new(11,0,0,0).is_usable_private()); + + assert!(!Ipv4Addr::new(172,15,255,255).is_usable_private()); + assert!(Ipv4Addr::new(172,16,0,0).is_usable_private()); // private intra-network + assert!(Ipv4Addr::new(172,31,255,255).is_usable_private()); // private intra-network + assert!(!Ipv4Addr::new(172,32,255,255).is_usable_private()); + + assert!(!Ipv4Addr::new(192,167,255,255).is_usable_private()); + assert!(Ipv4Addr::new(192,168,0,0).is_usable_private()); // private intra-network + assert!(Ipv4Addr::new(192,168,255,255).is_usable_private()); // private intra-network + assert!(!Ipv4Addr::new(192,169,0,0).is_usable_private()); +} + #[test] fn ipv6_properties() { fn check(str_addr: &str, unspec: bool, loopback: bool, global: bool) { let ip: Ipv6Addr = str_addr.parse().unwrap(); assert_eq!(str_addr, ip.to_string()); - assert_eq!(ip.is_unspecified_s(), unspec); + assert_eq!(ip.is_unspecified(), unspec); assert_eq!(ip.is_loopback(), loopback); assert_eq!(ip.is_global_s(), global); } @@ -279,3 +534,5 @@ fn ipv6_properties() { check("::", true, false, true); check("::1", false, true, false); } + + diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 5a3fdc1e6..74e30a750 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -77,6 +77,7 @@ extern crate rlp; extern crate bytes; extern crate path; extern crate ethcore_logger; +extern crate ipnetwork; #[macro_use] extern crate log; @@ -106,6 +107,8 @@ pub use session::SessionInfo; pub use io::TimerToken; pub use node_table::{is_valid_node_url, NodeId}; +use ipnetwork::{IpNetwork, IpNetworkError}; +use std::str::FromStr; const PROTOCOL_VERSION: u32 = 4; @@ -145,8 +148,49 @@ impl NonReservedPeerMode { } } +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] +pub struct IpFilter { + pub predefined: AllowIP, + pub custom_allow: Vec, + pub custom_block: Vec, +} + +impl Default for IpFilter { + fn default() -> Self { + IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![], + } + } +} + +impl IpFilter { + /// Attempt to parse the peer mode from a string. + pub fn parse(s: &str) -> Result { + let mut filter = IpFilter::default(); + for f in s.split_whitespace() { + match f { + "all" => filter.predefined = AllowIP::All, + "private" => filter.predefined = AllowIP::Private, + "public" => filter.predefined = AllowIP::Public, + "none" => filter.predefined = AllowIP::None, + custom => { + if custom.starts_with("-") { + filter.custom_block.push(IpNetwork::from_str(&custom.to_owned().split_off(1))?) + } else { + filter.custom_allow.push(IpNetwork::from_str(custom)?) + } + } + } + } + Ok(filter) + } +} + /// IP fiter -#[derive(Clone, Debug, PartialEq, Eq, Copy)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum AllowIP { /// Connect to any address All, @@ -154,5 +198,7 @@ pub enum AllowIP { Private, /// Connect to public network only Public, + /// Block all addresses + None, } diff --git a/util/network/src/node_table.rs b/util/network/src/node_table.rs index 1481187d4..f9d4e9589 100644 --- a/util/network/src/node_table.rs +++ b/util/network/src/node_table.rs @@ -30,7 +30,7 @@ use util::UtilError; use rlp::*; use time::Tm; use error::NetworkError; -use AllowIP; +use {AllowIP, IpFilter}; use discovery::{TableUpdates, NodeEntry}; use ip_utils::*; pub use rustc_serialize::json::Json; @@ -55,11 +55,21 @@ impl NodeEndpoint { } } - pub fn is_allowed(&self, filter: AllowIP) -> bool { + pub fn is_allowed(&self, filter: &IpFilter) -> bool { + (self.is_allowed_by_predefined(&filter.predefined) || filter.custom_allow.iter().any(|ipnet| { + self.address.ip().is_within(ipnet) + })) + && !filter.custom_block.iter().any(|ipnet| { + self.address.ip().is_within(ipnet) + }) + } + + pub fn is_allowed_by_predefined(&self, filter: &AllowIP) -> bool { match filter { - AllowIP::All => true, - AllowIP::Private => !self.address.ip().is_global_s(), - AllowIP::Public => self.address.ip().is_global_s(), + &AllowIP::All => true, + &AllowIP::Private => self.address.ip().is_usable_private(), + &AllowIP::Public => self.address.ip().is_usable_public(), + &AllowIP::None => false, } } @@ -101,8 +111,8 @@ impl NodeEndpoint { pub fn is_valid(&self) -> bool { self.udp_port != 0 && self.address.port() != 0 && match self.address { - SocketAddr::V4(a) => !a.ip().is_unspecified_s(), - SocketAddr::V6(a) => !a.ip().is_unspecified_s() + SocketAddr::V4(a) => !a.ip().is_unspecified(), + SocketAddr::V6(a) => !a.ip().is_unspecified() } } } @@ -219,8 +229,8 @@ impl NodeTable { } /// Returns node ids sorted by number of failures - pub fn nodes(&self, filter: AllowIP) -> Vec { - let mut refs: Vec<&Node> = self.nodes.values().filter(|n| !self.useless_nodes.contains(&n.id) && n.endpoint.is_allowed(filter)).collect(); + pub fn nodes(&self, filter: IpFilter) -> Vec { + let mut refs: Vec<&Node> = self.nodes.values().filter(|n| !self.useless_nodes.contains(&n.id) && n.endpoint.is_allowed(&filter)).collect(); refs.sort_by(|a, b| a.failures.cmp(&b.failures)); refs.iter().map(|n| n.id.clone()).collect() } @@ -283,7 +293,7 @@ impl NodeTable { let mut json = String::new(); json.push_str("{\n"); json.push_str("\"nodes\": [\n"); - let node_ids = self.nodes(AllowIP::All); + let node_ids = self.nodes(IpFilter::default()); for i in 0 .. node_ids.len() { let node = self.nodes.get(&node_ids[i]).expect("self.nodes() only returns node IDs from self.nodes"); json.push_str(&format!("\t{{ \"url\": \"{}\", \"failures\": {} }}{}\n", node, node.failures, if i == node_ids.len() - 1 {""} else {","})) @@ -366,7 +376,7 @@ mod tests { use util::H512; use std::str::FromStr; use devtools::*; - use AllowIP; + use ipnetwork::IpNetwork; #[test] fn endpoint_parse() { @@ -412,7 +422,7 @@ mod tests { table.note_failure(&id1); table.note_failure(&id2); - let r = table.nodes(AllowIP::All); + let r = table.nodes(IpFilter::default()); assert_eq!(r[0][..], id3[..]); assert_eq!(r[1][..], id2[..]); assert_eq!(r[2][..], id1[..]); @@ -434,9 +444,55 @@ mod tests { { let table = NodeTable::new(Some(temp_path.as_path().to_str().unwrap().to_owned())); - let r = table.nodes(AllowIP::All); + let r = table.nodes(IpFilter::default()); assert_eq!(r[0][..], id1[..]); assert_eq!(r[1][..], id2[..]); } } + + #[test] + fn custom_allow() { + let filter = IpFilter { + predefined: AllowIP::None, + custom_allow: vec![IpNetwork::from_str(&"10.0.0.0/8").unwrap(), IpNetwork::from_str(&"1.0.0.0/8").unwrap()], + custom_block: vec![], + }; + assert!(!NodeEndpoint::from_str("123.99.55.44:7770").unwrap().is_allowed(&filter)); + assert!(NodeEndpoint::from_str("10.0.0.1:7770").unwrap().is_allowed(&filter)); + assert!(NodeEndpoint::from_str("1.0.0.55:5550").unwrap().is_allowed(&filter)); + } + + #[test] + fn custom_block() { + let filter = IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str(&"10.0.0.0/8").unwrap(), IpNetwork::from_str(&"1.0.0.0/8").unwrap()], + }; + assert!(NodeEndpoint::from_str("123.99.55.44:7770").unwrap().is_allowed(&filter)); + assert!(!NodeEndpoint::from_str("10.0.0.1:7770").unwrap().is_allowed(&filter)); + assert!(!NodeEndpoint::from_str("1.0.0.55:5550").unwrap().is_allowed(&filter)); + } + + #[test] + fn custom_allow_ipv6() { + let filter = IpFilter { + predefined: AllowIP::None, + custom_allow: vec![IpNetwork::from_str(&"fc00::/8").unwrap()], + custom_block: vec![], + }; + assert!(NodeEndpoint::from_str("[fc00::]:5550").unwrap().is_allowed(&filter)); + assert!(!NodeEndpoint::from_str("[fd00::]:5550").unwrap().is_allowed(&filter)); + } + + #[test] + fn custom_block_ipv6() { + let filter = IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str(&"fc00::/8").unwrap()], + }; + assert!(!NodeEndpoint::from_str("[fc00::]:5550").unwrap().is_allowed(&filter)); + assert!(NodeEndpoint::from_str("[fd00::]:5550").unwrap().is_allowed(&filter)); + } } From f212ae6322ce7e6742f3df02de46414b9fb88cc9 Mon Sep 17 00:00:00 2001 From: Nicolas Ochem Date: Fri, 28 Jul 2017 10:07:38 -0700 Subject: [PATCH 21/48] fix #6052. honor --no-color for signer command (#6100) * fix #6052. honor --no-color for signer command * replace call to paint closure with the body, apply to generate_new_token too --- parity/configuration.rs | 10 +++++++--- parity/main.rs | 2 +- parity/run.rs | 12 ++++++------ parity/signer.rs | 30 +++++++++++++++++++----------- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index f1399e47c..d05f26f53 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -57,7 +57,7 @@ pub enum Cmd { Account(AccountCmd), ImportPresaleWallet(ImportWallet), Blockchain(BlockchainCmd), - SignerToken(WsConfiguration, UiConfiguration), + SignerToken(WsConfiguration, UiConfiguration, LogConfig), SignerSign { id: Option, pwfile: Option, @@ -149,7 +149,7 @@ impl Configuration { let authfile = ::signer::codes_path(&ws_conf.signer_path); if self.args.cmd_new_token { - Cmd::SignerToken(ws_conf, ui_conf) + Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone()) } else if self.args.cmd_sign { let pwfile = self.args.flag_password.get(0).map(|pwfile| { PathBuf::from(pwfile) @@ -1285,7 +1285,11 @@ mod tests { interface: "127.0.0.1".into(), port: 8180, hosts: Some(vec![]), - })); + }, LogConfig { + color: true, + mode: None, + file: None, + } )); } #[test] diff --git a/parity/main.rs b/parity/main.rs index 311ce8b35..48e752bf2 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -164,7 +164,7 @@ fn execute(command: Execute, can_restart: bool) -> Result account::execute(account_cmd).map(|s| PostExecutionAction::Print(s)), Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| PostExecutionAction::Print(s)), Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| PostExecutionAction::Quit), - Cmd::SignerToken(ws_conf, ui_conf) => signer::execute(ws_conf, ui_conf).map(|s| PostExecutionAction::Print(s)), + Cmd::SignerToken(ws_conf, ui_conf, logger_config) => signer::execute(ws_conf, ui_conf, logger_config).map(|s| PostExecutionAction::Print(s)), Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| PostExecutionAction::Print(s)), Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| PostExecutionAction::Print(s)), Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| PostExecutionAction::Print(s)), diff --git a/parity/run.rs b/parity/run.rs index 7c835aa3f..c08294a42 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -118,12 +118,12 @@ pub struct RunCmd { pub whisper: ::whisper::Config } -pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> Result<(), String> { +pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result<(), String> { if !ui_conf.enabled { return Err("Cannot use UI command with UI turned off.".into()) } - let token = signer::generate_token_and_url(ws_conf, ui_conf)?; + let token = signer::generate_token_and_url(ws_conf, ui_conf, logger_config)?; // Open a browser url::open(&token.url); // Print a message @@ -282,7 +282,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc) -> let rpc_stats = Arc::new(informant::RpcStats::default()); // the dapps server - let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf)); + let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)); let dapps_deps = { let contract_client = Arc::new(::dapps::LightRegistrar { client: service.client().clone(), @@ -378,7 +378,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // Check if Parity is already running let addr = format!("{}:{}", cmd.ui_conf.interface, cmd.ui_conf.port); if !TcpListener::bind(&addr as &str).is_ok() { - return open_ui(&cmd.ws_conf, &cmd.ui_conf).map(|_| (false, None)); + return open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config).map(|_| (false, None)); } } @@ -658,7 +658,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R false => Some(account_provider.clone()) }; - let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf)); + let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)); // the dapps server let dapps_deps = { @@ -791,7 +791,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // start ui if cmd.ui { - open_ui(&cmd.ws_conf, &cmd.ui_conf)?; + open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)?; } if let Some(dapp) = cmd.dapp { diff --git a/parity/signer.rs b/parity/signer.rs index 7a5e90341..8bdf18bd0 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -17,13 +17,13 @@ use std::io; use std::path::{Path, PathBuf}; -use ansi_term::Colour; +use ansi_term::Colour::White; +use ethcore_logger::Config as LogConfig; use rpc; use rpc_apis; use parity_rpc; use path::restrict_permissions_owner; - pub const CODES_FILENAME: &'static str = "authcodes"; pub struct NewToken { @@ -32,12 +32,13 @@ pub struct NewToken { pub message: String, } -pub fn new_service(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> rpc_apis::SignerService { +pub fn new_service(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> rpc_apis::SignerService { let signer_path = ws_conf.signer_path.clone(); + let logger_config_color = logger_config.color; let signer_enabled = ui_conf.enabled; rpc_apis::SignerService::new(move || { - generate_new_token(&signer_path).map_err(|e| format!("{:?}", e)) + generate_new_token(&signer_path, logger_config_color).map_err(|e| format!("{:?}", e)) }, signer_enabled) } @@ -48,13 +49,14 @@ pub fn codes_path(path: &Path) -> PathBuf { p } -pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration) -> Result { - Ok(generate_token_and_url(&ws_conf, &ui_conf)?.message) +pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration, logger_config: LogConfig) -> Result { + Ok(generate_token_and_url(&ws_conf, &ui_conf, &logger_config)?.message) } -pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> Result { - let code = generate_new_token(&ws_conf.signer_path).map_err(|err| format!("Error generating token: {:?}", err))?; +pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result { + let code = generate_new_token(&ws_conf.signer_path, logger_config.color).map_err(|err| format!("Error generating token: {:?}", err))?; let auth_url = format!("http://{}:{}/#/auth?token={}", ui_conf.interface, ui_conf.port, code); + // And print in to the console Ok(NewToken { token: code.clone(), @@ -65,18 +67,24 @@ Open: {} to authorize your browser. Or use the generated token: {}"#, - Colour::White.bold().paint(auth_url), + match logger_config.color { + true => format!("{}", White.bold().paint(auth_url)), + false => auth_url + }, code ) }) } -fn generate_new_token(path: &Path) -> io::Result { +fn generate_new_token(path: &Path, logger_config_color: bool) -> io::Result { let path = codes_path(path); let mut codes = parity_rpc::AuthCodes::from_file(&path)?; codes.clear_garbage(); let code = codes.generate_new()?; codes.to_file(&path)?; - trace!("New key code created: {}", Colour::White.bold().paint(&code[..])); + trace!("New key code created: {}", match logger_config_color { + true => format!("{}", White.bold().paint(&code[..])), + false => format!("{}", &code[..]) + }); Ok(code) } From 9f0bfa01ca9769153b4f0c5579a7f853397e6708 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Fri, 28 Jul 2017 23:18:02 +0200 Subject: [PATCH 22/48] typo in uninstaller --- nsis/installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nsis/installer.nsi b/nsis/installer.nsi index 564fbfce8..7173beccc 100644 --- a/nsis/installer.nsi +++ b/nsis/installer.nsi @@ -149,7 +149,7 @@ function un.onInit SetShellVarContext all #Verify the uninstaller - last chance to back out - MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next + MessageBox MB_OKCANCEL "Permanently remove ${APPNAME}?" IDOK next Abort next: From eecd823d32b3f4d88f64a6c41acec9c2b0b78994 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 17:12:07 +0200 Subject: [PATCH 23/48] util reexports less std --- Cargo.lock | 14 ++++++-- ethcore/Cargo.toml | 3 ++ ethcore/evm/src/interpreter/gasometer.rs | 3 +- ethcore/evm/src/interpreter/mod.rs | 3 +- ethcore/evm/src/tests.rs | 2 ++ ethcore/src/account_db.rs | 1 + ethcore/src/blockchain/blockchain.rs | 2 ++ ethcore/src/blockchain/extras.rs | 9 ++++-- ethcore/src/client/test_client.rs | 2 ++ ethcore/src/engines/authority_round/mod.rs | 9 ++++-- ethcore/src/engines/basic_authority.rs | 12 ++++--- ethcore/src/engines/instant_seal.rs | 4 +-- ethcore/src/engines/mod.rs | 2 ++ ethcore/src/engines/tendermint/message.rs | 5 +-- ethcore/src/engines/tendermint/mod.rs | 7 ++-- ethcore/src/engines/validator_set/contract.rs | 8 ++--- ethcore/src/engines/validator_set/multi.rs | 1 + .../engines/validator_set/safe_contract.rs | 10 +++--- ethcore/src/engines/vote_collector.rs | 1 + ethcore/src/error.rs | 1 + ethcore/src/ethereum/ethash.rs | 32 +++++++++++-------- ethcore/src/executive.rs | 6 ++-- ethcore/src/externalities.rs | 9 +++--- ethcore/src/header.rs | 8 ++--- ethcore/src/lib.rs | 3 ++ ethcore/src/miner/miner.rs | 3 +- ethcore/src/miner/transaction_queue.rs | 4 +-- ethcore/src/miner/work_notify.rs | 1 + ethcore/src/pod_account.rs | 4 ++- ethcore/src/pod_state.rs | 4 ++- ethcore/src/spec/spec.rs | 3 ++ ethcore/src/state/account.rs | 2 ++ ethcore/src/state/mod.rs | 2 ++ ethcore/src/tests/client.rs | 1 + ethcore/src/tests/helpers.rs | 3 +- ethcore/src/trace/types/filter.rs | 4 +-- ethcore/src/trace/types/trace.rs | 2 +- ethcore/src/verification/queue/mod.rs | 17 +++++----- ethcore/src/verification/verification.rs | 2 ++ ethcore/types/Cargo.toml | 1 + ethcore/types/src/filter.rs | 2 +- ethcore/types/src/lib.rs | 1 + ethcore/types/src/log_entry.rs | 6 ++-- ethkey/cli/src/main.rs | 16 +++++----- ethkey/src/secret.rs | 7 ++++ hash-fetch/src/client.rs | 3 +- ipc/hypervisor/src/lib.rs | 2 +- ipfs/src/lib.rs | 4 +-- ipfs/src/route.rs | 3 +- js/src/lib.rs.in | 2 +- rpc/src/v1/tests/helpers/miner_service.rs | 1 + stratum/src/lib.rs | 8 ++--- sync/src/block_sync.rs | 4 ++- sync/src/blocks.rs | 1 + sync/src/chain.rs | 28 ++++++++-------- sync/src/tests/helpers.rs | 1 + sync/src/tests/snapshot.rs | 1 + util/Cargo.toml | 2 -- util/bloomable/Cargo.toml | 10 ++++++ util/{src/bloom.rs => bloomable/src/lib.rs} | 32 ++----------------- util/bloomable/tests/test.rs | 31 ++++++++++++++++++ util/src/common.rs | 5 +-- util/src/journaldb/archivedb.rs | 1 + util/src/journaldb/earlymergedb.rs | 2 ++ util/src/journaldb/mod.rs | 3 +- util/src/journaldb/overlayrecentdb.rs | 1 + util/src/journaldb/refcounteddb.rs | 1 + util/src/kvdb.rs | 2 ++ util/src/lib.rs | 5 --- util/src/migration/tests.rs | 1 + util/src/misc.rs | 6 ++-- util/src/nibblevec.rs | 2 +- util/src/standard.rs | 18 ----------- util/src/trie/triedb.rs | 1 + 74 files changed, 255 insertions(+), 168 deletions(-) create mode 100644 util/bloomable/Cargo.toml rename util/{src/bloom.rs => bloomable/src/lib.rs} (70%) create mode 100644 util/bloomable/tests/test.rs diff --git a/Cargo.lock b/Cargo.lock index 359b2d2f9..2f9cb3f6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,6 +181,14 @@ name = "blastfig" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bloomable" +version = "0.1.0" +dependencies = [ + "ethcore-bigint 0.1.3", + "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bloomchain" version = "0.1.0" @@ -271,6 +279,7 @@ dependencies = [ name = "common-types" version = "0.1.0" dependencies = [ + "bloomable 0.1.0", "ethcore-util 1.8.0", "ethjson 0.1.0", "rlp 0.2.0", @@ -462,6 +471,7 @@ name = "ethcore" version = "1.8.0" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bloomable 0.1.0", "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bn 0.4.4 (git+https://github.com/paritytech/bn)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -502,8 +512,10 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", + "table 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "using_queue 0.1.0", ] [[package]] @@ -751,11 +763,9 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.1.0", - "table 0.1.0", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "using_queue 0.1.0", "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 71e329201..7ac147cd0 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -53,6 +53,9 @@ semver = "0.6" stats = { path = "../util/stats" } time = "0.1" transient-hashmap = "0.4" +using_queue = { path = "../util/using_queue" } +table = { path = "../util/table" } +bloomable = { path = "../util/bloomable" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index c2dcf5412..5f4ef80a1 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::cmp; use util::*; use super::u256_to_address; @@ -82,7 +83,7 @@ impl Gasometer { }; if let Some(Ok(r)) = requested { - Ok(min(r, max_gas_provided)) + Ok(cmp::min(r, max_gas_provided)) } else { Ok(max_gas_provided) } diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 30b431912..621febffd 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -23,12 +23,13 @@ mod stack; mod memory; mod shared_cache; +use std::marker::PhantomData; +use std::{cmp, mem}; use self::gasometer::Gasometer; use self::stack::{Stack, VecStack}; use self::memory::Memory; pub use self::shared_cache::SharedCache; -use std::marker::PhantomData; use action_params::{ActionParams, ActionValue}; use call_type::CallType; use instructions::{self, Instruction, InstructionInfo}; diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index d0502f79a..c19a575f3 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . use std::fmt::Debug; +use std::str::FromStr; +use std::collections::{HashMap, HashSet}; use rustc_hex::FromHex; use util::*; use action_params::{ActionParams, ActionValue}; diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index 10e63dba3..5ce555aef 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! DB backend wrapper for Account trie +use std::collections::HashMap; use util::*; use rlp::NULL_RLP; diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 4412df567..59b4fb7c3 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -16,6 +16,8 @@ //! Blockchain database. +use std::collections::{HashMap, HashSet}; +use std::mem; use bloomchain as bc; use util::*; use rlp::*; diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index 04c12d53a..ed3a5009b 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -16,6 +16,8 @@ //! Blockchain DB extras. +use std::ops; +use std::io::Write; use bloomchain; use blooms::{GroupPosition, BloomGroup}; use db::Key; @@ -56,7 +58,7 @@ fn with_index(hash: &H256, i: ExtrasIndex) -> H264 { pub struct BlockNumberKey([u8; 5]); -impl Deref for BlockNumberKey { +impl ops::Deref for BlockNumberKey { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -88,7 +90,7 @@ impl Key for H256 { pub struct LogGroupKey([u8; 6]); -impl Deref for LogGroupKey { +impl ops::Deref for LogGroupKey { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -160,7 +162,8 @@ pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[ ]; pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]); -impl Deref for EpochTransitionsKey { + +impl ops::Deref for EpochTransitionsKey { type Target = [u8]; fn deref(&self) -> &[u8] { &self.0[..] } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5dfdf5c25..e33888e72 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -17,6 +17,8 @@ //! Test client. use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; +use std::collections::{HashMap, BTreeMap}; +use std::mem; use rustc_hex::FromHex; use util::*; use rlp::*; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 3210368db..a72091e5e 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -19,6 +19,8 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::Weak; use std::time::{UNIX_EPOCH, Duration}; +use std::collections::{BTreeMap, HashSet, HashMap}; +use std::cmp; use account_provider::AccountProvider; use block::*; @@ -463,9 +465,9 @@ impl Engine for AuthorityRound { let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -815,7 +817,7 @@ impl Engine for AuthorityRound { } } - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> { t.check_low_s()?; if let Some(n) = t.network_id() { @@ -852,6 +854,7 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; + use std::str::FromStr; use util::*; use header::Header; use error::{Error, BlockError}; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 68759131d..a3f4b9114 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -17,6 +17,8 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. use std::sync::Weak; +use std::collections::BTreeMap; +use std::cmp; use util::*; use ethkey::{recover, public_to_address, Signature}; use account_provider::AccountProvider; @@ -121,9 +123,9 @@ impl Engine for BasicAuthority { let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -147,7 +149,7 @@ impl Engine for BasicAuthority { Seal::None } - fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // check the seal fields. // TODO: pull this out into common code. if header.seal().len() != self.seal_fields() { @@ -158,11 +160,11 @@ impl Engine for BasicAuthority { Ok(()) } - fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) } - fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // Do not calculate difficulty for genesis blocks. if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 38834622c..4d297dc3f 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::collections::BTreeMap; -use util::{Address, HashMap}; +use std::collections::{BTreeMap, HashMap}; +use util::Address; use builtin::Builtin; use engines::{Engine, Seal}; use spec::CommonParams; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index c5fa4818e..77b89e59c 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -36,6 +36,8 @@ pub use self::null_engine::NullEngine; pub use self::tendermint::Tendermint; use std::sync::Weak; +use std::collections::{BTreeMap, HashMap}; +use std::fmt; use self::epoch::PendingTransition; diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index b9465f429..623284839 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -16,6 +16,7 @@ //! Tendermint message handling. +use std::cmp; use util::*; use super::{Height, View, BlockHash, Step}; use error::Error; @@ -110,13 +111,13 @@ impl Default for VoteStep { } impl PartialOrd for VoteStep { - fn partial_cmp(&self, m: &VoteStep) -> Option { + fn partial_cmp(&self, m: &VoteStep) -> Option { Some(self.cmp(m)) } } impl Ord for VoteStep { - fn cmp(&self, m: &VoteStep) -> Ordering { + fn cmp(&self, m: &VoteStep) -> cmp::Ordering { if self.height != m.height { self.height.cmp(&m.height) } else if self.view != m.view { diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 453e8f9fb..5d334a610 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -27,6 +27,8 @@ mod params; use std::sync::Weak; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; +use std::collections::{HashSet, BTreeMap, HashMap}; +use std::cmp; use util::*; use client::{Client, EngineClient}; use error::{Error, BlockError}; @@ -473,9 +475,9 @@ impl Engine for Tendermint { let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -771,6 +773,7 @@ impl Engine for Tendermint { #[cfg(test)] mod tests { + use std::str::FromStr; use rustc_hex::FromHex; use util::*; use block::*; diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 46f5c8512..e93d06a27 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -142,11 +142,11 @@ mod tests { #[test] fn fetches_validators() { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None); - let vc = Arc::new(ValidatorContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); + let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_contract(Arc::downgrade(&client)); let last_hash = client.best_block_header().hash(); - assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); - assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); + assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::
().unwrap())); + assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::
().unwrap())); } #[test] @@ -155,7 +155,7 @@ mod tests { let v1 = tap.insert_account("1".sha3().into(), "").unwrap(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone())); client.engine().register_client(Arc::downgrade(&client)); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); // Make sure reporting can be done. client.miner().set_gas_floor_target(1_000_000.into()); diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 5835dbcdb..79a5a7d26 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -142,6 +142,7 @@ impl ValidatorSet for Multi { #[cfg(test)] mod tests { + use std::collections::BTreeMap; use account_provider::AccountProvider; use client::{BlockChainClient, EngineClient}; use engines::EpochChange; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 2c42323be..172ec53b7 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -438,11 +438,11 @@ mod tests { #[test] fn fetches_validators() { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); - let vc = Arc::new(ValidatorSafeContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); + let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_contract(Arc::downgrade(&client)); let last_hash = client.best_block_header().hash(); - assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); - assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); + assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::
().unwrap())); + assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::
().unwrap())); } #[test] @@ -454,7 +454,7 @@ mod tests { let network_id = Spec::new_validator_safe_contract().network_id(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); client.engine().register_client(Arc::downgrade(&client)); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); client.miner().set_engine_signer(v1, "".into()).unwrap(); // Remove "1" validator. @@ -520,7 +520,7 @@ mod tests { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); let engine = client.engine().clone(); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); let last_hash = client.best_block_header().hash(); let mut new_header = Header::default(); diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index d01d07f15..de9188e74 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -17,6 +17,7 @@ //! Collects votes on hashes at each Message::Round. use std::fmt::Debug; +use std::collections::{BTreeMap, HashSet, HashMap}; use util::*; use rlp::{Encodable, RlpStream}; diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 2d908cdb6..194cbcb38 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -16,6 +16,7 @@ //! General error types for use in ethcore. +use std::fmt; use util::*; use io::*; use header::BlockNumber; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 1fbd711c9..06a4ad0d8 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . use std::path::Path; +use std::cmp; +use std::collections::{BTreeMap, HashMap}; use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; @@ -235,15 +237,15 @@ impl Engine for Arc { let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into(); let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into(); let gas_limit = if gas_limit < gas_floor_target { - let gas_limit = min(gas_floor_target, upper_limit); + let gas_limit = cmp::min(gas_floor_target, upper_limit); round_block_gas_limit(gas_limit, lower_limit, upper_limit) } else if gas_limit > gas_ceil_target { - let gas_limit = max(gas_ceil_target, lower_limit); + let gas_limit = cmp::max(gas_ceil_target, lower_limit); round_block_gas_limit(gas_limit, lower_limit, upper_limit) } else { - let total_lower_limit = max(lower_limit, gas_floor_target); - let total_upper_limit = min(upper_limit, gas_ceil_target); - let gas_limit = max(gas_floor_target, min(total_upper_limit, + let total_lower_limit = cmp::max(lower_limit, gas_floor_target); + let total_upper_limit = cmp::min(upper_limit, gas_ceil_target); + let gas_limit = cmp::max(gas_floor_target, cmp::min(total_upper_limit, lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor)); round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit) }; @@ -319,7 +321,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // check the seal fields. if header.seal().len() != self.seal_fields() { return Err(From::from(BlockError::InvalidSealArity( @@ -357,7 +359,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { if header.seal().len() != self.seal_fields() { return Err(From::from(BlockError::InvalidSealArity( Mismatch { expected: self.seal_fields(), found: header.seal().len() } @@ -376,7 +378,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // we should not calculate difficulty for genesis blocks if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); @@ -400,7 +402,7 @@ impl Engine for Arc { Ok(()) } - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> { if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price { return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into()); } @@ -493,28 +495,28 @@ impl Ethash { if diff_inc <= threshold { *parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into() } else { - let multiplier = min(diff_inc - threshold, 99).into(); + let multiplier = cmp::min(diff_inc - threshold, 99).into(); parent.difficulty().saturating_sub( *parent.difficulty() / difficulty_bound_divisor * multiplier ) } }; - target = max(min_difficulty, target); + target = cmp::max(min_difficulty, target); if header.number() < self.ethash_params.bomb_defuse_transition { if header.number() < self.ethash_params.ecip1010_pause_transition { let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; if period > 1 { - target = max(min_difficulty, target + (U256::from(1) << (period - 2))); + target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2))); } } else if header.number() < self.ethash_params.ecip1010_continue_transition { let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize; - target = max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); + target = cmp::max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); } else { let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize; - target = max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); + target = cmp::max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); } } target @@ -559,6 +561,8 @@ impl Header { #[cfg(test)] mod tests { + use std::str::FromStr; + use std::collections::BTreeMap; use util::*; use block::*; use tests::helpers::*; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9e25b6671..9845d4575 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Transaction Execution environment. +use std::cmp; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; @@ -74,7 +75,7 @@ pub struct TransactOptions { pub check_nonce: bool, } -pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) +pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) -> Box where E: Engine + ?Sized { if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) { @@ -597,10 +598,11 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { #[allow(dead_code)] mod tests { use std::sync::Arc; + use std::str::FromStr; use rustc_hex::FromHex; use ethkey::{Generator, Random}; use super::*; - use util::{H256, U256, U512, Address, FromStr}; + use util::{H256, U256, U512, Address}; use util::bytes::BytesRef; use evm::action_params::{ActionParams, ActionValue}; use evm::env_info::EnvInfo; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 39c8673a9..d718fd256 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Transaction Execution environment. +use std::cmp; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; @@ -470,7 +471,7 @@ mod tests { let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); - let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); assert_eq!(hash, H256::zero()); } @@ -494,7 +495,7 @@ mod tests { let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); - let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); assert_eq!(test_hash, hash); } @@ -513,10 +514,10 @@ mod tests { // this should panic because we have no balance on any account ext.call( - &U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap(), + &"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap(), &Address::new(), &Address::new(), - Some(U256::from_str("0000000000000000000000000000000000000000000000000000000000150000").unwrap()), + Some("0000000000000000000000000000000000000000000000000000000000150000".parse::().unwrap()), &[], &Address::new(), &mut output, diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 83c69e97d..a9a4f948d 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -16,13 +16,13 @@ //! Block header. +use std::cmp; +use std::cell::RefCell; use util::*; use basic_types::{LogBloom, ZERO_LOGBLOOM}; use time::get_time; use rlp::*; -use std::cell::RefCell; - pub use basic_types::Seal; pub use types::BlockNumber; @@ -175,7 +175,7 @@ impl Header { /// Set the timestamp field of the header. pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); } /// Set the timestamp field of the header to the current time. - pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } + pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = cmp::max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } /// Set the number field of the header. pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); } /// Set the author field of the header. @@ -275,7 +275,7 @@ impl Decodable for Header { number: r.val_at(8)?, gas_limit: r.val_at(9)?, gas_used: r.val_at(10)?, - timestamp: min(r.val_at::(11)?, u64::max_value().into()).as_u64(), + timestamp: cmp::min(r.val_at::(11)?, u64::max_value().into()).as_u64(), extra_data: r.val_at(12)?, seal: vec![], hash: RefCell::new(Some(r.as_raw().sha3())), diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 89f9d2e57..0805fc7a0 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -106,6 +106,9 @@ extern crate semver; extern crate stats; extern crate time; extern crate transient_hashmap; +extern crate using_queue; +extern crate table; +extern crate bloomable; #[macro_use] extern crate log; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 80971355b..cc5c8b6f3 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -15,9 +15,10 @@ // along with Parity. If not, see . use std::time::{Instant, Duration}; +use std::collections::{BTreeMap, HashSet}; use util::*; -use util::using_queue::{UsingQueue, GetAction}; +use using_queue::{UsingQueue, GetAction}; use account_provider::{AccountProvider, SignError as AccountError}; use state::{State, CleanupMode}; use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockId, CallAnalytics, TransactionId}; diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 542b42b93..263143ee8 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -106,7 +106,7 @@ use std::cmp; use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap}; use linked_hash_map::LinkedHashMap; use util::{Address, H256, U256, HeapSizeOf}; -use util::table::Table; +use table::Table; use transaction::*; use error::{Error, TransactionError}; use client::TransactionImportResult; @@ -1447,7 +1447,7 @@ fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option. +use std::fmt; +use std::collections::BTreeMap; use util::*; use state::Account; use ethjson; @@ -166,7 +168,7 @@ pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option StateDiff { #[cfg(test)] mod test { - use util::*; + use std::collections::BTreeMap; use types::state_diff::*; use types::account_diff::*; use pod_account::PodAccount; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 7d3900f2c..c4afc93d7 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -16,6 +16,8 @@ //! Parameters for a block chain. +use std::io::Read; +use std::collections::BTreeMap; use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; @@ -484,6 +486,7 @@ impl Spec { #[cfg(test)] mod tests { + use std::str::FromStr; use util::*; use views::*; use tests::helpers::get_temp_state_db; diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 9e58f2ec0..8f528b9d8 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -16,6 +16,8 @@ //! Single account in the system. +use std::fmt; +use std::collections::HashMap; use util::*; use pod_account::*; use rlp::*; diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 354da2cc3..25c019dc0 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -21,6 +21,8 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; +use std::collections::{HashMap, BTreeMap, HashSet}; +use std::fmt; use receipt::Receipt; use engines::Engine; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 3b32f9094..54256b285 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::str::FromStr; use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockId}; use state::{self, State, CleanupMode}; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index f8e412073..2c50f0fc2 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::BTreeMap; use ethkey::KeyPair; use io::*; use client::{BlockChainClient, Client, ClientConfig}; @@ -347,7 +348,7 @@ pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_h for i in start_number .. start_number + count + 1 { let mut block_header = Header::new(); block_header.set_gas_limit(test_engine.params().min_gas_limit); - block_header.set_difficulty(U256::from(i).mul(U256([0, 1, 0, 0]))); + block_header.set_difficulty(U256::from(i) * U256([0, 1, 0, 0])); block_header.set_timestamp(rolling_timestamp); block_header.set_number(i as u64); block_header.set_parent_hash(parent); diff --git a/ethcore/src/trace/types/filter.rs b/ethcore/src/trace/types/filter.rs index 2dc810442..1b2e2077a 100644 --- a/ethcore/src/trace/types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -20,7 +20,7 @@ use std::ops::Range; use bloomchain::{Filter as BloomFilter, Bloom, Number}; use util::Address; use util::sha3::Hashable; -use util::bloom::Bloomable; +use bloomable::Bloomable; use basic_types::LogBloom; use trace::flat::FlatTrace; use super::trace::{Action, Res}; @@ -137,7 +137,7 @@ impl Filter { mod tests { use util::Address; use util::sha3::Hashable; - use util::bloom::Bloomable; + use bloomable::Bloomable; use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide}; use trace::flat::FlatTrace; use trace::{Filter, AddressesFilter, TraceError}; diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 24250935f..9a22f31a9 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -18,7 +18,7 @@ use util::{U256, Bytes, Address}; use util::sha3::Hashable; -use util::bloom::Bloomable; +use bloomable::Bloomable; use rlp::*; use evm::action_params::ActionParams; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 7e9a70f7c..192a0dc77 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -20,6 +20,8 @@ use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; use std::sync::{Condvar as SCondvar, Mutex as SMutex}; +use std::cmp; +use std::collections::{VecDeque, HashSet, HashMap}; use util::*; use io::*; use error::*; @@ -234,8 +236,8 @@ impl VerificationQueue { let scale_verifiers = config.verifier_settings.scale_verifiers; let num_cpus = ::num_cpus::get(); - let max_verifiers = min(num_cpus, MAX_VERIFIERS); - let default_amount = max(1, min(max_verifiers, config.verifier_settings.num_verifiers)); + let max_verifiers = cmp::min(num_cpus, MAX_VERIFIERS); + let default_amount = cmp::max(1, cmp::min(max_verifiers, config.verifier_settings.num_verifiers)); let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new())); let mut verifier_handles = Vec::with_capacity(max_verifiers); @@ -278,8 +280,8 @@ impl VerificationQueue { processing: RwLock::new(HashMap::new()), empty: empty, ticks_since_adjustment: AtomicUsize::new(0), - max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT), - max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT), + max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT), + max_mem_use: cmp::max(config.max_mem_use, MIN_MEM_LIMIT), scale_verifiers: scale_verifiers, verifier_handles: verifier_handles, state: state, @@ -567,7 +569,7 @@ impl VerificationQueue { /// Removes up to `max` verified items from the queue pub fn drain(&self, max: usize) -> Vec { let mut verified = self.verification.verified.lock(); - let count = min(max, verified.len()); + let count = cmp::min(max, verified.len()); let result = verified.drain(..count).collect::>(); let drained_size = result.iter().map(HeapSizeOf::heap_size_of_children).fold(0, |a, c| a + c); @@ -687,8 +689,8 @@ impl VerificationQueue { // or below 1. fn scale_verifiers(&self, target: usize) { let current = self.num_verifiers(); - let target = min(self.verifier_handles.len(), target); - let target = max(1, target); + let target = cmp::min(self.verifier_handles.len(), target); + let target = cmp::max(1, target); debug!(target: "verification", "Scaling from {} to {} verifiers", current, target); @@ -725,7 +727,6 @@ impl Drop for VerificationQueue { #[cfg(test)] mod tests { - use util::*; use io::*; use spec::*; use super::{BlockQueue, Config, State}; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 823d2ef70..00976dca7 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -21,6 +21,7 @@ //! 2. Signatures verification done in the queue. //! 3. Final verification against the blockchain done before enactment. +use std::collections::HashSet; use util::*; use engines::Engine; use error::{BlockError, Error}; @@ -264,6 +265,7 @@ fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: & #[cfg(test)] mod tests { + use std::collections::{BTreeMap, HashMap}; use util::*; use ethkey::{Random, Generator}; use header::*; diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 2a3ac6a80..77f392bf6 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] rlp = { path = "../../util/rlp" } ethcore-util = { path = "../../util" } ethjson = { path = "../../json" } +bloomable = { path = "../../util/bloomable" } [dev-dependencies] rustc-hex= "1.0" diff --git a/ethcore/types/src/filter.rs b/ethcore/types/src/filter.rs index 6ab53b536..6e344b4ef 100644 --- a/ethcore/types/src/filter.rs +++ b/ethcore/types/src/filter.rs @@ -17,7 +17,7 @@ //! Blockchain filter use util::{Address, H256, Hashable, H2048}; -use util::bloom::Bloomable; +use bloomable::Bloomable; use ids::BlockId; use log_entry::LogEntry; diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 589034066..7650cf651 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -19,6 +19,7 @@ extern crate ethcore_util as util; extern crate ethjson; extern crate rlp; +extern crate bloomable; #[cfg(test)] extern crate rustc_hex; diff --git a/ethcore/types/src/log_entry.rs b/ethcore/types/src/log_entry.rs index 724e6a7dc..f917a4dab 100644 --- a/ethcore/types/src/log_entry.rs +++ b/ethcore/types/src/log_entry.rs @@ -18,7 +18,7 @@ use std::ops::Deref; use util::{H256, Address, Bytes, HeapSizeOf, Hashable}; -use util::bloom::Bloomable; +use bloomable::Bloomable; use rlp::*; use {BlockNumber}; @@ -114,8 +114,8 @@ mod tests { #[test] fn test_empty_log_bloom() { - let bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let bloom = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap(); + let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse::
().unwrap(); let log = LogEntry { address: address, topics: vec![], diff --git a/ethkey/cli/src/main.rs b/ethkey/cli/src/main.rs index 7ad07e295..e60b4583a 100644 --- a/ethkey/cli/src/main.rs +++ b/ethkey/cli/src/main.rs @@ -25,7 +25,7 @@ extern crate panic_hook; use std::{env, fmt, process}; use std::num::ParseIntError; use docopt::Docopt; -use rustc_hex::{FromHex, FromHexError}; +use rustc_hex::{ToHex, FromHex, FromHexError}; use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, sign, verify_public, verify_address}; use std::io; @@ -170,7 +170,7 @@ fn main() { fn display(keypair: KeyPair, mode: DisplayMode) -> String { match mode { DisplayMode::KeyPair => format!("{}", keypair), - DisplayMode::Secret => format!("{:?}", keypair.secret()), + DisplayMode::Secret => format!("{}", keypair.secret().to_hex()), DisplayMode::Public => format!("{:?}", keypair.public()), DisplayMode::Address => format!("{:?}", keypair.address()), } @@ -248,9 +248,9 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .collect::>(); let expected = -"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 -public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 -address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); +"secret: aa22b54c0cb43ee30a014afe5ef3664b1cde299feabca46cd3167a85a57c39f2 +public: c4c5398da6843632c123f543d714d2d2277716c11ff612b2a2f23c6bda4d6f0327c31cd58c55a9572c3cc141dade0c32747a13b7ef34c241b26c84adbb28fcf4 +address: 006e27b6a72e1f34c626762f3c4761547aff1421".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -261,7 +261,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55".to_owned(); + let expected = "aa22b54c0cb43ee30a014afe5ef3664b1cde299feabca46cd3167a85a57c39f2".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -272,7 +272,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124".to_owned(); + let expected = "c4c5398da6843632c123f543d714d2d2277716c11ff612b2a2f23c6bda4d6f0327c31cd58c55a9572c3cc141dade0c32747a13b7ef34c241b26c84adbb28fcf4".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -283,7 +283,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); + let expected = "006e27b6a72e1f34c626762f3c4761547aff1421".to_owned(); assert_eq!(execute(command).unwrap(), expected); } diff --git a/ethkey/src/secret.rs b/ethkey/src/secret.rs index 982962684..433d8c68e 100644 --- a/ethkey/src/secret.rs +++ b/ethkey/src/secret.rs @@ -17,6 +17,7 @@ use std::fmt; use std::ops::Deref; use std::str::FromStr; +use rustc_hex::ToHex; use secp256k1::key; use bigint::hash::H256; use {Error, SECP256K1}; @@ -26,6 +27,12 @@ pub struct Secret { inner: H256, } +impl ToHex for Secret { + fn to_hex(&self) -> String { + self.inner.to_hex() + } +} + impl fmt::Debug for Secret { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "Secret: 0x{:x}{:x}..{:x}{:x}", self.inner[0], self.inner[1], self.inner[30], self.inner[31]) diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index d52bda7d9..bd773e9b3 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -188,8 +188,9 @@ fn random_temp_path() -> PathBuf { #[cfg(test)] mod tests { + use rustc_hex::FromHex; use std::sync::{Arc, mpsc}; - use util::{Mutex, FromHex}; + use util::Mutex; use futures::future; use fetch::{self, Fetch}; use parity_reactor::Remote; diff --git a/ipc/hypervisor/src/lib.rs b/ipc/hypervisor/src/lib.rs index 1031905d4..b522122b5 100644 --- a/ipc/hypervisor/src/lib.rs +++ b/ipc/hypervisor/src/lib.rs @@ -260,7 +260,7 @@ mod tests { let client = nanoipc::fast_client::>(url).unwrap(); client.handshake().unwrap(); - client.module_ready(test_module_id); + client.module_ready(test_module_id, url.to_owned()); }); let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index 4821ef59d..104c7db19 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -233,7 +233,7 @@ mod tests { let _ = write_chunk(&mut transport, &mut progress, b"foobar"); - assert_eq!(b"foobar".into_vec(), transport); + assert_eq!(b"foobar".to_vec(), transport); assert_eq!(6, progress); } @@ -244,7 +244,7 @@ mod tests { let _ = write_chunk(&mut transport, &mut progress, b"foobar"); - assert_eq!(b"bar".into_vec(), transport); + assert_eq!(b"bar".to_vec(), transport); assert_eq!(6, progress); } diff --git a/ipfs/src/route.rs b/ipfs/src/route.rs index b034c2d4c..40edc8de0 100644 --- a/ipfs/src/route.rs +++ b/ipfs/src/route.rs @@ -119,7 +119,8 @@ mod tests { use ethcore::client::TestBlockChainClient; fn get_mocked_handler() -> IpfsHandler { - IpfsHandler::new(None, None, Arc::new(TestBlockChainClient::new())) + //IpfsHandler::new(None, None, Arc::new(TestBlockChainClient::new())) + unimplemented!(); } #[test] diff --git a/js/src/lib.rs.in b/js/src/lib.rs.in index 220811656..b811c1066 100644 --- a/js/src/lib.rs.in +++ b/js/src/lib.rs.in @@ -51,5 +51,5 @@ impl WebApp for App { #[test] fn test_js() { - parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR")); + parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR"), "build"); } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index c5bc0a259..ecc453622 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -16,6 +16,7 @@ //! Test implementation of miner service. +use std::collections::{BTreeMap, HashMap}; use std::collections::hash_map::Entry; use util::{Address, H256, Bytes, U256}; use util::standard::*; diff --git a/stratum/src/lib.rs b/stratum/src/lib.rs index d87bf59a8..0042ab1e9 100644 --- a/stratum/src/lib.rs +++ b/stratum/src/lib.rs @@ -342,7 +342,7 @@ mod tests { let mut core = Core::new().expect("Tokio Core should be created with no errors"); let mut buffer = vec![0u8; 2048]; - let mut data_vec = data.as_bytes().into_vec(); + let mut data_vec = data.as_bytes().to_vec(); data_vec.extend(b"\n"); let stream = TcpStream::connect(addr, &core.handle()) @@ -353,7 +353,7 @@ mod tests { io::read(stream, &mut buffer) }) .and_then(|(_, read_buf, len)| { - future::ok(read_buf[0..len].into_vec()) + future::ok(read_buf[0..len].to_vec()) }); let result = core.run(stream).expect("Core should run with no errors"); @@ -454,7 +454,7 @@ mod tests { let mut auth_request = r#"{"jsonrpc": "2.0", "method": "mining.authorize", "params": ["miner1", ""], "id": 1}"# .as_bytes() - .into_vec(); + .to_vec(); auth_request.extend(b"\n"); let mut core = Core::new().expect("Tokio Core should be created with no errors"); @@ -487,7 +487,7 @@ mod tests { }) .and_then(|(_, read_buf, len)| { trace!(target: "stratum", "Received work from server"); - future::ok(read_buf[0..len].into_vec()) + future::ok(read_buf[0..len].to_vec()) }); let response = String::from_utf8( core.run(stream).expect("Core should run with no errors") diff --git a/sync/src/block_sync.rs b/sync/src/block_sync.rs index e7192d525..8215b775b 100644 --- a/sync/src/block_sync.rs +++ b/sync/src/block_sync.rs @@ -18,6 +18,8 @@ /// Blockchain downloader /// +use std::collections::{HashSet, VecDeque}; +use std::cmp; use util::*; use rlp::*; use ethcore::views::{BlockView}; @@ -386,7 +388,7 @@ impl BlockDownloader { debug!(target: "sync", "Could not revert to previous ancient block, last: {} ({})", start, start_hash); self.reset(); } else { - let n = start - min(self.retract_step, start); + let n = start - cmp::min(self.retract_step, start); self.retract_step *= 2; match io.chain().block_hash(BlockId::Number(n)) { Some(h) => { diff --git a/sync/src/blocks.rs b/sync/src/blocks.rs index 3dcc912a7..dbd797007 100644 --- a/sync/src/blocks.rs +++ b/sync/src/blocks.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::{HashSet, HashMap}; use std::collections::hash_map::Entry; use smallvec::SmallVec; use util::*; diff --git a/sync/src/chain.rs b/sync/src/chain.rs index b3ca25328..38872b24f 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -89,6 +89,8 @@ /// All other messages are ignored. /// +use std::collections::{HashSet, HashMap}; +use std::cmp; use util::*; use rlp::*; use network::*; @@ -421,7 +423,7 @@ impl ChainSync { start_block_number: self.starting_block, last_imported_block_number: Some(last_imported_number), last_imported_old_block_number: self.old_blocks.as_ref().map(|d| d.last_imported_block_number()), - highest_block_number: self.highest_block.map(|n| max(n, last_imported_number)), + highest_block_number: self.highest_block.map(|n| cmp::max(n, last_imported_number)), blocks_received: if last_imported_number > self.starting_block { last_imported_number - self.starting_block } else { 0 }, blocks_total: match self.highest_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 }, num_peers: self.peers.values().filter(|p| p.is_allowed()).count(), @@ -961,7 +963,7 @@ impl ChainSync { } if self.state != SyncState::Idle { trace!(target: "sync", "Ignoring new hashes since we're already downloading."); - let max = r.iter().take(MAX_NEW_HASHES).map(|item| item.val_at::(1).unwrap_or(0)).fold(0u64, max); + let max = r.iter().take(MAX_NEW_HASHES).map(|item| item.val_at::(1).unwrap_or(0)).fold(0u64, cmp::max); if max > self.highest_block.unwrap_or(0) { self.highest_block = Some(max); } @@ -1473,7 +1475,7 @@ impl ChainSync { let mut item_count = r.item_count()?; trace!(target: "sync", "{:02} -> Transactions ({} entries)", peer_id, item_count); - item_count = min(item_count, MAX_TX_TO_IMPORT); + item_count = cmp::min(item_count, MAX_TX_TO_IMPORT); let mut transactions = Vec::with_capacity(item_count); for i in 0 .. item_count { let rlp = r.at(i)?; @@ -1549,11 +1551,11 @@ impl ChainSync { }; let mut number = if reverse { - min(last, number) + cmp::min(last, number) } else { - max(0, number) + cmp::max(0, number) }; - let max_count = min(MAX_HEADERS_TO_SEND, max_headers); + let max_count = cmp::min(MAX_HEADERS_TO_SEND, max_headers); let mut count = 0; let mut data = Bytes::new(); let inc = (skip + 1) as BlockNumber; @@ -1594,7 +1596,7 @@ impl ChainSync { debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); return Ok(None); } - count = min(count, MAX_BODIES_TO_SEND); + count = cmp::min(count, MAX_BODIES_TO_SEND); let mut added = 0usize; let mut data = Bytes::new(); for i in 0..count { @@ -1617,7 +1619,7 @@ impl ChainSync { debug!(target: "sync", "Empty GetNodeData request, ignoring."); return Ok(None); } - count = min(count, MAX_NODE_DATA_TO_SEND); + count = cmp::min(count, MAX_NODE_DATA_TO_SEND); let mut added = 0usize; let mut data = Vec::new(); for i in 0..count { @@ -1641,7 +1643,7 @@ impl ChainSync { debug!(target: "sync", "Empty GetReceipts request, ignoring."); return Ok(None); } - count = min(count, MAX_RECEIPTS_HEADERS_TO_SEND); + count = cmp::min(count, MAX_RECEIPTS_HEADERS_TO_SEND); let mut added_headers = 0usize; let mut added_receipts = 0usize; let mut data = Bytes::new(); @@ -1915,8 +1917,8 @@ impl ChainSync { // take sqrt(x) peers let mut peers = peers.to_vec(); let mut count = (peers.len() as f64).powf(0.5).round() as usize; - count = min(count, MAX_PEERS_PROPAGATION); - count = max(count, MIN_PEERS_PROPAGATION); + count = cmp::min(count, MAX_PEERS_PROPAGATION); + count = cmp::max(count, MIN_PEERS_PROPAGATION); random::new().shuffle(&mut peers); peers.truncate(count); peers @@ -2006,7 +2008,7 @@ impl ChainSync { fn select_peers_for_transactions(&self, filter: F) -> Vec where F: Fn(&PeerId) -> bool { // sqrt(x)/x scaled to max u32 - let fraction = (self.peers.len() as f64).powf(-0.5).mul(u32::max_value() as f64).round() as u32; + let fraction = ((self.peers.len() as f64).powf(-0.5) * (u32::max_value() as f64).round()) as u32; let small = self.peers.len() < MIN_PEERS_PROPAGATION; let mut random = random::new(); @@ -2112,7 +2114,7 @@ impl ChainSync { peers.insert(peer_id); self.send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp); trace!(target: "sync", "{:02} <- Transactions ({} entries)", peer_id, sent); - max_sent = max(max_sent, sent); + max_sent = cmp::max(max_sent, sent); } debug!(target: "sync", "Sent up to {} transactions to {} peers.", max_sent, lucky_peers_len); } diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index 9d32d1951..fa3039b63 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::{VecDeque, HashSet, HashMap}; use util::*; use network::*; use tests::snapshot::*; diff --git a/sync/src/tests/snapshot.rs b/sync/src/tests/snapshot.rs index f52cdb39a..0a3b31fb0 100644 --- a/sync/src/tests/snapshot.rs +++ b/sync/src/tests/snapshot.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::HashMap; use util::*; use ethcore::snapshot::{SnapshotService, ManifestData, RestorationStatus}; use ethcore::header::BlockNumber; diff --git a/util/Cargo.toml b/util/Cargo.toml index aa846898f..5306e3c57 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -28,8 +28,6 @@ vergen = "0.1" target_info = "0.1" ethcore-bigint = { path = "bigint", features = ["heapsizeof"] } parking_lot = "0.4" -using_queue = { path = "using_queue" } -table = { path = "table" } ansi_term = "0.9" tiny-keccak= "1.0" ethcore-bloom-journal = { path = "bloom" } diff --git a/util/bloomable/Cargo.toml b/util/bloomable/Cargo.toml new file mode 100644 index 000000000..46009d381 --- /dev/null +++ b/util/bloomable/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "bloomable" +version = "0.1.0" +authors = ["debris "] + +[dependencies] +ethcore-bigint = { path = "../bigint" } + +[dev-dependencies] +tiny-keccak = "1.2.1" diff --git a/util/src/bloom.rs b/util/bloomable/src/lib.rs similarity index 70% rename from util/src/bloom.rs rename to util/bloomable/src/lib.rs index c39921f5d..29a9abde5 100644 --- a/util/src/bloom.rs +++ b/util/bloomable/src/lib.rs @@ -16,9 +16,11 @@ //! Bloom operations. +extern crate ethcore_bigint; + use std::mem; use std::ops::DerefMut; -use {H64, H160, H256, H512, H520, H2048}; +use ethcore_bigint::hash::{H64, H160, H256, H512, H520, H2048}; /// Returns log2. pub fn log2(x: usize) -> u32 { @@ -115,31 +117,3 @@ impl_bloomable_for_hash!(H256, 32); impl_bloomable_for_hash!(H512, 64); impl_bloomable_for_hash!(H520, 65); impl_bloomable_for_hash!(H2048, 256); - -#[cfg(test)] -mod tests { - use {H160, H256, H2048}; - use sha3::Hashable; - use super::Bloomable; - - #[test] - fn shift_bloomed() { - let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(); - let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); - let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into(); - - let mut my_bloom = H2048::default(); - assert!(!my_bloom.contains_bloomed(&address.sha3())); - assert!(!my_bloom.contains_bloomed(&topic.sha3())); - - my_bloom.shift_bloomed(&address.sha3()); - assert!(my_bloom.contains_bloomed(&address.sha3())); - assert!(!my_bloom.contains_bloomed(&topic.sha3())); - - my_bloom.shift_bloomed(&topic.sha3()); - assert_eq!(my_bloom, bloom); - assert!(my_bloom.contains_bloomed(&address.sha3())); - assert!(my_bloom.contains_bloomed(&topic.sha3())); - } -} - diff --git a/util/bloomable/tests/test.rs b/util/bloomable/tests/test.rs new file mode 100644 index 000000000..85ced83e6 --- /dev/null +++ b/util/bloomable/tests/test.rs @@ -0,0 +1,31 @@ +extern crate tiny_keccak; +extern crate ethcore_bigint; +extern crate bloomable; + +use ethcore_bigint::hash::{H160, H256, H2048}; +use bloomable::Bloomable; +use tiny_keccak::keccak256; + +fn sha3(input: &[u8]) -> H256 { + keccak256(input).into() +} + +#[test] +fn shift_bloomed() { + let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(); + let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); + let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into(); + + let mut my_bloom = H2048::default(); + assert!(!my_bloom.contains_bloomed(&sha3(&address))); + assert!(!my_bloom.contains_bloomed(&sha3(&topic))); + + my_bloom.shift_bloomed(&sha3(&address)); + assert!(my_bloom.contains_bloomed(&sha3(&address))); + assert!(!my_bloom.contains_bloomed(&sha3(&topic))); + + my_bloom.shift_bloomed(&sha3(&topic)); + assert_eq!(my_bloom, bloom); + assert!(my_bloom.contains_bloomed(&sha3(&address))); + assert!(my_bloom.contains_bloomed(&sha3(&topic))); +} diff --git a/util/src/common.rs b/util/src/common.rs index eff697bc2..89ce9d95f 100644 --- a/util/src/common.rs +++ b/util/src/common.rs @@ -16,6 +16,7 @@ //! Utils common types and macros global reexport. +use std::io; pub use standard::*; pub use error::*; pub use bytes::*; @@ -100,8 +101,8 @@ macro_rules! flushln { #[doc(hidden)] pub fn flush(s: String) { - let _ = ::std::io::stdout().write(s.as_bytes()); - let _ = ::std::io::stdout().flush(); + let _ = io::Write::write(&mut io::stdout(), s.as_bytes()); + let _ = io::Write::flush(&mut io::stdout()); } #[test] diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index cf21fbd9f..e882f3f18 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -16,6 +16,7 @@ //! Disk-backed `HashDB` implementation. +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index 7eb3f3259..de0e19d6e 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -16,6 +16,8 @@ //! Disk-backed `HashDB` implementation. +use std::fmt; +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/journaldb/mod.rs b/util/src/journaldb/mod.rs index 84a71339a..80ddbf7a1 100644 --- a/util/src/journaldb/mod.rs +++ b/util/src/journaldb/mod.rs @@ -16,6 +16,7 @@ //! `JournalDB` interface and implementation. +use std::{fmt, str}; use common::*; /// Export the journaldb module. @@ -59,7 +60,7 @@ impl Default for Algorithm { fn default() -> Algorithm { Algorithm::OverlayRecent } } -impl FromStr for Algorithm { +impl str::FromStr for Algorithm { type Err = String; fn from_str(s: &str) -> Result { diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 915e64d05..73a63bd4b 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -16,6 +16,7 @@ //! `JournalDB` over in-memory overlay +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index 4f8600bde..772281abd 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -16,6 +16,7 @@ //! Disk-backed, ref-counted `JournalDB` implementation. +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs index d1cf67218..6692064ed 100644 --- a/util/src/kvdb.rs +++ b/util/src/kvdb.rs @@ -16,6 +16,8 @@ //! Key-Value store abstraction with `RocksDB` backend. +use std::{mem, fs}; +use std::collections::{HashMap, BTreeMap}; use std::io::ErrorKind; use std::marker::PhantomData; use std::path::PathBuf; diff --git a/util/src/lib.rs b/util/src/lib.rs index c6a50f58b..c2d9c59d3 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -112,10 +112,6 @@ extern crate ethcore_logger; #[macro_use] extern crate log as rlog; -pub extern crate using_queue; -pub extern crate table; - -pub mod bloom; pub mod standard; #[macro_use] pub mod common; @@ -147,7 +143,6 @@ pub use overlaydb::*; pub use journaldb::JournalDB; pub use triehash::*; pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrieDB, SecTrieDBMut}; -pub use nibbleslice::*; pub use semantic_version::*; pub use kvdb::*; pub use timer::*; diff --git a/util/src/migration/tests.rs b/util/src/migration/tests.rs index 585bb5f36..7cd19009a 100644 --- a/util/src/migration/tests.rs +++ b/util/src/migration/tests.rs @@ -18,6 +18,7 @@ //! A random temp directory is created. A database is created within it, and migrations //! are performed in temp sub-directories. +use std::collections::BTreeMap; use common::*; use migration::{Batch, Config, Error, SimpleMigration, Migration, Manager}; use kvdb::Database; diff --git a/util/src/misc.rs b/util/src/misc.rs index 6dc2fba12..120805f0c 100644 --- a/util/src/misc.rs +++ b/util/src/misc.rs @@ -60,9 +60,9 @@ pub fn version() -> String { pub fn version_data() -> Bytes { let mut s = RlpStream::new_list(4); let v = - (u32::from_str(env!("CARGO_PKG_VERSION_MAJOR")).expect("Environment variables are known to be valid; qed") << 16) + - (u32::from_str(env!("CARGO_PKG_VERSION_MINOR")).expect("Environment variables are known to be valid; qed") << 8) + - u32::from_str(env!("CARGO_PKG_VERSION_PATCH")).expect("Environment variables are known to be valid; qed"); + (env!("CARGO_PKG_VERSION_MAJOR").parse::().expect("Environment variables are known to be valid; qed") << 16) + + (env!("CARGO_PKG_VERSION_MINOR").parse::().expect("Environment variables are known to be valid; qed") << 8) + + env!("CARGO_PKG_VERSION_PATCH").parse::().expect("Environment variables are known to be valid; qed"); s.append(&v); s.append(&"Parity"); s.append(&rustc_version()); diff --git a/util/src/nibblevec.rs b/util/src/nibblevec.rs index 718ff8e9e..b38198593 100644 --- a/util/src/nibblevec.rs +++ b/util/src/nibblevec.rs @@ -17,7 +17,7 @@ //! An owning, nibble-oriented byte vector. -use ::NibbleSlice; +use nibbleslice::NibbleSlice; use elastic_array::ElasticArray36; /// Owning, nibble-oriented byte vector. Counterpart to `NibbleSlice`. diff --git a/util/src/standard.rs b/util/src/standard.rs index 19521a5d5..cc67b0de5 100644 --- a/util/src/standard.rs +++ b/util/src/standard.rs @@ -16,28 +16,10 @@ //! Std lib global reexports. -pub use std::io; -pub use std::fs; -pub use std::str; -pub use std::fmt; -pub use std::cmp; -pub use std::ptr; -pub use std::mem; -pub use std::ops; -pub use std::slice; -pub use std::result; -pub use std::option; - pub use std::path::Path; -pub use std::str::{FromStr}; -pub use std::io::{Read,Write}; pub use std::hash::{Hash, Hasher}; -pub use std::error::Error as StdError; -pub use std::ops::*; -pub use std::cmp::*; pub use std::sync::Arc; -pub use std::collections::*; pub use heapsize::HeapSizeOf; pub use itertools::Itertools; diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index 5da304167..a8600914c 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::fmt; use common::*; use hashdb::*; use nibbleslice::*; From c4989ddc442df2d8a09a7a28057a640f8898894b Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 21:56:42 +0200 Subject: [PATCH 24/48] removed util::common --- dapps/src/api/time.rs | 5 ++-- ethcore/evm/src/ext.rs | 1 + ethcore/evm/src/interpreter/mod.rs | 1 + ethcore/evm/src/tests.rs | 2 ++ ethcore/src/blockchain/blockchain.rs | 1 + ethcore/src/client/test_client.rs | 1 + ethcore/src/engines/authority_round/mod.rs | 22 +++++++-------- ethcore/src/engines/basic_authority.rs | 3 ++- ethcore/src/engines/instant_seal.rs | 1 + ethcore/src/engines/mod.rs | 3 ++- ethcore/src/engines/signer.rs | 3 ++- ethcore/src/engines/tendermint/message.rs | 1 + ethcore/src/engines/tendermint/mod.rs | 2 +- ethcore/src/engines/validator_set/contract.rs | 1 + ethcore/src/engines/validator_set/multi.rs | 1 + .../engines/validator_set/safe_contract.rs | 3 ++- ethcore/src/engines/validator_set/test.rs | 3 ++- ethcore/src/engines/vote_collector.rs | 1 + ethcore/src/ethereum/ethash.rs | 2 ++ ethcore/src/executive.rs | 1 + ethcore/src/externalities.rs | 1 + ethcore/src/miner/miner.rs | 1 + ethcore/src/service.rs | 2 ++ ethcore/src/spec/spec.rs | 2 ++ ethcore/src/state/account.rs | 1 + ethcore/src/state/mod.rs | 1 + ethcore/src/state_db.rs | 3 ++- ethcore/src/tests/client.rs | 1 + ethcore/src/tests/evm.rs | 1 + ethcore/src/tests/helpers.rs | 1 + ethcore/src/verification/queue/mod.rs | 2 +- json/src/spec/authority_round.rs | 5 ++-- rpc/src/v1/tests/helpers/miner_service.rs | 3 +-- sync/src/tests/chain.rs | 2 +- sync/src/tests/consensus.rs | 1 + sync/src/tests/helpers.rs | 1 + sync/src/tests/snapshot.rs | 1 + util/network/src/tests.rs | 3 ++- util/src/common.rs | 11 ++------ util/src/error.rs | 2 +- util/src/journaldb/archivedb.rs | 6 +++-- util/src/journaldb/earlymergedb.rs | 9 +++++-- util/src/journaldb/mod.rs | 2 +- util/src/journaldb/overlayrecentdb.rs | 8 ++++-- util/src/journaldb/refcounteddb.rs | 6 +++-- util/src/journaldb/traits.rs | 3 ++- util/src/kvdb.rs | 7 +++-- util/src/lib.rs | 12 +++++++-- util/src/migration/tests.rs | 5 ++-- util/src/misc.rs | 2 +- util/src/standard.rs | 27 ------------------- util/src/trie/triedb.rs | 3 ++- 52 files changed, 109 insertions(+), 84 deletions(-) delete mode 100644 util/src/standard.rs diff --git a/dapps/src/api/time.rs b/dapps/src/api/time.rs index b81b4a844..3117f4cc9 100644 --- a/dapps/src/api/time.rs +++ b/dapps/src/api/time.rs @@ -33,13 +33,14 @@ use std::io; use std::{fmt, mem, time}; - +use std::sync::Arc; use std::collections::VecDeque; + use futures::{self, Future, BoxFuture}; use futures_cpupool::CpuPool; use ntp; use time::{Duration, Timespec}; -use util::{Arc, RwLock}; +use util::RwLock; /// Time checker error. #[derive(Debug, Clone, PartialEq)] diff --git a/ethcore/evm/src/ext.rs b/ethcore/evm/src/ext.rs index 1c3ddb317..2861b1ca5 100644 --- a/ethcore/evm/src/ext.rs +++ b/ethcore/evm/src/ext.rs @@ -16,6 +16,7 @@ //! Interface for Evm externalities. +use std::sync::Arc; use util::*; use call_type::CallType; use env_info::EnvInfo; diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 621febffd..36e652ab2 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -25,6 +25,7 @@ mod shared_cache; use std::marker::PhantomData; use std::{cmp, mem}; +use std::sync::Arc; use self::gasometer::Gasometer; use self::stack::{Stack, VecStack}; use self::memory::Memory; diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index c19a575f3..7679ab980 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -16,6 +16,8 @@ use std::fmt::Debug; use std::str::FromStr; +use std::hash::Hash; +use std::sync::Arc; use std::collections::{HashMap, HashSet}; use rustc_hex::FromHex; use util::*; diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 59b4fb7c3..bd0defa47 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -17,6 +17,7 @@ //! Blockchain database. use std::collections::{HashMap, HashSet}; +use std::sync::Arc; use std::mem; use bloomchain as bc; use util::*; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index e33888e72..aa49e6abc 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -17,6 +17,7 @@ //! Test client. use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; +use std::sync::Arc; use std::collections::{HashMap, BTreeMap}; use std::mem; use rustc_hex::FromHex; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index a72091e5e..d260c9ac8 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -17,7 +17,7 @@ //! A blockchain engine that supports a non-instant BFT proof-of-authority. use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, Duration}; use std::collections::{BTreeMap, HashSet, HashMap}; use std::cmp; @@ -853,8 +853,8 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { + use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; - use std::str::FromStr; use util::*; use header::Header; use error::{Error, BlockError}; @@ -944,10 +944,10 @@ mod tests { let addr = tap.insert_account("0".sha3().into(), "0").unwrap(); let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&0usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -970,10 +970,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&0usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -996,10 +996,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&4usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -1017,7 +1017,7 @@ mod tests { fn reports_skipped() { let last_benign = Arc::new(AtomicUsize::new(0)); let params = AuthorityRoundParams { - gas_limit_bound_divisor: U256::from_str("400").unwrap(), + gas_limit_bound_divisor: "400".parse::().unwrap(), step_duration: Default::default(), block_reward: Default::default(), registrar: Default::default(), @@ -1032,10 +1032,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&1usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_seal(vec![encode(&3usize).into_vec()]); // Do not report when signer not present. diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index a3f4b9114..38db41c53 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -16,7 +16,7 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::collections::BTreeMap; use std::cmp; use util::*; @@ -256,6 +256,7 @@ impl Engine for BasicAuthority { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use block::*; use error::{BlockError, Error}; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 4d297dc3f..94e3184ef 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -65,6 +65,7 @@ impl Engine for InstantSeal { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use tests::helpers::*; use spec::Spec; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 77b89e59c..b5a0d934f 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -35,7 +35,7 @@ pub use self::instant_seal::InstantSeal; pub use self::null_engine::NullEngine; pub use self::tendermint::Tendermint; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::collections::{BTreeMap, HashMap}; use std::fmt; @@ -395,6 +395,7 @@ pub trait Engine : Sync + Send { /// Common engine utilities pub mod common { + use std::sync::Arc; use block::ExecutedBlock; use evm::env_info::{EnvInfo, LastHashes}; use error::Error; diff --git a/ethcore/src/engines/signer.rs b/ethcore/src/engines/signer.rs index 4ec4318c9..4069488ab 100644 --- a/ethcore/src/engines/signer.rs +++ b/ethcore/src/engines/signer.rs @@ -16,7 +16,8 @@ //! A signer used by Engines which need to sign messages. -use util::{Arc, H256, Address}; +use std::sync::Arc; +use util::{H256, Address}; use ethkey::Signature; use account_provider::{self, AccountProvider}; diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index 623284839..68bdcb0f7 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -199,6 +199,7 @@ pub fn message_hash(vote_step: VoteStep, block_hash: H256) -> H256 { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use rlp::*; use account_provider::AccountProvider; diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 5d334a610..a340db5d4 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -25,7 +25,7 @@ mod message; mod params; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::collections::{HashSet, BTreeMap, HashMap}; use std::cmp; diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index e93d06a27..7c1890379 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -126,6 +126,7 @@ impl ValidatorSet for ValidatorContract { #[cfg(test)] mod tests { + use std::sync::Arc; use rustc_hex::FromHex; use util::*; use rlp::encode; diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 79a5a7d26..9acf6050b 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -142,6 +142,7 @@ impl ValidatorSet for Multi { #[cfg(test)] mod tests { + use std::sync::Arc; use std::collections::BTreeMap; use account_provider::AccountProvider; use client::{BlockChainClient, EngineClient}; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 172ec53b7..8148846e7 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -16,7 +16,7 @@ /// Validator set maintained in a contract, updated using `getValidators` method. -use std::sync::Weak; +use std::sync::{Weak, Arc}; use futures::Future; use native_contracts::ValidatorSet as Provider; @@ -422,6 +422,7 @@ impl ValidatorSet for ValidatorSafeContract { #[cfg(test)] mod tests { + use std::sync::Arc; use rustc_hex::FromHex; use util::*; use types::ids::BlockId; diff --git a/ethcore/src/engines/validator_set/test.rs b/ethcore/src/engines/validator_set/test.rs index 4960ee7be..25eeff66e 100644 --- a/ethcore/src/engines/validator_set/test.rs +++ b/ethcore/src/engines/validator_set/test.rs @@ -17,8 +17,9 @@ /// Used for Engine testing. use std::str::FromStr; +use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; -use util::{Arc, Bytes, H256, Address, HeapSizeOf}; +use util::{Bytes, H256, Address, HeapSizeOf}; use engines::{Call, Engine}; use header::{Header, BlockNumber}; diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index de9188e74..b934fdb2e 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -18,6 +18,7 @@ use std::fmt::Debug; use std::collections::{BTreeMap, HashSet, HashMap}; +use std::hash::Hash; use util::*; use rlp::{Encodable, RlpStream}; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 06a4ad0d8..0f984517c 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -17,6 +17,7 @@ use std::path::Path; use std::cmp; use std::collections::{BTreeMap, HashMap}; +use std::sync::Arc; use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; @@ -563,6 +564,7 @@ impl Header { mod tests { use std::str::FromStr; use std::collections::BTreeMap; + use std::sync::Arc; use util::*; use block::*; use tests::helpers::*; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9845d4575..a63605a81 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -16,6 +16,7 @@ //! Transaction Execution environment. use std::cmp; +use std::sync::Arc; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index d718fd256..5baca496d 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -16,6 +16,7 @@ //! Transaction Execution environment. use std::cmp; +use std::sync::Arc; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index cc5c8b6f3..241d90c32 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -16,6 +16,7 @@ use std::time::{Instant, Duration}; use std::collections::{BTreeMap, HashSet}; +use std::sync::Arc; use util::*; use using_queue::{UsingQueue, GetAction}; diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index e4c3d7519..5e65a4de8 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -16,6 +16,8 @@ //! Creates and registers client and network services. +use std::sync::Arc; +use std::path::Path; use util::*; use io::*; use spec::Spec; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index c4afc93d7..a5426faa8 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -18,6 +18,8 @@ use std::io::Read; use std::collections::BTreeMap; +use std::path::Path; +use std::sync::Arc; use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 8f528b9d8..1235fd289 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -17,6 +17,7 @@ //! Single account in the system. use std::fmt; +use std::sync::Arc; use std::collections::HashMap; use util::*; use pod_account::*; diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 25c019dc0..1dd6204c3 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -23,6 +23,7 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; use std::collections::{HashMap, BTreeMap, HashSet}; use std::fmt; +use std::sync::Arc; use receipt::Receipt; use engines::Engine; diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index de5a3f75b..e2f6fdaf0 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::{VecDeque, HashSet}; +use std::sync::Arc; use lru_cache::LruCache; use util::cache::MemoryLruCache; use util::journaldb::JournalDB; @@ -23,7 +24,7 @@ use util::hash::{H256}; use util::hashdb::HashDB; use state::{self, Account}; use header::BlockNumber; -use util::{Arc, Address, DBTransaction, UtilError, Mutex, Hashable}; +use util::{Address, DBTransaction, UtilError, Mutex, Hashable}; use bloom_journal::{Bloom, BloomJournal}; use db::COL_ACCOUNT_BLOOM; use byteorder::{LittleEndian, ByteOrder}; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 54256b285..639fce3ab 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::str::FromStr; +use std::sync::Arc; use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockId}; use state::{self, State, CleanupMode}; diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs index c97fd4ac0..50cf4deb7 100644 --- a/ethcore/src/tests/evm.rs +++ b/ethcore/src/tests/evm.rs @@ -1,5 +1,6 @@ //! Tests of EVM integration with transaction execution. +use std::sync::Arc; use evm::action_params::{ActionParams, ActionValue}; use evm::env_info::EnvInfo; use evm::{Factory, VMType}; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 2c50f0fc2..2d48e470b 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::BTreeMap; +use std::sync::Arc; use ethkey::KeyPair; use io::*; use client::{BlockChainClient, Client, ClientConfig}; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 192a0dc77..ce0cb4179 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -19,7 +19,7 @@ use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; -use std::sync::{Condvar as SCondvar, Mutex as SMutex}; +use std::sync::{Condvar as SCondvar, Mutex as SMutex, Arc}; use std::cmp; use std::collections::{VecDeque, HashSet, HashMap}; use util::*; diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 0fdbfbfb3..91a5fd828 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -63,11 +63,10 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { + use util::{H160, U256}; use uint::Uint; - use util::U256; - use util::H160; - use serde_json; use hash::Address; + use serde_json; use spec::validator_set::ValidatorSet; use spec::authority_round::AuthorityRound; diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index ecc453622..ef9b5724b 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -18,8 +18,7 @@ use std::collections::{BTreeMap, HashMap}; use std::collections::hash_map::Entry; -use util::{Address, H256, Bytes, U256}; -use util::standard::*; +use util::{Address, H256, Bytes, U256, RwLock, Mutex}; use ethcore::error::{Error, CallError}; use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics}; use ethcore::block::{ClosedBlock, IsBlock}; diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index 23ed4b7ea..f9ce17b5b 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use util::*; +use std::sync::Arc; use ethcore::client::{TestBlockChainClient, BlockChainClient, BlockId, EachBlockWith}; use chain::{SyncState}; use super::helpers::*; diff --git a/sync/src/tests/consensus.rs b/sync/src/tests/consensus.rs index 6b91b11c6..499b7de17 100644 --- a/sync/src/tests/consensus.rs +++ b/sync/src/tests/consensus.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; use util::*; use io::{IoHandler, IoContext, IoChannel}; use ethcore::client::{BlockChainClient, Client}; diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index fa3039b63..3ac68b0fb 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::{VecDeque, HashSet, HashMap}; +use std::sync::Arc; use util::*; use network::*; use tests::snapshot::*; diff --git a/sync/src/tests/snapshot.rs b/sync/src/tests/snapshot.rs index 0a3b31fb0..9303aa9f7 100644 --- a/sync/src/tests/snapshot.rs +++ b/sync/src/tests/snapshot.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::HashMap; +use std::sync::Arc; use util::*; use ethcore::snapshot::{SnapshotService, ManifestData, RestorationStatus}; use ethcore::header::BlockNumber; diff --git a/util/network/src/tests.rs b/util/network/src/tests.rs index 52184061c..81325f57b 100644 --- a/util/network/src/tests.rs +++ b/util/network/src/tests.rs @@ -16,9 +16,10 @@ use super::*; use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; +use std::sync::Arc; use std::thread; use std::time::*; -use util::common::*; +use util::{Bytes, Mutex}; use io::TimerToken; use ethkey::{Random, Generator}; diff --git a/util/src/common.rs b/util/src/common.rs index 89ce9d95f..4bf3a06ed 100644 --- a/util/src/common.rs +++ b/util/src/common.rs @@ -17,13 +17,6 @@ //! Utils common types and macros global reexport. use std::io; -pub use standard::*; -pub use error::*; -pub use bytes::*; -pub use vector::*; -pub use sha3::*; -pub use bigint::prelude::*; -pub use bigint::hash; #[macro_export] macro_rules! vec_into { @@ -89,8 +82,8 @@ macro_rules! map_into { #[macro_export] macro_rules! flush { - ($arg:expr) => ($crate::flush($arg.into())); - ($($arg:tt)*) => ($crate::flush(format!("{}", format_args!($($arg)*)))); + ($arg:expr) => ($crate::common::flush($arg.into())); + ($($arg:tt)*) => ($crate::common::flush(format!("{}", format_args!($($arg)*)))); } #[macro_export] diff --git a/util/src/error.rs b/util/src/error.rs index 4ed2fc9bd..b0e887434 100644 --- a/util/src/error.rs +++ b/util/src/error.rs @@ -19,7 +19,7 @@ use rustc_hex::FromHexError; use rlp::DecoderError; use std::fmt; -use hash::H256; +use bigint::hash::H256; #[derive(Debug)] /// Error in database subsystem. diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index e882f3f18..fc893654a 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -17,13 +17,14 @@ //! Disk-backed `HashDB` implementation. use std::collections::HashMap; -use common::*; +use std::sync::Arc; use rlp::*; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; +use {Bytes, H256, BaseDataError, UtilError}; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. @@ -197,11 +198,12 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; + use std::path::Path; use hashdb::{HashDB, DBValue}; use super::*; use journaldb::traits::JournalDB; use kvdb::Database; + use {Hashable, H32}; #[test] fn insert_same_in_fork() { diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index de0e19d6e..5f409d327 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -18,13 +18,17 @@ use std::fmt; use std::collections::HashMap; -use common::*; +use std::sync::Arc; +use parking_lot::RwLock; +use heapsize::HeapSizeOf; +use itertools::Itertools; use rlp::*; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; +use {H256, BaseDataError, UtilError, Bytes}; #[derive(Clone, PartialEq, Eq)] struct RefInfo { @@ -551,12 +555,13 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; + use std::path::Path; use hashdb::{HashDB, DBValue}; use super::*; use super::super::traits::JournalDB; use ethcore_logger::init_log; use kvdb::{DatabaseConfig}; + use {Hashable, H32}; #[test] fn insert_same_in_fork() { diff --git a/util/src/journaldb/mod.rs b/util/src/journaldb/mod.rs index 80ddbf7a1..4f0f2fb1b 100644 --- a/util/src/journaldb/mod.rs +++ b/util/src/journaldb/mod.rs @@ -17,7 +17,7 @@ //! `JournalDB` interface and implementation. use std::{fmt, str}; -use common::*; +use std::sync::Arc; /// Export the journaldb module. pub mod traits; diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 73a63bd4b..e96430e06 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -17,13 +17,16 @@ //! `JournalDB` over in-memory overlay use std::collections::HashMap; -use common::*; +use std::sync::Arc; +use parking_lot::RwLock; +use heapsize::HeapSizeOf; use rlp::*; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use kvdb::{KeyValueDB, DBTransaction}; use super::JournalDB; +use {H256, BaseDataError, UtilError, Bytes, H256FastMap}; /// Implementation of the `JournalDB` trait for a disk-backed database with a memory overlay /// and, possibly, latent-removal semantics. @@ -451,12 +454,13 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; + use std::path::Path; use super::*; use hashdb::{HashDB, DBValue}; use ethcore_logger::init_log; use journaldb::JournalDB; use kvdb::Database; + use {H32, Hashable}; fn new_db(path: &Path) -> OverlayRecentDB { let backing = Arc::new(Database::open_default(path.to_str().unwrap()).unwrap()); diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index 772281abd..e38994700 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -17,7 +17,8 @@ //! Disk-backed, ref-counted `JournalDB` implementation. use std::collections::HashMap; -use common::*; +use std::sync::Arc; +use heapsize::HeapSizeOf; use rlp::*; use hashdb::*; use overlaydb::OverlayDB; @@ -25,6 +26,7 @@ use memorydb::MemoryDB; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; +use {UtilError, H256, Bytes}; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. @@ -211,10 +213,10 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; use hashdb::{HashDB, DBValue}; use super::*; use super::super::traits::JournalDB; + use {Hashable}; #[test] fn long_history() { diff --git a/util/src/journaldb/traits.rs b/util/src/journaldb/traits.rs index 8a89f1368..1f14e9765 100644 --- a/util/src/journaldb/traits.rs +++ b/util/src/journaldb/traits.rs @@ -16,9 +16,10 @@ //! Disk-backed `HashDB` implementation. -use common::*; +use std::sync::Arc; use hashdb::*; use kvdb::{self, DBTransaction}; +use {Bytes, H256, UtilError}; /// A `HashDB` which can manage a short-term journal potentially containing many forks of mutually /// exclusive actions. diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs index 6692064ed..c231e682d 100644 --- a/util/src/kvdb.rs +++ b/util/src/kvdb.rs @@ -20,14 +20,17 @@ use std::{mem, fs}; use std::collections::{HashMap, BTreeMap}; use std::io::ErrorKind; use std::marker::PhantomData; -use std::path::PathBuf; +use std::path::{PathBuf, Path}; +use parking_lot::{Mutex, MutexGuard, RwLock}; -use common::*; use elastic_array::*; use hashdb::DBValue; use rlp::{UntrustedRlp, RlpType, Compressible}; use rocksdb::{DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBIterator, Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache, Column, ReadOptions}; +use {UtilError, Bytes}; + + #[cfg(target_os = "linux")] use regex::Regex; #[cfg(target_os = "linux")] diff --git a/util/src/lib.rs b/util/src/lib.rs index c2d9c59d3..544f60d39 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -112,7 +112,6 @@ extern crate ethcore_logger; #[macro_use] extern crate log as rlog; -pub mod standard; #[macro_use] pub mod common; pub mod error; @@ -135,7 +134,6 @@ pub mod snappy; pub mod cache; mod timer; -pub use common::*; pub use misc::*; pub use hashdb::*; pub use memorydb::MemoryDB; @@ -146,7 +144,17 @@ pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrie pub use semantic_version::*; pub use kvdb::*; pub use timer::*; +pub use error::*; +pub use bytes::*; +pub use vector::*; +pub use sha3::*; +pub use bigint::prelude::*; +pub use bigint::hash; + pub use ansi_term::{Colour, Style}; +pub use heapsize::HeapSizeOf; +pub use itertools::Itertools; +pub use parking_lot::{Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; /// 160-bit integer representing account address pub type Address = H160; diff --git a/util/src/migration/tests.rs b/util/src/migration/tests.rs index 7cd19009a..64f2d976a 100644 --- a/util/src/migration/tests.rs +++ b/util/src/migration/tests.rs @@ -19,12 +19,11 @@ //! are performed in temp sub-directories. use std::collections::BTreeMap; -use common::*; +use std::sync::Arc; +use std::path::{Path, PathBuf}; use migration::{Batch, Config, Error, SimpleMigration, Migration, Manager}; use kvdb::Database; - use devtools::RandomTempPath; -use std::path::PathBuf; fn db_path(path: &Path) -> PathBuf { let mut p = path.to_owned(); diff --git a/util/src/misc.rs b/util/src/misc.rs index 120805f0c..e33b5e857 100644 --- a/util/src/misc.rs +++ b/util/src/misc.rs @@ -16,9 +16,9 @@ //! Diff misc. -use common::*; use rlp::RlpStream; use target_info::Target; +use Bytes; include!(concat!(env!("OUT_DIR"), "/version.rs")); include!(concat!(env!("OUT_DIR"), "/rustc_version.rs")); diff --git a/util/src/standard.rs b/util/src/standard.rs deleted file mode 100644 index cc67b0de5..000000000 --- a/util/src/standard.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Std lib global reexports. - -pub use std::path::Path; -pub use std::hash::{Hash, Hasher}; - -pub use std::sync::Arc; - -pub use heapsize::HeapSizeOf; -pub use itertools::Itertools; - -pub use parking_lot::{Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index a8600914c..262a874ea 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -15,13 +15,14 @@ // along with Parity. If not, see . use std::fmt; -use common::*; +use itertools::Itertools; use hashdb::*; use nibbleslice::*; use rlp::*; use super::node::{Node, OwnedNode}; use super::lookup::Lookup; use super::{Trie, TrieItem, TrieError, TrieIterator, Query}; +use {ToPretty, Bytes, H256}; /// A `Trie` implementation using a generic `HashDB` backing database. /// From 2b02651bbfef634c157d06534d3de80d3c93c9c4 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 22:53:52 +0200 Subject: [PATCH 25/48] alway test --all (temporary exclude ipfs and evmjit) --- scripts/cov.sh | 3 +-- scripts/doc.sh | 4 +--- scripts/hook.sh | 4 +--- scripts/targets.sh | 22 ---------------------- test.sh | 3 +-- 5 files changed, 4 insertions(+), 32 deletions(-) delete mode 100755 scripts/targets.sh diff --git a/scripts/cov.sh b/scripts/cov.sh index eae6a4f72..8d618e2c3 100755 --- a/scripts/cov.sh +++ b/scripts/cov.sh @@ -20,8 +20,7 @@ if ! type $KCOV > /dev/null; then exit 1 fi -. ./scripts/targets.sh -RUSTFLAGS="-C link-dead-code" cargo test $TARGETS --no-run || exit $? +RUSTFLAGS="-C link-dead-code" cargo test --all --exclude ipfs --exclude evmjit --no-run || exit $? KCOV_TARGET="target/cov" diff --git a/scripts/doc.sh b/scripts/doc.sh index 657f47567..8174ed5d6 100755 --- a/scripts/doc.sh +++ b/scripts/doc.sh @@ -1,7 +1,5 @@ #!/bin/sh # generate documentation only for partiy and ethcore libraries -. ./scripts/targets.sh - -cargo doc --no-deps --verbose $TARGETS && +cargo doc --no-deps --verbose --all --exclude ipfs --exclude evmjit && echo '' > target/doc/index.html diff --git a/scripts/hook.sh b/scripts/hook.sh index 9b5512ac0..c8977aacf 100755 --- a/scripts/hook.sh +++ b/scripts/hook.sh @@ -1,6 +1,5 @@ #!/bin/sh FILE=./.git/hooks/pre-push -. ./scripts/targets.sh echo "#!/bin/sh\n" > $FILE # Exit on any error @@ -8,7 +7,6 @@ echo "set -e" >> $FILE # Run release build echo "cargo build --features dev" >> $FILE # Build tests -echo "cargo test --no-run --features dev \\" >> $FILE -echo $TARGETS >> $FILE +echo "cargo test --no-run --features dev --all --exclude ipfs --exclude evmjit" >> $FILE echo "" >> $FILE chmod +x $FILE diff --git a/scripts/targets.sh b/scripts/targets.sh deleted file mode 100755 index fb10c43f2..000000000 --- a/scripts/targets.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -export TARGETS=" - -p rlp\ - -p ethash \ - -p ethcore \ - -p ethcore-bigint\ - -p parity-dapps \ - -p parity-rpc \ - -p parity-rpc-client \ - -p rpc-cli \ - -p ethcore-util \ - -p ethcore-network \ - -p ethcore-io \ - -p ethkey \ - -p ethstore \ - -p ethsync \ - -p ethcore-ipc \ - -p ethcore-ipc-tests \ - -p ethcore-ipc-nano \ - -p ethcore-light \ - -p parity" diff --git a/test.sh b/test.sh index 2d0cc2e5f..6eb447970 100755 --- a/test.sh +++ b/test.sh @@ -22,5 +22,4 @@ case $1 in ;; esac -. ./scripts/targets.sh -cargo test -j 8 $OPTIONS --features "$FEATURES" $TARGETS $1 \ +cargo test -j 8 $OPTIONS --features "$FEATURES" --all --exclude ipfs --exclude evmjit $1 \ From 48f28fe29c180a8fe634bd0695650f0b9dc90fe9 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 23:19:33 +0200 Subject: [PATCH 26/48] fixed json_tests --- ethcore/src/json_tests/chain.rs | 2 +- ethcore/src/json_tests/executive.rs | 1 + ethcore/src/json_tests/test_common.rs | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index ccdd7d499..7047c9882 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use super::test_common::*; +use std::sync::Arc; use client::{BlockChainClient, Client, ClientConfig}; use block::Block; use ethereum; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 0c5a6a90d..495ff3cdb 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; use super::test_common::*; use evm::action_params::ActionParams; use state::{Backend as StateBackend, State, Substate}; diff --git a/ethcore/src/json_tests/test_common.rs b/ethcore/src/json_tests/test_common.rs index f9716d221..fa1078776 100644 --- a/ethcore/src/json_tests/test_common.rs +++ b/ethcore/src/json_tests/test_common.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . pub use util::*; +use std::collections::HashSet; +use std::io::Read; use std::fs::{File, read_dir}; use std::path::Path; use std::ffi::OsString; From 32fafd7a24ad3f0e38b469c11358385517fb6477 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Mon, 31 Jul 2017 10:58:49 +0200 Subject: [PATCH 27/48] CI fix: Interface shh subscribe params --- js/src/jsonrpc/interfaces/shh.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/src/jsonrpc/interfaces/shh.js b/js/src/jsonrpc/interfaces/shh.js index 87af117fe..7084aa3bf 100644 --- a/js/src/jsonrpc/interfaces/shh.js +++ b/js/src/jsonrpc/interfaces/shh.js @@ -268,7 +268,10 @@ export default { }, subscribe: { desc: 'Open a subscription to a filter.', - params: 'See [shh_newMessageFilter](#shh_newmessagefilter)', + params: [{ + type: Data, + desc: 'See [shh_newMessageFilter](#shh_newmessagefilter)' + }], returns: { type: Quantity, desc: 'Unique subscription identifier' From 003eef982bf1194ee4096f5ce5eee5545529819c Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 31 Jul 2017 12:34:29 +0200 Subject: [PATCH 28/48] Move more params to the common section. (#6134) * move common forks and parameters to common params * port specs over to new format * fix RPC tests --- Cargo.lock | 2 +- ethcore/res/authority_round.json | 2 +- ethcore/res/basic_authority.json | 2 +- ethcore/res/constructor.json | 2 + ethcore/res/ethereum/classic.json | 9 ++-- ethcore/res/ethereum/eip150_test.json | 10 ++-- ethcore/res/ethereum/eip161_test.json | 10 ++-- ethcore/res/ethereum/expanse.json | 10 ++-- ethcore/res/ethereum/foundation.json | 9 ++-- ethcore/res/ethereum/frontier_like_test.json | 10 ++-- ethcore/res/ethereum/frontier_test.json | 10 ++-- ethcore/res/ethereum/homestead_test.json | 10 ++-- ethcore/res/ethereum/kovan.json | 12 ++--- ethcore/res/ethereum/metropolis_test.json | 11 ++-- ethcore/res/ethereum/morden.json | 9 ++-- ethcore/res/ethereum/olympic.json | 10 ++-- ethcore/res/ethereum/ropsten.json | 9 ++-- ethcore/res/ethereum/transition_test.json | 10 ++-- ethcore/res/instant_seal.json | 7 +-- ethcore/res/null.json | 1 + ethcore/res/null_morden.json | 1 + ethcore/res/tendermint.json | 2 +- ethcore/res/validator_contract.json | 2 +- ethcore/res/validator_multi.json | 2 +- ethcore/res/validator_safe_contract.json | 1 + ethcore/src/engines/authority_round/mod.rs | 44 +++++---------- ethcore/src/engines/basic_authority.rs | 9 +--- ethcore/src/engines/instant_seal.rs | 6 +-- ethcore/src/engines/tendermint/mod.rs | 17 +++--- ethcore/src/engines/tendermint/params.rs | 10 ---- ethcore/src/ethereum/ethash.rs | 54 +++++++------------ ethcore/src/miner/miner.rs | 12 ++++- .../tests/test_validator_contract.json | 2 +- ethcore/src/spec/spec.rs | 36 +++++++++++-- ethcore/src/tests/helpers.rs | 6 +-- json/Cargo.toml | 2 +- json/src/hash.rs | 4 +- json/src/lib.rs | 2 +- json/src/maybe.rs | 2 +- json/src/spec/account.rs | 2 +- json/src/spec/authority_round.rs | 22 +------- json/src/spec/basic_authority.rs | 8 +-- json/src/spec/engine.rs | 18 ++----- json/src/spec/ethash.rs | 37 ++----------- json/src/spec/genesis.rs | 4 +- json/src/spec/instant_seal.rs | 53 ------------------ json/src/spec/mod.rs | 2 - json/src/spec/params.rs | 17 +++++- json/src/spec/seal.rs | 3 +- json/src/spec/spec.rs | 6 +-- json/src/spec/tendermint.rs | 20 +------ json/src/spec/validator_set.rs | 3 +- json/src/uint.rs | 4 +- json/src/vm/call.rs | 2 +- rpc/src/v1/tests/eth.rs | 12 ++--- 55 files changed, 224 insertions(+), 358 deletions(-) delete mode 100644 json/src/spec/instant_seal.rs diff --git a/Cargo.lock b/Cargo.lock index 52d0434a5..4b787a656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -777,7 +777,7 @@ name = "ethjson" version = "0.1.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.8.0", + "ethcore-bigint 0.1.3", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/res/authority_round.json b/ethcore/res/authority_round.json index d8014ff25..a56618d1c 100644 --- a/ethcore/res/authority_round.json +++ b/ethcore/res/authority_round.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 2, "validators": { @@ -17,6 +16,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/basic_authority.json b/ethcore/res/basic_authority.json index 6b9f4c0ed..192b48cad 100644 --- a/ethcore/res/basic_authority.json +++ b/ethcore/res/basic_authority.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "list": ["0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6"] @@ -12,6 +11,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0100000", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/constructor.json b/ethcore/res/constructor.json index 0be5b3be4..2932ce164 100644 --- a/ethcore/res/constructor.json +++ b/ethcore/res/constructor.json @@ -4,12 +4,14 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2" }, "genesis": { + "gasLimitBoundDivisor": "0x0400", "seal": { "generic": "0x" }, diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 6edfef460..bfd64248e 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": 1150000, "eip150Transition": 2500000, - "eip155Transition": 3000000, "eip160Transition": 3000000, "ecip1010PauseTransition": 3000000, "ecip1010ContinueTransition": 5000000, @@ -24,6 +20,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -31,6 +30,8 @@ "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", + "eip155Transition": 3000000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/eip150_test.json b/ethcore/res/ethereum/eip150_test.json index 3091ee27b..22ebf5500 100644 --- a/ethcore/res/ethereum/eip150_test.json +++ b/ethcore/res/ethereum/eip150_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff", @@ -20,12 +16,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffffff", - "eip86Transition": "0x7fffffffffffffff" + "eip86Transition": "0x7fffffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/eip161_test.json b/ethcore/res/ethereum/eip161_test.json index e6e8bf3bb..50d28570b 100644 --- a/ethcore/res/ethereum/eip161_test.json +++ b/ethcore/res/ethereum/eip161_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x0", "eip161abcTransition": "0x0", "eip161dTransition": "0x0", @@ -20,12 +16,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffffff", - "eip86Transition": "0x7fffffffffffffff" + "eip86Transition": "0x7fffffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json index b7d22ac3e..d79ab6b3c 100644 --- a/ethcore/res/ethereum/expanse.json +++ b/ethcore/res/ethereum/expanse.json @@ -4,19 +4,15 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "difficultyIncrementDivisor": "60", "durationLimit": "0x3C", - "blockReward": "0x6f05b59d3b200000", - "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", "homesteadTransition": "0x30d40", "difficultyHardforkTransition": "0x59d9", "difficultyHardforkBoundDivisor": "0x0200", "bombDefuseTransition": "0x30d40", "eip150Transition": "0x927C0", - "eip155Transition": "0x927C0", "eip160Transition": "0x927C0", "eip161abcTransition": "0x927C0", "eip161dTransition": "0x927C0" @@ -24,6 +20,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x6f05b59d3b200000", + "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -31,7 +30,8 @@ "chainID": "0x2", "subprotocolName": "exp", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x927C0" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index a77b39934..b30453082 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -4,12 +4,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142", "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -132,7 +129,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0x259518", - "eip155Transition": 2675000, "eip160Transition": 2675000, "eip161abcTransition": 2675000, "eip161dTransition": 2675000, @@ -141,12 +137,17 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "forkBlock": "0x1d4c00", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", + "eip155Transition": 2675000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index fde04f6b5..0f4b8850f 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -3,12 +3,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -131,7 +128,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -139,12 +135,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 6761c79f3..802a77f8d 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index 25b061857..557a48a64 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 7cdb79e16..ca7638e33 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -4,10 +4,7 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x400", - "registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3", "stepDuration": "4", - "blockReward": "0x4563918244F40000", "validators" : { "list": [ "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", @@ -25,16 +22,19 @@ ] }, "validateScoreTransition": 1000000, - "eip155Transition": 1000000, "validateStepTransition": 1500000 } } }, "params": { - "maximumExtraDataSize": "0x20", + "gasLimitBoundDivisor": "0x400", + "registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3", + "blockReward": "0x4563918244F40000", + "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2A", - "validateReceiptsTransition" : 1000000 + "validateReceiptsTransition" : 1000000, + "eip155Transition": 1000000 }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/metropolis_test.json b/ethcore/res/ethereum/metropolis_test.json index 76189e731..a452e5a80 100644 --- a/ethcore/res/ethereum/metropolis_test.json +++ b/ethcore/res/ethereum/metropolis_test.json @@ -3,15 +3,12 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x0", "eip160Transition": "0x0", "eip161abcTransition": "0x0", "eip161dTransition": "0x0", @@ -20,6 +17,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -27,7 +27,8 @@ "eip98Transition": "0x0", "eip86Transition": "0x0", "eip140Transition": "0x0", - "eip210Transition": "0x0" + "eip210Transition": "0x0", + "eip155Transition": "0x0" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 495849daf..f316fdf5f 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "homesteadTransition": 494000, "eip150Transition": 1783000, - "eip155Transition": 1915000, "eip160Transition": 1915000, "ecip1010PauseTransition": 1915000, "ecip1010ContinueTransition": 3415000, @@ -23,6 +19,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "accountStartNonce": "0x0100000", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -30,6 +29,8 @@ "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", + "eip155Transition": 1915000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 3d2e7baf9..c73dcb815 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x08", - "blockReward": "0x14D1120D7B160000", - "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", "homesteadTransition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x14D1120D7B160000", + "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x0400", "minGasLimit": "125000", "networkID" : "0x0", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 1e350d636..1706c433b 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2", "homesteadTransition": 0, "eip150Transition": 0, - "eip155Transition": 10, "eip160Transition": 10, "eip161abcTransition": 10, "eip161dTransition": 10, @@ -21,12 +17,17 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x3", "forkBlock": 641350, "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", + "eip155Transition": 10, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/transition_test.json b/ethcore/res/ethereum/transition_test.json index 7709ba015..409210a76 100644 --- a/ethcore/res/ethereum/transition_test.json +++ b/ethcore/res/ethereum/transition_test.json @@ -3,12 +3,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x5", "daoHardforkTransition": "0x8", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -131,7 +128,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0xa", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -139,12 +135,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index c791b9a2d..f59feb0bd 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -1,13 +1,10 @@ { "name": "DevelopmentChain", "engine": { - "instantSeal": { - "params": { - "registrar": "0x0000000000000000000000000000000000000005" - } - } + "instantSeal": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/null.json b/ethcore/res/null.json index ffb0ea061..97ce1afc5 100644 --- a/ethcore/res/null.json +++ b/ethcore/res/null.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/null_morden.json b/ethcore/res/null_morden.json index 96d804b5b..b615cdc29 100644 --- a/ethcore/res/null_morden.json +++ b/ethcore/res/null_morden.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/tendermint.json b/ethcore/res/tendermint.json index 642f5b385..e7fa69ea0 100644 --- a/ethcore/res/tendermint.json +++ b/ethcore/res/tendermint.json @@ -3,7 +3,6 @@ "engine": { "tendermint": { "params": { - "gasLimitBoundDivisor": "0x0400", "validators" : { "list": [ "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1", @@ -18,6 +17,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_contract.json b/ethcore/res/validator_contract.json index 3faec7665..9d007ac23 100644 --- a/ethcore/res/validator_contract.json +++ b/ethcore/res/validator_contract.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 2, "validators": { @@ -14,6 +13,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_multi.json b/ethcore/res/validator_multi.json index 5d51b73da..9eba2d5ba 100644 --- a/ethcore/res/validator_multi.json +++ b/ethcore/res/validator_multi.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "multi": { @@ -15,6 +14,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_safe_contract.json b/ethcore/res/validator_safe_contract.json index 3f5241c96..7845c898d 100644 --- a/ethcore/res/validator_safe_contract.json +++ b/ethcore/res/validator_safe_contract.json @@ -12,6 +12,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 3210368db..ebe7cacea 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -47,22 +47,14 @@ mod finality; /// `AuthorityRound` params. pub struct AuthorityRoundParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Time to wait before next block or authority switching. pub step_duration: Duration, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, /// Starting step, pub start_step: Option, /// Valid validators. pub validators: Box, /// Chain score validation transition block. pub validate_score_transition: u64, - /// Number of first block where EIP-155 rules are validated. - pub eip155_transition: u64, /// Monotonic step validation transition block. pub validate_step_transition: u64, /// Immediate transitions. @@ -72,14 +64,10 @@ pub struct AuthorityRoundParams { impl From for AuthorityRoundParams { fn from(p: ethjson::spec::AuthorityRoundParams) -> Self { AuthorityRoundParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), step_duration: Duration::from_secs(p.step_duration.into()), validators: new_validator_set(p.validators), - block_reward: p.block_reward.map_or_else(U256::zero, Into::into), - registrar: p.registrar.map_or_else(Address::new, Into::into), start_step: p.start_step.map(Into::into), validate_score_transition: p.validate_score_transition.map_or(0, Into::into), - eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_step_transition: p.validate_step_transition.map_or(0, Into::into), immediate_transitions: p.immediate_transitions.unwrap_or(false), } @@ -214,9 +202,6 @@ impl EpochManager { /// Engine using `AuthorityRound` proof-of-authority BFT consensus. pub struct AuthorityRound { params: CommonParams, - gas_limit_bound_divisor: U256, - block_reward: U256, - registrar: Address, builtins: BTreeMap, transition_service: IoService<()>, step: Arc, @@ -225,7 +210,6 @@ pub struct AuthorityRound { signer: RwLock, validators: Box, validate_score_transition: u64, - eip155_transition: u64, validate_step_transition: u64, epoch_manager: Mutex, immediate_transitions: bool, @@ -362,9 +346,6 @@ impl AuthorityRound { let engine = Arc::new( AuthorityRound { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, - block_reward: our_params.block_reward, - registrar: our_params.registrar, builtins: builtins, transition_service: IoService::<()>::start()?, step: Arc::new(Step { @@ -377,7 +358,6 @@ impl AuthorityRound { signer: Default::default(), validators: our_params.validators, validate_score_transition: our_params.validate_score_transition, - eip155_transition: our_params.eip155_transition, validate_step_transition: our_params.validate_step_transition, epoch_manager: Mutex::new(EpochManager::blank()), immediate_transitions: our_params.immediate_transitions, @@ -433,7 +413,9 @@ impl Engine for AuthorityRound { fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.registrar.hex()] } + fn additional_params(&self) -> HashMap { + hash_map!["registrar".to_owned() => self.params().registrar.hex()] + } fn builtins(&self) -> &BTreeMap { &self.builtins } @@ -461,7 +443,7 @@ impl Engine for AuthorityRound { header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { @@ -564,7 +546,8 @@ impl Engine for AuthorityRound { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { let fields = block.fields_mut(); // Bestow block reward - let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) + let reward = self.params().block_reward; + let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty) .map_err(::error::Error::from) .and_then(|_| fields.state.commit()); // Commit state so that we can actually figure out the state root. @@ -629,7 +612,7 @@ impl Engine for AuthorityRound { } } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { @@ -819,7 +802,7 @@ impl Engine for AuthorityRound { t.check_low_s()?; if let Some(n) = t.network_id() { - if header.number() >= self.eip155_transition && n != self.params().chain_id { + if header.number() >= self.params().eip155_transition && n != self.params().chain_id { return Err(TransactionError::InvalidNetworkId.into()); } } @@ -1014,18 +997,19 @@ mod tests { fn reports_skipped() { let last_benign = Arc::new(AtomicUsize::new(0)); let params = AuthorityRoundParams { - gas_limit_bound_divisor: U256::from_str("400").unwrap(), step_duration: Default::default(), - block_reward: Default::default(), - registrar: Default::default(), start_step: Some(1), validators: Box::new(TestSet::new(Default::default(), last_benign.clone())), validate_score_transition: 0, validate_step_transition: 0, - eip155_transition: 0, immediate_transitions: true, }; - let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap(); + + let aura = { + let mut c_params = ::spec::CommonParams::default(); + c_params.gas_limit_bound_divisor = 5.into(); + AuthorityRound::new(c_params, params, Default::default()).unwrap() + }; let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&1usize).into_vec()]); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 68759131d..360a32ddd 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -35,8 +35,6 @@ use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `BasicAuthority` params. #[derive(Debug, PartialEq)] pub struct BasicAuthorityParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Valid signatories. pub validators: ethjson::spec::ValidatorSet, } @@ -44,7 +42,6 @@ pub struct BasicAuthorityParams { impl From for BasicAuthorityParams { fn from(p: ethjson::spec::BasicAuthorityParams) -> Self { BasicAuthorityParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), validators: p.validators, } } @@ -80,7 +77,6 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err /// Engine using `BasicAuthority`, trivial proof-of-authority consensus. pub struct BasicAuthority { params: CommonParams, - gas_limit_bound_divisor: U256, builtins: BTreeMap, signer: RwLock, validators: Box, @@ -91,7 +87,6 @@ impl BasicAuthority { pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap) -> Self { BasicAuthority { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, validators: new_validator_set(our_params.validators), signer: Default::default(), @@ -119,7 +114,7 @@ impl Engine for BasicAuthority { header.set_difficulty(parent.difficulty().clone()); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { @@ -172,7 +167,7 @@ impl Engine for BasicAuthority { if header.difficulty() != parent.difficulty() { return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() }))) } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 38834622c..6e9988521 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -24,16 +24,14 @@ use block::ExecutedBlock; /// An engine which does not provide any consensus mechanism, just seals blocks internally. pub struct InstantSeal { params: CommonParams, - registrar: Address, builtins: BTreeMap, } impl InstantSeal { /// Returns new instance of InstantSeal with default VM Factory - pub fn new(params: CommonParams, registrar: Address, builtins: BTreeMap) -> Self { + pub fn new(params: CommonParams, builtins: BTreeMap) -> Self { InstantSeal { params: params, - registrar: registrar, builtins: builtins, } } @@ -49,7 +47,7 @@ impl Engine for InstantSeal { } fn additional_params(&self) -> HashMap { - hash_map!["registrar".to_owned() => self.registrar.hex()] + hash_map!["registrar".to_owned() => self.params().registrar.hex()] } fn builtins(&self) -> &BTreeMap { diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 453e8f9fb..1f3dbeb4e 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -71,12 +71,9 @@ pub type BlockHash = H256; /// Engine using `Tendermint` consensus algorithm, suitable for EVM chain. pub struct Tendermint { params: CommonParams, - gas_limit_bound_divisor: U256, builtins: BTreeMap, step_service: IoService, client: RwLock>>, - block_reward: U256, - registrar: Address, /// Blockchain height. height: AtomicUsize, /// Consensus view. @@ -166,12 +163,9 @@ impl Tendermint { let engine = Arc::new( Tendermint { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, client: RwLock::new(None), step_service: IoService::::start()?, - block_reward: our_params.block_reward, - registrar: our_params.registrar, height: AtomicUsize::new(1), view: AtomicUsize::new(0), step: RwLock::new(Step::Propose), @@ -446,7 +440,9 @@ impl Engine for Tendermint { fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.registrar.hex()] } + fn additional_params(&self) -> HashMap { + hash_map!["registrar".to_owned() => self.params().registrar.hex()] + } fn builtins(&self) -> &BTreeMap { &self.builtins } @@ -471,7 +467,7 @@ impl Engine for Tendermint { header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { @@ -545,7 +541,8 @@ impl Engine for Tendermint { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{ let fields = block.fields_mut(); // Bestow block reward - let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) + let reward = self.params().block_reward; + let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty) .map_err(::error::Error::from) .and_then(|_| fields.state.commit()); // Commit state so that we can actually figure out the state root. @@ -617,7 +614,7 @@ impl Engine for Tendermint { self.check_above_threshold(origins.len())? } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { diff --git a/ethcore/src/engines/tendermint/params.rs b/ethcore/src/engines/tendermint/params.rs index 16b47a0fb..7ff3d697f 100644 --- a/ethcore/src/engines/tendermint/params.rs +++ b/ethcore/src/engines/tendermint/params.rs @@ -17,7 +17,6 @@ //! Tendermint specific parameters. use ethjson; -use util::{U256, Address}; use time::Duration; use super::super::validator_set::{ValidatorSet, new_validator_set}; use super::super::transition::Timeouts; @@ -25,16 +24,10 @@ use super::Step; /// `Tendermint` params. pub struct TendermintParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// List of validators. pub validators: Box, /// Timeout durations for different steps. pub timeouts: TendermintTimeouts, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, } /// Base timeout of each step in ms. @@ -81,7 +74,6 @@ impl From for TendermintParams { fn from(p: ethjson::spec::TendermintParams) -> Self { let dt = TendermintTimeouts::default(); TendermintParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), validators: new_validator_set(p.validators), timeouts: TendermintTimeouts { propose: p.timeout_propose.map_or(dt.propose, to_duration), @@ -89,8 +81,6 @@ impl From for TendermintParams { precommit: p.timeout_precommit.map_or(dt.precommit, to_duration), commit: p.timeout_commit.map_or(dt.commit, to_duration), }, - block_reward: p.block_reward.map_or_else(U256::zero, Into::into), - registrar: p.registrar.map_or_else(Address::new, Into::into), } } } diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 1fbd711c9..ef6bb64cd 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -41,8 +41,6 @@ const SNAPSHOT_BLOCKS: u64 = 30000; /// Ethash params. #[derive(Debug, PartialEq)] pub struct EthashParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Minimum difficulty. pub minimum_difficulty: U256, /// Difficulty bound divisor. @@ -53,10 +51,6 @@ pub struct EthashParams { pub metropolis_difficulty_increment_divisor: u64, /// Block duration. pub duration_limit: u64, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, /// Homestead transition block number. pub homestead_transition: u64, /// DAO hard-fork transition block (X). @@ -75,8 +69,6 @@ pub struct EthashParams { pub eip100b_transition: u64, /// Number of first block where EIP-150 rules begin. pub eip150_transition: u64, - /// Number of first block where EIP-155 rules begin. - pub eip155_transition: u64, /// Number of first block where EIP-160 rules begin. pub eip160_transition: u64, /// Number of first block where EIP-161.abc begin. @@ -104,14 +96,11 @@ pub struct EthashParams { impl From for EthashParams { fn from(p: ethjson::spec::EthashParams) -> Self { EthashParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), minimum_difficulty: p.minimum_difficulty.into(), difficulty_bound_divisor: p.difficulty_bound_divisor.into(), difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into), metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into), duration_limit: p.duration_limit.map_or(0, Into::into), - block_reward: p.block_reward.into(), - registrar: p.registrar.map_or_else(Address::new, Into::into), homestead_transition: p.homestead_transition.map_or(0, Into::into), dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into), dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into), @@ -121,7 +110,6 @@ impl From for EthashParams { bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into), eip100b_transition: p.eip100b_transition.map_or(u64::max_value(), Into::into), eip150_transition: p.eip150_transition.map_or(0, Into::into), - eip155_transition: p.eip155_transition.map_or(0, Into::into), eip160_transition: p.eip160_transition.map_or(0, Into::into), eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into), eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into), @@ -185,7 +173,7 @@ impl Engine for Arc { fn seal_fields(&self) -> usize { 2 } fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.ethash_params.registrar.hex()] } + fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.params().registrar.hex()] } fn builtins(&self) -> &BTreeMap { &self.builtins @@ -216,7 +204,7 @@ impl Engine for Arc { } fn signing_network_id(&self, env_info: &EnvInfo) -> Option { - if env_info.number >= self.ethash_params.eip155_transition { + if env_info.number >= self.params().eip155_transition { Some(self.params().chain_id) } else { None @@ -231,7 +219,7 @@ impl Engine for Arc { } let gas_limit = { let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.ethash_params.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into(); let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into(); let gas_limit = if gas_limit < gas_floor_target { @@ -284,7 +272,7 @@ impl Engine for Arc { /// Apply the block reward on finalisation of the block. /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { - let reward = self.ethash_params.block_reward; + let reward = self.params().block_reward; let fields = block.fields_mut(); let eras_rounds = self.ethash_params.ecip1017_era_rounds; let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number()); @@ -387,7 +375,7 @@ impl Engine for Arc { if header.difficulty() != &expected_difficulty { return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() }))) } - let gas_limit_divisor = self.ethash_params.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let parent_gas_limit = *parent.gas_limit(); let min_gas = parent_gas_limit - parent_gas_limit / gas_limit_divisor; let max_gas = parent_gas_limit + parent_gas_limit / gas_limit_divisor; @@ -406,7 +394,7 @@ impl Engine for Arc { } let check_low_s = header.number() >= self.ethash_params.homestead_transition; - let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None }; + let network_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None }; t.verify_basic(check_low_s, network_id, false)?; Ok(()) } @@ -809,36 +797,32 @@ mod tests { #[test] fn has_valid_ecip1017_eras_block_reward() { - let ethparams = EthashParams { - // see ethcore/res/ethereum/classic.json - ecip1017_era_rounds: 5000000, - block_reward: U256::from_str("4563918244F40000").unwrap(), - ..get_default_ethash_params() - }; - let eras_rounds = ethparams.ecip1017_era_rounds; - let reward = ethparams.block_reward; + let eras_rounds = 5000000; + + let start_reward: U256 = "4563918244F40000".parse().unwrap(); + let block_number = 0; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(0, eras); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 5000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(0, eras); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 10000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(1, eras); assert_eq!(U256::from_str("3782DACE9D900000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 20000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(3, eras); assert_eq!(U256::from_str("2386F26FC1000000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 80000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(15, eras); assert_eq!(U256::from_str("271000000000000").unwrap(), reward); } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 80971355b..f193c4cf9 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1112,6 +1112,8 @@ impl MinerService for Miner { /// Prepare the block and work if the Engine does not seal internally. fn update_sealing(&self, chain: &MiningBlockChainClient) { trace!(target: "miner", "update_sealing"); + const NO_NEW_CHAIN_WITH_FORKS: &str = "Your chain specification contains one or more hard forks which are required to be \ + on by default. Please remove these forks and start your chain again."; if self.requires_reseal(chain.chain_info().best_block_number) { // -------------------------------------------------------------------------- @@ -1120,6 +1122,14 @@ impl MinerService for Miner { // -------------------------------------------------------------------------- trace!(target: "miner", "update_sealing: preparing a block"); let (block, original_work_hash) = self.prepare_block(chain); + + // refuse to seal the first block of the chain if it contains hard forks + // which should be on by default. + if block.block().fields().header.number() == 1 && self.engine.params().contains_bugfix_hard_fork() { + warn!("{}", NO_NEW_CHAIN_WITH_FORKS); + return; + } + match self.engine.seals_internally() { Some(true) => { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); @@ -1127,11 +1137,11 @@ impl MinerService for Miner { trace!(target: "miner", "update_sealing: imported internally sealed block"); } }, + Some(false) => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now"), None => { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); self.prepare_work(block, original_work_hash) }, - _ => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now") } } } diff --git a/ethcore/src/snapshot/tests/test_validator_contract.json b/ethcore/src/snapshot/tests/test_validator_contract.json index e2485fe82..b0aeb8785 100644 --- a/ethcore/src/snapshot/tests/test_validator_contract.json +++ b/ethcore/src/snapshot/tests/test_validator_contract.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 0, "validators": { @@ -17,6 +16,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 7d3900f2c..959793e4c 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -39,7 +39,12 @@ use trace::{NoopTracer, NoopVMTracer}; use evm::CallType; use util::*; -/// Parameters common to all engines. +/// Parameters common to ethereum-like blockchains. +/// NOTE: when adding bugfix hard-fork parameters, +/// add to `contains_bugfix_hard_fork` +/// +/// we define a "bugfix" hard fork as any hard fork which +/// you would put on-by-default in a new chain. #[derive(Debug, PartialEq, Default)] #[cfg_attr(test, derive(Clone))] pub struct CommonParams { @@ -59,8 +64,10 @@ pub struct CommonParams { pub fork_block: Option<(BlockNumber, H256)>, /// Number of first block where EIP-98 rules begin. pub eip98_transition: BlockNumber, + /// Number of first block where EIP-155 rules begin. + pub eip155_transition: BlockNumber, /// Validate block receipts root. - pub validate_receipts_transition: u64, + pub validate_receipts_transition: BlockNumber, /// Number of first block where EIP-86 (Metropolis) rules begin. pub eip86_transition: BlockNumber, /// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin. @@ -85,6 +92,12 @@ pub struct CommonParams { pub remove_dust_contracts: bool, /// Wasm support pub wasm: bool, + /// Gas limit bound divisor (how much gas limit can change per block) + pub gas_limit_bound_divisor: U256, + /// Block reward in wei. + pub block_reward: U256, + /// Registrar contract address. + pub registrar: Address, } impl CommonParams { @@ -111,6 +124,19 @@ impl CommonParams { }; } } + + /// Whether these params contain any bug-fix hard forks. + pub fn contains_bugfix_hard_fork(&self) -> bool { + self.eip98_transition != 0 && + self.eip155_transition != 0 && + self.validate_receipts_transition != 0 && + self.eip86_transition != 0 && + self.eip140_transition != 0 && + self.eip210_transition != 0 && + self.eip211_transition != 0 && + self.eip214_transition != 0 && + self.dust_protection_transition != 0 + } } impl From for CommonParams { @@ -124,6 +150,7 @@ impl From for CommonParams { min_gas_limit: p.min_gas_limit.into(), fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, eip98_transition: p.eip98_transition.map_or(0, Into::into), + eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), eip86_transition: p.eip86_transition.map_or(BlockNumber::max_value(), Into::into), eip140_transition: p.eip140_transition.map_or(BlockNumber::max_value(), Into::into), @@ -139,6 +166,9 @@ impl From for CommonParams { nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), wasm: p.wasm.unwrap_or(false), + gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), + block_reward: p.block_reward.map_or_else(U256::zero, Into::into), + registrar: p.registrar.map_or_else(Address::new, Into::into), } } } @@ -242,7 +272,7 @@ impl Spec { ) -> Arc { match engine_spec { ethjson::spec::Engine::Null => Arc::new(NullEngine::new(params, builtins)), - ethjson::spec::Engine::InstantSeal(instant) => Arc::new(InstantSeal::new(params, instant.params.registrar.map_or_else(Address::new, Into::into), builtins)), + ethjson::spec::Engine::InstantSeal => Arc::new(InstantSeal::new(params, builtins)), ethjson::spec::Engine::Ethash(ethash) => Arc::new(ethereum::Ethash::new(cache_dir, params, From::from(ethash.params), builtins)), ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(params, From::from(basic_authority.params), builtins)), ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(params, From::from(authority_round.params), builtins).expect("Failed to start AuthorityRound consensus engine."), diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index f8e412073..21dc16fa8 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -394,16 +394,13 @@ pub fn get_bad_state_dummy_block() -> Bytes { create_test_block(&block_header) } -pub fn get_default_ethash_params() -> EthashParams{ +pub fn get_default_ethash_params() -> EthashParams { EthashParams { - gas_limit_bound_divisor: U256::from(1024), minimum_difficulty: U256::from(131072), difficulty_bound_divisor: U256::from(2048), difficulty_increment_divisor: 10, metropolis_difficulty_increment_divisor: 9, duration_limit: 13, - block_reward: U256::from(0), - registrar: "0000000000000000000000000000000000000001".into(), homestead_transition: 1150000, dao_hardfork_transition: u64::max_value(), dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(), @@ -413,7 +410,6 @@ pub fn get_default_ethash_params() -> EthashParams{ bomb_defuse_transition: u64::max_value(), eip100b_transition: u64::max_value(), eip150_transition: u64::max_value(), - eip155_transition: u64::max_value(), eip160_transition: u64::max_value(), eip161abc_transition: u64::max_value(), eip161d_transition: u64::max_value(), diff --git a/json/Cargo.toml b/json/Cargo.toml index 81af58ac7..dbc365a1d 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -ethcore-util = { path = "../util" } +ethcore-bigint = { path = "../util/bigint" } rustc-hex = "1.0" serde = "1.0" serde_json = "1.0" diff --git a/json/src/hash.rs b/json/src/hash.rs index 64da93e1c..32c707d5b 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -21,7 +21,7 @@ use std::fmt; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::de::{Error, Visitor}; use rustc_hex::ToHex; -use util::hash::{H64 as Hash64, H160 as Hash160, H256 as Hash256, H520 as Hash520, H2048 as Hash2048}; +use bigint::hash::{H64 as Hash64, H160 as Hash160, H256 as Hash256, H520 as Hash520, H2048 as Hash2048}; macro_rules! impl_hash { @@ -99,7 +99,7 @@ impl_hash!(Bloom, Hash2048); mod test { use std::str::FromStr; use serde_json; - use util::hash; + use bigint::hash; use hash::H256; #[test] diff --git a/json/src/lib.rs b/json/src/lib.rs index c03b9f439..4af7384a0 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -17,7 +17,7 @@ extern crate rustc_hex; extern crate serde; extern crate serde_json; -extern crate ethcore_util as util; +extern crate ethcore_bigint as bigint; #[macro_use] extern crate serde_derive; pub mod hash; diff --git a/json/src/maybe.rs b/json/src/maybe.rs index 075aaefbd..b799b7ef6 100644 --- a/json/src/maybe.rs +++ b/json/src/maybe.rs @@ -68,7 +68,7 @@ impl Into> for MaybeEmpty { mod tests { use std::str::FromStr; use serde_json; - use util::hash; + use bigint::hash; use hash::H256; use maybe::MaybeEmpty; diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index 2c98fd3f1..32d5ec42d 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -50,7 +50,7 @@ mod tests { use std::collections::BTreeMap; use serde_json; use spec::account::Account; - use util::U256; + use bigint::prelude::U256; use uint::Uint; use bytes::Bytes; diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 0fdbfbfb3..2d7d64086 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -17,25 +17,16 @@ //! Authority params deserialization. use uint::Uint; -use hash::Address; use super::ValidatorSet; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct AuthorityRoundParams { - /// Gas limit divisor. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// Block duration. #[serde(rename="stepDuration")] pub step_duration: Uint, /// Valid authorities pub validators: ValidatorSet, - /// Block reward. - #[serde(rename="blockReward")] - pub block_reward: Option, - /// Address of the registrar contract. - pub registrar: Option
, /// Starting step. Determined automatically if not specified. /// To be used for testing only. #[serde(rename="startStep")] @@ -43,9 +34,6 @@ pub struct AuthorityRoundParams { /// Block at which score validation should start. #[serde(rename="validateScoreTransition")] pub validate_score_transition: Option, - /// See main AuthorityRoundParams docs. - #[serde(rename="eip155Transition")] - pub eip155_transition: Option, /// Block from which monotonic steps start. #[serde(rename="validateStepTransition")] pub validate_step_transition: Option, @@ -63,9 +51,8 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { + use bigint::prelude::{U256, H160}; use uint::Uint; - use util::U256; - use util::H160; use serde_json; use hash::Address; use spec::validator_set::ValidatorSet; @@ -75,26 +62,19 @@ mod tests { fn authority_round_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": "0x02", "validators": { "list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] }, - "blockReward": "0x50", "startStep" : 24, - "eip155Transition": "0x42", "validateStepTransition": 150 } }"#; let deserialized: AuthorityRound = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.gas_limit_bound_divisor, Uint(U256::from(0x0400))); assert_eq!(deserialized.params.step_duration, Uint(U256::from(0x02))); assert_eq!(deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))])); - assert_eq!(deserialized.params.block_reward, Some(Uint(U256::from(0x50)))); - assert!(deserialized.params.registrar.is_none()); assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24)))); - assert_eq!(deserialized.params.eip155_transition, Some(Uint(U256::from(0x42)))); assert_eq!(deserialized.params.immediate_transitions, None); } } diff --git a/json/src/spec/basic_authority.rs b/json/src/spec/basic_authority.rs index 01fe8f088..d8182a990 100644 --- a/json/src/spec/basic_authority.rs +++ b/json/src/spec/basic_authority.rs @@ -22,9 +22,6 @@ use super::ValidatorSet; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct BasicAuthorityParams { - /// Gas limit divisor. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// Block duration. #[serde(rename="durationLimit")] pub duration_limit: Uint, @@ -43,9 +40,8 @@ pub struct BasicAuthority { mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::{U256, H160}; use hash::Address; - use util::hash::H160; use spec::basic_authority::BasicAuthority; use spec::validator_set::ValidatorSet; @@ -53,7 +49,6 @@ mod tests { fn basic_authority_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators" : { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] @@ -63,7 +58,6 @@ mod tests { let deserialized: BasicAuthority = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.gas_limit_bound_divisor, Uint(U256::from(0x0400))); assert_eq!(deserialized.params.duration_limit, Uint(U256::from(0x0d))); let vs = ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]); assert_eq!(deserialized.params.validators, vs); diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index 5706b0680..8b487041e 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -16,7 +16,7 @@ //! Engine deserialization. -use super::{Ethash, InstantSeal, BasicAuthority, AuthorityRound, Tendermint}; +use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint}; /// Engine deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -26,7 +26,7 @@ pub enum Engine { Null, /// Instantly sealing engine. #[serde(rename="instantSeal")] - InstantSeal(InstantSeal), + InstantSeal, /// Ethash engine. Ethash(Ethash), /// BasicAuthority engine. @@ -55,23 +55,21 @@ mod tests { assert_eq!(Engine::Null, deserialized); let s = r#"{ - "instantSeal": { "params": {} } + "instantSeal": null }"#; let deserialized: Engine = serde_json::from_str(s).unwrap(); match deserialized { - Engine::InstantSeal(_) => {}, // instant seal is unit tested in its own file. + Engine::InstantSeal => {}, // instant seal is unit tested in its own file. _ => assert!(false), }; let s = r#"{ "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition" : "0x", "daoHardforkTransition": "0xffffffffffffffff", @@ -90,7 +88,6 @@ mod tests { let s = r#"{ "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators" : { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] @@ -107,14 +104,11 @@ mod tests { let s = r#"{ "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": "0x02", "validators": { "list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] }, - "blockReward": "0x50", "startStep" : 24, - "eip155Transition": "0x42", "validateStepTransition": 150 } } @@ -128,11 +122,9 @@ mod tests { let s = r#"{ "tendermint": { "params": { - "gasLimitBoundDivisor": "0x0400", "validators": { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] - }, - "blockReward": "0x50" + } } } }"#; diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index f3391e067..784a9d477 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -22,9 +22,6 @@ use hash::Address; /// Deserializable doppelganger of EthashParams. #[derive(Debug, PartialEq, Deserialize)] pub struct EthashParams { - /// See main EthashParams docs. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// See main EthashParams docs. #[serde(rename="minimumDifficulty")] pub minimum_difficulty: Uint, @@ -40,11 +37,6 @@ pub struct EthashParams { /// See main EthashParams docs. #[serde(rename="durationLimit")] pub duration_limit: Option, - /// See main EthashParams docs. - #[serde(rename="blockReward")] - pub block_reward: Uint, - /// See main EthashParams docs. - pub registrar: Option
, /// See main EthashParams docs. #[serde(rename="homesteadTransition")] @@ -78,10 +70,6 @@ pub struct EthashParams { #[serde(rename="eip150Transition")] pub eip150_transition: Option, - /// See main EthashParams docs. - #[serde(rename="eip155Transition")] - pub eip155_transition: Option, - /// See main EthashParams docs. #[serde(rename="eip160Transition")] pub eip160_transition: Option, @@ -136,21 +124,17 @@ pub struct Ethash { mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::{H160, U256}; use hash::Address; - use util::hash::H160; use spec::ethash::{Ethash, EthashParams}; #[test] fn ethash_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x42", "daoHardforkTransition": "0x08", "daoHardforkBeneficiary": "0xabcabcabcabcabcabcabcabcabcabcabcabcabca", @@ -181,7 +165,6 @@ mod tests { "bombDefuseTransition": "0x41", "eip100bTransition": "0x42", "eip150Transition": "0x43", - "eip155Transition": "0x44", "eip160Transition": "0x45", "eip161abcTransition": "0x46", "eip161dTransition": "0x47" @@ -190,16 +173,13 @@ mod tests { let deserialized: Ethash = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized, Ethash{ + assert_eq!(deserialized, Ethash { params: EthashParams{ - gas_limit_bound_divisor: Uint(U256::from(0x0400)), minimum_difficulty: Uint(U256::from(0x020000)), difficulty_bound_divisor: Uint(U256::from(0x0800)), difficulty_increment_divisor: None, metropolis_difficulty_increment_divisor: None, duration_limit: Some(Uint(U256::from(0x0d))), - block_reward: Uint(U256::from(0x4563918244F40000u64)), - registrar: Some(Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))), homestead_transition: Some(Uint(U256::from(0x42))), dao_hardfork_transition: Some(Uint(U256::from(0x08))), dao_hardfork_beneficiary: Some(Address(H160::from("0xabcabcabcabcabcabcabcabcabcabcabcabcabca"))), @@ -230,7 +210,6 @@ mod tests { bomb_defuse_transition: Some(Uint(U256::from(0x41))), eip100b_transition: Some(Uint(U256::from(0x42))), eip150_transition: Some(Uint(U256::from(0x43))), - eip155_transition: Some(Uint(U256::from(0x44))), eip160_transition: Some(Uint(U256::from(0x45))), eip161abc_transition: Some(Uint(U256::from(0x46))), eip161d_transition: Some(Uint(U256::from(0x47))), @@ -250,24 +229,19 @@ mod tests { fn ethash_deserialization_missing_optionals() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", - "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", - "blockReward": "0x4563918244F40000" + "minimumDifficulty": "0x020000" } }"#; let deserialized: Ethash = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized, Ethash{ - params: EthashParams{ - gas_limit_bound_divisor: Uint(U256::from(0x0400)), + assert_eq!(deserialized, Ethash { + params: EthashParams { minimum_difficulty: Uint(U256::from(0x020000)), difficulty_bound_divisor: Uint(U256::from(0x0800)), difficulty_increment_divisor: None, metropolis_difficulty_increment_divisor: None, duration_limit: None, - block_reward: Uint(U256::from(0x4563918244F40000u64)), - registrar: None, homestead_transition: None, dao_hardfork_transition: None, dao_hardfork_beneficiary: None, @@ -277,7 +251,6 @@ mod tests { bomb_defuse_transition: None, eip100b_transition: None, eip150_transition: None, - eip155_transition: None, eip160_transition: None, eip161abc_transition: None, eip161d_transition: None, diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index 120df4fc1..98bc75c69 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -60,10 +60,8 @@ mod tests { use serde_json; use bytes::Bytes; use uint::Uint; - use util::U256; + use bigint::prelude::{U256, H160, H64 as Eth64, H256 as Eth256}; use hash::{H64, H256, Address}; - use util::hash::H160; - use util::{H64 as Eth64, H256 as Eth256}; use spec::genesis::Genesis; use spec::{Ethereum, Seal}; use std::str::FromStr; diff --git a/json/src/spec/instant_seal.rs b/json/src/spec/instant_seal.rs deleted file mode 100644 index ebf167d28..000000000 --- a/json/src/spec/instant_seal.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Instant params deserialization. - -use hash::Address; - -/// Instant params deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct InstantSealParams { - /// Address of the registrar contract. - pub registrar: Option
, -} - -/// Instant engine deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct InstantSeal { - /// Instant Seal params. - pub params: InstantSealParams, -} - -#[cfg(test)] -mod tests { - use serde_json; - use hash::Address; - use util::hash::H160; - use spec::instant_seal::InstantSeal; - - #[test] - fn instant_seal_deserialization() { - let s = r#"{ - "params": { - "registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b" - } - }"#; - - let deserialized: InstantSeal = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.registrar, Some(Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b")))); - } -} diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs index 63c26a010..bc7e751af 100644 --- a/json/src/spec/mod.rs +++ b/json/src/spec/mod.rs @@ -26,7 +26,6 @@ pub mod engine; pub mod state; pub mod ethash; pub mod validator_set; -pub mod instant_seal; pub mod basic_authority; pub mod authority_round; pub mod tendermint; @@ -41,7 +40,6 @@ pub use self::engine::Engine; pub use self::state::State; pub use self::ethash::{Ethash, EthashParams}; pub use self::validator_set::ValidatorSet; -pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams}; pub use self::authority_round::{AuthorityRound, AuthorityRoundParams}; pub use self::tendermint::{Tendermint, TendermintParams}; diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 0c0b1b01e..d72ead89a 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -55,6 +55,9 @@ pub struct Params { #[serde(rename="eip98Transition")] pub eip98_transition: Option, /// See `CommonParams` docs. + #[serde(rename="eip155Transition")] + pub eip155_transition: Option, + /// See `CommonParams` docs. #[serde(rename="validateReceiptsTransition")] pub validate_receipts_transition: Option, /// See `CommonParams` docs. @@ -91,13 +94,21 @@ pub struct Params { pub remove_dust_contracts : Option, /// Wasm support flag pub wasm: Option, + /// See `CommonParams` docs. + #[serde(rename="gasLimitBoundDivisor")] + pub gas_limit_bound_divisor: Uint, + /// See `CommonParams` docs. + #[serde(rename="blockReward")] + pub block_reward: Option, + /// See `CommonParams` docs. + pub registrar: Option
, } #[cfg(test)] mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::U256; use spec::params::Params; #[test] @@ -108,7 +119,8 @@ mod tests { "chainID" : "0x15", "subprotocolName" : "exp", "minGasLimit": "0x1388", - "accountStartNonce": "0x01" + "accountStartNonce": "0x01", + "gasLimitBoundDivisor": "0x20" }"#; let deserialized: Params = serde_json::from_str(s).unwrap(); @@ -118,5 +130,6 @@ mod tests { assert_eq!(deserialized.subprotocol_name, Some("exp".to_owned())); assert_eq!(deserialized.min_gas_limit, Uint(U256::from(0x1388))); assert_eq!(deserialized.account_start_nonce, Some(Uint(U256::from(0x01)))); + assert_eq!(deserialized.gas_limit_bound_divisor, Uint(U256::from(0x20))); } } diff --git a/json/src/spec/seal.rs b/json/src/spec/seal.rs index 7345a623d..a428a0957 100644 --- a/json/src/spec/seal.rs +++ b/json/src/spec/seal.rs @@ -73,8 +73,7 @@ mod tests { use hash::*; use bytes::Bytes; use uint::Uint; - use util::U256; - use util::{H64 as Eth64, H256 as Eth256, H520 as Eth520}; + use bigint::prelude::{U256, H64 as Eth64, H256 as Eth256, H520 as Eth520}; use spec::{Ethereum, AuthorityRoundSeal, TendermintSeal, Seal}; #[test] diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index b4b73d9d0..6aa419b18 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -61,12 +61,9 @@ mod tests { "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition" : "0x", "daoHardforkTransition": "0xffffffffffffffff", "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", @@ -81,7 +78,8 @@ mod tests { "minGasLimit": "0x1388", "networkID" : "0x2", "forkBlock": "0xffffffffffffffff", - "forkCanonHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + "forkCanonHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimitBoundDivisor": "0x20" }, "genesis": { "seal": { diff --git a/json/src/spec/tendermint.rs b/json/src/spec/tendermint.rs index 5a15a0841..f5a178d50 100644 --- a/json/src/spec/tendermint.rs +++ b/json/src/spec/tendermint.rs @@ -17,15 +17,11 @@ //! Tendermint params deserialization. use uint::Uint; -use hash::Address; use super::ValidatorSet; /// Tendermint params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct TendermintParams { - /// Gas limit divisor. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// Valid validators. pub validators: ValidatorSet, /// Propose step timeout in milliseconds. @@ -40,11 +36,6 @@ pub struct TendermintParams { /// Commit step timeout in milliseconds. #[serde(rename="timeoutCommit")] pub timeout_commit: Option, - /// Block reward. - #[serde(rename="blockReward")] - pub block_reward: Option, - /// Address of the registrar contract. - pub registrar: Option
, } /// Tendermint engine deserialization. @@ -57,10 +48,7 @@ pub struct Tendermint { #[cfg(test)] mod tests { use serde_json; - use uint::Uint; - use util::U256; - use hash::Address; - use util::hash::H160; + use bigint::prelude::H160; use spec::tendermint::Tendermint; use spec::validator_set::ValidatorSet; @@ -68,18 +56,14 @@ mod tests { fn tendermint_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "validators": { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] - }, - "blockReward": "0x50" + } } }"#; let deserialized: Tendermint = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.gas_limit_bound_divisor, Uint(U256::from(0x0400))); let vs = ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]); assert_eq!(deserialized.params.validators, vs); - assert_eq!(deserialized.params.block_reward, Some(Uint(U256::from(0x50)))); } } diff --git a/json/src/spec/validator_set.rs b/json/src/spec/validator_set.rs index abcb35848..3526bed93 100644 --- a/json/src/spec/validator_set.rs +++ b/json/src/spec/validator_set.rs @@ -41,9 +41,8 @@ pub enum ValidatorSet { mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::{H160, U256}; use hash::Address; - use util::hash::H160; use spec::validator_set::ValidatorSet; #[test] diff --git a/json/src/uint.rs b/json/src/uint.rs index 5e98a9dca..b6962c762 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -20,7 +20,7 @@ use std::fmt; use std::str::FromStr; use serde::{Deserialize, Deserializer}; use serde::de::{Error, Visitor}; -use util::U256; +use bigint::prelude::U256; /// Lenient uint json deserialization for test json files. #[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] @@ -93,7 +93,7 @@ impl<'a> Visitor<'a> for UintVisitor { #[cfg(test)] mod test { use serde_json; - use util::U256; + use bigint::prelude::U256; use uint::Uint; #[test] diff --git a/json/src/vm/call.rs b/json/src/vm/call.rs index 711d7b538..14e067f5f 100644 --- a/json/src/vm/call.rs +++ b/json/src/vm/call.rs @@ -39,7 +39,7 @@ pub struct Call { mod tests { use serde_json; use vm::Call; - use util::{U256, H160 as Hash160}; + use bigint::prelude::{U256, H160 as Hash160}; use uint::Uint; use hash::Address; use maybe::MaybeEmpty; diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 7cd146082..cbbfa8dc0 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -227,12 +227,9 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0xffffffffffffffff", "daoHardforkTransition": "0xffffffffffffffff", "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", @@ -241,6 +238,9 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x50000", @@ -275,12 +275,9 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0xffffffffffffffff", "daoHardforkTransition": "0xffffffffffffffff", "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", @@ -289,6 +286,9 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x0100", "maximumExtraDataSize": "0x20", "minGasLimit": "0x50000", From fe6bdc870c150a708253a2338d29e8605c1514be Mon Sep 17 00:00:00 2001 From: fro Date: Mon, 31 Jul 2017 16:54:26 +0300 Subject: [PATCH 29/48] realloc test contract submodule update --- ethcore/res/wasm-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index 9ed630431..04c9d84c5 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit 9ed6304313fa949ed92aa0570fb2bc759fb6dc58 +Subproject commit 04c9d84c5fe5c3ad707be58664c7e72b97cc9996 From 2ca4adb62cf605830f35ee89c0b42205bd98a3b5 Mon Sep 17 00:00:00 2001 From: maciejhirsz Date: Mon, 31 Jul 2017 17:51:23 +0200 Subject: [PATCH 30/48] Re-enable wallets, fixed forgetting accounts --- js/src/api/local/accounts/account.js | 4 ++++ js/src/api/local/accounts/accounts.js | 6 ++++++ js/src/api/local/localAccountsMiddleware.js | 4 ++++ js/src/views/Accounts/accounts.js | 4 ---- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/js/src/api/local/accounts/account.js b/js/src/api/local/accounts/account.js index 0bb069c8b..224a05cd9 100644 --- a/js/src/api/local/accounts/account.js +++ b/js/src/api/local/accounts/account.js @@ -31,6 +31,10 @@ export default class Account { } isValidPassword (password) { + if (!this._keyObject) { + return false; + } + return decryptPrivateKey(this._keyObject, password) .then((privateKey) => { if (!privateKey) { diff --git a/js/src/api/local/accounts/accounts.js b/js/src/api/local/accounts/accounts.js index 823ab3624..d11ea2bad 100644 --- a/js/src/api/local/accounts/accounts.js +++ b/js/src/api/local/accounts/accounts.js @@ -168,6 +168,12 @@ export default class Accounts { return false; } + if (!account.uuid) { + this.removeUnsafe(address); + + return true; + } + return account .isValidPassword(password) .then((isValid) => { diff --git a/js/src/api/local/localAccountsMiddleware.js b/js/src/api/local/localAccountsMiddleware.js index c8e767f89..c452f541a 100644 --- a/js/src/api/local/localAccountsMiddleware.js +++ b/js/src/api/local/localAccountsMiddleware.js @@ -206,6 +206,10 @@ export default class LocalAccountsMiddleware extends Middleware { return accounts.remove(address, password); }); + register('parity_removeAddress', ([address]) => { + return accounts.remove(address, null); + }); + register('parity_testPassword', ([address, password]) => { const account = accounts.get(address); diff --git a/js/src/views/Accounts/accounts.js b/js/src/views/Accounts/accounts.js index 2d37b7a4b..c8828cff6 100644 --- a/js/src/views/Accounts/accounts.js +++ b/js/src/views/Accounts/accounts.js @@ -373,10 +373,6 @@ class Accounts extends Component { } renderNewWalletButton () { - if (this.props.availability !== 'personal') { - return null; - } - return (